jeremija / unipicker

Search unicode characters in console and copy to clipboard
MIT License
75 stars 10 forks source link

Clipboard support on Wayland #8

Open NicoWeio opened 1 year ago

NicoWeio commented 1 year ago

As per the README, unipicker uses xclip for clipboard support, which does not work on Wayland. Maybe we could integrate wl-clipboard?

jeremija commented 1 year ago

The README also states there is a --copy-command argument which should allow you to set wl-clipboard. Or is there something I'm missing here?

Epsylon42 commented 1 year ago

I tried using it on wayland and there is something weird going on. echo abc | wl-copy works, but unipicker --copy-command wl-copy just clears the clipboard. I also tried replacing wl-copy with cat to check if it even receives anything from stdin, and it does - the input is correct.

There is a workaround though. Just using unipicker | wl-copy seems to work fine

jeremija commented 1 year ago

This is a really weird issue, I can reproduce the issue with just echo -n t | wl-copy does not work, but echo -n tt | wl-copy does. But the wl-paste command works in both cases.

I was able to work around it by explicitly specifying the MIME type:

unipicker --copy-command 'wl-copy -t text/plain'
elder-n00b commented 1 year ago

I got the same problem with wl-copy elsewhere, and worked around it the same way. My theory is that sometimes it mistakes the input for binary data (that is the clipboard type reported when copying apparently fails). On a side note, when I unipicker|wl-copy I also get a newline that isn't there using --copy-command. To support more systems out of the box, perhaps something similar to the fish shell function fish_clipboard_copy could be used.

fish❯ functions fish_clipboard_copy
# Defined in /usr/share/fish/functions/fish_clipboard_copy.fish @ line 1
function fish_clipboard_copy
    set -l cmdline
    if isatty stdin
        # Copy the current selection, or the entire commandline if that is empty.
        # Don't use `string collect -N` here - `commandline` adds a newline.
        set cmdline (commandline --current-selection | string collect)
        test -n "$cmdline"; or set cmdline (commandline | string collect)
    else
        # Read from stdin
        while read -lz line
            set -a cmdline $line
        end
    end

    if type -q pbcopy
        printf '%s' $cmdline | pbcopy
    else if set -q WAYLAND_DISPLAY; and type -q wl-copy
        printf '%s' $cmdline | wl-copy
    else if set -q DISPLAY; and type -q xsel
        printf '%s' $cmdline | xsel --clipboard
    else if set -q DISPLAY; and type -q xclip
        printf '%s' $cmdline | xclip -selection clipboard
    else if type -q clip.exe
        printf '%s' $cmdline | clip.exe
    end

    # Copy with OSC 52; useful if we are running in an SSH session or in
    # a container.
    if type -q base64
        if not isatty stdout
            echo "fish_clipboard_copy: stdout is not a terminal" >&2
            return 1
        end
        set -l encoded (printf %s $cmdline | base64 | string join '')
        printf '\e]52;c;%s\a' "$encoded"
        # tmux requires user configuration to interpret OSC 52 on stdout.
        # Luckily we can still make this work for the common case by bypassing
        # tmux and writing to its underlying terminal.
        if set -q TMUX
            set -l tmux_tty (tmux display-message -p '#{client_tty}')
            or return 1
            # The terminal might not be writable if we switched user.
            if test -w $tmux_tty
                printf '\e]52;c;%s\a' "$encoded" >$tmux_tty
            end
        end
    end
end

edit: nevermind, I see there's also UNIPICKER_COPY_COMMAND in unipickerrc.