Working color correction in Plasma Wayland

Recently I had a discussion with Zamundaaa on Reddit regarding color correction. He was quite helpful and pointed me to the page he made with instructions on how to calibrate Plasma Wayland.

I hope I can at possibly help with QA or testing, as I have a bit of time as of late. Also it kind of sucks for any art or photography just hearing people say “stick to X11.”

So, I followed the directions to try and work through color correction on Wayland.

The good news: it works! Color correction does indeed work. As long as an image used by the system has an embedded ICC profile, it seems to adjust.

However… it only works with Rec709 (sRGB range).

The monitors I’m using have a wider gamut than sRGB, and if I am understanding how plasma handles things under the hood (which may be wrong), I won’t be able to calibrate/verify it via DisplayCAL since it takes any uncalibrated application and assigns sRGB to it.

Example verification reports:
Wayland - Rec709
Wayland - AdobeRGB

The gamut chart at the bottom bears this out, as the measured colors are in the exact same spot for both. For completeness, here’s the X11 ones:
X11 - Rec709
X11 - AdobeRGB

This means that under Wayland currently, a good part of the color range of my monitors is mostly unusable.

So I have a few questions.

Is it or will it be possible to force an application into a specific color profile? Or perhaps an ability to assign an app it’s own ICC profile if it normally would be unassigned or an older X11 application. Possibly assign a synthetic profile that has the whole CIE color gamut so that it allows any raw color through? That seems like it could get real messy real fast tho.

DisplayCAL is effectively abandoned, with work being done on it only to keep it functioning with python updates. It also uses wxPython for it’s GUI so it would have to be rewritten using something else in order to even be usable it seems. Argyll also seems destined to remain on X11.

Does this mean that the only way forward would be for a new application to be written in Qt (i.e. using QColorSpace) or something similar? (Kalibrate?)

I know things have been moving fast with Plasma and color profiling is kind of on the bleeding edge currently. Just trying to gather more information on what can be done.

P.S. I didn’t want to go deeply into this here, but it seems that since plasma handles the color temp, which means that profiles might not need to be made for each separate temp. The night light feature does this well–but it’s global, so that would make it difficult for two monitors to be two different white points. Just bringing this up as it could be an issue down the line.

3 Likes

Something that should work is

  1. set the “sRGB color intensity” slider (new in Plasma 6.3) to 100%, which makes all sRGB-assumed apps use the full gamut
  2. profile the screen with that, and your ICC profile still set in system settings. Save that new profile somewhere, but do not use it in the display settings
  3. set that profile in apps

I also had plans to make a compatibility mode that generates this profile automatically, but I didn’t manage to complete that in time for Plasma 6.3. It’s now relatively simple to make it happen for Plasma 6.4 at least.

DisplayCAL wouldn’t be super difficult to adapt for profiling on Wayland, but for verification argyllcms being stuck on X11 is indeed a problem.

Doesn’t need to be in Qt - it’ll only natively support the color management protocol in Qt 6.10 anyways - but yes, a new app would be great. I have plans to make one (ideally integrated right into system settings), but adapting argyll’s hardware access functionality takes some effort, and time is always a limiting factor, so not a lot has happened on that front yet.

See draft: extend night light to change the color temperature to the desired value, instead of assuming the display to be 6500K (!6113) · Merge requests · Plasma / KWin · GitLab :slight_smile:

2 Likes

Great stuff overall!

I installed neon testing on my spare box with the intent to try this. However, after setting the initial calibrated ICC profile in display (without doing anything with SRGB intensity) the screen went blank with no way to recover outside of removing the ICC file and relogging in. Searching logs, this seemed related:

Operating System: KDE neon Testing Edition
KDE Plasma Version: 6.2.90
KDE Frameworks Version: 6.11.0
Qt Version: 6.8.1
Kernel Version: 6.8.0-52-generic (64-bit)
Graphics Platform: Wayland
Graphics Processor: NVIDIA GeForce RTX 2060/PCIe/SSE2

1/29/25 12:12 PM	dbus-daemon	[session uid=0 pid=2065] Activating service name='org.freedesktop.impl.portal.desktop.kde' requested by ':1.1' (uid=0 pid=2069 comm="/usr/libexec/xdg-desktop-portal" label="unconfined")
1/29/25 12:12 PM	org.freedesktop.impl.portal.desktop.kde	error: XDG_RUNTIME_DIR is invalid or not set in the environment.
1/29/25 12:12 PM	xdg-desktop-portal-kde	Failed to create wl_display (No such file or directory)
1/29/25 12:12 PM	xdg-desktop-portal-kde	qt.qpa.plugin: Could not load the Qt platform plugin "wayland" in "" even though it was found.
1/29/25 12:12 PM	dbus-daemon	[session uid=0 pid=2065] Successfully activated service 'org.freedesktop.impl.portal.desktop.kde'
1/29/25 12:12 PM	dbus-daemon	[session uid=0 pid=2065] Successfully activated service 'org.freedesktop.portal.Desktop'
1/29/25 12:12 PM	kwin_wayland	kf.windowsystem: static bool KX11Extras::mapViewport() may only be used on X11
1/29/25 12:12 PM	kwin_wayland	kwin_core: XCB error: 3 (BadWindow), sequence: 645, resource id: 27263029, major code: 129 (SHAPE), minor code: 6 (Input)
1/29/25 12:14 PM	systemd	Started app-systemsettings@6599032469b642dea19c48b44dcbc9a8.service - Display Configuration.
1/29/25 12:14 PM	systemsettings	qrc:/qt/qml/org/kde/kirigami/dialogs/Dialog.qml:344:18: QML ScrollView: Binding loop detected for property "calculatedImplicitWidth":
qrc:/qt/qml/org/kde/kirigami/dialogs/Dialog.qml:358:9
1/29/25 12:14 PM	systemsettings	qt.qpa.wayland: eglSwapBuffers failed with 0x300d, surface: 0x0

I don’t think the desktop portal stuff is related (and XDG_RUNTIME_DIR=/run/user/1000 when checked), but the kwin_core and egl stuff seemed to be.

I don’t know if this is known (as it’s in an active testing branch) and I don’t have a kde bugs account yet, but I can create one and make a bug regarding this with any additional info if it’d help. I couldn’t find anything for this on initial searches.

Having it built in would be sweet. Regarding hardware, in the past I have done a little bit of work with microcontrollers in C (STM and PICs), maybe I can poke around in the argyll code and see if I can get enough to make a library to access color devices. No guarantees, I might fail spectacularly, but I do have a few devices to test against at least.

uhh that’s weird, and definitely not known. The log has nothing I’d consider relevant in it… could you upload the the ICC profile for me so that I can check it out?

That would be great!

Here ya go.

I also removed the Nvidia driver to eliminate it as a possibility, and test other ICC files, but same thing. Moving/renaming the .icc and restarting plasmashell gets it back up and running. I also tested that particular ICC file on my art computer (Fedora 41, Plasma 6.2.5) and it worked. I set up the test box next to it so I can easily switch over the monitors/peripherals, since I don’t want to screw around too much with with the main one.

(Edit: The same behavior happened in a VM running neon-unstable, so presumably newer than testing. So this could just be a recent neon issue.)

Let me know to get any information/output you need and I’ll be happy to make a bug. I honestly don’t care about the test box–nothing that can’t be reinstalled over there.

Also, good news about the calibration hardware. Argyll has it’s own USB implementation for every OS it runs on, and a lot of the individual hardware code is intertwined with it. Literally thousands of lines of code that could be replaced by libusb. I did a small test using libusb and was able to get raw results from a device:

higgins@spyro:~/dev/measure$ ./measuretest 
Init
Getting device handle...
control: reset, check OK
0x0000
HW version: 2.07
Measuring raw data...

X: 24685
Y: 48785
Z: 37216
ir: 56576
Closing device...
higgins@spyro:~/dev/measure$

So I at least have a decent starting point now.

That same profile works fine for me on git master. I’ll try a Neon VM as well, maybe it is specific to Neon.

Cool!