diff --git a/src/lib/clipboardv3/clipboard_linux.v b/src/lib/clipboardv3/clipboard_linux.v index b8725514..67aa6553 100644 --- a/src/lib/clipboardv3/clipboard_linux.v +++ b/src/lib/clipboardv3/clipboard_linux.v @@ -17,13 +17,54 @@ module clipboardv3 import os import time +const xdg_session_type_env_name = 'XDG_SESSION_TYPE' +const xclip_path = '/usr/bin/xclip' +const xclip_paste_args = ['-selection', 'clipboard', '-out'] +const xclip_copy_args = ['-selection', 'clipboard', '-in'] +const wayland_copy_path = '/usr/bin/wl-copy' +const wayland_paste_path = '/usr/bin/wl-paste' +const wayland_copy_args = ['--type', 'text/plain'] +const wayland_paste_args = ['--type', 'text/plain'] + +type Getenv = fn (key string) string + +struct Proc { + copy_proc_path string + paste_proc_path string + paste_args []string + copy_args []string +} + +fn resolve_clipboard_proc(os_getenv Getenv) Proc { + if is_x11(os_getenv) { + return Proc{ + copy_proc_path: xclip_path + paste_proc_path: xclip_path // on x11 we use the same util for copy and paste + paste_args: xclip_paste_args + copy_args: xclip_copy_args + } + } + return Proc{ + copy_proc_path: wayland_copy_path + paste_proc_path: wayland_paste_path + paste_args: wayland_paste_args + copy_args: wayland_copy_args + } +} + +fn is_x11(os_getenv Getenv) bool { + return os_getenv(xdg_session_type_env_name) == 'x11' +} + struct LinuxClipboard { mut: + proc Proc last_type ContentType } fn new_linux_clipboard() Clipboard { return LinuxClipboard{ + proc: resolve_clipboard_proc(os.getenv) last_type: .block } } @@ -32,8 +73,8 @@ fn (c LinuxClipboard) get_content() ?ClipboardContent { mut out := []string{} mut er := []string{} - mut p := os.new_process('/usr/bin/xclip') - p.set_args(['-selection', 'clipboard', '-out']) + mut p := os.new_process(c.proc.paste_proc_path) + p.set_args(c.proc.paste_args) p.set_redirect_stdio() p.run() @@ -59,8 +100,8 @@ fn (c LinuxClipboard) get_content() ?ClipboardContent { } fn (mut c LinuxClipboard) set_content(content ClipboardContent) { - mut p := os.new_process('/usr/bin/xclip') - p.set_args(['-selection', 'clipboard', '-in']) + mut p := os.new_process(c.proc.copy_proc_path) + p.set_args(c.proc.copy_args) p.set_redirect_stdio() p.run() diff --git a/src/lib/clipboardv3/clipboard_test.v b/src/lib/clipboardv3/clipboard_test.v index 788e12b0..fcfca6ec 100644 --- a/src/lib/clipboardv3/clipboard_test.v +++ b/src/lib/clipboardv3/clipboard_test.v @@ -32,6 +32,18 @@ fn test_clipboard_native_implementation_sets_type_to_block() ! { } } +@[if linux ?] +fn test_linux_clipboard_chooses_proc_to_invoke_depending_on_window_server() { + mock_get_env_x11 := fn (key string) string { + return 'x11' + } + mock_get_env_wayland := fn (key string) string { + return 'wayland' + } + assert is_x11(mock_get_env_x11) + assert is_x11(mock_get_env_wayland) == false +} + @[if darwin ?] fn test_clipboard_native_implementation_returns_no_content_type_from_plaintext_data() { $if darwin {