jtheoof / swappy

A Wayland native snapshot editing tool, inspired by Snappy on macOS
MIT License
1.04k stars 39 forks source link

Swappy cannot read screenshots from Firefox from the clipboard #163

Closed ChrisLane closed 8 months ago

ChrisLane commented 8 months ago

To Reproduce

  1. Open a webpage in Firefox
  2. Right click, select "Take Screenshot"
  3. Click "Save Visible"
  4. Click "Copy"
  5. Run wl-paste | swappy -f -

An error is produced e.g.

unable to load file: /tmp/swappy-stdin-8WB3I2.png - reason: Failed to load image “/tmp/swappy-stdin-8WB3I2.png”: Fatal error in PNG image file: Read Error

Additional Info

kadamski commented 8 months ago

This is not swappy issue. Can you check if adding "-t image/png" to the wl-paste command fixes the problem?

Also, what does the "wl-paste -l" say? I guess it doesn't just say "image/png", but it also lists some "text/*" mimetype.

Also, I'm pretty sure that swappy will work fine if you do it like this:

  1. Copy firefox screenshot to clipboard.
  2. Do: wl-paste > /tmp/screenshot.png
  3. Do: wl-copy < /tmp/screenshot.png
  4. Do: wl-paste | swappy -f -

So the problem is that wl-paste is offered many mime-types (as you can see calling wl-paste -l) and it has to choose one of them since we didn't choose any using -t option. Here's the code that does this: https://github.com/bugaevc/wl-clipboard/blob/abfd513ecceef5f33632e0f63daea92f9bbe08e2/src/wl-paste.c#L475

As you can see, the code is running path_for_fd() which, if we do "wl-paste > x.png" will return "x.png" so the infer_mime_type_from_name() will infer it is a png file. But in other case, it will fail since we don't have a file extension and thus inferred_type will be NULL.

This mean it will go here: https://github.com/bugaevc/wl-clipboard/blob/abfd513ecceef5f33632e0f63daea92f9bbe08e2/src/wl-paste.c#L152 where, as you can see, it will first _try_anytext before doing _tryany. Since firefox offers "text/ico", wl-paste will use it. Problem is, if you request this type from the clipboard, you will get an empty string and this is exactly what swappy is getting on its input.

So the problem is wl-paste has to many options to choose and it makes a wrong choice. You can fix this by always calling "wl-paste -t image" which will limit filetypes wl-paste considers to just "image/*". In this case, as long as the program writing to clipboard (in this case firefox) will be able to serve the image on the first "image/XXX" type, you will be fine.

As a side-note, I don't understand why firefox offers so many mime types. That is weird. It will for example offer image/png and mage/jpeg but if you try "wl-paste -t image/jpeg" it will not return anything.

Another option would be to change wl-paste to be a little smarter and try multiple types until it gets some non-empty data. In this case it would check text/ico but that is empty so it could try image/jpeg which is also empty and at some point it will finally get into image/png which would actually return some data. But, again, that is not something swappy can do.

ChrisLane commented 8 months ago

Thanks for the detailed explanation and workaround @kadamski!

Pasting to a file, copying and pasting to Swappy works. Adding -t image/{format} works. Interestingly, though you state that image/jpeg does not return anything for you, it works fine for me and returns valid jpeg data.

I suppose wl-clipboard would likely not implement a "try until not blank" process since an assumption of blank being incorrect could introduce unexpected behaviour for use cases where blank is expected.

ChrisLane commented 8 months ago

Closing since this is not a Swappy issue.