Yes, GHKs on GKC buttons only work when the window is open, so I also find, at least in recent versions of Vassal.
It looks to me like the solution for a Hotkey that must execute even if a window is closed is to define it on the main toolbar (module level or attached main window). An associated GKC button in a subsidiary window will still be possible. The ultimate action should be coded on a common piece, that both the GKC Hotkey and any other GKCs can direct to.
Actually, let me modify that; I have one situation where a Hotkey seems to work when a window is closed; the reshuffle Deck hotkey, where the deck is in another window. This might be a special case though - I have the impression that Decks are a global component not actually tied logically to the windows on which they sit.
each of them contains a deck (Deck1 and Deck2) with the same (few) cards, just for the demo;
both decks have shuffling set to be on a hotkey, which is shuffleDeck1 and shuffleDeck2, respectively;
each of Map 1 and Map 2 have a map level global key command, called Shuffler1 and Shuffler2, which one can press to shuffle the deck in the given window;
the above work by calling a piece called Shuffler in the same window, which has a global hotkey issuing shuffleDeck1 and shuffleDeck2, respectively (NOTE: just having Shuffler1 and Shuffler2 issue shuffleDeck1 or shuffleDeck2 wouldn’t work);
now to the thorny part… Map 1 has 3 different map level GKCs, called Method 1, Method 2 and Method 3, all aimed at shuffling both decks with a single command (yes, I could have used the same hotkey on the decks to achieve this - as marktb1961 hints to - but this is not the issue here, because I still want to be able to shuffle them indipendently when needed);
Method 1 calls a piece on Map 1 called Customer which issues a global hotkey to both Shuffler1 (in the same window) and Shuffler2 (which is in the other window) THIS SHUFFLES THE DECK ON MAP 2 ONLY IF THAT MAP IS OPEN AT THE SAME TIME
8 ) Method 2 calls the same Customer piece to issue a global hotkey to Shuffler1 (as above) and then ask a piece called Middleman on Map 2 (via a GKC) to issue the global hotkey to Invoke Shuffler 2 himself AGAIN THIS SHUFFLES THE DECK ON MAP 2 ONLY IF THAT MAP IS OPEN AT THE SAME TIME
Method 3 is the only one working, because Middleman is asked to call the Shuffler on Map 2 himself (via a GKC), bypassing the Shuffler2 hotkey THIS ONE WORKS EVEN IF MAP 2 IS CLOSED
I was able to make “Method 1” work by changing the Global Hotkey called by “Customer” to “shuffleDeck2” – so the Customer just talks directly to the deck (from a piece). Similarly the GKC Button on the first map could also talk directly to “MiddleMan” (the piece on the other map) if you wanted it to.
The thing that won’t work is “Talking to a button on a toolbar of a window that is not currently open”. Because something in the way the Java KeyListeners are implemented doesn’t like that and won’t let them “hear hotkeys” when the window whose toolbar they are on is not visible.
So, to talk to a Deck on another map, I suggest always doing it through a piece, and NEVER through “another toolbar button button” (i.e. never through a second GKC component that you just add directly to a map rather than to a piece on the map).
The DECK is apparently (or as far as I can tell from all the test cases in the module) always allowed to hear its hotkeys, it is “buttons on the toolbar of a hidden window” that cannot hear their hotkeys.
Not quite right – global hotkeys will correctly talk directly to Decks on other maps (even if the map windows are currently not available). What will not work is talking to anything that has a theoretical button presence on the toolbar, while the window the toolbar is on isn’t visible (so e.g. Global Key Commands or Global Property setters that you add directly to the map as opposed to adding to a piece)
Possibly the following would be useful? A “MapName_isVisible” property to be “true” or “false” depending on whether map window is currently visible?
I set it up so that if the map’s name is “Map With Spaces” then you can either use “Map_With_Spaces_isVisible” or “Map With Spaces.isVisible” to read the property. Since in some contexts spaces create extra challenges.
That would be nice, yes. So that one can force opening the window, in case it’s not open, and then close it again. Ideally the player pushing the button won’t see anything. Or perhaps he/she would see a disturbing flash of something appearing and disappearing, hmm. Worth testing and having the option, thanks.
I think I must be missing something here. Why would I open a window, programmatically press a toolbar button, and then close the window? Why not just do what the button does directly via a proxy piece? Yes, you can check to see if your screen “blinks” when you open and close a window quickly, but that only tests your computer and not the hundreds of others out there. It seems to me this is a solution looking for a problem.
Here is another (or an additional) way forward – for 3.6 we could have a Global Option that allowed the designer to turn on “accepting Global Hotkeys in closed map windows” as a module-level option. So that would avoid the breaking-old-modules problem because it would be something the designer explicitly turned on and therefore “signed up for”.
Those interested (e.g. barbanera) please go to vassalengine.org/builds/ and try out the build marked “14283”. It seems to work with barbanera’s example module, but please try it out with others (BUT I recommend making a separate save of your module for this purpose, because this feature will not be available until 3.6 in order to maintain proper backwards-compatibility standards, so that could be a month or two – although we don’t have a packed schedule for 3.6 it will likely be small, it can’t happen until the 3.5 line is judged to be very-very-stable and not likely to need another patch). Anyway please DO try and give feedback.
The ability to check if a window is open still seems useful to me in some contexts (e.g. open Window-X if it isn’t currently open), but this alternative solution should more closely address the key problem.
My reason for raising this issue was a) because of the inconsistent behaviour with hotkeys firing on open windows and not on closed windows (either both or none?) or firing anyway (hotkeys aimed at decks) - contrast that with GKCs which instead fire on all pieces wherever they are (with an option to fire only on the current map) and b) the (perceived?) overhead of having to duplicate commands/traits when you are forced to call a middleman piece - or several middleman pieces if you are doing a sequence of tasks - on the closed windows, instead of a single (multi) toolbar button already designed to do that.
Cattlesquat, will give build 14283 a try today, sorry was away these past few days. Your new way forward seems pretty nice, but I wonder if it would not be possible to make that a global hotkey option, rather than a module-level one. Just like one has on GKCs. Something like “Allow running on any map, even if closed”. That would allow more fine tuning options to module designers. BTW, yes, please leave the ability to check if a window is open in, that might be very useful.
Cattlesquat, I tried build 14283 with the module I was developing, going back to the hotkeys (=method1) in place of using GKCs+Middleman (=method3).
First of all, I tried with 3.5.3, just to make sure, and the hotkey fires on open windows only.
Then I tried with your build 14283, without touching the global options, and the hotkey does NOT fire even on open windows now.
I also tried switching your new global option to “ALWAYS” but with the same result. Basically hotkeys to other windows are ignored with 14283, be their window open or not.
My only hint is that the other window where this hotkey is located is in an extension, not the main module. If that can help. I agree that the test module works, instead (but no extension involved there). Thanks.