You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
6.5 KiB
150 lines
6.5 KiB
10 years ago
|
https://github.com/knopwob/dunst/commit/be7d2b351
|
||
|
|
||
|
From be7d2b3511dc528b135e5dc6d5358c700fefaa30 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= <necoro@necoro.net>
|
||
|
Date: Mon, 3 Jun 2013 14:39:24 +0200
|
||
|
Subject: [PATCH] Correctly handle Num_Lock.
|
||
|
|
||
|
Find out which modifier key is used by Num_Lock (`x_numlock_mod()`) and
|
||
|
register grabs for both variants: modifier present/not present.
|
||
|
---
|
||
|
x.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
|
||
|
1 file changed, 67 insertions(+), 6 deletions(-)
|
||
|
|
||
|
--- a/x.c
|
||
|
+++ b/x.c
|
||
|
@@ -485,6 +485,58 @@ static void setopacity(Window win, unsigned long opacity)
|
||
|
|
||
|
|
||
|
|
||
|
+ /*
|
||
|
+ * Returns the modifier which is NumLock.
|
||
|
+ */
|
||
|
+static KeySym x_numlock_mod()
|
||
|
+{
|
||
|
+ static KeyCode nl = 0;
|
||
|
+ KeySym sym = 0;
|
||
|
+ XModifierKeymap * map = XGetModifierMapping(xctx.dpy);
|
||
|
+
|
||
|
+ if (!nl)
|
||
|
+ nl = XKeysymToKeycode(xctx.dpy, XStringToKeysym("Num_Lock"));
|
||
|
+
|
||
|
+ for (int mod = 0; mod < 8; mod++) {
|
||
|
+ for (int j = 0; j < map->max_keypermod; j++) {
|
||
|
+ if (map->modifiermap[mod*map->max_keypermod+j] == nl) {
|
||
|
+ /* In theory, one could use `1 << mod`, but this
|
||
|
+ * could count as 'using implementation details',
|
||
|
+ * so use this large switch. */
|
||
|
+ switch (mod) {
|
||
|
+ case ShiftMapIndex:
|
||
|
+ sym = ShiftMask;
|
||
|
+ goto end;
|
||
|
+ case LockMapIndex:
|
||
|
+ sym = LockMask;
|
||
|
+ goto end;
|
||
|
+ case ControlMapIndex:
|
||
|
+ sym = ControlMask;
|
||
|
+ goto end;
|
||
|
+ case Mod1MapIndex:
|
||
|
+ sym = Mod1Mask;
|
||
|
+ goto end;
|
||
|
+ case Mod2MapIndex:
|
||
|
+ sym = Mod2Mask;
|
||
|
+ goto end;
|
||
|
+ case Mod3MapIndex:
|
||
|
+ sym = Mod3Mask;
|
||
|
+ goto end;
|
||
|
+ case Mod4MapIndex:
|
||
|
+ sym = Mod4Mask;
|
||
|
+ goto end;
|
||
|
+ case Mod5MapIndex:
|
||
|
+ sym = Mod5Mask;
|
||
|
+ goto end;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+end:
|
||
|
+ XFreeModifiermap(map);
|
||
|
+ return sym;
|
||
|
+}
|
||
|
|
||
|
/*
|
||
|
* Helper function to use glib's mainloop mechanic
|
||
|
@@ -515,6 +567,7 @@ gboolean x_mainloop_fd_dispatch(GSource * source, GSourceFunc callback,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
XEvent ev;
|
||
|
+ unsigned int state;
|
||
|
while (XPending(xctx.dpy) > 0) {
|
||
|
XNextEvent(xctx.dpy, &ev);
|
||
|
switch (ev.type) {
|
||
|
@@ -535,10 +588,13 @@ gboolean x_mainloop_fd_dispatch(GSource * source, GSourceFunc callback,
|
||
|
}
|
||
|
break;
|
||
|
case KeyPress:
|
||
|
+ state = ev.xkey.state;
|
||
|
+ /* NumLock is also encoded in the state. Remove it. */
|
||
|
+ state &= ~x_numlock_mod();
|
||
|
if (settings.close_ks.str
|
||
|
&& XLookupKeysym(&ev.xkey,
|
||
|
0) == settings.close_ks.sym
|
||
|
- && settings.close_ks.mask == ev.xkey.state) {
|
||
|
+ && settings.close_ks.mask == state) {
|
||
|
if (displayed) {
|
||
|
notification *n = g_queue_peek_head(displayed);
|
||
|
if (n)
|
||
|
@@ -548,19 +604,19 @@ gboolean x_mainloop_fd_dispatch(GSource * source, GSourceFunc callback,
|
||
|
if (settings.history_ks.str
|
||
|
&& XLookupKeysym(&ev.xkey,
|
||
|
0) == settings.history_ks.sym
|
||
|
- && settings.history_ks.mask == ev.xkey.state) {
|
||
|
+ && settings.history_ks.mask == state) {
|
||
|
history_pop();
|
||
|
}
|
||
|
if (settings.close_all_ks.str
|
||
|
&& XLookupKeysym(&ev.xkey,
|
||
|
0) == settings.close_all_ks.sym
|
||
|
- && settings.close_all_ks.mask == ev.xkey.state) {
|
||
|
+ && settings.close_all_ks.mask == state) {
|
||
|
move_all_to_history();
|
||
|
}
|
||
|
if (settings.context_ks.str
|
||
|
&& XLookupKeysym(&ev.xkey,
|
||
|
0) == settings.context_ks.sym
|
||
|
- && settings.context_ks.mask == ev.xkey.state) {
|
||
|
+ && settings.context_ks.mask == state) {
|
||
|
context_menu();
|
||
|
}
|
||
|
break;
|
||
|
@@ -953,9 +1009,12 @@ int x_shortcut_grab(keyboard_shortcut * ks)
|
||
|
|
||
|
x_shortcut_setup_error_handler();
|
||
|
|
||
|
- if (ks->is_valid)
|
||
|
+ if (ks->is_valid) {
|
||
|
XGrabKey(xctx.dpy, ks->code, ks->mask, root,
|
||
|
true, GrabModeAsync, GrabModeAsync);
|
||
|
+ XGrabKey(xctx.dpy, ks->code, ks->mask | x_numlock_mod() , root,
|
||
|
+ true, GrabModeAsync, GrabModeAsync);
|
||
|
+ }
|
||
|
|
||
|
if (x_shortcut_tear_down_error_handler()) {
|
||
|
fprintf(stderr, "Unable to grab key \"%s\"\n", ks->str);
|
||
|
@@ -972,8 +1031,10 @@ void x_shortcut_ungrab(keyboard_shortcut * ks)
|
||
|
{
|
||
|
Window root;
|
||
|
root = RootWindow(xctx.dpy, DefaultScreen(xctx.dpy));
|
||
|
- if (ks->is_valid)
|
||
|
+ if (ks->is_valid) {
|
||
|
XUngrabKey(xctx.dpy, ks->code, ks->mask, root);
|
||
|
+ XUngrabKey(xctx.dpy, ks->code, ks->mask | x_numlock_mod(), root);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
--
|
||
|
1.9.1
|
||
|
|