aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2020-10-08 10:59:12 +0200
committerOmar Polo <op@omarpolo.com>2020-10-08 10:59:12 +0200
commitc21d6eaf97dbcc03bbf6bd90096349dba8e1b071 (patch)
tree939880211e01d3d5bae9e6189ff99c33bd0242cb
parentc85d4bf338efd6371825dfe51680c62ee65be408 (diff)
downloadstar-platinum-c21d6eaf97dbcc03bbf6bd90096349dba8e1b071.tar.gz
star-platinum-c21d6eaf97dbcc03bbf6bd90096349dba8e1b071.tar.bz2
grabkey only on the targeted windows
now we grabkey() only on the window that matches what the user requested. That is, given match class 'Firefox' on "C-n" do "<Down>" we only bind C-n on windows that match the class Firefox, and not on the root window as we did before. In order to do this, we traverse the tree during startup and grabkey on matching windows, than we subscribe also to SubstructureNotify so that when a window gets mapped we receive an event. There are still some downsides to this. Firefox uses also '/usr/local/lib/firefox/firefox' as class name on my machine, and sometimes it seems like we don’t grab the key at the first try (maybe Firefox changes the class after the window gets mapped?)
-rw-r--r--star-platinum.c58
-rw-r--r--star-platinum.h2
2 files changed, 53 insertions, 7 deletions
diff --git a/star-platinum.c b/star-platinum.c
index 1bfeb83..03c5636 100644
--- a/star-platinum.c
+++ b/star-platinum.c
@@ -119,8 +119,6 @@ int
main(int argc, char **argv)
{
int status = 0, dump_config = 0, conftest = 0, ch;
- struct group *g;
- struct rule *r;
XEvent e;
Window root;
@@ -182,12 +180,9 @@ main(int argc, char **argv)
root = DefaultRootWindow(d);
- /* grab all the keys */
- for (g = config; g != NULL; g = g->next)
- for (r = g->rules; r != NULL; r = r->next)
- grabkey(r->key, root);
+ grabkey_matching_windows();
- XSelectInput(d, root, KeyPressMask);
+ XSelectInput(d, root, SubstructureNotifyMask | KeyPressMask);
XFlush(d);
pledge("stdio proc exec", NULL);
@@ -200,6 +195,20 @@ main(int argc, char **argv)
process_event(config, (XKeyEvent*)&e);
break;
+ case MapNotify: {
+ XMapEvent *ev = (XMapEvent*)&e;
+ grab_matching_keys(ev->window);
+ break;
+ }
+
+ case UnmapNotify:
+ case ConfigureNotify:
+ case CreateNotify:
+ case DestroyNotify:
+ case ClientMessage:
+ /* ignored */
+ break;
+
default:
printf("Unknown event %d\n", e.type);
break;
@@ -236,6 +245,41 @@ grabkey(struct key k, Window w)
}
}
+void
+grab_matching_keys(Window w)
+{
+ XClassHint ch;
+ struct group *g;
+ struct rule *r;
+
+ if (!XGetClassHint(d, w, &ch))
+ return;
+
+ for (g = config; g != NULL; g = g->next) {
+ if (!group_match(g, w))
+ continue;
+
+ for (r = g->rules; r != NULL; r = r->next)
+ grabkey(r->key, w);
+ }
+}
+
+int
+grabkey_matching_windows()
+{
+ Window root, parent, *children;
+ unsigned int len, i;
+
+ root = DefaultRootWindow(d);
+ if (!XQueryTree(d, root, &root, &parent, &children, &len))
+ return 0;
+
+ for (i = 0; i < len; ++i)
+ grab_matching_keys(children[i]);
+
+ return 1;
+}
+
KeySym
keycode_to_keysym(unsigned int kc)
{
diff --git a/star-platinum.h b/star-platinum.h
index 96277b5..b92ba21 100644
--- a/star-platinum.h
+++ b/star-platinum.h
@@ -91,6 +91,8 @@ int group_match(struct group*, Window);
/* xlib-related */
int error_handler(Display*, XErrorEvent*);
void grabkey(struct key, Window);
+void grab_matching_keys(Window);
+int grabkey_matching_windows();
KeySym keycode_to_keysym(unsigned int);
Window focused_window();
void send_fake(Window, struct key, XKeyEvent*);