diff --git a/patch/keyd/SwayFocus.patch b/patch/keyd/SwayFocus.patch new file mode 100644 index 00000000..bc5fe2c6 --- /dev/null +++ b/patch/keyd/SwayFocus.patch @@ -0,0 +1,120 @@ +From 8ab68aba77e29f2a75f35d1409da0503d79a74e3 Mon Sep 17 00:00:00 2001 +From: blankie +Date: Sat, 29 Jul 2023 09:48:54 +1000 +Subject: [PATCH 1/2] keyd-application-mapper: Apply bindings when title/app id + changes on wlroots + +Fixes #525 +--- + scripts/keyd-application-mapper | 47 ++++++++++++++++++++++++++------- + 1 file changed, 38 insertions(+), 9 deletions(-) + +diff --git a/scripts/keyd-application-mapper b/scripts/keyd-application-mapper +index 55dd63b..9fefcfc 100755 +--- a/scripts/keyd-application-mapper ++++ b/scripts/keyd-application-mapper +@@ -176,18 +176,47 @@ class Wlroots(): + + def run(self): + windows = {} ++ active_window = None ++ + while True: + (obj, event, payload) = self.wl.recv_msg() + if obj == 4 and event == 0: +- windows[struct.unpack('I', payload)[0]] = {} +- +- if obj in windows: +- if event == 0: +- windows[obj]['title'] = self.wl.read_string(payload) +- if event == 1: +- windows[obj]['appid'] = self.wl.read_string(payload) +- if event == 4 and payload[0] > 0 and payload[4] == 2: +- self.on_window_change(windows[obj].get('appid', ''), windows[obj].get('title', '')) ++ # zwlr_foreign_toplevel_manager_v1::toplevel event ++ windows[struct.unpack('I', payload)[0]] = {'title': '', 'appid': '', 'state': 0} ++ continue ++ ++ if obj not in windows: ++ continue ++ ++ if event == 0: ++ # zwlr_foreign_toplevel_handle_v1::title event ++ windows[obj]['title'] = self.wl.read_string(payload) ++ elif event == 1: ++ # zwlr_foreign_toplevel_handle_v1::app_id event ++ windows[obj]['appid'] = self.wl.read_string(payload) ++ elif event == 4: ++ # zwlr_foreign_toplevel_handle_v1::state event ++ windows[obj]['state'] = 0 ++ if active_window == windows[obj]: ++ active_window = None ++ ++ array_size = struct.unpack('I', payload[0:4])[0] ++ for i in range(0, array_size, 4): ++ start_offset = i + 4 ++ end_offset = start_offset + 4 ++ windows[obj]['state'] |= struct.unpack('I', payload[start_offset:end_offset])[0] ++ ++ # zwlr_foreign_toplevel_handle_v1::state enum -> activated ++ if windows[obj]['state'] & 2: ++ active_window = windows[obj] ++ elif event == 5 and active_window == windows[obj]: ++ # zwlr_foreign_toplevel_handle_v1::done event ++ self.on_window_change(active_window['appid'], active_window['title']) ++ elif event == 6: ++ # zwlr_foreign_toplevel_handle_v1::closed event ++ closed_window = windows.pop(obj) ++ if closed_window == active_window: ++ active_window = None + + class XMonitor(): + def __init__(self, on_window_change): + +From e31186ee8526e0f2601e2ee9a4071a340506cb99 Mon Sep 17 00:00:00 2001 +From: blankie +Date: Sat, 29 Jul 2023 10:04:49 +1000 +Subject: [PATCH 2/2] keyd-application-mapper: Properly check window state + +--- + scripts/keyd-application-mapper | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/scripts/keyd-application-mapper b/scripts/keyd-application-mapper +index 9fefcfc..ed74f4e 100755 +--- a/scripts/keyd-application-mapper ++++ b/scripts/keyd-application-mapper +@@ -182,7 +182,7 @@ class Wlroots(): + (obj, event, payload) = self.wl.recv_msg() + if obj == 4 and event == 0: + # zwlr_foreign_toplevel_manager_v1::toplevel event +- windows[struct.unpack('I', payload)[0]] = {'title': '', 'appid': '', 'state': 0} ++ windows[struct.unpack('I', payload)[0]] = {'title': '', 'appid': ''} + continue + + if obj not in windows: +@@ -196,18 +196,20 @@ class Wlroots(): + windows[obj]['appid'] = self.wl.read_string(payload) + elif event == 4: + # zwlr_foreign_toplevel_handle_v1::state event +- windows[obj]['state'] = 0 + if active_window == windows[obj]: + active_window = None ++ window_is_active = False + + array_size = struct.unpack('I', payload[0:4])[0] + for i in range(0, array_size, 4): + start_offset = i + 4 + end_offset = start_offset + 4 +- windows[obj]['state'] |= struct.unpack('I', payload[start_offset:end_offset])[0] ++ state = struct.unpack('I', payload[start_offset:end_offset])[0] ++ # zwlr_foreign_toplevel_handle_v1::state enum -> activated ++ if state == 2: ++ window_is_active = True + +- # zwlr_foreign_toplevel_handle_v1::state enum -> activated +- if windows[obj]['state'] & 2: ++ if window_is_active: + active_window = windows[obj] + elif event == 5 and active_window == windows[obj]: + # zwlr_foreign_toplevel_handle_v1::done event