Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions src/lib/clipboardv3/clipboard_linux.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand All @@ -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()

Expand All @@ -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()

Expand Down
12 changes: 12 additions & 0 deletions src/lib/clipboardv3/clipboard_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading