Prompt for permission when reading from clipboard by default
Fixes #4022
This commit is contained in:
parent
38a5e38f88
commit
b1322fbe04
@ -18,6 +18,10 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
- Allow the user to supply a custom Python function to draw tab bar. See
|
||||
:opt:`tab_bar_style`
|
||||
|
||||
- When programs ask to read from the clipboard prompt the user to allow
|
||||
the request by default instead of denying by default. See
|
||||
:opt:`clipboard_control` for details (:iss:`4022`)
|
||||
|
||||
- Fix a regression that caused :option:`kitty --title` to not work when
|
||||
opening new OS windows using :option:`kitty --single-instance` (:iss:`3893`)
|
||||
|
||||
|
||||
@ -57,9 +57,9 @@ OPTIONS = r'''
|
||||
--get-clipboard
|
||||
default=False
|
||||
type=bool-set
|
||||
Output the current contents of the clipboard to stdout. Note that this
|
||||
will not work if you have not enabled the option to allow reading the clipboard
|
||||
in kitty.conf
|
||||
Output the current contents of the clipboard to STDOUT. Note that by default
|
||||
kitty will prompt you asking to allow access to the clipboard. Can be controlled
|
||||
by :opt:`clipboard_control`.
|
||||
|
||||
|
||||
--use-primary
|
||||
@ -80,8 +80,8 @@ Read or write to the system clipboard.
|
||||
|
||||
To set the clipboard text, pipe in the new text on stdin. Use the
|
||||
:option:`--get-clipboard` option to output the current clipboard contents to
|
||||
:file:`stdout`. Note that you must enable reading of clipboard in
|
||||
:file:`kitty.conf` first.
|
||||
:file:`stdout`. Note that reading the clipboard will cause a permission
|
||||
popup, see :opt:`clipboard_control` for details.
|
||||
'''
|
||||
|
||||
usage = ''
|
||||
|
||||
@ -2544,16 +2544,17 @@ the config is not supported.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('clipboard_control', 'write-clipboard write-primary',
|
||||
opt('clipboard_control', 'write-clipboard write-primary read-clipboard-ask read-primary-ask',
|
||||
option_type='clipboard_control',
|
||||
long_text='''
|
||||
Allow programs running in kitty to read and write from the clipboard. You can
|
||||
control exactly which actions are allowed. The set of possible actions is:
|
||||
write-clipboard read-clipboard write-primary read-primary. The default is to
|
||||
allow writing to the clipboard and primary selection. Note that enabling the
|
||||
read functionality is a security risk as it means that any program, even one
|
||||
running on a remote server via SSH can read your clipboard. See also
|
||||
:opt:`clipboard_max_size`.
|
||||
:code:`write-clipboard read-clipboard write-primary read-primary read-clipboard-ask read-primary-ask`.
|
||||
The default is to allow writing to the clipboard and primary selection and to
|
||||
ask for permission when a program tries to read from the clipboard. Note that
|
||||
disabling the read confirmation is a security risk as it means that any
|
||||
program, even one running on a remote server via SSH can read your clipboard.
|
||||
See also :opt:`clipboard_max_size`.
|
||||
'''
|
||||
)
|
||||
|
||||
|
||||
2
kitty/options/types.py
generated
2
kitty/options/types.py
generated
@ -463,7 +463,7 @@ class Options:
|
||||
clear_all_mouse_actions: bool = False
|
||||
clear_all_shortcuts: bool = False
|
||||
click_interval: float = -1.0
|
||||
clipboard_control: typing.Tuple[str, ...] = ('write-clipboard', 'write-primary')
|
||||
clipboard_control: typing.Tuple[str, ...] = ('write-clipboard', 'write-primary', 'read-clipboard-ask', 'read-primary-ask')
|
||||
clipboard_max_size: float = 64.0
|
||||
close_on_child_death: bool = False
|
||||
command_on_bell: typing.List[str] = ['none']
|
||||
|
||||
@ -328,6 +328,7 @@ class Window:
|
||||
):
|
||||
self.watchers = watchers or Watchers()
|
||||
self.current_mouse_event_button = 0
|
||||
self.current_clipboard_read_ask: Optional[bool] = None
|
||||
self.prev_osc99_cmd = NotificationCommand()
|
||||
self.action_on_close: Optional[Callable] = None
|
||||
self.action_on_removal: Optional[Callable] = None
|
||||
@ -842,15 +843,17 @@ class Window:
|
||||
if text == '?':
|
||||
response = None
|
||||
if 's' in where or 'c' in where:
|
||||
if 'read-clipboard-ask' in cc:
|
||||
return self.ask_to_read_clipboard(False)
|
||||
response = get_clipboard_string() if 'read-clipboard' in cc else ''
|
||||
loc = 'c'
|
||||
elif 'p' in where:
|
||||
if 'read-primary-ask' in cc:
|
||||
return self.ask_to_read_clipboard(True)
|
||||
response = get_primary_selection() if 'read-primary' in cc else ''
|
||||
loc = 'p'
|
||||
response = response or ''
|
||||
from base64 import standard_b64encode
|
||||
self.screen.send_escape_code_to_child(OSC, '52;{};{}'.format(
|
||||
loc, standard_b64encode(response.encode('utf-8')).decode('ascii')))
|
||||
self.send_osc52(loc, response or '')
|
||||
|
||||
else:
|
||||
from base64 import standard_b64decode
|
||||
@ -867,6 +870,33 @@ class Window:
|
||||
set_primary_selection(text)
|
||||
self.clipboard_pending = None
|
||||
|
||||
def send_osc52(self, loc: str, response: str) -> None:
|
||||
from base64 import standard_b64encode
|
||||
self.screen.send_escape_code_to_child(OSC, '52;{};{}'.format(
|
||||
loc, standard_b64encode(response.encode('utf-8')).decode('ascii')))
|
||||
|
||||
def ask_to_read_clipboard(self, primary: bool = False) -> None:
|
||||
if self.current_clipboard_read_ask is not None:
|
||||
self.current_clipboard_read_ask = primary
|
||||
return
|
||||
self.current_clipboard_read_ask = primary
|
||||
get_boss()._run_kitten('ask', ['--type=yesno', '--message', _(
|
||||
'A program running in this window wants to read from the system clipboard.'
|
||||
' Allow it do so, once?')],
|
||||
window=self,
|
||||
custom_callback=self.handle_clipboard_confirmation
|
||||
)
|
||||
|
||||
def handle_clipboard_confirmation(self, data: Dict[str, Any], *a: Any) -> None:
|
||||
try:
|
||||
loc = 'p' if self.current_clipboard_read_ask else 'c'
|
||||
response = ''
|
||||
if data['response'] == 'y':
|
||||
response = get_primary_selection() if self.current_clipboard_read_ask else get_clipboard_string()
|
||||
self.send_osc52(loc, response)
|
||||
finally:
|
||||
self.current_clipboard_read_ask = None
|
||||
|
||||
def manipulate_title_stack(self, pop: bool, title: str, icon: Any) -> None:
|
||||
if title:
|
||||
if pop:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user