Bug 465972 - Spectacle copy uses a BMP instead of PNG with a manual copy, but only on Wayland
Summary: Spectacle copy uses a BMP instead of PNG with a manual copy, but only on Wayland
Status: RESOLVED FIXED
Alias: None
Product: Spectacle
Classification: Applications
Component: General (show other bugs)
Version: 21.12.3
Platform: Kubuntu Linux
: NOR minor
Target Milestone: ---
Assignee: Boudhayan Gupta
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-02-18 00:21 UTC by incoming
Modified: 2024-08-23 21:07 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
Debugging files, read comment (118.06 KB, application/zip)
2023-02-18 00:30 UTC, incoming
Details

Note You need to log in before you can comment on or make changes to this bug.
Description incoming 2023-02-18 00:21:36 UTC
SUMMARY
***
NOTE: If you are reporting a crash, please try to attach a backtrace with debug symbols.
See https://community.kde.org/Guidelines_and_HOWTOs/Debugging/How_to_create_useful_crash_reports
***


STEPS TO REPRODUCE
1. Take any screenshot while on Wayland, using Spectacle
2. Press the "Copy to clipboard" button
3. Attempt something such as `wl-paste | xxd | head -n 1` to view the actual container that the file is saved in.
4. You will get an output with a magic byte starting with `424d`, which is a PC bitmap, Windows 3.x format.
5. Now attempt to save the same screenshot to a file manually, and run something such as `cat image | xxd | head -n 1`.
5. You will get an output with a magic byte starting with `8950 4e47 0d0a 1a0a`, which is a "real" PNG. 
6. Repeating the same test while running X11 instead of wayland will result in a PNG for both files.

This behavior is also reproducible when trying to use the spectacle commandline options to copy the image to clipboard, or the automatic image copy that happens on a successful screenshot.
I have also tested with multiple modes, and background screenshots, and dbus mode, this behavior is entirely specific to the "Copy to clipboard" functionality *as a whole*, on Wayland.
I have tried this on the same system using Xorg.

OBSERVED RESULT

The copied image is a BMP image, which does not display properly or paste properly in some applications (especially when a png is expected, and it is called a .png).

EXPECTED RESULT

The copied image is a PNG image.

SOFTWARE/OS VERSIONS

Operating System: Kubuntu 22.04
KDE Plasma Version: 5.24.7
KDE Frameworks Version: 5.92.0
Qt Version: 5.15.3
Kernel Version: 5.15.0-60-generic (64-bit)
Graphics Platform: Wayland
Processors: 16 × 12th Gen Intel® Core™ i7-1260P
Memory: 15.3 GiB of RAM
Graphics Processor: Mesa Intel® Graphics

ADDITIONAL INFORMATION

wayland package versions:
kwayland-data/jammy,jammy,now 4:5.92.0-0ubuntu1 all [installed,automatic]
kwayland-integration/jammy,now 4:5.24.4-0ubuntu1 amd64 [installed,automatic]
kwin-wayland-backend-drm/jammy-updates,now 4:5.24.7-0ubuntu0.1 amd64 [installed,automatic]
kwin-wayland/jammy-updates,now 4:5.24.7-0ubuntu0.1 amd64 [installed,automatic]
libkf5waylandclient5/jammy,now 4:5.92.0-0ubuntu1 amd64 [installed,automatic]
libkf5waylandserver5/jammy,now 4:5.92.0-0ubuntu1 amd64 [installed,automatic]
libkwaylandserver5/jammy-updates,now 5.24.6-0ubuntu0.1 amd64 [installed,automatic]
libqt5waylandclient5/jammy,now 5.15.3-1 amd64 [installed,automatic]
libqt5waylandcompositor5/jammy,now 5.15.3-1 amd64 [installed,automatic]
libva-wayland2/jammy,now 2.14.0-1 amd64 [installed,automatic]
libwayland-bin/jammy-updates,jammy-security,now 1.20.0-1ubuntu0.1 amd64 [installed,automatic]
libwayland-client0/jammy-updates,jammy-security,now 1.20.0-1ubuntu0.1 amd64 [installed,automatic]
libwayland-cursor0/jammy-updates,jammy-security,now 1.20.0-1ubuntu0.1 amd64 [installed,automatic]
libwayland-dev/jammy-updates,jammy-security,now 1.20.0-1ubuntu0.1 amd64 [installed,automatic]
libwayland-egl1/jammy-updates,jammy-security,now 1.20.0-1ubuntu0.1 amd64 [installed,automatic]
libwayland-server0/jammy-updates,jammy-security,now 1.20.0-1ubuntu0.1 amd64 [installed,automatic]
plasma-workspace-wayland/jammy-updates,now 4:5.24.7-0ubuntu0.1 amd64 [installed]
qtwayland5/jammy,now 5.15.3-1 amd64 [installed,automatic]
wayland-protocols/jammy,jammy,now 1.25-1 all [installed,automatic]
xwayland/jammy-updates,jammy-security,now 2:22.1.1-1ubuntu0.5 amd64 [installed,automatic]
Comment 1 incoming 2023-02-18 00:30:48 UTC
Created attachment 156407 [details]
Debugging files, read comment

