Nidhoegger
Nidhoegger

Reputation: 5232

Get status of currently active modifiers in X11

Is there a way to get informations on current active modifiers in X? E.g. if Capslock is active, if shift is pressed, etc.

According to the xkbcommon-keysyms.h this is a list of all X11 modifiers:

#define XKB_KEY_Shift_L                       0xffe1  /* Left shift */
#define XKB_KEY_Shift_R                       0xffe2  /* Right shift */
#define XKB_KEY_Control_L                     0xffe3  /* Left control */
#define XKB_KEY_Control_R                     0xffe4  /* Right control */
#define XKB_KEY_Caps_Lock                     0xffe5  /* Caps lock */
#define XKB_KEY_Shift_Lock                    0xffe6  /* Shift lock */

#define XKB_KEY_Meta_L                        0xffe7  /* Left meta */
#define XKB_KEY_Meta_R                        0xffe8  /* Right meta */
#define XKB_KEY_Alt_L                         0xffe9  /* Left alt */
#define XKB_KEY_Alt_R                         0xffea  /* Right alt */
#define XKB_KEY_Super_L                       0xffeb  /* Left super */
#define XKB_KEY_Super_R                       0xffec  /* Right super */
#define XKB_KEY_Hyper_L                       0xffed  /* Left hyper */
#define XKB_KEY_Hyper_R                       0xffee  /* Right hyper */

But how can I get the status of these keys? I did not find an according function for this. Thanks in advance!

Upvotes: 4

Views: 2809

Answers (2)

arashka
arashka

Reputation: 1325

The correct way to do this is exactly as follows:

Upon receiving KeyPress event, you take the XKeyEvent data, and take the state from it, and convert it as follows (this is a part of GLFW internal mechanism of handling X11 events https://github.com/glfw/glfw/blob/7e8da57094281c73a0be5669a4b79686b4917f6c/src/x11_window.c#L186):

static int translateState(int state)
{
    int mods = 0;

    if (state & ShiftMask)
        mods |= GLFW_MOD_SHIFT;
    if (state & ControlMask)
        mods |= GLFW_MOD_CONTROL;
    if (state & Mod1Mask)
        mods |= GLFW_MOD_ALT;
    if (state & Mod4Mask)
        mods |= GLFW_MOD_SUPER;
    if (state & LockMask)
        mods |= GLFW_MOD_CAPS_LOCK;
    if (state & Mod2Mask)
        mods |= GLFW_MOD_NUM_LOCK;

    return mods;
}

You call that function like:

translateState(xev.xkey.state);

where xev is the XEvent you have received. Of course you should use your own flags instead of GLFW enumeration, or do something else with it.

Upvotes: 4

n. m. could be an AI
n. m. could be an AI

Reputation: 119877

No, this is not a list of modifiers. This is a list of modifier keys.

X11 modifiers are ShiftMask, Mod1Mask etc. Logical modifiers are different from the physical keys. Left shift and right shift keys result in the same modifier mask.

If you need the modifier mask, then every X11 key and button event contains a mask of active modifiers in the state member. If you are using Xkb (you probably should), there is XkbGetState.

I don't know of any way to get the state of a physical key, other than monitoring key press and key release events.

Upvotes: 4

Related Questions