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

Every Key event is Key'UnknownKey #94

Open
unclechu opened this issue Nov 14, 2021 · 18 comments
Open

Every Key event is Key'UnknownKey #94

unclechu opened this issue Nov 14, 2021 · 18 comments

Comments

@unclechu
Copy link

I set a callback using setKeyCallback function but every key press is just Key'UnknownKey. For instance if I press Escape the Key would be Key'UnknownKey and scancode would be 9. Any ideas why the keys are not recognized? Maybe I’m missing some dependencies like Xkb to map some layouts or something?

@unclechu
Copy link
Author

GLFW.getKeyScancode GLFW.Key'Escape returns -1 🤷

@unclechu
Copy link
Author

Prelude Graphics.UI.GLFW> getKeyScancode Key'Q
-1

@bsl
Copy link
Owner

bsl commented Nov 14, 2021

Hmm, has GLFW been initialized? I have not messed around with this stuff for a long time, but I just saw this in the underlying library that provides all the functionality.
https://github.com/glfw/glfw/blob/master/src/input.c#L648

@unclechu
Copy link
Author

Yep, GLFW is initialized.

  GLFW.init >>= flip unless (fail "Failed to initialize GLFW!")

If you’d like to see the whole thing:
https://github.com/unclechu/playing-with-shaders/tree/e881105a01e954b2ec384fbd63509a547a4623a6/haskell-version

@bsl
Copy link
Owner

bsl commented Nov 14, 2021

OK. Could you try to do some stuff with e.g. getError and/or setErrorCallback? Maybe something useful is being returned from GLFW.

@unclechu
Copy link
Author

@bsl I have the error callback as well. Nothing is triggered I believe.

@bsl
Copy link
Owner

bsl commented Nov 14, 2021

I see, maybe we have to look deeper to the platform implementation of getKeyScancode. You're on Linux, right?

@bsl
Copy link
Owner

bsl commented Nov 14, 2021

I think maybe you were onto something about xkb. In GLFW's x11_init.c I see a createKeyTables that begins by memseting some scan code array to -1, which seems related to your issue. Then, a lot of code is conditioned by if (_glfw.x11.xkb.available). I don't know what that means, but maybe GLFW thinks xkb is not available on your system? Is that some optional component you can install?

@unclechu
Copy link
Author

You're on Linux, right?

Yes. I have similar implementation in C++ and this works fine:

  if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
    cout
      << "Received escape key press event. "
      << "Marking window as closing…"
      << endl;
    glfwSetWindowShouldClose(window, GLFW_TRUE);
  } else if (on_key_event != nullptr) {
    on_key_event.value()(key, scancode, action, mods);
  }

@unclechu
Copy link
Author

@bsl

I don't know what that means, but maybe GLFW thinks xkb is not available on your system? Is that some optional component you can install?

Yeah, I had the same idea, that xkb is not available or something. It is available in my system but it could be, I think, that the source code of libxkb or something was not provided. Will try to look into the project setup in this context.

@bsl
Copy link
Owner

bsl commented Nov 14, 2021

One more thing that occurs to me is, your C++ program and GLFW-b program may be using different GLFW versions. I don't know if that matters in this case, but it might. GLFW-b depends on bindings-GLFW, which bundles GLFW 3.3.2 (I think). But your C++ program will be linked against whatever version of GLFW was installed by apt (or whatever).

@bsl
Copy link
Owner

bsl commented Nov 14, 2021

Some other ideas came to me. I was looking at https://github.com/bsl/bindings-GLFW/blob/master/bindings-GLFW.cabal and I see first of all that there are some flags. It could be helpful to build or install with different flags. Secondly, I see that we link in additional libraries via the extra-libraries section. Is there an xkb library we could add there? And/or xkbcommon?

I'm sorry I can't just try these things directly, but these ideas may help the other devs who still have the setup to do the builds.

@unclechu
Copy link
Author

