GDK returns incorrect keysyms for keypad on Windows

I’m having an issue with GDK returning incorrect keysyms when using the numeric keypad on Windows: when I press ‘Home’ on the keypad (numlock off) Linux correctly returns KP_Home, but Windows returns Home, same goes for other ‘special’ keys such as KP_End, KP_Page_Down, etc, these return their non-KP_ equivalents.

Is this a known issue? Couldn’t find anything about this on GitLab and asked on IRC, but it seems the mention of ‘Windows’ scared people away.

Perhaps there’s some workaround for this, at least until this gets fixed? Maybe something along the lines of redefining macros when a certain GDK-version is lower than the eventual fixed GDK?
We need to able to differentiate between Home and KP_Home (and others) to allow our virtual keymaps to work (mapping a PC keyboard’s positional key matrix to something that resembles a CBM PET keyboard, among others).

I don’t know much about keyboard input in Windows and GDK, so I can’t really help you. If you get no answer here, open an issue on Gitlab.

I will,but I’ll wait a bit, see if any useful answers turn up here.

I took a glance at the GDK Win32 code, and I’m not seeing any opportunities to redefine macros to ‘fix’ issues, I probably saw some ancient Gtk2 bug report where there where a few checks via macros to determine what key was pressed. The current code seems to get a keymap from Windows and then somehow map that to GDK, apparently making a few mistakes.

I’m not a Windows dev, at all, so I’d rather not get involved in fixing this upstream. Our SDL2 port correctly handles the numpad keys, so this seems to be a GDK bug on Windows.

Could you share a code where we can check it?

Sure, but I don’t have any minimal example, here’s the keyboard handling code as part of the VICE emulator:

You can download a nightly build from If you run x64sc.exe (the C64 emulator), you can go into settings (Alt+O) and then select “Input devices -> Keyboard” where you can toggle the “keyboard debugging”. which will provide some info on the keyboard handling on the statusbar.

On Linux when I press the keypad Home/7 key I get 0xff95 / KP_Home, but just Home on Windows. I cannot look up the actual code since I wiped Windows.

I do not use windows at all, but this looks similar to

Yeah, we use that:

On Linux when I press Home it correctly sends ‘Home’ to the emulated C64 and when I press Home on the keypad, nothing happens, which is correct, since GDK_KEY_Home is mapped to the emulated C64’s CLR/HOME key and not GDK_KEY_KP_Home. On Windows GDK_KEY_KP_Home is sent as GDK_KEY_Home to the emulator, which triggers CLR/HOME.

With the C64, this isn’t much of a problem, it doesn’t have a keypad and the KP_0 - KP_9 codes do work correctly, so we can emulate a joystick via those keys. With machines like the C128, PET and CBM-II, which do have a keypad, the incorrectly scanned keys (or rather the mapping of whatever Windows returns to GDK), this becomes a problem and makes it hard to provide working positional keymaps for the machines I just mentioned.

As said, it works fine on Linux, and I’m waiting on reports about MacOS. On Windows, both compiled via msys2 on Windows and cross-compiled on Debian, it fails.

I know it is not related to your problem, but from my GTK(beginner) side it looks like, that the source code of your application is a C code rather then working with GTK.

You should subclass those repeating Widgets instead of C style.

There are a lot of functions which calls another functions, which …
You should concentrate more on subclassing Widgets by creating new ones.
I am just saying.

Thanks, but that wouldn’t make much sense.

We do indeed use C, so subclassing is out. There are ways to ‘subclass’ widgets using a lot of macros in Gtk, but I found that more trouble than it’s worth. I do use OOP-ish constructs and ‘composition’, if you can call it that when using C.

Should I have been using C++ or Python, I probably would have subclassed certain simple widgets because those language have proper support for that.

As far as our project being C rather than Gtk: we use Gtk3 for one of our UI’s (on any ‘modern’ OS that supports Gtk3), most of the core (emulation) code is ‘plain’ C, using various libs for sound, graphics, input/output etc. If you take a look at src/arch/gtk3, you’ll notice plenty of Gtk3/GDK/GLib code. Likewise you’ll notice a lot of SDL code in src/arch/sdl. We used to have code for win32, cocoa, gtk2 and xaw, but we dumped that in favour of Gtk3.

1 Like

Here’s a small code example that’ll show the issues on Windows:

 * compile command:
 * gcc keypress.c -o keypress  `pkg-config --libs --cflags gtk+-3.0`
 * on windows use -mconsole to see the output on console (using msys2)

keyval: ff7f keyname: Num_Lock
keyval: ffaf keyname: KP_Divide   
keyval: ffaa keyname: KP_Multiply 
keyval: ffad keyname: KP_Subtract 
keyval: ffab keyname: KP_Add      
keyval: ff8d keyname: KP_Enter    

the "white" keys on the numpad should produce different keycodes depending
on the "numlock" state: (also pressing shift together with one of the keys will
result in "the other" keycode)

numlock on:                             numlock off:

keyval: ffb0 keyname: KP_0              keyval: ff9e keyname: KP_Insert
keyval: ffb1 keyname: KP_1              keyval: ff9c keyname: KP_End
keyval: ffb2 keyname: KP_2              keyval: ff99 keyname: KP_Down
keyval: ffb3 keyname: KP_3              keyval: ff9b keyname: KP_Next
keyval: ffb4 keyname: KP_4              keyval: ff96 keyname: KP_Left
keyval: ffb5 keyname: KP_5              keyval: ff9d keyname: KP_Begin
keyval: ffb6 keyname: KP_6              keyval: ff98 keyname: KP_Right
keyval: ffb7 keyname: KP_7              keyval: ff95 keyname: KP_Home
keyval: ffb8 keyname: KP_8              keyval: ff97 keyname: KP_Up
keyval: ffb9 keyname: KP_9              keyval: ff9a keyname: KP_Page_Up
keyval: ffac keyname: KP_Separator      keyval: ff9f keyname: KP_Delete

on windows the keys with numlock off produce wrong keycodes, eg "Home" instead
of "KP_Home".


#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

gboolean on_key_press (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
  printf("keyval: %04x keyname: %s\n", event->keyval, gdk_keyval_name(event->keyval));
  return FALSE; 

int main (int argc, char *argv[])
  GtkWidget *window;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
  g_signal_connect (G_OBJECT (window), "key_press_event", G_CALLBACK (on_key_press), NULL);

  gtk_widget_show_all (window);

  gtk_main ();

  return 0;

The way how I see the things is that on Windows (i have no windows to test it) you get another number which is different from the one reported by event->keyval on Linux.
So if I am right and you print the event->keyval with the %u specifier you will notice it.

This means that the problem is not the gdk_keyval_from_name().

The problem is that on windows event->keyval reports a different key which is definitely not the same on Linux.

If this is the case, then probably is a Bug.

Yes, you’re basically repeating what I said in the original post . It’s most likely a bug on Windows since it works fine on Linux. And using the invalid GDK keyval will obviously return an invalid string representation and vice-versa.

I’ll take this to GitLab, this discussion isn’t helpful at all.

This does not means that you need to be rude.

I’m not being rude, I’m just explaining that the answers I got so far, which I’m sure are well meant, don’t help me.

For example:

the source code of your application is a C code rather then working with GTK.

You should subclass those repeating Widgets instead of C style.

That, and I’m trying to be very friendly here, indicates to me you do not have a firm grasp of various concepts when it comes to working with Gtk or any other toolkit/library and how each programming language will/might a have different way of interfacing with those toolkits/libraries.

And if you think I’m rude, you probably haven’t been on usenet, back when it was still somewhat useful.

Bumping this. Someone surely would know why this stuff works on Linux and not on Windows or MacOS?

From what I’ve seen of the Gtk/GDK code it doesn’t go ‘deep’ enough into the Win32 API, ie the VK_* stuff is too high level. I suspect something similar happens on MacOS.

I’ve been told this will be ‘solved’ with Gtk4, but since that’s not ready for general use/release, I’m stuck with Gtk3. So perhaps someone has a solution for this? Preferably something portable, ie Gtk/GLib/GDK/GIO-based, but if that doesn’t work perhaps some arch-dependent code that somehow produces Gtk/GLib objects I can use in a non-arch manner?

I’d recommend filing a bug about this.

I did:

The report was removed, or at least this is what I get if I click that link.

Page Not Found

There’s a typo; the correct issue number is 2540.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.