Skip to content

Commit 96d5c9c

Browse files
committedMar 12, 2025··
A new option to clear selections when they no longer reflect the contents of the clipboard
1 parent b34a880 commit 96d5c9c

File tree

7 files changed

+37
-1
lines changed

7 files changed

+37
-1
lines changed
 

‎docs/changelog.rst

+2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ Detailed list of changes
9999

100100
- Do not count background processes by default for :opt:`confirm_os_window_close` (:iss:`8358`)
101101

102+
- A new option :opt:`clear_selection_on_clipboard_loss` to clear selections when they no longer reflect the contents of the clipboard
103+
102104
- Fix flickering of hyperlink underline when client program continuously
103105
redraws on mouse movement (:iss:`8414`)
104106

‎kittens/hints/main.py

+2
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,10 @@ def is_copy_action(s: str) -> bool:
296296
w.paste_bytes(text)
297297
elif program == '@':
298298
set_clipboard_string(text)
299+
boss.handle_clipboard_loss('clipboard')
299300
elif program == '*':
300301
set_primary_selection(text)
302+
boss.handle_clipboard_loss('primary')
301303
elif program.startswith('@'):
302304
boss.set_clipboard_buffer(program[1:], text)
303305
else:

‎kitty/boss.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,7 @@ def set_primary_selection(self) -> None:
22432243
text = w.text_for_selection()
22442244
if text:
22452245
set_primary_selection(text)
2246+
self.handle_clipboard_loss('primary', w.id)
22462247
if get_options().copy_on_select:
22472248
self.copy_to_buffer(get_options().copy_on_select)
22482249

@@ -2280,8 +2281,10 @@ def copy_to_buffer(self, buffer_name: str) -> None:
22802281
if text:
22812282
if buffer_name == 'clipboard':
22822283
set_clipboard_string(text)
2284+
self.handle_clipboard_loss('clipboard', w.id)
22832285
elif buffer_name == 'primary':
22842286
set_primary_selection(text)
2287+
self.handle_clipboard_loss('primary', w.id)
22852288
else:
22862289
self.set_clipboard_buffer(buffer_name, text)
22872290

@@ -2508,8 +2511,10 @@ def create_window() -> SpecialWindowInstance:
25082511
if stdin:
25092512
if dest == 'clipboard':
25102513
set_clipboard_string(stdin)
2514+
self.handle_clipboard_loss('clipboard')
25112515
else:
25122516
set_primary_selection(stdin)
2517+
self.handle_clipboard_loss('primary')
25132518
else:
25142519
env, stdin = self.process_stdin_source(stdin=source, window=window)
25152520
self.run_background_process(cmd, cwd_from=cwd_from, stdin=stdin, env=env)
@@ -3062,6 +3067,7 @@ def debug_config(self) -> None:
30623067
if w is not None:
30633068
output = debug_config(get_options(), self.mappings.global_shortcuts)
30643069
set_clipboard_string(re.sub(r'\x1b.+?m', '', output))
3070+
self.handle_clipboard_loss('clipboard')
30653071
output += '\n\x1b[35mThis debug output has been copied to the clipboard\x1b[m' # ]]]
30663072
self.display_scrollback(w, output, title=_('Current kitty options'), report_cursor=False)
30673073

@@ -3112,4 +3118,12 @@ def update_progress_in_dock(self) -> None:
31123118
cocoa_show_progress_bar_on_dock_icon()
31133119

31143120
def on_clipboard_lost(self, which: Literal['clipboard', 'primary']) -> None:
3115-
pass
3121+
self.handle_clipboard_loss(which)
3122+
3123+
def handle_clipboard_loss(self, which: Literal['clipboard', 'primary'], exception: int = 0) -> None:
3124+
opts = get_options()
3125+
if opts.clear_selection_on_clipboard_loss and (which == 'primary' or opts.copy_on_select == 'clipboard'):
3126+
for wid, window in self.window_id_map.items():
3127+
if wid == exception:
3128+
continue
3129+
window.screen.clear_selection()

‎kitty/launch.py

+2
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,10 @@ def _launch(
709709
if stdin is not None:
710710
if opts.type == 'clipboard':
711711
set_clipboard_string(stdin)
712+
boss.handle_clipboard_loss('clipboard')
712713
else:
713714
set_primary_selection(stdin)
715+
boss.handle_clipboard_loss('primary')
714716
else:
715717
kw['hold'] = opts.hold
716718
if force_target_tab and target_tab is not None:

‎kitty/options/definition.py

+11
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,17 @@
603603
'''
604604
)
605605

606+
opt('clear_selection_on_clipboard_loss', 'no', option_type='to_bool', long_text='''
607+
When the contents of the clipboard no longer reflect the current selection, clear it.
608+
This is primarily useful on platforms such as Linux where selecting text automatically
609+
copies it to a special "primary selection" clipboard or if you have :opt:`copy_on_select`
610+
set to :code:`clipboard`.
611+
612+
Note that on macOS the system does not provide notifications when the clipboard owner
613+
is changed, so there, copying to clipboard in a non-kitty application will not clear
614+
selections even if :opt:`copy_on_select` is enabled.
615+
''')
616+
606617
opt('paste_actions', 'quote-urls-at-prompt,confirm',
607618
option_type='paste_actions',
608619
long_text='''

‎kitty/options/parse.py

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎kitty/options/types.py

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.