This is something else I want to clean up after the mouse capture anomalies are fixed. We have made a total mess of handling the focus gain and lost events across different platforms, and seemingly performing the same redundant code. The origin of this had to deal with freezing on focus lost setting and clearing of the input state on focus lost. This can be tested in GM8.1 with ALT+TAB and I can confirm that GM always seems to clear the state of input when losing focus regardless of whether the freeze setting is enabled.
What we need to do is extract a common helper method that performs the generalized logic we want focus gain and lost events to apply. I also want to research how this is handled in other game engines and test GMS.
We can see Windows just has the original duplicate code and has literally inlined what our general
input_initialize method does.
SDL was only handling the freeze setting.
xlib is repeating the same as Windows, except not fully handling focus lost clearing of the input?
It doesn't look like Cocoa handles focus at all.
WM_SETFOCUSwrong somehow. With GM8.1 and GMSv1.4, although switching to another window with ALT+TAB clears the down state, if we leave the button held and switch back to the window to release, we should still see the mouse flash a release on the right of the first line. ENIGMA does not pick up this mouse release at all.
Another anomaly though is if we press the mouse in GM8.1, hold it and ALT+TAB, release the mouse and repress it, ALT+TAB back to the game, then release, then it will not be picked up by GM. That suggests GM8.1 is somehow remembering the mouse press started in its window.
I think what we are doing wrong is clearing the previous state when we don't need to be. I may need to expand my unit test to really be sure.
I've discovered that the infamous imgui is working on a fix to make it do what ENIGMA does on Windows or whatever.
Thanks to CMU, I also found that some Disney Panda 3D Software will actually poll the keyboard state on focus lost.
00958 case WM_KILLFOCUS: 00959 // Record the current state of the keyboard when the focus is 00960 // lost, so we can check it for changes when we regain focus. 00961 GetKeyboardState(_keyboard_state); 00962 break;
Processing the input on focus lost is also something I see some other GitHub projects doing.
case WM_SETFOCUS: if (is_session_ready()) this->process_input(key_focus); goto defproc; case WM_KILLFOCUS: this->cancel_ime_composition(); this->process_input(key_blur); goto defproc;
It seems DOSBox likes to do this as well.
04863 /* Window has lost focus, pause the emulator. 04864 * This is similar to what PauseDOSBox() does, but the exit criteria is different. 04865 * Instead of waiting for the user to hit Alt-Break, we wait for the window to 04866 * regain window or input focus. 04867 */ 04868 bool paused = true; 04869 SDL_Event ev; 04870 04871 GFX_SetTitle(-1,-1,-1,true); 04872 KEYBOARD_ClrBuffer();