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

[win32] Standard shortcuts stop working in input widgets #2976

Closed
crackedmind opened this issue Jan 11, 2020 · 4 comments
Closed

[win32] Standard shortcuts stop working in input widgets #2976

crackedmind opened this issue Jan 11, 2020 · 4 comments

Comments

@crackedmind
Copy link

crackedmind commented Jan 11, 2020

Version/Branch of Dear ImGui:

Version: 1.75 WIP (17401)
Branch: master and docking

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_sdl.cpp and imgui_impl_glfw.cpp
Operating System: Windows 10 1909

My Issue/Question:
Standard ctrl based hotkeys for input widgets stop working after using some windows/keysuper system shortcuts like win+space (change input language) and win+v (clipboard history, appeared in Windows 10 1809). It stops working until window reactivation.

Problem is here:

io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER];

io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);

And when we pressed: win-space, then ctrl-z. we got is_shortcut_key == false, because io.KeySuper ==1 and io.KeyCtrl also equals to 1.

const bool is_shortcut_key = (is_osx ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl

I don't know why KeySuper state not clears after KEYUP event. As workaround i use #ifndef _WIN32 guard

In pure win32 backend io.KeySuper always sets to false.

io.KeySuper = false;

Standalone, minimal, complete and verifiable example:
Just open Demo window in default sdl/glfw examples and go to Multi-line text widget example.

@ocornut
Copy link
Owner

ocornut commented Jan 11, 2020

Thank you for the report. This is the first time I use Win+V I didn't even know this feature existed.

So it looks like there are multiple issues at end:

(1) Investigate why SDL and GLFW don't correctly report when the Super/GUI key is released. I tested with GLFW and confirmed that KeySuper was stuck after releasing it after a Win+V.

In this screenshot the Win+V ui is open, and the Windows key has been released already and it's still reported as pressed: (note that text appearing in the OS UI on the top-right is just my clipboard history!).

Image1

This is essentially similar to #2062 in essence.

(2) Investigate if we could expose the Super key in imgui_impl_win32.cpp, when I looked it wasn't obvious to me how to read that key.


My intuition is the following:

  • The "Windows key" is not really properly usable for user applications under Win32, and because of this neither SDL nor GLFW have worked out nice workarounds to catch when it has been released.
  • Maybe we easily prove that both SDL and GLFW have a bug and possibly aim to report and fix it there.
  • If that's the case, since this is a key that's difficult to even access/use under Windos, my suggested answer for both 1 and 2 is simply to not forward the key in the SDL and GLFW backup when running on Windows (so simply #ifdef that section out of both back-ends).

In fact that later option we should apply right now, since that's the immediate best fix we have, while we investigate SDL/GLFW further.

@rokups
Copy link
Contributor

rokups commented Jan 13, 2020

Reason for this happening is that WM_KEYUP is not sent for Super keys upon release in some cases. This explains why both GLFW and SDL have same issue - it is win32 problem. Both libraries would require a workaround for this quirk. This conclusion is based on testing win32_dx11 example.

A workaround:

    io.KeysDown[VK_LWIN] &= (::GetKeyState(VK_LWIN) & 0x8000) != 0;
    io.KeysDown[VK_RWIN] &= (::GetKeyState(VK_RWIN) & 0x8000) != 0;
    io.KeySuper = io.KeysDown[VK_LWIN] || io.KeysDown[VK_RWIN];

This clears keys in stuck state manually. Bonus: it also implements Super modifier.

Problem is actually deeper than this. Turns out any key will get stuck in a pressed key state because win32 does not send WM_KEYUP to unfocused window. It is unclear what the right solution is here.


Reported bugs:

rokups added a commit to rokups/imgui that referenced this issue Jan 13, 2020
… cases. Fixes ocornut#2976.

Issue can be observed if we press WinKey+v when win32/SDL/GLFW window is focused. Application would get stuck in a state thinking WinKey is pressed even after it was released.
rokups added a commit to rokups/imgui that referenced this issue Jan 13, 2020
… cases. Fixes ocornut#2976.

Issue can be observed if we press WinKey+v when win32/SDL/GLFW window is focused. Application would get stuck in a state thinking WinKey is pressed even after it was released.
@rokups
Copy link
Contributor

rokups commented Jan 16, 2020

This will be fixed in next GLFW release.

@ocornut
Copy link
Owner

ocornut commented Jan 17, 2020

Closing this as a non-dear imgui issue, reported to GLFW and SDL and fixed in GLFW. Thanks Stanislav and Rokups.

@ocornut ocornut closed this as completed Jan 17, 2020
ocornut added a commit that referenced this issue Jan 17, 2020
…istency with other backends. (#2976)

Even if realistically it is difficult to make good use of under Windows.
+ Style editor: Use a more explicit form of RadioButton() to avoid being depending on underlying flags type. (#2983)
ocornut added a commit that referenced this issue Jan 17, 2020
…sed.

Neither GLFW nor SDL can correctly report the key release in every cases (e.g. when using Win+V) causing problems with some widgets. The next release of GLFW (3.4+) will have a fix for it. However since it is both difficult and discouraged to make use of this key for Windows application anyway, we just hide it. (#2976)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants