Repository navigation
Screen capture is clipped to SDR on HDR outputs #16882
Replies: 2 comments 1 reply
|
Sorry, a follow-up to my own post. If I’ve understood it correctly, there is now a Wayland protocol for exactly the part I said was missing: telling a capture client what color space a frame is in. xx-image-capture-color-management-v1 was merged into wayland-protocols as an experimental protocol at the end of September (MR 531), and the stable version, ext-image-capture-color-management-v1, is in review (MR 448). That sounds like a much better way to do this than the convention in my local patch. So my question is really: is supporting this protocol something Hyprland would consider, once it settles? MR 531: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/531 #16542 asked for the same protocol from the wide-gamut side (colors outside sRGB clipping in screenshots), but it was closed automatically because of the format. |
|
yeeaah they probably should be tonemapped instead of clipped, though weird, because on my end I can't repro this |
Uh oh!
There was an error while loading. Please reload this page.
What's the problem?
Setup
· Arch Linux, Hyprland 0.57.1
· RTX 4090, NVIDIA driver 615.78.08
· ASUS PG42UQ, monitor config: cm = hdr, 10-bit
The problem
As far as I can tell, there’s no way to capture HDR output in Hyprland other than through a capture card. Whether it’s a screenshot, a recording or a screenshare, I get an SDR picture clipped at SDR white. Anything brighter than SDR white comes out as flat white.
What I’ve tested
I don’t think this is a limitation of the apps I’ve tried. It seems to come from the compositor.
To rule out what other tools do with the image, I used my own capture client, which uses ext-image-copy-capture directly. On an HDR wallpaper whose own peak is 1010 nits, 99.96% of the captured pixels came back at the maximum value.
It doesn’t matter how the client asks for the image. I tried both ways a client can receive a frame from Hyprland:
Both came back clipped in exactly the same way.
My guess is that every capture path reads the SDR copy that’s made for screen sharing, so a client never gets to see the monitor’s real HDR content, however it asks. I can’t confirm that from the code, though.
Related discussions
This has come up before, but I think from a slightly different angle.
#16412 asks for the same thing from the Sunshine side (HDR streaming), but it was closed automatically because of the format, not because of a decision on the feature. Sunshine has an open PR that expects HDR from Hyprland: SunshineStream/Sunshine#5615.
#11626 and #11824 are about HDR screenshare looking wrong, and the answer there was to turn HDR off and use wide or edid. Those are about getting a good SDR picture out of an HDR screen. What I’m asking about is getting the HDR picture itself.
What's your proposed solution?
What I’d like is:
For a color-managed capture client to be able to get the monitor’s content in HDR, instead of only the SDR copy. Clients that don’t ask for it would keep getting exactly what they get today, so nothing changes for existing tools.
There seems to be two ways to deliver it:
In the output’s own colour space (PQ / BT.2020, 10-bit). That’s what the Sunshine PR expects, and it matches what the monitor is actually showing.
In a linear high-precision format (fp16), which the client converts itself. That’s what I tried locally.
Either way, the client needs to know what colour space the frame is in. Right now there’s no protocol for that in screen capture, so it would either need a convention or an extension, for example tying the capture to the output’s image description from the colour management protocol.
I don’t know which of these fits Hyprland’s renderer best, so I’d mostly like to hear which direction you’d prefer, if any.
What I tried locally
To find out whether it’s possible at all, I got it working locally with a patch.
Roughly what it does: when a client that is bound to the color management protocol captures a monitor or a region, Hyprland also offers a 16-bit floating point format. If the client picks it, it gets a copy of the finished frame in linear light, before the SDR conversion. Every other client gets exactly the same formats as before, so nothing changes for grim, the portal or anything else.
With it, a screenshot of the same 1010-nit wallpaper keeps its full range, and the saved file matches what’s on screen to within about half a percent. It works through both shared memory and dmabuf, and I’ve been using it for HDR screenshots and HDR video recordings since.
I’m only mentioning it to show that the path works on the hardware side. It probably isn’t how you’d want to do it, and the format it uses is a made-up convention, since there’s no protocol for telling a client what colour space a frame is in. I’m happy to share the diff if it’s useful as a reference.
Full disclosure
An AI (Claude) found the approach and wrote both the patch and my capture client. I tested them and measured the results, but I didn’t design them and couldn’t explain every line, so I’m not offering the patch as a PR. I wrote this post myself without any AI involvement as mandated by your AI policy.
Why I’m posting
Hyprland already handles a lot of HDR well and I appreciate the work that’s gone into it. Capture is the one piece I keep running into. Right now I have to rebuild with a local patch after every update, and I’d love for that not to be necessary – and I think there are others out there who’d appreciate it as well.
KDE Plasma has also put a lot of work into HDR, and it would be great to see the Linux desktop as a whole close the gap here. I don’t know what’s already planned or what the right approach would be, so mainly I’d like to ask: is HDR capture something you’d be open to supporting, and if so, is there a direction you’d prefer?
Thanks for reading.
Attachments
Image 1: A screenshot of my HDR monitor taken with grim. 99.8% of the pixels are pure white: the sky, the clouds and almost all of the glider are gone.

Image 2: The same scene, captured a second later with the local patch, then tone mapped down to SDR so it can be shown here. The clouds, the sky and the glider are all there, since the capture kept the full range.

I acknowledge that:
I have searched all (open and closed) discussions and issues, checked the wiki, and my feature is not there.
I have read the Code of Conduct and agree to follow it.
I wrote this request with my own hands, my own keyboard, and in my own words.
All reactions