broadcast kitten: Keep the ghost cursors in target windows as long as broadcast window has focus
This commit is contained in:
@@ -7,7 +7,7 @@ from functools import partial
|
|||||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Union
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Union
|
||||||
|
|
||||||
from kitty.fast_data_types import (
|
from kitty.fast_data_types import (
|
||||||
KeyEvent as WindowSystemKeyEvent, add_timer, get_boss, remove_timer, get_options
|
KeyEvent as WindowSystemKeyEvent, get_boss, remove_timer
|
||||||
)
|
)
|
||||||
from kitty.key_encoding import decode_key_event_as_window_system_key
|
from kitty.key_encoding import decode_key_event_as_window_system_key
|
||||||
from kitty.options.utils import parse_send_text_bytes
|
from kitty.options.utils import parse_send_text_bytes
|
||||||
@@ -45,6 +45,17 @@ def clear_unfocused_cursors(sid: str, *a: Any) -> None:
|
|||||||
qw.screen.render_unfocused_cursor = 0
|
qw.screen.render_unfocused_cursor = 0
|
||||||
|
|
||||||
|
|
||||||
|
def handle_focus_change(sid: str, window: Window, focused: bool) -> None:
|
||||||
|
s = sessions_map.get(sid)
|
||||||
|
if s is not None:
|
||||||
|
boss = get_boss()
|
||||||
|
val = int(focused)
|
||||||
|
for wid in s.window_ids:
|
||||||
|
qw = boss.window_id_map.get(wid)
|
||||||
|
if qw is not None:
|
||||||
|
qw.screen.render_unfocused_cursor = val
|
||||||
|
|
||||||
|
|
||||||
class SendText(RemoteCommand):
|
class SendText(RemoteCommand):
|
||||||
'''
|
'''
|
||||||
data+: The data being sent. Can be either: text: followed by text or base64: followed by standard base64 encoded bytes
|
data+: The data being sent. Can be either: text: followed by text or base64: followed by standard base64 encoded bytes
|
||||||
@@ -190,8 +201,6 @@ Do not send text to the active window, even if it is one of the matched windows.
|
|||||||
remove_timer(s.timer_id)
|
remove_timer(s.timer_id)
|
||||||
s.timer_id = 0
|
s.timer_id = 0
|
||||||
return s
|
return s
|
||||||
blink_time = 15 if not get_options().cursor_stop_blinking_after else max(3, get_options().cursor_stop_blinking_after)
|
|
||||||
|
|
||||||
if session == 'end':
|
if session == 'end':
|
||||||
s = create_or_update_session()
|
s = create_or_update_session()
|
||||||
for w in actual_windows:
|
for w in actual_windows:
|
||||||
@@ -201,15 +210,14 @@ Do not send text to the active window, even if it is one of the matched windows.
|
|||||||
elif session == 'start':
|
elif session == 'start':
|
||||||
s = create_or_update_session()
|
s = create_or_update_session()
|
||||||
if window is not None:
|
if window is not None:
|
||||||
window.actions_on_close.append(partial(clear_unfocused_cursors, sid))
|
window.actions_on_removal.append(partial(clear_unfocused_cursors, sid))
|
||||||
s.timer_id = add_timer(partial(clear_unfocused_cursors, sid), blink_time, False)
|
window.actions_on_focus_change.append(partial(handle_focus_change, sid))
|
||||||
for w in actual_windows:
|
for w in actual_windows:
|
||||||
w.screen.render_unfocused_cursor = 1
|
w.screen.render_unfocused_cursor = 1
|
||||||
s.window_ids.add(w.id)
|
s.window_ids.add(w.id)
|
||||||
else:
|
else:
|
||||||
if sid:
|
if sid:
|
||||||
s = create_or_update_session()
|
s = create_or_update_session()
|
||||||
s.timer_id = add_timer(partial(clear_unfocused_cursors, sid), blink_time, False)
|
|
||||||
for w in actual_windows:
|
for w in actual_windows:
|
||||||
if sid:
|
if sid:
|
||||||
w.screen.render_unfocused_cursor = 1
|
w.screen.render_unfocused_cursor = 1
|
||||||
|
|||||||
@@ -480,6 +480,7 @@ class Window:
|
|||||||
self.current_clipboard_read_ask: Optional[bool] = None
|
self.current_clipboard_read_ask: Optional[bool] = None
|
||||||
self.prev_osc99_cmd = NotificationCommand()
|
self.prev_osc99_cmd = NotificationCommand()
|
||||||
self.actions_on_close: List[Callable[['Window'], None]] = []
|
self.actions_on_close: List[Callable[['Window'], None]] = []
|
||||||
|
self.actions_on_focus_change: List[Callable[['Window', bool], None]] = []
|
||||||
self.actions_on_removal: List[Callable[['Window'], None]] = []
|
self.actions_on_removal: List[Callable[['Window'], None]] = []
|
||||||
self.current_marker_spec: Optional[Tuple[str, Union[str, Tuple[Tuple[int, str], ...]]]] = None
|
self.current_marker_spec: Optional[Tuple[str, Union[str, Tuple[Tuple[int, str], ...]]]] = None
|
||||||
self.pty_resized_once = False
|
self.pty_resized_once = False
|
||||||
@@ -843,6 +844,12 @@ class Window:
|
|||||||
if self.destroyed:
|
if self.destroyed:
|
||||||
return
|
return
|
||||||
call_watchers(weakref.ref(self), 'on_focus_change', {'focused': focused})
|
call_watchers(weakref.ref(self), 'on_focus_change', {'focused': focused})
|
||||||
|
for c in self.actions_on_focus_change:
|
||||||
|
try:
|
||||||
|
c(self, focused)
|
||||||
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
self.screen.focus_changed(focused)
|
self.screen.focus_changed(focused)
|
||||||
if focused:
|
if focused:
|
||||||
self.last_focused_at = monotonic()
|
self.last_focused_at = monotonic()
|
||||||
|
|||||||
Reference in New Issue
Block a user