diff --git a/readconfig.c b/readconfig.c index 91520bb..f34e9b4 100644 --- a/readconfig.c +++ b/readconfig.c @@ -15,9 +15,9 @@ I output J output - When focus is on a window whose title matches regex, the following - translation class is in effect. An empty regex for the last class - will always match, allowing default translations. Any output + When focus is on a window whose class or title matches regex, the + following translation class is in effect. An empty regex for the last + class will always match, allowing default translations. Any output sequences not bound in a matched section will be loaded from the default section if they are bound there. @@ -809,7 +809,7 @@ read_config_file(void) } translation * -get_translation(char *win_title) +get_translation(char *win_title, char *win_class) { translation *tr; @@ -819,6 +819,12 @@ get_translation(char *win_title) if (tr->is_default) { return tr; } + // AG: We first try to match the class name, since it usually provides + // better identification clues. + if (win_class && *win_class && + regexec(&tr->regex, win_class, 0, NULL, 0) == 0) { + return tr; + } if (regexec(&tr->regex, win_title, 0, NULL, 0) == 0) { return tr; } diff --git a/shuttle.h b/shuttle.h index e9cb5ef..090c4f2 100644 --- a/shuttle.h +++ b/shuttle.h @@ -94,6 +94,6 @@ typedef struct _translation { stroke *jog[NUM_JOGS]; } translation; -extern translation *get_translation(char *win_title); +extern translation *get_translation(char *win_title, char *win_class); extern void print_stroke_sequence(char *name, char *up_or_down, stroke *s); extern int debug_keys; diff --git a/shuttlepro.c b/shuttlepro.c index af2fc72..63d1841 100644 --- a/shuttlepro.c +++ b/shuttlepro.c @@ -243,7 +243,26 @@ get_window_name(Window win) } char * -walk_window_tree(Window win) +get_window_class(Window win) +{ + Atom prop = XInternAtom(display, "WM_CLASS", False); + Atom type; + int form; + unsigned long remain, len; + unsigned char *list; + + if (XGetWindowProperty(display, win, prop, 0, 1024, False, + AnyPropertyType, &type, &form, &len, &remain, + &list) != Success) { + fprintf(stderr, "XGetWindowProperty failed for window 0x%x\n", (int)win); + return NULL; + } + + return (char*)list; +} + +char * +walk_window_tree(Window win, char **window_class) { char *window_name; Window root = 0; @@ -254,6 +273,7 @@ walk_window_tree(Window win) while (win != root) { window_name = get_window_name(win); if (window_name != NULL) { + *window_class = get_window_class(win); return window_name; } if (XQueryTree(display, win, &root, &parent, &children, &nchildren)) { @@ -275,29 +295,33 @@ get_focused_window_translation() { Window focus; int revert_to; - char *window_name = NULL; + char *window_name = NULL, *window_class = NULL; char *name; XGetInputFocus(display, &focus, &revert_to); if (focus != last_focused_window) { last_focused_window = focus; - window_name = walk_window_tree(focus); + window_name = walk_window_tree(focus, &window_class); if (window_name == NULL) { name = "-- Unlabeled Window --"; } else { name = window_name; } - last_window_translation = get_translation(name); + last_window_translation = get_translation(name, window_class); if (debug_regex) { if (last_window_translation != NULL) { - printf("translation: %s for %s\n", last_window_translation->name, name); + printf("translation: %s for %s (class %s)\n", + last_window_translation->name, name, window_class); } else { - printf("no translation found for %s\n", name); + printf("no translation found for %s (class %s)\n", name, window_class); } } if (window_name != NULL) { XFree(window_name); } + if (window_class != NULL) { + XFree(window_class); + } } return last_window_translation; }