Purpose of gdk -> get_n_keys()?

This function always returns ‘0.’ So, I have to ask. If it’s not telling me how many keys are on my keyboard, what is it’s purpose?

1 Like

So maybe fix your D bindings?

I can not imagine that a call of gdk->get_n_keys() without any meaningful parameters makes any sense.

For testing, I guess one has to ask for default monitor, then default seat, then keyboard…

I can not try that now, too busy. General, I can imagine that not all Keyboards may report umber of keys properly. Maybe never USB once do, maybe old PS2 not? Don’t know.

I have no idea how to do that. I don’t maintain that code base.

My thoughts exactly, thus my question.

Yup, did all that.

That’s possible, although mine is a fairly pricey one, so if it doesn’t, I can’t imagine any other keyboard doing so, either.

This may be the case, but I have no way of testing.

Thanks for your response, Stefan.

Are you calling gdk->get_n_keys(), or device->get_n_keys() for a Gdk::Device?

You can see how Inkscape uses it in their device manager code, here: https://inkscape.gitlab.io/inkscape/doxygen/device-manager_8cpp_source.html

(Though they don’t really make much use of the return value, other than when comparing different devices to… it looks like they’re looking for duplicate or alias devices, to exclude from the device list.)

Edit: So, experimenting with the Python API, I’ve discovered:

>>> from gi.repository import Gdk
>>> d = Gdk.Display.list_devices(Gdk.Display.get_default())  # Deprecated but w/e
>>> print("\n".join([f'{x.get_name()}, {x.get_n_axes()}, {x.get_n_keys()}' for x in d]))
Virtual core pointer, 4, 0
HP HP Link-5 micro dongle Consumer Control, 4, 0
Virtual core XTEST pointer, 2, 0
HP HP Link-5 micro dongle Mouse, 4, 0


  1. The devices are all pointing devices
  2. Which is why they all have some number of axes
  3. Keys on pointing devices, while not impossible, are very uncommon.

If you had an advanced drawing tablet or something, I would expect it might have keys on it. But get_n_keys() being 0 for the majority of pointing devices seems correct to me.

1 Like

I’m using: device->get_n_keys()

That looks like they’re just running through a list of devices to make sure they’re not fake… whatever that means.

I did the same thing in D and got a list of devices, one of which was my keyboard. Interestingly, the other devices (Virtual Core Pointer and System Aggregated Pointer) both report 0 keys while the keyboard (Virtual Core Keyboard) didn’t even acknowledge the call to getNKeys().

I suspect this has something to do with the whole master/slave thing.

Thanks for jumping into the discussion, Frank.

Yeah, but I suspect it wasn’t your keyboard’s keyboard interface. A lot of keyboards speak multiple USB input protocols, for instance any keyboard with media keys is going to be a Consumer Control device. (You can see the same interface on the list for my devices, from my HP wireless input receiver.) But the FULL list of input devices on my system is much longer:

$ xinput list
⎡ Virtual core pointer                      	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ HP HP Link-5 micro dongle Mouse         	id=10	[slave  pointer  (2)]
⎜   ↳ HP HP Link-5 micro dongle Consumer Control id=11	[slave  pointer  (2)]
⎜   ↳ YSPRINGTECH USB OPTICAL MOUSE           	id=16	[slave  pointer  (2)]
⎣ Virtual core keyboard                     	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Power Button                            	id=7	[slave  keyboard (3)]
    ↳ VIA Technologies Inc. USB Audio Device  	id=8	[slave  keyboard (3)]
    ↳ HP HP Link-5 micro dongle               	id=9	[slave  keyboard (3)]
    ↳ HP HP Link-5 micro dongle System Control	id=12	[slave  keyboard (3)]
    ↳ DELL DELL USB Keyboard                  	id=13	[slave  keyboard (3)]
    ↳ DELL DELL USB Keyboard System Control   	id=14	[slave  keyboard (3)]
    ↳ DELL DELL USB Keyboard Consumer Control 	id=15	[slave  keyboard (3)]
    ↳ HP WMI hotkeys                          	id=17	[slave  keyboard (3)]
    ↳ HP HP Link-5 micro dongle Consumer Control id=18	[slave  keyboard (3)]

So, I still contend that keyboard interfaces aren’t included in Gdk.Device.

Somehow I missed this contention the first time around. :slight_smile:
So, if the keyboard interface isn’t in Device… I still have no idea why Device has a get_n_keys() function.

Like I said, it’s theoretically possible for a pointing device to have keys. I’d imagine that certain Wacom tablets or similar devices would be possible contenders, since they have a lot more going on than the typical mouse or touchpad. But if it exists it’d be very uncommon, which is why 0 is typically the only return value you’ll see.

(In truth I don’t know if there ARE any pointing devices with keys — this may be entirely theoretical. There’s no real reason a tablet or similar pointing device couldn’t just implement the USB keyboard protocol (the same way some keyboard hardware also implements pointing-device protocols), so that its keys are supported in a more standard/common fashion, rather than exporting them over the pointing-device protocol. It’s entirely possible that the device manufacturers came to that same conclusion way back when, and this obscure, random keypress-input support for pointing devices was never actually used.)

I’m getting the impression that get_n_keys() has nothing to do with keyboards and is all about pointing devices. Give it to me straight, Frank. I can take it. :slight_smile:

And if that’s the case, I now have a new question:

Does get_key() get a keypress from a keyboard or only from a pointing device?

get_n_keys() seems to work fine for the keyboard device returned by gdk_seat_get_keyboard().

This is Ruby, but things should be similar in other languages:

display = Gdk::Display.get_default
seat = display.default_seat
k = seat.keyboard
# => 248
1 Like

Yup, very similar to my D code:

myDisplay = Display.getDefault();
seat = myDisplay.getDefaultSeat();
keyboard = seat.getKeyboard();
listG = myDisplay.listDevices();
Device[] devices = listG.toArray!Device();
foreach(currentDevice; devices)
	writeln("device: ", currentDevice.getName());
	writeln("keys: ", currentDevice.getNKeys());
// output: 0

I can only assume at this point that the wrapper code is busted.

No, seems to be the actual device.

I get zero as well for my keyboard and mouse, it is a cheap Cherry.

You should be able to create C code for that example and test that, when you really care.


What I forget – I used Nim code similar like the ruby code above and got zero. To lazy and busy to try C code.

Ron, your code seems to make not much sense to me. Why assign values to seat and keyboard, when you do not use these variables later? Maybe try keyboard.getNKeys, to ensure that there is indeed not a problem with your foreach loop.

This is Ruby, but things should be similar in other languages

I’m getting 0 in Python:

import gi
from gi.repository import Gdk
# prints 0

I’m on Gtk 3.24.12, PyGObject 3.34.0, and I’m using a Wayland session, in case that matters.

1 Like

The purpose of gdk_device_get_n_keys() is to relay information from the windowing system.

Currently (for GTK 3), the only windowing system that sets the number of keys on a particular input device is the X11 backend—and only when using the XInput 2.x extension.

There are various APIs in GDK that exist in the generic code path, but only work on specific backends because nobody ever needed to implement the functionality in every backend.

1 Like

No: any input device can have associated keys. Mice can have additional buttons; tablets can have additional keys; and so on, and so forth.

gdk_device_get_key() doesn’t get “key presses”: it returns the hardware key symbol and the modifier that a key may generate when pressed. For instance, there are buttons on keyboards that are wired to pop up a dialog that lets you move the current display output to another screen; that is achieved by having a hardware key generating a Shift+P key combination. Calling gdk_device_get_key() with the index of that key will return p as the key symbol, and a GDK_SHIFT_MASK modifier.

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