Num-lock not working and Keypad not working with numbers!

Hello, I would like to fix this bug. I have programmed before but not a lot. How would I go about finding and fixing this bug?

I would start with:


and see if any message is being generated at all when you press the keys in question.


I have done that and no message is made. It was also tested by pro-soft on a 32 bit edgy system with the same results. Numlock makes no message and thus pressing the numbers also makes no message. However it does make the up down etc that would be expected without num-lock pressed. The numlock light goes on and off but the buttons do not change.

In that case, the next thing I would do would be to put a cerr statement in glxGraphicsWindow::handle_keypress(), and/or in glxGraphicsWindow::process_events(), to see what event, if any, is being generated by the windowing system in response to this keypress.

If the windowing system isn’t generating any events, it’s a Linux-level problem, and there’s nothing Panda can do about it. But if the windowing system is generating an event that Panda isn’t responding to for some reason, that’s where you can figure out why.


gee dont make num lock used for any thing :slight_smile: For instance i am on a laptop where pressing the numlock requires 2 keys at the opposite end of the keyboard. Also if you make only the numluck numbers 1-9 affect the game that makes half the keyboard inactive. I suggest sticking to standard AWSD for movement.

Of course numlock never throws any event, since it’s never catched. It happens too for scrolllock and printscreen. While for pause, it’s not even registered.
Pause button is very representative for pause-resume toggle. Is there any good reason for not including those buttons ?

Here are my simple additions :
glxGraphicsWindow.cxx :

  case XK_Num_Lock:
    return KeyboardButton::num_lock();
  case XK_Scroll_Lock:
    return KeyboardButton::scroll_lock();
  case XK_Print:
    return KeyboardButton::print_screen();
  case XK_Pause:
    return KeyboardButton::pause();

keyboardButton.h :

  static ButtonHandle pause();

keyboardButton.cxx :


  ButtonRegistry::ptr()->register_button(_pause, "pause");

I’m still unable to solve keypad digit buttons down-event problem, changing from this :

  case XK_0:
    return KeyboardButton::ascii_key('0');

to this :

  case XK_KP_0:
  case XK_0:
    return KeyboardButton::ascii_key('0');

didn’t help.
I don’t know how to query numlock on/off state. I googled without any useful results.

I’ve added the suggested changes. Many thanks, ynjh_jo!


The pleasure is mine. :smiley:
And in winGraphicsWindow.cxx :

  case VK_PAUSE: return KeyboardButton::pause();

