Exclude the currently active window when visually selecting
This commit is contained in:
parent
8458b9e7d6
commit
dc09a5183a
@ -9,7 +9,8 @@ from contextlib import suppress
|
||||
from functools import partial
|
||||
from gettext import gettext as _
|
||||
from typing import (
|
||||
Any, Callable, Dict, Iterable, Iterator, List, Optional, Tuple, Union, cast
|
||||
Any, Callable, Container, Dict, Iterable, Iterator, List, Optional, Tuple,
|
||||
Union, cast
|
||||
)
|
||||
from weakref import WeakValueDictionary
|
||||
|
||||
@ -859,29 +860,38 @@ class Boss:
|
||||
self.current_visual_select.cancel()
|
||||
self.current_visual_select = None
|
||||
|
||||
def visual_window_select_action(self, tab: Tab, callback: Callable[[Optional[Tab], Optional[Window]], None], choose_msg: str) -> None:
|
||||
def visual_window_select_action(
|
||||
self, tab: Tab,
|
||||
callback: Callable[[Optional[Tab], Optional[Window]], None],
|
||||
choose_msg: str,
|
||||
only_window_ids: Container[int] = ()
|
||||
) -> None:
|
||||
self.cancel_current_visual_select()
|
||||
tm = tab.tab_manager_ref()
|
||||
if tm is not None:
|
||||
tm.set_active_tab(tab)
|
||||
self.current_visual_select = VisualSelect(tab.id, tab.os_window_id, choose_msg, callback)
|
||||
if tab.current_layout.only_active_window_visible:
|
||||
self.select_window_in_tab_using_overlay(tab, choose_msg)
|
||||
self.select_window_in_tab_using_overlay(tab, choose_msg, only_window_ids)
|
||||
return
|
||||
pending_sequences: SubSequenceMap = {}
|
||||
fmap = get_name_to_functional_number_map()
|
||||
num = 0
|
||||
for idx, window in tab.windows.iter_windows_with_number(only_visible=True):
|
||||
if idx > 9:
|
||||
break
|
||||
num = idx + 1
|
||||
if only_window_ids and window.id not in only_window_ids:
|
||||
continue
|
||||
ac = KeyAction('visual_window_select_action_trigger', (window.id,))
|
||||
if num == 10:
|
||||
num += 1
|
||||
is_last = num == 10
|
||||
if is_last:
|
||||
num = 0
|
||||
window.screen.set_window_number(num)
|
||||
self.current_visual_select.window_ids.append(window.id)
|
||||
for mods in (0, GLFW_MOD_CONTROL, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT, GLFW_MOD_SUPER, GLFW_MOD_ALT, GLFW_MOD_SHIFT):
|
||||
pending_sequences[(SingleKey(mods=mods, key=ord(str(num))),)] = ac
|
||||
pending_sequences[(SingleKey(mods=mods, key=fmap[f'KP_{num}']),)] = ac
|
||||
if is_last:
|
||||
break
|
||||
if len(self.current_visual_select.window_ids) > 1:
|
||||
self.set_pending_sequences(pending_sequences, default_pending_action=KeyAction('visual_window_select_action_trigger', (0,)))
|
||||
redirect_mouse_handling(True)
|
||||
@ -914,8 +924,9 @@ class Boss:
|
||||
ev = WindowSystemMouseEvent(in_tab_bar, window_id, action, modifiers, button, currently_pressed_button, x, y)
|
||||
self.mouse_handler(ev)
|
||||
|
||||
def select_window_in_tab_using_overlay(self, tab: Tab, msg: str) -> None:
|
||||
windows = tuple((w.id, w.title) for i, w in tab.windows.iter_windows_with_number(only_visible=False))
|
||||
def select_window_in_tab_using_overlay(self, tab: Tab, msg: str, only_window_ids: Container[int] = ()) -> None:
|
||||
windows = tuple((w.id, w.title) for i, w in tab.windows.iter_windows_with_number(only_visible=False)
|
||||
if not only_window_ids or w.id in only_window_ids)
|
||||
if len(windows) < 1:
|
||||
self.visual_window_select_action_trigger(windows[0][0] if windows else 0)
|
||||
if get_options().enable_audio_bell:
|
||||
|
||||
@ -19,6 +19,7 @@ class SelectWindow(RemoteCommand):
|
||||
match: The tab to open the new window in
|
||||
self: Boolean, if True use tab the command was run in
|
||||
title: A title for this selection
|
||||
exclude_active: Exclude the currently active window from the list to pick
|
||||
'''
|
||||
|
||||
short_desc = 'Visually select a window in the specified tab'
|
||||
@ -41,11 +42,16 @@ instead of the active tab.
|
||||
|
||||
--title
|
||||
A title that will be displayed to the user to describe what this selection is for
|
||||
|
||||
|
||||
--exclude-active
|
||||
type=bool-set
|
||||
Exclude the currently active window from the list of windows to pick
|
||||
'''
|
||||
is_asynchronous = True
|
||||
|
||||
def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
|
||||
ans = {'self': opts.self, 'match': opts.match, 'title': opts.title}
|
||||
ans = {'self': opts.self, 'match': opts.match, 'title': opts.title, 'exclude_active': opts.exclude_active}
|
||||
return ans
|
||||
|
||||
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
|
||||
@ -58,7 +64,11 @@ A title that will be displayed to the user to describe what this selection is fo
|
||||
responder.send_error('No window selected')
|
||||
for tab in self.tabs_for_match_payload(boss, window, payload_get):
|
||||
if tab:
|
||||
boss.visual_window_select_action(tab, callback, payload_get('title') or 'Choose window')
|
||||
if payload_get('exclude_active'):
|
||||
wids = tab.all_window_ids_except_active_window
|
||||
else:
|
||||
wids = set()
|
||||
boss.visual_window_select_action(tab, callback, payload_get('title') or 'Choose window', only_window_ids=wids)
|
||||
break
|
||||
return no_response
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ from operator import attrgetter
|
||||
from time import monotonic
|
||||
from typing import (
|
||||
Any, Deque, Dict, Generator, Iterable, Iterator, List, NamedTuple,
|
||||
Optional, Pattern, Sequence, Tuple, Union, cast
|
||||
Optional, Pattern, Sequence, Set, Tuple, Union, cast
|
||||
)
|
||||
|
||||
from .borders import Border, Borders
|
||||
@ -596,6 +596,14 @@ class Tab: # {{{
|
||||
if self.current_layout.move_window_to_group(self.windows, group.id):
|
||||
self.relayout()
|
||||
|
||||
@property
|
||||
def all_window_ids_except_active_window(self) -> Set[int]:
|
||||
all_window_ids = {w.id for w in self}
|
||||
aw = self.active_window
|
||||
if aw is not None:
|
||||
all_window_ids.discard(aw.id)
|
||||
return all_window_ids
|
||||
|
||||
@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.
|
||||
@ -605,14 +613,14 @@ class Tab: # {{{
|
||||
if tab and window:
|
||||
tab.set_active_window(window)
|
||||
|
||||
get_boss().visual_window_select_action(self, callback, 'Choose window to switch to')
|
||||
get_boss().visual_window_select_action(self, callback, 'Choose window to switch to', only_window_ids=self.all_window_ids_except_active_window)
|
||||
|
||||
@ac('win', 'Swap the current window with another window in the current tab, selected visually')
|
||||
def swap_with_window(self) -> None:
|
||||
def callback(tab: Optional[Tab], window: Optional[Window]) -> None:
|
||||
if tab and window:
|
||||
tab.swap_active_window_with(window.id)
|
||||
get_boss().visual_window_select_action(self, callback, 'Choose window to swap with')
|
||||
get_boss().visual_window_select_action(self, callback, 'Choose window to swap with', only_window_ids=self.all_window_ids_except_active_window)
|
||||
|
||||
@ac('win', 'Move active window to the top (make it the first window)')
|
||||
def move_window_to_top(self) -> None:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user