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

Keyboard layout ignored for keybinds #2959

Closed
zeroeightysix opened this issue Jan 2, 2020 · 4 comments
Closed

Keyboard layout ignored for keybinds #2959

zeroeightysix opened this issue Jan 2, 2020 · 4 comments

Comments

@zeroeightysix
Copy link

Version/Branch of Dear ImGui:

Version: 1.75 WIP (latest commit)
Branch: master

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
Operating System: Linux (Arch)
Keyboard layout: AZERTY

Note: Testing was done using the example_glfw_opengl3 example

My Issue:

Text entry widgets ignore keyboard layout: all keybinds, e.g. Select all (CTRL+A) assume the user is using QWERTY.
Someone typing using AZERTY (France, Belgium) or any non-qwerty layout will have to press the keys where A is on QWERTY, instead of pressing the actual A key.
For AZERTY, Q is in the same place as the A key on QWERTY, making it so that CTRL+Q will result in a "Select all" operation happening.

This will happen with other keybinds, such as CTRL+Z etc.

Screenshots/Video

Video

First I type all as to show the key code of a, and then attempt to press CTRL+A.
After that, I do the same for Q. Only then a selection happens.

Standalone, minimal, complete and verifiable example:

examples/example_glfw_opengl3
All can be tested in the demo window(s).

@ocornut
Copy link
Owner

ocornut commented Jan 2, 2020

Hello @zeroeightysix and thank you for your report.

You are right about this. Similar things are discussed in #2625 and #456.
In particular see #2625 (comment) then the discussion in glfw/glfw#672 (comment) (messages from March 2019) then forked into glfw/glfw#1502

My opinion is that GLFW doesn't provide the info we need in an ideal manner. Somehow the ideas discussed in glfw's 672 derailed a little in 1502 into api details.

Realistically speaking we should:

  • Figure out a workaround with current GLFW version (perhaps using glfwGetKeyName())
  • Suggest/design/push for a correcter fix in GLFW via a new API (that's the purpose of the 1502).
  • May be some redesign needed on dear imgui side.

TL;DR; not a trivial issue to move forward on, but we will eventually.

@blep
Copy link

blep commented Mar 23, 2020

For SDL2, I solved this by first initializing the scancodes to unknown, and then dynamically setting them on keypress looking at the ASCII code of the pressed letter.

Here a gist with the change I made. Not having Ctrl+A and Ctrl+Z working as usual in text field was driving me nuts.

Not clear to me if GLFW provides a way to get the ASCII code associated to a keypress that would allow this "trick" to be used. SDL2 had a function to statically returns the letter associated to a scancode, but it was hard-coded to QWERTY (my first failed attempt at a solution for this problem).

@jamesthomasgriffin
Copy link

I also encountered this problem when using a Dvorak layout. I used glfwGetKeyName to remap the keys in the callback, see below. Ofcourse this does mean the connection is lost between the GLFW_KEY_ names and the physical keys (assuming a US layout), so for example this isn't appropriate for WASD arrow keys. But it was what I needed.

I'm not sure how it would be possible to integrate this into Dear ImGui (perhaps an option in imconfig.h?), but in the future having both IsKeyPressed(int) for physical keys and IsKeyWithNamePressed(char) or similar would be convenient.

void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
  {
    if (g_PrevUserCallbackKey != NULL)
        g_PrevUserCallbackKey(window, key, scancode, action, mods);

    // New code - remap keys using glfwGetKeyName
    const char* key_name = glfwGetKeyName(key, 0);
    if (key_name)
    {
        key = (int)key_name[0];

        // Convert to upper-case
        if (key >= 97 && key <= 122)
            key -= 32;  
    }

    ImGuiIO& io = ImGui::GetIO();
    if (action == GLFW_PRESS)
        io.KeysDown[key] = true;
    if (action == GLFW_RELEASE)
        io.KeysDown[key] = false;

    // Modifiers are not reliable across systems
    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];
#ifdef _WIN32
    io.KeySuper = false;
#else
    io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER];
#endif
}

p.s. this is my first comment in this repo, so a huge thanks to ocornut and anyone else for doing such a great job

@ocornut
Copy link
Owner

ocornut commented Jun 27, 2023

Hello,
Stumbled on this through a link that got shared to me and noticed that this should have been closed a while ago.
#4921 (~january 2022) standardized the fact that backends submit translated keys so this should be solved already!

@ocornut ocornut closed this as completed Jun 27, 2023
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