Allow programs running in kitty to read/write from the clipboard
By default only writing is allowed. There is a config option to enable reading, if needed.
This commit is contained in:
parent
23ee6b3109
commit
889ca77912
@ -355,6 +355,7 @@ type_map = {
|
|||||||
'bell_on_tab': to_bool,
|
'bell_on_tab': to_bool,
|
||||||
'kitty_mod': to_modifiers,
|
'kitty_mod': to_modifiers,
|
||||||
'clear_all_shortcuts': to_bool,
|
'clear_all_shortcuts': to_bool,
|
||||||
|
'clipboard_control': lambda x: frozenset(x.lower().split()),
|
||||||
}
|
}
|
||||||
|
|
||||||
for name in (
|
for name in (
|
||||||
|
|||||||
@ -318,6 +318,14 @@ close_on_child_death no
|
|||||||
# Note that this even works over ssh connections.
|
# Note that this even works over ssh connections.
|
||||||
allow_remote_control no
|
allow_remote_control no
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
clipboard_control write-clipboard write-primary
|
||||||
|
|
||||||
# The value of the TERM environment variable to set. Changing this can break
|
# The value of the TERM environment variable to set. Changing this can break
|
||||||
# many terminal programs, only change it if you know what you are doing, not
|
# many terminal programs, only change it if you know what you are doing, not
|
||||||
# because you read some advice on Stack Overflow to change it.
|
# because you read some advice on Stack Overflow to change it.
|
||||||
|
|||||||
@ -341,6 +341,9 @@ dispatch_osc(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
|
|||||||
case 119:
|
case 119:
|
||||||
SET_COLOR(set_dynamic_color);
|
SET_COLOR(set_dynamic_color);
|
||||||
break;
|
break;
|
||||||
|
case 52:
|
||||||
|
DISPATCH_OSC(clipboard_control);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
REPORT_ERROR("Unknown OSC code: %u", code);
|
REPORT_ERROR("Unknown OSC code: %u", code);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1194,6 +1194,11 @@ set_dynamic_color(Screen *self, unsigned int code, PyObject *color) {
|
|||||||
else { CALLBACK("set_dynamic_color", "IO", code, color); }
|
else { CALLBACK("set_dynamic_color", "IO", code, color); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clipboard_control(Screen *self, PyObject *data) {
|
||||||
|
CALLBACK("clipboard_control", "O", data);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_color_table_color(Screen *self, unsigned int code, PyObject *color) {
|
set_color_table_color(Screen *self, unsigned int code, PyObject *color) {
|
||||||
if (color == NULL) { CALLBACK("set_color_table_color", "Is", code, ""); }
|
if (color == NULL) { CALLBACK("set_color_table_color", "Is", code, ""); }
|
||||||
|
|||||||
@ -143,6 +143,7 @@ void screen_use_latin1(Screen *, bool);
|
|||||||
void set_title(Screen *self, PyObject*);
|
void set_title(Screen *self, PyObject*);
|
||||||
void set_icon(Screen *self, PyObject*);
|
void set_icon(Screen *self, PyObject*);
|
||||||
void set_dynamic_color(Screen *self, unsigned int code, PyObject*);
|
void set_dynamic_color(Screen *self, unsigned int code, PyObject*);
|
||||||
|
void clipboard_control(Screen *self, PyObject*);
|
||||||
void set_color_table_color(Screen *self, unsigned int code, PyObject*);
|
void set_color_table_color(Screen *self, unsigned int code, PyObject*);
|
||||||
uint32_t* translation_table(uint32_t which);
|
uint32_t* translation_table(uint32_t which);
|
||||||
void screen_request_capabilities(Screen *, char, PyObject *);
|
void screen_request_capabilities(Screen *, char, PyObject *);
|
||||||
|
|||||||
@ -17,17 +17,17 @@ from .fast_data_types import (
|
|||||||
BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM, CELL_PROGRAM,
|
BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM, CELL_PROGRAM,
|
||||||
CELL_SPECIAL_PROGRAM, CSI, CURSOR_PROGRAM, DCS, GRAPHICS_PREMULT_PROGRAM,
|
CELL_SPECIAL_PROGRAM, CSI, CURSOR_PROGRAM, DCS, GRAPHICS_PREMULT_PROGRAM,
|
||||||
GRAPHICS_PROGRAM, OSC, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen,
|
GRAPHICS_PROGRAM, OSC, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen,
|
||||||
add_window, compile_program, glfw_post_empty_event, init_cell_program,
|
add_window, compile_program, get_clipboard_string, glfw_post_empty_event,
|
||||||
init_cursor_program, set_clipboard_string, set_titlebar_color,
|
init_cell_program, init_cursor_program, set_clipboard_string,
|
||||||
set_window_render_data, update_window_title, update_window_visibility,
|
set_titlebar_color, set_window_render_data, update_window_title,
|
||||||
viewport_for_window
|
update_window_visibility, viewport_for_window
|
||||||
)
|
)
|
||||||
from .keys import keyboard_mode_name
|
from .keys import keyboard_mode_name
|
||||||
from .rgb import to_color
|
from .rgb import to_color
|
||||||
from .terminfo import get_capabilities
|
from .terminfo import get_capabilities
|
||||||
from .utils import (
|
from .utils import (
|
||||||
color_as_int, load_shaders, open_cmd, open_url, parse_color_set,
|
color_as_int, get_primary_selection, load_shaders, log_error, open_cmd,
|
||||||
sanitize_title
|
open_url, parse_color_set, sanitize_title, set_primary_selection
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -331,6 +331,37 @@ class Window:
|
|||||||
def send_cmd_response(self, response):
|
def send_cmd_response(self, response):
|
||||||
self.screen.send_escape_code_to_child(DCS, '@kitty-cmd' + json.dumps(response))
|
self.screen.send_escape_code_to_child(DCS, '@kitty-cmd' + json.dumps(response))
|
||||||
|
|
||||||
|
def clipboard_control(self, data):
|
||||||
|
where, text = data.partition(';')[::2]
|
||||||
|
if text == '?':
|
||||||
|
response = None
|
||||||
|
if 'read-clipboard' in self.opts.clipboard_control and ('s' in where or 'c' in where):
|
||||||
|
response = get_clipboard_string()
|
||||||
|
loc = 'c'
|
||||||
|
elif 'p' in where and 'read-primary' in self.opts.clipboard_control:
|
||||||
|
response = get_primary_selection()
|
||||||
|
loc = 'p'
|
||||||
|
if response is not None:
|
||||||
|
from base64 import standard_b64encode
|
||||||
|
self.screen.send_escape_code_to_child(OSC, '{};{}'.format(
|
||||||
|
loc, standard_b64encode(response.encode('utf-8')).decode('ascii')))
|
||||||
|
|
||||||
|
else:
|
||||||
|
from base64 import standard_b64decode
|
||||||
|
try:
|
||||||
|
text = standard_b64decode(text).decode('utf-8')
|
||||||
|
except Exception:
|
||||||
|
log_error('Invalid data to write to clipboard received, ignoring')
|
||||||
|
return
|
||||||
|
if 's' in where or 'c' in where:
|
||||||
|
if 'write-clipboard' in self.opts.clipboard_control:
|
||||||
|
set_clipboard_string(text)
|
||||||
|
if 'p' in where:
|
||||||
|
if self.opts.copy_on_select:
|
||||||
|
if 'write-clipboard' in self.opts.clipboard_control:
|
||||||
|
set_clipboard_string(text)
|
||||||
|
if 'write-primary' in self.opts.clipboard_control:
|
||||||
|
set_primary_selection(text)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
def text_for_selection(self):
|
def text_for_selection(self):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user