[ACCEPTED]-Global Hotkey with X11/Xlib-xlib
Your program works here. My guess is you 4 have another modifier active, such as NumLock. GrabKey 3 only works on the exact modifier mask.
For example 2 here is some (GPL) code from metacity window 1 manager
/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */
static void
meta_change_keygrab (MetaDisplay *display,
Window xwindow,
gboolean grab,
int keysym,
unsigned int keycode,
int modmask)
{
unsigned int ignored_mask;
/* Grab keycode/modmask, together with
* all combinations of ignored modifiers.
* X provides no better way to do this.
*/
meta_topic (META_DEBUG_KEYBINDINGS,
"%s keybinding %s keycode %d mask 0x%x on 0x%lx\n",
grab ? "Grabbing" : "Ungrabbing",
keysym_name (keysym), keycode,
modmask, xwindow);
/* efficiency, avoid so many XSync() */
meta_error_trap_push (display);
ignored_mask = 0;
while (ignored_mask <= display->ignored_modifier_mask)
{
if (ignored_mask & ~(display->ignored_modifier_mask))
{
/* Not a combination of ignored modifiers
* (it contains some non-ignored modifiers)
*/
++ignored_mask;
continue;
}
if (meta_is_debugging ())
meta_error_trap_push_with_return (display);
if (grab)
XGrabKey (display->xdisplay, keycode,
modmask | ignored_mask,
xwindow,
True,
GrabModeAsync, GrabModeSync);
else
XUngrabKey (display->xdisplay, keycode,
modmask | ignored_mask,
xwindow);
if (meta_is_debugging ())
{
int result;
result = meta_error_trap_pop_with_return (display, FALSE);
if (grab && result != Success)
{
if (result == BadAccess)
meta_warning (_("Some other program is already using the key %s with modifiers %x as a binding\n"), keysym_name (keysym), modmask | ignored_mask);
else
meta_topic (META_DEBUG_KEYBINDINGS,
"Failed to grab key %s with modifiers %x\n",
keysym_name (keysym), modmask | ignored_mask);
}
}
++ignored_mask;
}
meta_error_trap_pop (display, FALSE);
}
With your mask ControlMask | ShiftMask
you will not get the key 12 if another modifier key is held. This sounds 11 okay in the first place, but there's a pitfall: NumLock, CapsLock and 10 alike all are treated as modifiers, too.
You 9 have two options:
- You call
XGrabKey()
multiple times, once for each explicit combination that you're interested in. - You call
XGrabKey()
withAnyModifier
and useevent.xkey.state
to check whether the modifiers are as you expected.
The header file <X.h>
defines 8 ShiftMask
, LockMask
, ControlMask
, Mod1Mask
, Mod2Mask
, Mod3Mask
, Mod4Mask
, Mod5Mask
and AnyModifier
.
The keys are:
Mask | Value | Key
------------+-------+------------
ShiftMask | 1 | Shift
LockMask | 2 | Caps Lock
ControlMask | 4 | Ctrl
Mod1Mask | 8 | Alt
Mod2Mask | 16 | Num Lock
Mod3Mask | 32 | Scroll Lock
Mod4Mask | 64 | Windows
Mod5Mask | 128 | ???
Warning I found 7 out about the ModNMask
keys by trying and I do not 6 know if this is valid on all machines / configurations 5 / versions / operating systems.
In your case, you 4 probably want to make sure that ShiftMask | CtrlMask
is set, Mod1Mask | Mod4Mask
are 3 clear, and the others to be ignored.
I'd 2 do this to setup the key grab:
XGrabKey(dpy, keycode, AnyModifier, grab_window, owner_events, pointer_mode, keyboard_mode);
And this to 1 check whether the right modifiers are set:
switch (ev.type) {
case KeyPress:
if ((ev.xkey.state & (ShiftMask | CtrlMask | Mod1Mask | Mod4Mask)) == (ShiftMask | CtrlMask))
// ...
}
If you're using/targeting gtk on X11, there's 3 a C library with a much simpler interface:
https://github.com/engla/keybinder
Includes 2 Python, Lua and Vala bindings. (Also mentioned 1 here.)
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.