Support Wayland clipboard
Hello, thanks for this awesome app!
I am trying to get clipbard integration working, and having several issues.
I'm running on Wayland, so I have clipboard-get-command = wl-paste -n in my config.
If the clipboard contains absolute path to a file, it works well 👍
If clipboard contains raw image data of type image/jpeg it crashes:
Details...
$ wl-copy < Downloads/whackamole-900px.jpg
$ wl-paste -l
image/jpeg
$ scli (and paste with :c)
.....
File "/usr/bin/scli", line 2935, in keypress
return self._keypress_cmd_mode(key, key_orig, txt)
File "/usr/bin/scli", line 2892, in _keypress_cmd_mode
self._cmds.exec(cmd, *args)
File "/usr/bin/scli", line 3965, in exec
return fn(*args)
File "/usr/bin/scli", line 4103, in attach_clip
files = clip.files()
File "/usr/bin/scli", line 450, in files
return callf(cmd, capture_output=True).stdout.split('\n')
File "/usr/bin/scli", line 102, in callf
proc = subprocess.run(cmd, **subprocess_kwargs)
File "/usr/lib/python3.10/subprocess.py", line 503, in run
stdout, stderr = process.communicate(input, timeout=timeout)
File "/usr/lib/python3.10/subprocess.py", line 1149, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "/usr/lib/python3.10/subprocess.py", line 2038, in _communicate
stdout = self._translate_newlines(stdout,
File "/usr/lib/python3.10/subprocess.py", line 1026, in _translate_newlines
data = data.decode(encoding, errors)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
If I copy an image from browser (right click - copy image), nothing happens.
Clipboard contents depend on a browser....
In Chromium:
$ wl-paste -l
text/x-moz-url
text/html
image/png
$ wl-paste -n
https://media.istockphoto.com/illustrations/mole-illustration-id1152565170?k=20&m=1152565170&s=612x612&w=0&h=INx4ZYSeEJBeT5-4pN_zRAoDnEDyU6pT-s9o94Xwuzo=
27 Whack A Mole Game Illustrations & Clip Art - iStock
In qutebrowser (QtWebEngine):
$ wl-paste -l
application/x-qt-image
text/html
text/x-moz-url
image/png
image/bmp
image/cur
image/icns
image/ico
image/jp2
image/jpeg
image/jpg
image/pbm
image/pgm
image/ppm
image/tif
image/tiff
image/wbmp
image/webp
image/xbm
image/xpm
$ wl-paste -n
<img src="https://media.istockphoto.com/illustrations/game-to-hit-the-mole-illustration-id1153033854?k=20&m=1153033854&s=612x612&w=0&h=qJ-V8PXl9n8w5351vniVy1b9cLdqFHXMhxI5O2vQ44s=" alt="27 Whack A Mole Game Illustrations &amp; Clip Art - iStock"/>
In Firefox:
$ wl-paste -l
text/html
text/_moz_htmlinfo
text/_moz_htmlcontext
image/png
image/bmp
image/x-bmp
image/x-MS-bmp
image/x-icon
image/x-ico
image/x-win-bitmap
image/vnd.microsoft.icon
application/ico
image/ico
image/icon
text/ico
image/jpeg
image/tiff
image/avif
SAVE_TARGETS
$ wl-paste -n
<meta http-equiv="content-type" content="text/html; charset=utf-8"><img src="https://media.istockphoto.com/illustrations/game-to-hit-the-mole-illustration-id1153033854?k=20&m=1153033854&s=612x612&w=0&h=qJ-V8PXl9n8w5351vniVy1b9cLdqFHXMhxI5O2vQ44s=" alt="27 Whack A Mole Illustrations &amp; Clip Art - iStock" jsaction="load:XAeZkd;" jsname="HiaYvf" class="n3VNCb" data-noaft="1" style="width: 612px; height: 437px; margin: 0px;">
--debug shows that in all those cases scli tries to parse those as file paths:
DEBUG:root:callf: `['wl-paste', '-n']`
DEBUG:root:callf: <img src="https://media.istockphoto.com/illustrations/game-to-hit-the-mole-illustration-id1153033854?k=20&m=1153033854&s=612x612&w=0&h=qJ-V8PXl9n8w5351vniVy1b9cLdqFHXMhxI5O2vQ44s=" alt="27 Whack A Mole Game Illustrations &amp; Clip Art - iStock"/>
WARNING:root:send_message: Attached file(s) does not exist.
DEBUG:root:callf: `['wl-paste', '-n']`
DEBUG:root:callf: <meta http-equiv="content-type" content="text/html; charset=utf-8"><img src="https://media.istockphoto.com/illustrations/game-to-hit-the-mole-illustration-id1153033854?k=20&m=1153033854&s=612x612&w=0&h=qJ-V8PXl9n8w5351vniVy1b9cLdqFHXMhxI5O2vQ44s=" alt="27 Whack A Mole Illustrations &amp; Clip Art - iStock" jsaction="load:XAeZkd;" jsname="HiaYvf" class="n3VNCb" data-noaft="1" style="width: 612px; height: 437px; margin: 0px;">
WARNING:root:send_message: Attached file(s) does not exist.
So it doesn't pick the right MIME-type from clipboard (obviously, as it just runs wl-paste -n as I told it to....)
For the last issue, do you think it's possible to teach scli to ask for the proper MIME type? On wayland, we can use wl-paste -l to list all available types, and select the type using -t like wl-paste -t image/jpg. Passing invalid type (jpg for a plaintext contents) will return an error. It works in Signal-Desktop, but they may be using some more native integration with clipboard.
Thanks for your help!
Thanks for the detailed tests! Related question about the Wayland clipboard: #150.
By default, scli tries to get the clipboard contents from xclip. As you note, when CLIPBOAND_GET_COMMAND is specified, its output is processed as one filepath per line. To adhere to this, a wrapper script around wl-clipboard is needed.
On scli's side, we can:
-
Expand what scli expects from the output of
CLIPBOAND_GET_COMMANDto check for: URLs, URLs embedded into HTML, etc. But the range of possible outputs is probably large. -
Add Wayland-specific code to treat it as another "special case" along with xclip. Wayland is becoming more widespread.
-
Use a python library that can handle clipboard for multiple display managers. Better than rolling our own solution (further). In general we try to have minimal dependencies, but a library will be more reliable.
Signal-desktop probably has it easy, with Electron taking care of it for them :)
The first does sound complicated indeed, I cannot easily find all possible formats that we should be prepare to parse...
Having code specific for wl-clipboard is probably what I had initially in mind - not great in some ways, but simple in a sense that we can experiment with it, and request necessary MIME types and so forth.
If there is a good library we could use to abstract away this complexity, it's something also worth considering!
Implemented in #198