From d233cd0a53b2b42cb7d263179dc7b1e2d4da5202 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 17 Aug 2025 13:33:16 +0530 Subject: [PATCH] Make switching OS window focus more robust under Wayland at various call sites --- kitty/boss.py | 24 +++++++++++++++++++----- kitty/session.py | 8 ++++++-- kitty/tabs.py | 4 +--- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/kitty/boss.py b/kitty/boss.py index 3ca349654..af34cbe52 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -593,6 +593,20 @@ def get_matches(location: str, query: str, candidates: set[int]) -> set[int]: if q: yield q + def focus_os_window(self, os_window_id: int, if_needed_only: bool = True) -> bool: + if if_needed_only and current_focused_os_window_id() == os_window_id: + return False + + def doit(token: str = '') -> None: + focus_os_window(os_window_id, True, token) + + if is_wayland(): + if not run_with_activation_token(doit): + doit() + else: + doit() + return True + def set_active_window( self, window: Window, switch_os_window_if_needed: bool = False, for_keep_focus: bool = False, activation_token: str = '' ) -> int | None: @@ -1560,7 +1574,7 @@ def visual_window_select_action( initial_tab_id = tm.active_tab.id tm.set_active_tab(tab) if initial_os_window_id != tab.os_window_id: - focus_os_window(tab.os_window_id, True) + self.focus_os_window(tab.os_window_id, False) self.current_visual_select = VisualSelect(tab.id, tab.os_window_id, initial_tab_id, initial_os_window_id, choose_msg, callback, reactivate_prev_tab) if tab.current_layout.only_active_window_visible: self.select_window_in_tab_using_overlay(tab, choose_msg, only_window_ids) @@ -1838,11 +1852,11 @@ def nth_os_window(self, num: int = 1) -> None: return if num == 0: os_window_id = current_focused_os_window_id() or last_focused_os_window_id() - focus_os_window(os_window_id, True) + self.focus_os_window(os_window_id) elif num > 0: ids = tuple(self.os_window_map.keys()) os_window_id = ids[min(num, len(ids)) - 1] - focus_os_window(os_window_id, True) + self.focus_os_window(os_window_id) elif num < 0: fc_map = os_window_focus_counters() s = sorted(fc_map.keys(), key=fc_map.__getitem__) @@ -1852,7 +1866,7 @@ def nth_os_window(self, num: int = 1) -> None: os_window_id = s[num-1] except IndexError: os_window_id = s[0] - focus_os_window(os_window_id, True) + self.focus_os_window(os_window_id) @ac('win', 'Close the currently active OS Window') def close_os_window(self) -> None: @@ -1933,7 +1947,7 @@ def quit(self, *args: Any) -> None: if tab is not None: ctm = tab.tab_manager_ref() if ctm is not None and tab in ctm and w in tab: - focus_os_window(ctm.os_window_id) + self.focus_os_window(ctm.os_window_id) ctm.set_active_tab(tab) tab.set_active_window(w) return diff --git a/kitty/session.py b/kitty/session.py index 05b1bd434..9a1dc9e6e 100644 --- a/kitty/session.py +++ b/kitty/session.py @@ -365,17 +365,21 @@ def skey(w: WindowType) -> float: def create_session(boss: BossType, path: str) -> str: session_name = '' for i, s in enumerate(create_sessions(get_options(), default_session=path)): + if i == 0: session_name = s.session_name if s.num_of_windows_in_definition == 0: # leading new_os_window continue tm = boss.active_tab_manager if tm is None: - boss.add_os_window(s) + os_window_id = boss.add_os_window(s) else: + os_window_id = tm.os_window_id tm.add_tabs_from_session(s) else: - boss.add_os_window(s) + os_window_id = boss.add_os_window(s) + if s.focus_os_window: + boss.focus_os_window(os_window_id) seen_session_paths[session_name] = path return session_name diff --git a/kitty/tabs.py b/kitty/tabs.py index fe4a00846..13cbe6721 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -32,7 +32,6 @@ buffer_keys_in_window, current_focused_os_window_id, detach_window, - focus_os_window, get_boss, get_click_interval, get_options, @@ -275,8 +274,7 @@ def _startup(self, session_tab: SessionTab) -> None: tm.set_active_tab(target_tab) if target_tab.active_window is not w: target_tab.set_active_window(w) - if current_focused_os_window_id() != w.os_window_id: - focus_os_window(w.os_window_id, True) + boss.focus_os_window(w.os_window_id) with suppress(IndexError): self.windows.set_active_window_group_for(self.windows.all_windows[session_tab.active_window_idx])