Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alt-Tabbing keeps the io.KeysDown[sf::Keyboard::Tab] to true #88

Open
Epholys opened this issue Jun 2, 2019 · 13 comments
Open

Alt-Tabbing keeps the io.KeysDown[sf::Keyboard::Tab] to true #88

Epholys opened this issue Jun 2, 2019 · 13 comments
Labels

Comments

@Epholys
Copy link
Contributor

Epholys commented Jun 2, 2019

Hello!

I found that, when alt-tabbing to another window, the io.KeysDown[sf::Keyboard::LAlt] stays true. It's because, in ProcessEvent(), the events are not processed when the window loses focus. As a consequence, for example, it is impossible to open/close CollapsingHeader when going back to the SFML window after alt-tabbing, as "Alt" is considered pressed.

An easy hack is possible, but I think a proper fix could be developed. I don't know how you would prefer to implement it, so I open this issue instead of a pull request.

Thank you for this project!

Cheers

@eliasdaler eliasdaler added the bug label Jun 3, 2019
@eliasdaler
Copy link
Contributor

Hello. Yes, I'll try to fix it, but let's talk about what should happen.
I think that when window loses the focus, all members of io.KeyDown should become false. Then, when window has focus restored, I'll poll the state of all relevant keys, so that I get "now" state of keyboard right.

I think I'll also poll keyboard state at startup, so if you start your program with some keyboard key already pressed, ImGui-SFML will register that.

@Epholys
Copy link
Contributor Author

Epholys commented Jun 3, 2019

I think that's a good idea! But there's maybe some other inputs to take care of, like joysticks or controllers.

And there's something I just thought off and that seems strange: when alt-tabbing back to the SFML window, there is the event "GainedFocus". So the "KeyReleased" of "Alt" should be registered and "KeysDown" set to false. But that's not the case. Maybe there's something not so obvious with the SFML event polling and/or the OS platform. I'm using Ubuntu with Gnome. Maybe it will have an influence on the fix.

@eliasdaler
Copy link
Contributor

Can you please test how ImGui's example OpenGL or SDL binding behave?
Looking at them, I don't see how they handle this.
Maybe they handle all keydown/keyup events even if you don't have window active?

@eliasdaler
Copy link
Contributor

I think that I can make ImGui-SFML handle all events regardless of window being focused.
This way, it'll be up to user to decide if they want this or not - e.g. just not call ImGui::SFML::ProcessEvent when window has lost its focus.

@Epholys
Copy link
Contributor Author

Epholys commented Jun 3, 2019

I can't test it right now, we'll have to wait a little. I quickly looked at them, I think you're right, they do not care if the window is focused or not... but it's maybe because there are just very simple examples.

I think that's a good idea, it'll probably remove this bug and probably other related unknown ones. And it could be a little more future-proof with the docking-and-more features of a next imgui release.

@DaveInDev
Copy link

DaveInDev commented Jun 13, 2020

Hi there, I just noticed that I have the same problem after ALT-ESC or ALT-TAB to others apps in windows 10. When returning to my app, io.KeyAlt remains set to true, and I cannot manage setting it back to false.... Seems that the io.KeyDown corresponding members remains on... Is there a workaround/solution to this problem ?

(Note that if I do not call ImGui::SFML::ProcessEvent when window has lost its focus, the problem is still here.)

@eliasdaler
Copy link
Contributor

Hello
Can you please comment out this "if" statement and see if it fixes the problem?
https://github.com/eliasdaler/imgui-sfml/blob/master/imgui-SFML.cpp#L289

@Epholys
Copy link
Contributor Author

Epholys commented Jun 13, 2020

Hello,

For my app, commenting this line doesn't fix this problem. I made a little hack a while ago to elude this issue: I added a line to reset the Alt key state: `

void ProcessEvent(const sf::Event& event) {

    // [CUT]

    switch (event.type) {
        case sf::Event::LostFocus:
            s_windowHasFocus = false;
            ImGui::GetIO().KeysDown[sf::Keyboard::LAlt] = false; // <=== THIS LINE
            break;
        case sf::Event::GainedFocus:
            s_windowHasFocus = true;
            break;
        default:
            break;
    }
}

It's just a band-aid, but for my case it works.

I investigated a bit further (sorry, I completely forgot to test with other backend the last time :( ), and it seems SFML has chosen to ignore an event if it doesn't come from the SFML window (which is reasonable).

The internal interface call processEvents() to poll the event from the OS. For Linux, in WindowImplX11.cpp, it calls XCheckIfEvent(...) (docs) with a callback to checkEvent(...) (here) where a comment states: Just check if the event matches the window.

For Windows, in (WindowImplWin32.cpp), a comment says: We process the window events only if we own it, which could be done by PeekMessageW(&message, NULL, 0, 0, PM_REMOVE), the NULL argument indicates that the message is retrieved only for the window in the current thread (documentation).

So it's logic that the ALT key is considered pressed when changing windows. And it's also logic that it doesn't un-pressed itself when alt-tabbing to go back (at least on Gnome), as the SFML window gain focus just after the ALT key is un-pressed.

Last thing: with this bug, I can simply press ALT to reset the state and everything go back to normal. But it doesn't seems to be so for @DaveInDev ?

@DaveInDev
Copy link

DaveInDev commented Jun 13, 2020

@Epholys thx again for your useful answer.

I used
for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) io.KeysDown[i] = false;

so that combination like CTRL+SHIFT+ESC or WINDOWS-KEY combinations that steal the focus, also reset at reentrance.

@Epholys
Copy link
Contributor Author

Epholys commented Jun 13, 2020

Okay, I spent a little more time one this: I tested the default demo app of imgui for SDL and glfw (example_sdl_opengl3 and example_glfw_opengl3) precisely, still on Linux (Gnome). Both of them have correct behavior concerning alt-tabbing, with really straightforward use of their respective backend API.

So I looked into SDL code to see what's happening inside, and it takes actually care of our case of alt-tabbing: when focusing in a window, it calls (for Linux) X11_ReconcileKeyboardState which seems to sync the keyboard to the internal SDL state.

So the fix could also be in SFML, but I don't know if our use case is too much of a niche to do so.

@DaveInDev
Copy link

So do you mean that we should ask the SFML developper to handle this ? I can write an issue on the SFML forum, if you do not have time.

@Epholys
Copy link
Contributor Author

Epholys commented Jun 14, 2020

Well, it's debatable I think. From a point of view SFML really doesn't do anything wrong: it simply forwards OS' events. But for our case the 'Alt' key has only an associated KeyPressed event and not a KeyReleased after, is that ok? It can absolutely be. The gist of the issue is that this behavior breaks code that has a internal state about the pressed keys, like imgui does.

Anyway, I think @eliasdaler has the final say!

@eliasdaler
Copy link
Contributor

Looking back into it - I think that the correct way to do things is to do what other implementations of backends for Dear ImGui do - just not handle FocusLost/FocusGained events and leave it up to user. This way, such problems won't be present and we'll be consistent with other impls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants