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

Not able to enter characters in InputText on german keyboard for which AltGr is needed as modifier #370

Closed
richardkogelnig opened this issue Oct 11, 2015 · 19 comments

Comments

@richardkogelnig
Copy link
Contributor

On german keyboards the user can't enter chars which use AltGr as a modifier (e.g '{' '[' ']' '}' '' ) because of:
“Alt Gr” on german (and other) keyboards – “Alt Gr” is not the same as right-hand “Alt” on US keyboards, it essentially is a short-cut for “Control” and right-hand “Alt”. (from http://blog.molecular-matters.com/2011/09/05/properly-handling-keyboard-input/)

With the existing code all chars are suppressed when CTRL-press is detected.

@richardkogelnig
Copy link
Contributor Author

I submitted a super basic pull request #369

ocornut added a commit that referenced this issue Oct 11, 2015
@ocornut
Copy link
Owner

ocornut commented Oct 11, 2015

Thanks Richard. I also have added a comment about it.
We in theory shouldn't be ignoring Control but not all back-end send translated characters consistently with Control held. Will need to address that when adding support for keyboard shortcuts.

@ocornut ocornut closed this as completed Oct 11, 2015
ocornut added a commit that referenced this issue Feb 23, 2019
@str0yd
Copy link

str0yd commented Nov 4, 2020

Hello there,

I still have this issue on german keyboard. I think it worked with older versions but I updtated the imgui to the latest verstion and have this issue now. I'm using the docking branch.

Everytime I press AltGR (precisely on key up) the context switches from the input field to the tab layer.

@ocornut
Copy link
Owner

ocornut commented Nov 4, 2020 via email

@str0yd
Copy link

str0yd commented Nov 4, 2020

I tested it with my usual keyboard, the keyboard on my notebook and the keyboard of a workmate.

Looks like the "AltGr" button on the german keyboard is intepreted as "Alt" for one frame on keyup.

@str0yd
Copy link

str0yd commented Nov 4, 2020

altgr

I only press the "AltGr" button here.

@ocornut
Copy link
Owner

ocornut commented Nov 4, 2020

Which Platform backend are you using, and you could test this in examples with all 3 major backends: sdl, glfw, win32?

@str0yd
Copy link

str0yd commented Nov 4, 2020

I use glfw as platform binding and opengl3 as renderer.

Unfortunately, I do only use glfw in my whole project and do not know how to test the other backends.

@ocornut
Copy link
Owner

ocornut commented Nov 4, 2020

I installed a German keyboard, confirmed that AltGR presses CTRL+ALT and confirmed that this combination does not trigger the menu layer here. Are on you latest version?

VERSION 1.69 (Released 2019-03-13) 
Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigating to the menu layer.

@ocornut
Copy link
Owner

ocornut commented Nov 4, 2020

Never mind, you said "I updtated the imgui to the latest verstion and have this issue now."

I can confirm that GLFW has an issue there, while SDL and Win32 backends don't.

Somehow, in GLFW AltGR does not send a CTRL+ALT but only a regular ALT, which is rather odd ihmo.

@ocornut
Copy link
Owner

ocornut commented Nov 4, 2020

By the way, the reason you are now getting the bug is not because of a recent change but presumably because you enabled keyboard navigation (bug wouldn't manifest without).

Logged events from all three backends under Windows 10, here's what I found:

GLFW added in ImGui_ImplGlfw_KeyCallback handler:
printf("KeyCallback %s key=%d, scancode=%d, mods=%08X\n", action == GLFW_PRESS ? "press" : "release", key, scancode, mods);

SDL added in SDL_KEYDOWN/SDL_KEYUP handler:
printf("SDL_KEY%s key=%08X, scancode=%d, mods=%04x\n", event->type == SDL_KEYDOWN ? "DOWN" : "UP ", event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.mod);

Win32 added in WM_KEYDOWN handler:
printf("WM_KEYDOWN wParam=%08X, lParam=%08X\n", wParam, lParam);

** GLFW, Windows, English Keyboard **
(Note: current glfw backend do NOT use mods)
(left alt)
KeyCallback press   key=342 (GLFW_KEY_LEFT_ALT), scancode=56, mods=00000004 (GLFW_MOD_ALT)
KeyCallback release key=342 (GLFW_KEY_LEFT_ALT), scancode=56, mods=00000000
(right altgr)
KeyCallback press   key=346 (GLFW_KEY_RIGHT_ALT), scancode=312, mods=00000006 (GLFW_MOD_CONTROL+GLFW_MOD_ALT)
KeyCallback release key=346 (GLFW_KEY_RIGHT_ALT), scancode=312, mods=00000000

** GLFW, Windows, German Keyboard **
(Note: current glfw backend do NOT use mods)
(left alt)
KeyCallback press   key=342 (GLFW_KEY_LEFT_ALT), scancode=56, mods=00000004 (GLFW_MOD_ALT)
KeyCallback release key=342 (GLFW_KEY_LEFT_ALT), scancode=56, mods=00000000
(right altgr)
KeyCallback press   key=346 (GLFW_KEY_RIGHT_ALT), scancode=312, mods=00000006 (GLFW_MOD_CONTROL+GLFW_MOD_ALT)
KeyCallback release key=346 (GLFW_KEY_RIGHT_ALT), scancode=312, mods=00000000

** SDL, Windows, English Keyboard **
(left alt)
SDL_KEYDOWN key=400000E2, scancode=226, mods=0100 (KMOD_LALT)
SDL_KEYUP   key=400000E2, scancode=226, mods=0000
(right altgr)
SDL_KEYDOWN key=400000E0, scancode=224, mods=0040 (KMOD_LCTRL)
SDL_KEYDOWN key=400000E6, scancode=230, mods=0240 (KMOD_LCTRL | KMOD_RALT)
SDL_KEYUP   key=400000E0, scancode=224, mods=0200 (KMOD_RALT)
SDL_KEYUP   key=400000E6, scancode=230, mods=0000

** SDL, Windows, German Keyboard **
(left alt)
SDL_KEYDOWN key=400000E2, scancode=226, mods=0100 (KMOD_LALT)
SDL_KEYUP   key=400000E2, scancode=226, mods=0000
(right altgr)
SDL_KEYDOWN key=400000E0, scancode=224, mods=0040 (KMOD_LCTRL)
SDL_KEYDOWN key=400000E6, scancode=230, mods=0240 (KMOD_LCTRL | KMOD_RALT)
SDL_KEYUP   key=400000E0, scancode=224, mods=0200 (KMOD_RALT)
SDL_KEYUP   key=400000E6, scancode=230, mods=0000

** Win32 backend, Windows, English Keyboard **
(left alt)
WM_KEYDOWN wParam=00000012 (VK_MENU), lParam=20380001
WM_KEYUP   wParam=00000012 (VK_MENU), lParam=C0380001
(right altgr)
WM_KEYDOWN wParam=00000012 (VK_MENU), lParam=21380001
WM_KEYUP   wParam=00000012 (VK_MENU), lParam=C1380001

** Win32 backend, Windows, German Keyboard **
(left alt)
WM_KEYDOWN wParam=00000012 (VK_MENU), lParam=20380001
WM_KEYUP   wParam=00000012 (VK_MENU), lParam=C0380001
(right altgr)
WM_KEYDOWN wParam=00000011 (VK_CONTROL), lParam=001D0001
WM_KEYDOWN wParam=00000012 (VK_MENU), lParam=21380001
WM_KEYUP   wParam=00000011 (VK_CONTROL), lParam=E01D0001
WM_KEYUP   wParam=00000012 (VK_MENU), lParam=C1380001

So interestingly no one seems to agree on a standard way to behave....
It looks like we can fix the GLFW backend with that info.

@ocornut
Copy link
Owner

ocornut commented Nov 4, 2020

Problem is GLFW key handler explicitely says:
// Modifiers are not reliable across systems

And uses keys insteads of the mods parameter:

io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL];
io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT];
io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT];

So we need to track why we made that change in the first place, and if it was a mistake.

Made the change in 2015
71429d3

Following
c735d30

Following
#183

On my Linux system, GLFW 3.1.1, the key callback handles modifier keys incorrectly. Pressing the modifier will set the flag true, but releasing it does not. The only way to unset the modifiers is to hit a non-modifier key.
This issue does not seem to be present on my MacBook Pro.

In particular
#183 (comment)

I think the behavior described in #183 perhaps was already fixed in GLFW and we ought to get back to using mods correctly but I'll be waiting on a similar event log for both SDL and GLFW, both English and German mappings on both Linux and Mac before taking action.

@ocornut
Copy link
Owner

ocornut commented Nov 4, 2020

Data for Linux and OSX courtesy of @rokups

Linux:
(US LALT) Glfw_KeyCallback press   key=342, scancode=64,  mods=00000000
(US LALT) Glfw_KeyCallback release key=342, scancode=64,  mods=00000004 (GLFW_MOD_ALT)
(US RALT) Glfw_KeyCallback press   key=346, scancode=108, mods=00000000
(US RALT) Glfw_KeyCallback release key=346, scancode=108, mods=00000000 (nothing ?????)

(DE LALT) Glfw_KeyCallback press   key=342, scancode=64,  mods=00000000
(DE LALT) Glfw_KeyCallback release key=342, scancode=64,  mods=00000004 (GLFW_MOD_ALT)
(DE RALT) Glfw_KeyCallback press   key=346, scancode=108, mods=00000000
(DE RALT) Glfw_KeyCallback release key=346, scancode=108, mods=00000000 (nothing????)

(US LALT) SDL_KEYDOWN key=400000E2, scancode=226, mods=1100/1100 (KMOD_LALT)
(US LALT) SDL_KEYUP   key=400000E2, scancode=226, mods=1000/1000
(US RALT) SDL_KEYDOWN key=400000E6, scancode=230, mods=1200/1200 (KMOD_RALT)
(US RALT) SDL_KEYUP   key=400000E6, scancode=230, mods=1000/1000

(DE LALT) SDL_KEYDOWN key=400000E2, scancode=226, mods=1100/1100 (KMOD_LALT)
(DE LALT) SDL_KEYUP   key=400000E2, scancode=226, mods=1000/1000
(DE RALT) SDL_KEYDOWN key=400000E6, scancode=230, mods=1200/1200 (KMOD_RALT)
(DE RALT) SDL_KEYUP   key=400000E6, scancode=230, mods=1000/1000

MacOS:
(US LALT) Glfw_KeyCallback press   key=342, scancode=58, mods=00000004 (GLFW_MOD_ALT)
(US LALT) Glfw_KeyCallback release key=342, scancode=58, mods=00000000
(US RALT) Glfw_KeyCallback press   key=346, scancode=61, mods=00000004 (GLFW_MOD_ALT)
(US RALT) Glfw_KeyCallback release key=346, scancode=61, mods=00000000

(DE LALT) Glfw_KeyCallback press   key=342, scancode=58, mods=00000004 (GLFW_MOD_ALT)
(DE LALT) Glfw_KeyCallback release key=342, scancode=58, mods=00000000
(DE RALT) Glfw_KeyCallback press   key=346, scancode=61, mods=00000004 (GLFW_MOD_ALT)
(DE RALT) Glfw_KeyCallback release key=346, scancode=61, mods=00000000

(US LALT) SDL_KEYDOWN key=400000E2, scancode=226, mods=0100/0100 (KMOD_LALT)
(US LALT) SDL_KEYUP   key=400000E2, scancode=226, mods=0000/0000
(US RALT) SDL_KEYDOWN key=400000E6, scancode=230, mods=0200/0200 (KMOD_RALT)
(US RALT) SDL_KEYUP   key=400000E6, scancode=230, mods=0000/0000

(DE LALT) SDL_KEYDOWN key=400000E2, scancode=226, mods=0100/0100 (KMOD_LALT)
(DE LALT) SDL_KEYUP   key=400000E2, scancode=226, mods=0000/0000
(DE RALT) SDL_KEYDOWN key=400000E6, scancode=230, mods=0200/0200 (KMOD_RALT)
(DE RALT) SDL_KEYUP   key=400000E6, scancode=230, mods=0000/0000

And unfortunately GLFW under Linux still does that weird thing of not reporting keyboard modifiers on press:

(US LALT) Glfw_KeyCallback press   key=342, scancode=64, mods=00000000
(US LALT) Glfw_KeyCallback release key=342, scancode=64, mods=00000004 (GLFW_MOD_ALT)
(US RALT) Glfw_KeyCallback press   key=346, scancode=108, mods=00000000
(US RALT) Glfw_KeyCallback release key=346, scancode=108, mods=00000000 (nothing ?????)

SDL gets it ok under Linux so I would assume it's a GLFW bug under Linux...
Will appreciate and devise a solution.

