2

I have a global key event handler in linux as below. I need to know which keyboard is grabbed. For example if key 'P' is pressed I get the corresponding key code. Is there any way to get the key name ("P") from this unsigned key code ?

#include <xcb/xcb.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include <QtX11Extras/QX11Info>

void EventFilter::setup(QWidget *target)
{
    this->target = target;

    Display * display = QX11Info::display();
    unsigned int modifiers = ControlMask;
    keycode = XKeysymToKeycode(display, XK_A);
    XGrabKey(display, keycode, modifiers, DefaultRootWindow(display), 1, GrabModeAsync, GrabModeAsync);
}

bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *)
{
    if (eventType == "xcb_generic_event_t")
    {
        xcb_generic_event_t* xcbevent = static_cast<xcb_generic_event_t *>(message);

        switch(xcbevent->response_type)
        {
        case XCB_KEY_PRESS:
            xcb_key_press_event_t * keypress_event = static_cast<xcb_key_press_event_t *>(message);
            if(keypress_event->state & XCB_MOD_MASK_CONTROL)
            {
                if(keypress_event->detail == keycode)
                {
                    //print key name here
                }
            }
        }
    }
   return false;
 } 
p-a-o-l-o
  • 9,807
  • 2
  • 22
  • 35
GUI-Novice
  • 351
  • 5
  • 17
  • Possible duplicate of [SO: How to map a X11 KeySym to a Unicode character?](https://stackoverflow.com/q/8970098/7478597). – Scheff's Cat Mar 27 '18 at 08:06
  • As this is tagged [tag:qt], the following may be of interest as well: [SO: How to construct Qt::Key out of KeySym or KeyCode?](https://stackoverflow.com/q/48592348/7478597) – Scheff's Cat Mar 27 '18 at 08:08

1 Answers1

4

Given a key code, from the event detail field, you can get the KeySym using the XkbKeycodeToKeysym function, then a textual representation of the pressed key, passing the KeySym to the XKeysymToString function.

Have this extra include:

#include <X11/XKBlib.h>

Then, in the event handler:

case XCB_KEY_PRESS:
    xcb_key_press_event_t * keypress_event = static_cast<xcb_key_press_event_t *>(message);           
    xcb_keycode_t code = keypress_event->detail;
    qDebug() << XKeysymToString( XkbKeycodeToKeysym(QX11Info::display(), code, 0, 0) );

In the example above, an index of 0 is passed as the last argument of XkbKeycodeToKeysym. This will return the symbol for the pressed key as if the shift key (or caps lock, or any other modifier key) is not pressed. Passing an index of 1 will return the symbol as if the shift key was pressed. Other values (i.e. 2) will yield symbols one obtains pressing more modifier keys (e.g. in my italian keyboard I have to press Alt Gr to type square brackets).

Please notice, the returned string is really a name to identify the keyboard symbol, which can be, for example, a, b, c or X for letters, but comma, or backslash for other symbols.

p-a-o-l-o
  • 9,807
  • 2
  • 22
  • 35