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