I can confirm that under Windows, with German keyboard enabled, AltGR doesn't open menus, whereas with French or English keyboard it does open menus. So if we were to add a naive:

io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_ALT];

This would break the flow for non-german users who use AltGR to open menus.

One half-solution we could do to solve it for German users under Windows is:

io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL] || (action == GLFW_PRESS && (mods & GLFW_MOD_CONTROL) != 0);

But for Linux and OSX users I would need more information on how Alt/AltGR behave in their OS.
Under Windows for the vast majority of apps, pressing Alt or AltGR once puts the focus on the first menu in the menu-bar.

@str0yd
Copy link

str0yd commented Nov 4, 2020

First of all, thank you very much for your work. ImGUI is really an insanley good tool for building GUIs in C++.

By the way, the reason you are now getting the bug is not because of a recent change but presumably because you enabled keyboard navigation (bug wouldn't manifest without).

I'm not 100% sure but I don't think I ever disabled the keyboard navigation, neither before nor after I updated.

Partial fix for people with the same problem: I just commented

//if (io.KeyAlt && !io.KeyCtrl) // AltGR is Alt+Ctrl, also even on keyboards without AltGR we don't want Alt+Ctrl to open menu.
//    io.NavInputs[ImGuiNavInput_KeyMenu_]  = 1.0f;

in the imgui.cpp. (quick and dirty)

@ocornut
Copy link
Owner

ocornut commented Nov 5, 2020

Here's a recap of using ALT in non-dear imgui applications (courtesy of @rokups)

  Windows/Win32 Windows/Swing Windows/Qt Windows/GTK
LALT (hold) Underline letters in menu bar items. Focus does not change. (same) (same) (same)
LALT (press) Focus first item in menu bar. (same) (same) Focus does not change.
LALT+underlined letter Closing menu, item that opens menu is focused. (same) (same) Closing menu maintains original focus.
LALT+other letter Focus does not change. (same) Focus does not change, also types pressed letter. Focus does not change, also types pressed letter.
LALT+number Focus does not change. (same) Focus does not change, types pressed number. Focus does not change.
LALT+keypard number Focus does not change. Produces non-ascii characters. (same) (same) (same)
LALT+modifier Focus does not change. (same) (same) (same)
  Linux/QT Linux/GTK Linux/Swing
LALT (hold) Underline letters in menu bar items. Focus does not change. (same) (same)
LALT (press) Focus does not change. (same) (same)
LALT+underlined letter Closing menu maintains original focus. (same) (same)
LALT+other letter Focus does not change, also types pressed letter. Focus does not change. Focus does not change.
LALT+number Focus does not change, also types pressed number. Focus does not change. Focus does not change.
LALT+keypard number Focus does not change, also types pressed number. Focus does not change. Focus does not change.
LALT+modifier Focus does not change. (same) (same)

MacOS: Option/Control/Command do not interact with menu.

@ocornut
Copy link
Owner

ocornut commented Apr 21, 2021

@str0yd could you clarify your OS, window manager etc?

@str0yd
Copy link

str0yd commented Apr 22, 2021

I'm on Windows 10.

Configuration of GLFW in my application:
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
glfwWindowHint(GLFW_SAMPLES, 4);
GLFWwindow* window = glfwCreateWindow(...)

Configuration for ImGui:
ImGui_ImplGlfw_InitForOpenGL(window, true);

ocornut added a commit that referenced this issue Apr 23, 2021
…ext will steal ActiveID. Previously wouldn't not, but ButtonBehavior() hover logic would not show Menu layer item as hovered when ActiveId != 0). (#787)

(Adjacent to #370)
ocornut pushed a commit that referenced this issue Apr 23, 2021
@ocornut
Copy link
Owner

ocornut commented Apr 23, 2021

A fix (21428ad) by @rokups has been merged for that.
Since we can't reliably detect AltGR accross all backends/platforms/layouts we simply disable toggling menu layer when characters are being successfully input while holding Alt.

@rokups
Copy link
Contributor

rokups commented Apr 26, 2021

For future us: neither MacOS and Linux (X11) report CTRL when typing text with AltGr (re-tested today on SDL/GLFW). Basically this is a confirmation that this table is valid and we did not miss anything when testing these behaviors.

ocornut added a commit that referenced this issue Sep 5, 2024
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

4 participants