One more thing that occurs to me is, your C++ program and GLFW-b program may be using different GLFW versions. I don't know if that matters in this case, but it might. GLFW-b depends on bindings-GLFW, which bundles GLFW 3.3.2 (I think). But your C++ program will be linked against whatever version of GLFW was installed by apt (or whatever).

I was about to say it’s not possible because I use Nix and the same nixpkgs pin for both Haskell and C++ versions. But I looked at bindings-GLFW:

https://github.com/bsl/bindings-GLFW/tree/master/glfw/src

And realized that it has its own copy of the GLFW sources. But still:

But your C++ program will be linked against whatever version of GLFW was installed by apt (or whatever).

In my case it’s a determined version by the nixpkgs pin that I use for the project.

C++ version build:

$ ldd result/bin/app | rg -i glfw
        libglfw.so.3 => /nix/store/a0j4adpnc5z9000lrhil0sv1xcj9y87k-glfw-3.3.4/lib/libglfw.so.3 (0x00007f97e05cc000)
$ nix repl <<< 'with import (import nix/sources.nix).nixpkgs {}; glfw.version'
Welcome to Nix version 2.3.16. Type :? for help.

"3.3.4"
$ jq .nixpkgs < nix/sources.json
{
  "branch": "release-21.05",
  "description": "Nix Packages collection",
  "homepage": "",
  "owner": "NixOS",
  "repo": "nixpkgs",
  "rev": "95eed9b64eee24975b880308065654fd059f22c3",
  "sha256": "1x59xdxh2vrnhh4j29nyq7npq70v178j5acdm2zsgamcagm3qif9",
  "type": "tarball",
  "url": "https://github.com/NixOS/nixpkgs/archive/95eed9b64eee24975b880308065654fd059f22c3.tar.gz",
  "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}

@unclechu
Copy link
Author

I also realized that even though in ghci REPL I get -1 for letter key they are still recognized in the event handler of the application. But:

  1. Only letter keys are recognized (Escape & Tab keys for instance result in Key'Unknown)
  2. Those letter keys are completely detached from the keyboard layout (if I change it to Finnish layout for instance Ä and Ö keys are recognized as Key'Aphostrophe and Key'Semicolon)

@unclechu
Copy link
Author

@bsl Tried to add extra-libraries: xkbcommon to the cabal file. It’s linked by nothing has changed still.

$ ldd result/bin/gl-playground | rg -i xkb
        libxkbcommon.so.0 => /nix/store/9w0vim093yahm7fbml7xr9wgzadpql1s-libxkbcommon-1.3.0/lib/libxkbcommon.so.0 (0x00007f590b67a000)

@unclechu
Copy link
Author

I think it should be bindings-GLFW package that is supposed to be patched?

@bsl
Copy link
Owner

bsl commented Nov 15, 2021

I think it should be bindings-GLFW package that is supposed to be patched?

Right. The situation is, bindings-GLFW is a very raw binding to the C library. Then GLFW-b makes use of bindings-GLFW to make the API much more Haskell-y. That was a common approach back in the day, hopefully still regarded as OK now.

The symptoms you mentioned, my intuition is that GLFW (the C library) judges xkb unavailable, and uses its alternate backup strategy to do that keyboard stuff. The critical code that GLFW uses to decide if xkb is available is this:

    _glfw.x11.xkb.available =
        XkbQueryExtension(_glfw.x11.display,
                          &_glfw.x11.xkb.majorOpcode,
                          &_glfw.x11.xkb.eventBase,
                          &_glfw.x11.xkb.errorBase,
                          &_glfw.x11.xkb.major,
                          &_glfw.x11.xkb.minor);

Could you see if xdpyinfo shows anything about the presence or absence of xkb on your system?

@Mokosha
Copy link
Collaborator

Mokosha commented Nov 15, 2021 via email

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

No branches or pull requests

3 participants