5

In a game I'm developing, I want to detect a NUMLOCK keypress (or keyup), like registering a "callback" function when it gets pressed.

I'm not asking to read its state in a given moment, I can do that already, nor I'm interested in changing its value. It's about being aware of the keypress when it happens so I don't have to poll its state every tenth of a sec or so.

The game uses curses, and currently a blocking getch(). Curses does not detect NUMLOCK keypresses, and I never expected it to (led-related keyboard don't "produce" any key), and I wonder if there is any way to do so that is better than than replacing the main curses loop with a non-blocking getch() and call a keyboard_leds() function to read current state.

For example: I could start a new thread after initializing curses, passing its stdscr screen as argument, and that thread would register register a callback function (say, special_keypress()) for the event of a NUMLOCK keypress. Thus, that function would only invoke keyboard_leds() when needed, and then update stdscr.

I'm not sure if this is possible, and I'm aware that I'll probably have to go down to some architecture-dependent stuff (kernel/X11, etc), so if a cross-platform solution is not possible, then I'm fine with a Linux-only one.

MestreLion
  • 12,698
  • 8
  • 66
  • 57
  • Probable dupe? http://stackoverflow.com/questions/10054681/capslock-numlock-insert-how-to-show-keyboard-status-on-screen-when-keyboard-h – Marc B Feb 04 '15 at 14:59
  • @MarcB: They are *related*, but I think very far from *duplicate*. He wants an app to run as daemon to show status in his DE. It is not even a programming question! – MestreLion Feb 04 '15 at 15:18

1 Answers1

2

OK, it's like using a steam-hammer to crack nuts (especially if you are creating a CLI rogue-like game), but Pyglet gets the at least NUMLOCK keypresses in OS X. I couldn't make it work with either CAPSLOCK or SCROLLLOCK though, but my system hotkeys are pretty much overriden in every way possible, so it may be just me.

You could try and test if it works better for you, and then look at how Pyglet detects these keys.

import pyglet

from pyglet.window import key


window = pyglet.window.Window()


@window.event
def on_key_press(symbol, modifiers):
    if symbol == key.NUMLOCK:
        print 'NumLock was pressed, yay!'
    elif symbol == key.CAPSLOCK:
        print 'CapsLock was pressed, yay!'
    elif symbol == key.SCROLLLOCK:
        print 'ScrollLock was pressed, yay!'


@window.event
def on_draw():
    window.clear()


if __name__ == '__main__':
    pyglet.app.run()
Igor Hatarist
  • 5,234
  • 2
  • 32
  • 45
  • Yeah, `pyglet` is a huge hammer for that nut. I cannot afford to create a window just for led status. It' CLI indeed, `X` might not even be running! :) But thanks for the effort anyway. – MestreLion Feb 04 '15 at 15:44
  • @MestreLion No problem, I'm digging further to find a better way. I guess the regular LED polling isn't that bad after all. It shouldn't take a lot of CPU usage. – Igor Hatarist Feb 04 '15 at 15:49
  • That's my backup plan. SO is a shot in the dark to see if there are better alternatives. – MestreLion Feb 04 '15 at 17:50
  • By the way... I'm not creating a "CLI rogue-like", I'm re-creating the _original_ Rogue in Python ;-) – MestreLion May 19 '23 at 06:38