mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-19 06:54:58 +02:00
A mappable action to visually select the window to focus with the keyboard
This commit is contained in:
@@ -34,7 +34,7 @@ from .fast_data_types import (
|
|||||||
current_application_quit_request, current_os_window, destroy_global_data,
|
current_application_quit_request, current_os_window, destroy_global_data,
|
||||||
focus_os_window, get_clipboard_string, get_options, get_os_window_size,
|
focus_os_window, get_clipboard_string, get_options, get_os_window_size,
|
||||||
global_font_size, mark_os_window_for_close, os_window_font_size,
|
global_font_size, mark_os_window_for_close, os_window_font_size,
|
||||||
patch_global_colors, safe_pipe, set_application_quit_request,
|
patch_global_colors, ring_bell, safe_pipe, set_application_quit_request,
|
||||||
set_background_image, set_boss, set_clipboard_string, set_in_sequence_mode,
|
set_background_image, set_boss, set_clipboard_string, set_in_sequence_mode,
|
||||||
set_options, set_os_window_size, thread_write, toggle_fullscreen,
|
set_options, set_os_window_size, thread_write, toggle_fullscreen,
|
||||||
toggle_maximized
|
toggle_maximized
|
||||||
@@ -158,6 +158,7 @@ class Boss:
|
|||||||
self.startup_colors = {k: opts[k] for k in opts if isinstance(opts[k], Color)}
|
self.startup_colors = {k: opts[k] for k in opts if isinstance(opts[k], Color)}
|
||||||
self.startup_cursor_text_color = opts.cursor_text_color
|
self.startup_cursor_text_color = opts.cursor_text_color
|
||||||
self.pending_sequences: Optional[SubSequenceMap] = None
|
self.pending_sequences: Optional[SubSequenceMap] = None
|
||||||
|
self.default_pending_action: Optional[KeyAction] = None
|
||||||
self.cached_values = cached_values
|
self.cached_values = cached_values
|
||||||
self.os_window_map: Dict[int, TabManager] = {}
|
self.os_window_map: Dict[int, TabManager] = {}
|
||||||
self.os_window_death_actions: Dict[int, Callable[[], None]] = {}
|
self.os_window_death_actions: Dict[int, Callable[[], None]] = {}
|
||||||
@@ -758,14 +759,18 @@ class Boss:
|
|||||||
if t is not None:
|
if t is not None:
|
||||||
return t.active_window
|
return t.active_window
|
||||||
|
|
||||||
|
def set_pending_sequences(self, sequences: SubSequenceMap, default_pending_action: Optional[KeyAction] = None) -> None:
|
||||||
|
self.pending_sequences = sequences
|
||||||
|
self.default_pending_action = default_pending_action
|
||||||
|
set_in_sequence_mode(True)
|
||||||
|
|
||||||
def dispatch_possible_special_key(self, ev: KeyEvent) -> bool:
|
def dispatch_possible_special_key(self, ev: KeyEvent) -> bool:
|
||||||
# Handles shortcuts, return True if the key was consumed
|
# Handles shortcuts, return True if the key was consumed
|
||||||
key_action = get_shortcut(self.keymap, ev)
|
key_action = get_shortcut(self.keymap, ev)
|
||||||
if key_action is None:
|
if key_action is None:
|
||||||
sequences = get_shortcut(get_options().sequence_map, ev)
|
sequences = get_shortcut(get_options().sequence_map, ev)
|
||||||
if sequences and not isinstance(sequences, KeyAction):
|
if sequences and not isinstance(sequences, KeyAction):
|
||||||
self.pending_sequences = sequences
|
self.set_pending_sequences(sequences)
|
||||||
set_in_sequence_mode(True)
|
|
||||||
return True
|
return True
|
||||||
if self.global_shortcuts_map and get_shortcut(self.global_shortcuts_map, ev):
|
if self.global_shortcuts_map and get_shortcut(self.global_shortcuts_map, ev):
|
||||||
return True
|
return True
|
||||||
@@ -790,11 +795,37 @@ class Boss:
|
|||||||
if remaining:
|
if remaining:
|
||||||
self.pending_sequences = remaining
|
self.pending_sequences = remaining
|
||||||
else:
|
else:
|
||||||
self.pending_sequences = None
|
matched_action = matched_action or self.default_pending_action
|
||||||
|
self.pending_sequences = self.default_pending_action = None
|
||||||
set_in_sequence_mode(False)
|
set_in_sequence_mode(False)
|
||||||
if matched_action is not None:
|
if matched_action is not None:
|
||||||
self.dispatch_action(matched_action)
|
self.dispatch_action(matched_action)
|
||||||
|
|
||||||
|
@ac('win', '''
|
||||||
|
Focus a visible window by pressing the number of the window. Window numbers are displayed
|
||||||
|
over the windows for easy selection in this mode.
|
||||||
|
''')
|
||||||
|
def focus_visible_window(self) -> None:
|
||||||
|
tab = self.active_tab
|
||||||
|
if tab is not None:
|
||||||
|
pending_sequences: SubSequenceMap = {}
|
||||||
|
for idx, window in tab.windows.iter_visible_windows_with_number():
|
||||||
|
window.screen.set_window_number(idx + 1)
|
||||||
|
pending_sequences[(SingleKey(key=ord(str(idx + 1))),)] = KeyAction('focus_visible_window_trigger', (idx,))
|
||||||
|
if pending_sequences:
|
||||||
|
self.set_pending_sequences(pending_sequences, default_pending_action=KeyAction('focus_visible_window_trigger'))
|
||||||
|
else:
|
||||||
|
if get_options().enable_audio_bell:
|
||||||
|
ring_bell()
|
||||||
|
|
||||||
|
def focus_visible_window_trigger(self, idx: int = -1) -> None:
|
||||||
|
tab = self.active_tab
|
||||||
|
if tab is not None:
|
||||||
|
for window in tab:
|
||||||
|
window.screen.set_window_number()
|
||||||
|
if idx > -1:
|
||||||
|
tab.nth_window(idx)
|
||||||
|
|
||||||
@ac('win', '''
|
@ac('win', '''
|
||||||
Resize the active window interactively
|
Resize the active window interactively
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import weakref
|
|||||||
from collections import deque
|
from collections import deque
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from itertools import count
|
from itertools import count
|
||||||
from typing import (
|
from typing import Any, Deque, Dict, Iterator, List, Optional, Tuple, Union
|
||||||
Any, Deque, Dict, Generator, Iterator, List, Optional, Tuple, Union
|
|
||||||
)
|
|
||||||
|
|
||||||
from .types import WindowGeometry
|
from .types import WindowGeometry
|
||||||
from .typing import EdgeLiteral, TabType, WindowType
|
from .typing import EdgeLiteral, TabType, WindowType
|
||||||
@@ -202,7 +200,7 @@ class WindowList:
|
|||||||
def change_tab(self, tab: TabType) -> None:
|
def change_tab(self, tab: TabType) -> None:
|
||||||
self.tabref = weakref.ref(tab)
|
self.tabref = weakref.ref(tab)
|
||||||
|
|
||||||
def iter_windows_with_visibility(self) -> Generator[Tuple[WindowType, bool], None, None]:
|
def iter_windows_with_visibility(self) -> Iterator[Tuple[WindowType, bool]]:
|
||||||
for g in self.groups:
|
for g in self.groups:
|
||||||
aw = g.active_window_id
|
aw = g.active_window_id
|
||||||
for window in g:
|
for window in g:
|
||||||
@@ -211,6 +209,16 @@ class WindowList:
|
|||||||
def iter_all_layoutable_groups(self, only_visible: bool = False) -> Iterator[WindowGroup]:
|
def iter_all_layoutable_groups(self, only_visible: bool = False) -> Iterator[WindowGroup]:
|
||||||
return iter(g for g in self.groups if g.is_visible_in_layout) if only_visible else iter(self.groups)
|
return iter(g for g in self.groups if g.is_visible_in_layout) if only_visible else iter(self.groups)
|
||||||
|
|
||||||
|
def iter_visible_windows_with_number(self) -> Iterator[Tuple[int, WindowType]]:
|
||||||
|
for i, g in enumerate(self.groups):
|
||||||
|
if g.is_visible_in_layout:
|
||||||
|
aw = g.active_window_id
|
||||||
|
for window in g:
|
||||||
|
if window in g:
|
||||||
|
if window.id == aw:
|
||||||
|
yield i, window
|
||||||
|
break
|
||||||
|
|
||||||
def make_previous_group_active(self, which: int = 1, notify: bool = True) -> None:
|
def make_previous_group_active(self, which: int = 1, notify: bool = True) -> None:
|
||||||
which = max(1, which)
|
which = max(1, which)
|
||||||
gid_map = {g.id: i for i, g in enumerate(self.groups)}
|
gid_map = {g.id: i for i, g in enumerate(self.groups)}
|
||||||
|
|||||||
Reference in New Issue
Block a user