From 74b6f236bdc561699cd47d948c3a22e3923d8d81 Mon Sep 17 00:00:00 2001 From: Akemi Izuko Date: Mon, 20 Feb 2023 19:10:25 -0700 Subject: [PATCH] Add inversion mappings to application-mapper Headings can now use a `!` in front, like `![kitty]` to bind keys to all apps except the specified one --- docs/keyd-application-mapper.scdoc | 12 +++++++++--- scripts/keyd-application-mapper | 21 +++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/docs/keyd-application-mapper.scdoc b/docs/keyd-application-mapper.scdoc index 1925472..e5d3527 100644 --- a/docs/keyd-application-mapper.scdoc +++ b/docs/keyd-application-mapper.scdoc @@ -34,6 +34,9 @@ to be matched, and may optionally contain unix style wildcards (\*). For example _[gnome|\*find\*]_ will match any window with a class of _gnome_ and a title containing the substring _find_. +An optional ! can be added ahead of the filter brackets to invert the match. This +matches everything that is not both the class expression and the given title. + E.G: ``` @@ -43,6 +46,9 @@ E.G: alt.[ = C-S-tab alt.t = C-S-t + ![kitty] + alt.[ = escape + [st-*] alt.1 = macro(Inside space st) @@ -56,7 +62,7 @@ E.G: ``` Will remap _A-1_ to the the string 'Inside st' when a window with a class -that begins with 'st-' (e.g st-256color) is active. +that begins with 'st-' (e.g st-256color) is active. Window class and title names can be obtained by inspecting the log output while the daemon is running (e.g _tail\ -f\ ~/.config/keyd/app.log_). A reload may be triggered @@ -68,12 +74,12 @@ At the moment X, Sway and Gnome are supported. Installation is a simple matter of running the command _keyd-application-mapper -d_ somewhere in your display server initialization logic (e.g _~/.xinitrc_ or -_~/.xsession_). If you are running Gnome, +_~/.xsession_). If you are running Gnome, running _keyd-application-mapper_ for the first time will install an extension which manages the script lifecycle. In order for this to work, keyd must be running and the user must have access -to */var/run/keyd.socket* (i.e be a member of the *keyd* group). +to */var/run/keyd.socket* (i.e be a member of the *keyd* group). # A note on security diff --git a/scripts/keyd-application-mapper b/scripts/keyd-application-mapper index 995e5f3..4eea526 100755 --- a/scripts/keyd-application-mapper +++ b/scripts/keyd-application-mapper @@ -63,8 +63,13 @@ def parse_config(path): for line in open(path): line = line.strip() - if line.startswith('[') and line.endswith(']'): - a = line[1:-1].split('|') + if (line.startswith('[') or line.startswith('!')) and line.endswith(']'): + if line.startswith('!'): + is_invert = True + a = line[2:-1].split('|') + else: + is_invert = False + a = line[1:-1].split('|') if len(a) < 2: cls = a[0] @@ -74,7 +79,7 @@ def parse_config(path): title = a[1] bindings = [] - config.append((cls, title, bindings)) + config.append((cls, title, is_invert, bindings)) elif line == '': continue elif line.startswith('#'): @@ -454,11 +459,15 @@ lock() def lookup_bindings(cls, title): bindings = [] - for cexp, texp, b in config: - if fnmatch(cls, cexp) and fnmatch(title, texp): - dbg(f'\tMatched {cexp}|{texp}') + for cexp, texp, is_invert, b in config: + if fnmatch(cls, cexp) and fnmatch(title, texp) and not is_invert: + dbg(f'\tMatched {cexp}|{texp} with no inverse') + bindings.extend(b) + elif not (fnmatch(cls, cexp) and fnmatch(title, texp)) and is_invert: + dbg(f'\tMatched {cexp}|{texp} by inversion') bindings.extend(b) + dbg(f"\tSetting keybinds: {b}") return bindings def normalize_class(s):