Got it.


  1. I just noticed that keypad’s /*-+ and enter were not caught, regardless of keypad-controlled-mouse setting.
  2. googling about keypad numbers problem only brought me to xev, so I ran xev and the result is :
    pressing keypad 7, numlock OFF :
    [size=75]KeyPress event, serial 30, synthetic NO, window 0x6a00001,
    root 0x188, subw 0x0, time 5608688, (-359,190), root:(335,662),
    state 0x0, keycode 79 (keysym 0xff95, KP_Home), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False[/size]
    pressing keypad 7, numlock ON :
    [size=75]KeyPress event, serial 30, synthetic NO, window 0x6a00001,
    root 0x188, subw 0x0, time 5642204, (-113,220), root:(581,692),
    state 0x10, keycode 79 (keysym 0xffb7, KP_7), same_screen YES,
    XLookupString gives 1 bytes: (37) “7”
    XmbLookupString gives 1 bytes: (37) “7”
    XFilterEvent returns: False[/size]

As you can see, the state is different.
shift : 0x1
ctrl : 0x4
alt : 0x8
capslock : 0x2
With capslock ON and all modifiers are pressed, the state is at most 0xf.
With capslock OFF and all modifiers are not pressed, the state is 0x10.
So, state value (at least) 0x10 tells us that the numlock is ON.
Note that if keypad-controlled-mouse is active, keypad down events cannot be caught, since it stops at window mgr level.
I’ve split and re-arranged the switch and added [/*-+ and enter] keys, this is my whole glxGraphicsWindow::get_button :

ButtonHandle glxGraphicsWindow::
get_button(XKeyEvent &key_event) {
  KeySym key = XLookupKeysym(&key_event, 0);

  // The minimum state value when numlock is ON is 0x10.
  // When numlock is OFF, with capslock ON and all modifiers down,
  // the state is at most 0xf.
  // NOTE : I don't know about shiftlock, there isn't one here on my keyb.
  if (key_event.state >= 0x10) {
    // numlock ON
    switch (key) {
    case XK_KP_Left:
      return KeyboardButton::ascii_key('4');
    case XK_KP_Up:
      return KeyboardButton::ascii_key('8');
    case XK_KP_Right:
      return KeyboardButton::ascii_key('6');
    case XK_KP_Down:
      return KeyboardButton::ascii_key('2');
    case XK_KP_Begin:
      return KeyboardButton::ascii_key('5');
    case XK_KP_Prior:
      return KeyboardButton::ascii_key('9');
    case XK_KP_Next:
      return KeyboardButton::ascii_key('3');
    case XK_KP_Home:
      return KeyboardButton::ascii_key('7');
    case XK_KP_End:
      return KeyboardButton::ascii_key('1');
    case XK_KP_Insert:
      return KeyboardButton::ascii_key('0');
    case XK_KP_Delete:
      return KeyboardButton::ascii_key('.');
  } else {
    // numlock OFF
    switch (key) {
    case XK_KP_Left:
      return KeyboardButton::left();
    case XK_KP_Up:
      return KeyboardButton::up();
    case XK_KP_Right:
      return KeyboardButton::right();
    case XK_KP_Down:
      return KeyboardButton::down();
    case XK_KP_Prior:
      return KeyboardButton::page_up();
    case XK_KP_Next:
      return KeyboardButton::page_down();
    case XK_KP_Home:
      return KeyboardButton::home();
    case XK_KP_End:
      return KeyboardButton::end();
    case XK_KP_Insert:
      return KeyboardButton::insert();
    case XK_KP_Delete:
      return KeyboardButton::del();
  switch (key) {
  case XK_BackSpace:
    return KeyboardButton::backspace();
  case XK_Tab:
    return KeyboardButton::tab();
  case XK_KP_Enter:
  case XK_Return:
    return KeyboardButton::enter();
  case XK_Escape:
    return KeyboardButton::escape();
  case XK_space:
    return KeyboardButton::space();
  case XK_exclam:
    return KeyboardButton::ascii_key('!');
  case XK_quotedbl:
    return KeyboardButton::ascii_key('"');
  case XK_numbersign:
    return KeyboardButton::ascii_key('#');
  case XK_dollar:
    return KeyboardButton::ascii_key('$');
  case XK_percent:
    return KeyboardButton::ascii_key('%');
  case XK_ampersand:
    return KeyboardButton::ascii_key('&');
  case XK_apostrophe: // == XK_quoteright
    return KeyboardButton::ascii_key('\'');
  case XK_parenleft:
    return KeyboardButton::ascii_key('(');
  case XK_parenright:
    return KeyboardButton::ascii_key(')');
  case XK_KP_Multiply:
  case XK_asterisk:
    return KeyboardButton::ascii_key('*');
  case XK_KP_Add:
  case XK_plus:
    return KeyboardButton::ascii_key('+');
  case XK_comma:
    return KeyboardButton::ascii_key(',');
  case XK_KP_Subtract:
  case XK_minus:
    return KeyboardButton::ascii_key('-');
  case XK_period:
    return KeyboardButton::ascii_key('.');
  case XK_KP_Divide:
  case XK_slash:
    return KeyboardButton::ascii_key('/');
  case XK_0:
    return KeyboardButton::ascii_key('0');
  case XK_1:
    return KeyboardButton::ascii_key('1');
  case XK_2:
    return KeyboardButton::ascii_key('2');
  case XK_3:
    return KeyboardButton::ascii_key('3');
  case XK_4:
    return KeyboardButton::ascii_key('4');
  case XK_5:
    return KeyboardButton::ascii_key('5');
  case XK_6:
    return KeyboardButton::ascii_key('6');
  case XK_7:
    return KeyboardButton::ascii_key('7');
  case XK_8:
    return KeyboardButton::ascii_key('8');
  case XK_9:
    return KeyboardButton::ascii_key('9');
  case XK_colon:
    return KeyboardButton::ascii_key(':');
  case XK_semicolon:
    return KeyboardButton::ascii_key(';');
  case XK_less:
    return KeyboardButton::ascii_key('<');
  case XK_equal:
    return KeyboardButton::ascii_key('=');
  case XK_greater:
    return KeyboardButton::ascii_key('>');
  case XK_question:
    return KeyboardButton::ascii_key('?');
  case XK_at:
    return KeyboardButton::ascii_key('@');
  case XK_A:
    return KeyboardButton::ascii_key('A');
  case XK_B:
    return KeyboardButton::ascii_key('B');
  case XK_C:
    return KeyboardButton::ascii_key('C');
  case XK_D:
    return KeyboardButton::ascii_key('D');
  case XK_E:
    return KeyboardButton::ascii_key('E');
  case XK_F:
    return KeyboardButton::ascii_key('F');
  case XK_G:
    return KeyboardButton::ascii_key('G');
  case XK_H:
    return KeyboardButton::ascii_key('H');
  case XK_I:
    return KeyboardButton::ascii_key('I');
  case XK_J:
    return KeyboardButton::ascii_key('J');
  case XK_K:
    return KeyboardButton::ascii_key('K');
  case XK_L:
    return KeyboardButton::ascii_key('L');
  case XK_M:
    return KeyboardButton::ascii_key('M');
  case XK_N:
    return KeyboardButton::ascii_key('N');
  case XK_O:
    return KeyboardButton::ascii_key('O');
  case XK_P:
    return KeyboardButton::ascii_key('P');
  case XK_Q:
    return KeyboardButton::ascii_key('Q');
  case XK_R:
    return KeyboardButton::ascii_key('R');
  case XK_S:
    return KeyboardButton::ascii_key('S');
  case XK_T:
    return KeyboardButton::ascii_key('T');
  case XK_U:
    return KeyboardButton::ascii_key('U');
  case XK_V:
    return KeyboardButton::ascii_key('V');
  case XK_W:
    return KeyboardButton::ascii_key('W');
  case XK_X:
    return KeyboardButton::ascii_key('X');
  case XK_Y:
    return KeyboardButton::ascii_key('Y');
  case XK_Z:
    return KeyboardButton::ascii_key('Z');
  case XK_bracketleft:
    return KeyboardButton::ascii_key('[');
  case XK_backslash:
    return KeyboardButton::ascii_key('\\');
  case XK_bracketright:
    return KeyboardButton::ascii_key(']');
  case XK_asciicircum:
    return KeyboardButton::ascii_key('^');
  case XK_underscore:
    return KeyboardButton::ascii_key('_');
  case XK_grave: // == XK_quoteleft
    return KeyboardButton::ascii_key('`');
  case XK_a:
    return KeyboardButton::ascii_key('a');
  case XK_b:
    return KeyboardButton::ascii_key('b');
  case XK_c:
    return KeyboardButton::ascii_key('c');
  case XK_d:
    return KeyboardButton::ascii_key('d');
  case XK_e:
    return KeyboardButton::ascii_key('e');
  case XK_f:
    return KeyboardButton::ascii_key('f');
  case XK_g:
    return KeyboardButton::ascii_key('g');
  case XK_h:
    return KeyboardButton::ascii_key('h');
  case XK_i:
    return KeyboardButton::ascii_key('i');
  case XK_j:
    return KeyboardButton::ascii_key('j');
  case XK_k:
    return KeyboardButton::ascii_key('k');
  case XK_l:
    return KeyboardButton::ascii_key('l');
  case XK_m:
    return KeyboardButton::ascii_key('m');
  case XK_n:
    return KeyboardButton::ascii_key('n');
  case XK_o:
    return KeyboardButton::ascii_key('o');
  case XK_p:
    return KeyboardButton::ascii_key('p');
  case XK_q:
    return KeyboardButton::ascii_key('q');
  case XK_r:
    return KeyboardButton::ascii_key('r');
  case XK_s:
    return KeyboardButton::ascii_key('s');
  case XK_t:
    return KeyboardButton::ascii_key('t');
  case XK_u:
    return KeyboardButton::ascii_key('u');
  case XK_v:
    return KeyboardButton::ascii_key('v');
  case XK_w:
    return KeyboardButton::ascii_key('w');
  case XK_x:
    return KeyboardButton::ascii_key('x');
  case XK_y:
    return KeyboardButton::ascii_key('y');
  case XK_z:
    return KeyboardButton::ascii_key('z');
  case XK_braceleft:
    return KeyboardButton::ascii_key('{');
  case XK_bar:
    return KeyboardButton::ascii_key('|');
  case XK_braceright:
    return KeyboardButton::ascii_key('}');
  case XK_asciitilde:
    return KeyboardButton::ascii_key('~');
  case XK_F1:
    return KeyboardButton::f1();
  case XK_F2:
    return KeyboardButton::f2();
  case XK_F3:
    return KeyboardButton::f3();
  case XK_F4:
    return KeyboardButton::f4();
  case XK_F5:
    return KeyboardButton::f5();
  case XK_F6:
    return KeyboardButton::f6();
  case XK_F7:
    return KeyboardButton::f7();
  case XK_F8:
    return KeyboardButton::f8();
  case XK_F9:
    return KeyboardButton::f9();
  case XK_F10:
    return KeyboardButton::f10();
  case XK_F11:
    return KeyboardButton::f11();
  case XK_F12:
    return KeyboardButton::f12();
  case XK_Left:
    return KeyboardButton::left();
  case XK_Up:
    return KeyboardButton::up();
  case XK_Right:
    return KeyboardButton::right();
  case XK_Down:
    return KeyboardButton::down();
  case XK_Prior:
    return KeyboardButton::page_up();
  case XK_Next:
    return KeyboardButton::page_down();
  case XK_Home:
    return KeyboardButton::home();
  case XK_End:
    return KeyboardButton::end();
  case XK_Insert:
    return KeyboardButton::insert();
  case XK_Delete:
    return KeyboardButton::del();
  case XK_Shift_L:
  case XK_Shift_R:
    return KeyboardButton::shift();
  case XK_Control_L:
  case XK_Control_R:
    return KeyboardButton::control();
  case XK_Alt_L:
  case XK_Alt_R:
    return KeyboardButton::alt();
  case XK_Meta_L:
  case XK_Meta_R:
    return KeyboardButton::meta();
  case XK_Caps_Lock:
    return KeyboardButton::caps_lock();
  case XK_Shift_Lock:
    return KeyboardButton::shift_lock();
  case XK_Num_Lock:
    return KeyboardButton::num_lock();
  case XK_Scroll_Lock:
    return KeyboardButton::scroll_lock();
  case XK_Print:
    return KeyboardButton::print_screen();
  case XK_Pause:
    return KeyboardButton::pause();

  return ButtonHandle::none();

One last weird thing :
shift-ctrl-alt /*-+ (keypad) down events cannot be caught. I’ve checked my keyb shortcuts, they’re not used anywhere.

OK, I didn’t check in this exact code, but I did look up in my Xlib reference book and find something that might be a bit less-specific to PC keyboards. Still does seem to require some a priori knowledge about the keyboard mapping, though, so it’s kind of a weird system, but that’s X for you.


GREAT, it works gorgeously.
But x_wheel_up_button and x_wheel_up_button are undefined. They don’t sound like standard X definition. Searching the web yields zero result.
Meanwhile, I hardcoded them to 4 and 5. I can’t search by content, I don’t know how. I’m still bumping into some weird stuff being a month Linuxer. :blush:

Those are config variables. They are defined in config_glxdisplay.cxx, and their default values are 4 and 5. I don’t know why they were coming up undefined for you, since glxGraphicsWindow.cxx includes config_glxdisplay.h.

grep is your Linux tool to search by content.


Oh, I got a little older version, when x_wheel* is glx_wheel*, so I use glx_wheel*, to avoid breaking other vars.

David, did you forget removing cerr in handle_keypress ?

Oops, careless of me. Thanks.


I noticed Panda didn’t catch the horizontal scroll yet (on my laptop touchpad), so I implemented it, (not checked in yet) but how should I name the events?
I could name it scroll_left and scroll_right but that wouldn’t be consistent with wheel_up and wheel_down, but if I called them wheel_left and wheel_right that would be rather odd since it’s not a wheel… :S

I’ve got no problem with wheel_left and wheel_right. It’s a wheel (or at least a ball) on some devices, for instance the Mighty Mouse.

I suppose scroll_up/down/left/right might be a little more conventional, but I dislike that it implies a semantic meaning for the events; and in any case I don’t think it’s worth deprecating the old event names in order to follow this loose convention.


Thanks for your prompt reply. I’ve checked in the code to mouseButton and glxdisplay.