For debugging and ease of understanding reasons, I am attaching two example files, the -manual one is a manual save from spectacle and is the expected behavior.

You can try the following commands yourself to test outputs from spectacle to see if they are working as intended:

```
# Pastes from the clipboard and shows the first line of xxd hex output, which shows the magic bytes.
wl-paste | xxd | head -n 1

# Shows the first line of xxd hex output from both of the files, as well as the "file" output to show you their interpreted file types.
unzip example_images.zip
cat file10.png | xxd | head -n 1
cat file10-manual.png | xxd | head -n 1
file file10.png
file file10-manual.png
```
Comment 2 Noah Davis 2023-11-24 20:37:01 UTC
Git commit e73b6d98542388db6c12c9f70145bb7abe56e5a0 by Noah Davis.
Committed on 22/11/2023 at 22:24.
Pushed by ndavis into branch 'master'.

Save image as temp file, then copy data when copying image

Now you can see a thumbnail of the image you copied in a notification
when only copying an image. The image is in whatever format you just
saved (if saving and copying image) or the default image format.

There is a known minor flaw where if you click the image thumbnail to open it in an image viewer, the image will be deleted before it can be viewed. This is because the image is in the temp dir, so it gets deleted when spectacle is closed.
Related: bug 422874, bug 465781

M  +21   -1    src/ExportManager.cpp

https://invent.kde.org/graphics/spectacle/-/commit/e73b6d98542388db6c12c9f70145bb7abe56e5a0
Comment 3 Bug Janitor Service 2024-08-13 01:11:08 UTC
A possibly relevant merge request was started @ https://invent.kde.org/graphics/spectacle/-/merge_requests/388
Comment 4 Bug Janitor Service 2024-08-16 13:13:28 UTC
A possibly relevant merge request was started @ https://invent.kde.org/graphics/spectacle/-/merge_requests/391
Comment 5 Noah Davis 2024-08-23 20:34:04 UTC
Git commit 83c9a81f3797140740ef9f31e2e6d4e1174115be by Noah Davis.
Committed on 23/08/2024 at 20:32.
Pushed by ndavis into branch 'master'.

Go back to copying images with setImageData

A previous change was made based on a wrong assumption that you could only
copy one format of image data and that the program doing the copying decides
the format that gets pasted.

The truth is that the app doing the copying gets to decide which formats
are sent to the clipboard and can send multiple types of data, but not which
format gets pasted. Only the app receiving the paste gets to decide which
format gets pasted. If it doesn't support the copied format, nothing will be
pasted. Because of this, images should be copied as uncompressed images. If
you want to paste a JPEG into Firefox/Chromium/Electron apps directly, you
can't really do that. You have to save a JPEG file and then copy the file as
a file URL. I'd like to do that instead so that the copied image can always
be compressed in the preferred format, but Flatpak apps currently can't use
/tmp without the user adding explicit permission specifically for /tmp.

Another issue with trying to copy images directly in the preferred format is
that lossy compressed formats like JPEG will be decompressed when Spectacle
closes, expanding 2-8x their compressed size. This is likely an issue with
Klipper (probably HistoryImageItem) and maybe KSystemClipboard.
Related: bug 485096, bug 465781

M  +26   -20   src/ExportManager.cpp

https://invent.kde.org/graphics/spectacle/-/commit/83c9a81f3797140740ef9f31e2e6d4e1174115be
Comment 6 Noah Davis 2024-08-23 21:07:39 UTC
Git commit 92a59d38ddf1c620a9c318d3f109f202c12c76d4 by Noah Davis.
Committed on 23/08/2024 at 21:07.
Pushed by ndavis into branch 'release/24.08'.

Go back to copying images with setImageData

A previous change was made based on a wrong assumption that you could only
copy one format of image data and that the program doing the copying decides
the format that gets pasted.

The truth is that the app doing the copying gets to decide which formats
are sent to the clipboard and can send multiple types of data, but not which
format gets pasted. Only the app receiving the paste gets to decide which
format gets pasted. If it doesn't support the copied format, nothing will be
pasted. Because of this, images should be copied as uncompressed images. If
you want to paste a JPEG into Firefox/Chromium/Electron apps directly, you
can't really do that. You have to save a JPEG file and then copy the file as
a file URL. I'd like to do that instead so that the copied image can always
be compressed in the preferred format, but Flatpak apps currently can't use
/tmp without the user adding explicit permission specifically for /tmp.

Another issue with trying to copy images directly in the preferred format is
that lossy compressed formats like JPEG will be decompressed when Spectacle
closes, expanding 2-8x their compressed size. This is likely an issue with
Klipper (probably HistoryImageItem) and maybe KSystemClipboard.
Related: bug 485096, bug 465781


(cherry picked from commit 83c9a81f3797140740ef9f31e2e6d4e1174115be)

Co-authored-by: Noah Davis <noahadvs@gmail.com>

M  +26   -20   src/ExportManager.cpp

https://invent.kde.org/graphics/spectacle/-/commit/92a59d38ddf1c620a9c318d3f109f202c12c76d4