Bug 254135

Summary: [GTK] User contrast preference for high contrast not reflected in prefers-contrast CSS media query
Product: WebKit Reporter: Patrick H. Lauke <redux>
Component: WebKitGTKAssignee: Nobody <webkit-unassigned>
Status: NEW    
Severity: Normal CC: alicem, aperez, bugs-noreply, mcatanzaro, nekohayo, pgriffis
Priority: P2    
Version: WebKit Nightly Build   
Hardware: PC   
OS: Linux   
See Also: https://bugs.webkit.org/show_bug.cgi?id=256436
Attachments:
Description Flags
Screenshot showing Epiphany (Webkit-based) and Firefox on Ubuntu with high contrast setting enabled - note the difference in which prefers-contrast value evaluates to true none

Patrick H. Lauke
Reported 2023-03-19 07:24:27 PDT
Created attachment 465504 [details] Screenshot showing Epiphany (Webkit-based) and Firefox on Ubuntu with high contrast setting enabled - note the difference in which prefers-contrast value evaluates to true # Steps to reproduce the problem: 1. In Linux's settings, enable high contrast (in my case, in Ubuntu, this is under Settings > Accessibility > Seeing > High Contrast) 2. Open https://codepen.io/patrickhlauke/full/NWyajBN which tests the various user preference media features of MQ Level 5 (tested using Epiphany) 3. Check the reported "prefers-contrast" values # Problem Description: The expectation is that once High Contrast is enabled, the "prefers-contrast: more" media feature should evaluate to true. Instead, that currently evaluates to false and "prefers-contrast: no-preference" evaluates to true. I.e. Epiphany is not picking up on the OS-level preference. Note that this works as expected in Firefox/Linux (but fails the same way in Chrome/Linux - see https://bugs.chromium.org/p/chromium/issues/detail?id=1425734) Tested in Epiphany 42.4 (the latest available from the Ubuntu software manager) Relates to support for https://www.w3.org/TR/mediaqueries-5/#mf-user-preferences
Attachments
Screenshot showing Epiphany (Webkit-based) and Firefox on Ubuntu with high contrast setting enabled - note the difference in which prefers-contrast value evaluates to true (593.02 KB, image/png)
2023-03-19 07:24 PDT, Patrick H. Lauke
no flags
Patrick H. Lauke
Comment 1 2023-03-19 07:24:58 PDT
Alice Mikhaylenko
Comment 2 2023-03-19 07:47:37 PDT
High contrast is a bit hard atm... Using GSettings alone won't work in Flatpak. Libadwaita has a fairly complicated logic to fetch it atm, I'm afraid WebKit may need to copy that... Otherwise - when using libadwaita it can hook into it directly - it's not impossible, and everything you need here is accessible via properties so it can be done without a hard dependency. And honestly - when not using libadwaita you can just check gtk-theme-name instead.
Michael Catanzaro
Comment 3 2023-03-19 07:53:50 PDT
(In reply to Alexander Mikhaylenko from comment #2) > Libadwaita has a fairly complicated logic to fetch it atm, I'm afraid WebKit > may need to copy that... Why aren't these settings exposed via settings portal? I think we should just look at the gsetting (carefully, to ensure we don't crash if not installed) and if it's not propagated by the portal then too bad. Desktop-wide settings that applications would be expected to read should be readable. There's also a reduced motion accessibility setting that we should propagate as well (InternalSettings.h). (The other accessibility settings there don't have equivalents in GNOME.)
Alice Mikhaylenko
Comment 4 2023-03-19 07:56:59 PDT
It is exposed by the settings portal. How would it work in other apps otherwise? ;) That's what libadwaita uses. Poratl + gsettings + deriving from gtk-theme-name on GdkDisplay + separate codepaths for macOS and Windows. But that's a lot of pretty fragile logic, do you really want to have it all in WebKit?
Alice Mikhaylenko
Comment 5 2023-03-19 07:58:54 PDT
Oh, forgot about those parts. There is also an env variable to override it on startup that Builder uses for its run -> accessibility -> high contrast toggle, and there's a toggle in inspector.
Patrick Griffis
Comment 6 2023-05-07 18:34:55 PDT
I did some initial work on this in https://github.com/WebKit/WebKit/pull/13558 It doesn't cover all situations and it is only for GTK3 but I think it is still valuable for some users. I looked into using libadwaita to determine high-contrast on GTK4 but the complicated part is WebKit proxies over all GtkSettings to the WebProcess, but this isn't a GtkSetting, so we'd have to proxy it another way. Otherwise just dynamically loading libadwaita wasn't too much effort and should work fine.
Michael Catanzaro
Comment 7 2023-05-07 21:09:00 PDT
Loading libadwaita only makes sense if the UI process is actually using libadwaita, though. How do you check whether you're in high contrast mode with libadwaita?
Patrick Griffis
Comment 8 2023-05-08 09:00:58 PDT
(In reply to Michael Catanzaro from comment #7) > Loading libadwaita only makes sense if the UI process is actually using > libadwaita, though. Yes. I was using `adw_is_initialized()` to conditionally check if we should respect libadwaita. > How do you check whether you're in high contrast mode with libadwaita? AdwStyleManager:high-contrast
Michael Catanzaro
Comment 9 2023-05-08 12:23:33 PDT
(In reply to Patrick Griffis from comment #8) > Yes. I was using `adw_is_initialized()` to conditionally check if we should > respect libadwaita. Bah, I guess that is indeed a good reason to dlopen libadwaita, if you want to be able to do this check without having WebKit actually depend on libadwaita. > > How do you check whether you're in high contrast mode with libadwaita? > > AdwStyleManager:high-contrast Hm, I know we are WebKitGTK and not WebKitAdwaita, but maybe it would be easiest to just link to libadwaita after all. Dunno. Well, if using dlopen is not too hard, I suppose that's fine.
Adrian Perez
Comment 10 2023-05-08 12:44:29 PDT
(In reply to Michael Catanzaro from comment #9) > (In reply to Patrick Griffis from comment #8) > > Yes. I was using `adw_is_initialized()` to conditionally check if we should > > respect libadwaita. > > Bah, I guess that is indeed a good reason to dlopen libadwaita, if you want > to be able to do this check without having WebKit actually depend on > libadwaita. > > > > How do you check whether you're in high contrast mode with libadwaita? > > > > AdwStyleManager:high-contrast > > Hm, I know we are WebKitGTK and not WebKitAdwaita, but maybe it would be > easiest to just link to libadwaita after all. Dunno. Well, if using dlopen > is not too hard, I suppose that's fine. Why not using the settings portal directly? We only need to watch the property “high-contrast” of the “org.gnome.desktop.a11y.interface”, and fallback to disabled if the interface is not available. I would rather not link libadwaita at all, and avoid dlopening it as well if possible. Alternatively, if we want to try libadwaita first, and fallback to the portal, we can: typedef struct _AdwStyleManager AdwStyleManager; void* handle = dlopen(NULL, RTLD_NOW); gboolean (*adwaitaIsInitialized)(void) = dlsym(handle, "adw_is_initialized"); AdwStyleManager (*adwaitaGetDefaultStyleManager)(void) = dlsym(handle, "adw_style_manager_get_default"); if (adwaitaIsInitialized && adwaitaGetDefaultStyleManager && adwaitaIsInitialized()) { // Proceed as before, but now we reach this code only iff the application // had already loaded libadwaita, without needing to load it ourselves. AdwStyleManager* styleManager = adwGetDefaultStyleManager(); g_signal_connect(styleManager, "notify::high-contrast", G_CALLBACK(...), ...); } else { // Assume high-contrast always off, or directly use DBus. }
Patrick Griffis
Comment 11 2023-05-08 12:52:19 PDT
(In reply to Adrian Perez from comment #10) > Why not using the settings portal directly? We only need to watch the > property “high-contrast” of the “org.gnome.desktop.a11y.interface”, and > fallback to disabled if the interface is not available. Any of these approaches are fine. We just have to proxy it similar to GtkSettingsManagerProxy.
Alice Mikhaylenko
Comment 12 2023-05-09 06:07:01 PDT
FWIW portal is an implementation detail, libadwaita does not guarantee that HC will be read from there at all. In fact, there are quite a few situations where it's not, like there is an environment variable to override it, there's a toggle in inspector that overrides it and so on. One thing you can do without having to load libadwaita is: when AdwApplication is used, you can get the application, access the style-manager property, access the high-contrast property. That can be done in runtime, without linking or dlopening anything. That won't work if adw_init() was used without AdwApplication though, but that's not recommended to begin with.
Michael Catanzaro
Comment 13 2023-05-09 12:09:49 PDT
(In reply to Alice Mikhaylenko from comment #12) > One thing you can do without having to load libadwaita is: when > AdwApplication is used, you can get the application, access the > style-manager property, access the high-contrast property. That can be done > in runtime, without linking or dlopening anything. Oh wow, so this works because it's GObjects all the way down? That's actually a really cool idea. We'd have to make sure the property actually exists before trying to get it using g_object_get(), to avoid criticals if the property doesn't exist, but I think that can be done by using G_OBJECT_GET_CLASS() then g_object_class_find_property().
Alice Mikhaylenko
Comment 14 2023-05-10 00:13:12 PDT
Yup. An upside of GObject properties existing entirely in runtime. But yeah, there's still the case where you're not using AdwApplication. :(
Patrick Griffis
Comment 15 2024-09-02 08:06:43 PDT
I wrote a solution to this using libadwaita - https://github.com/TingPing/WebKit/commit/e262dc251e5dc82493124751e64e0b57557e0a55 But I've learned upstream GTK is solving this issue: https://gitlab.gnome.org/GNOME/gtk/-/issues/6821 Any thoughts if we should handle it for now and adopt the new API once it exists? It isn't terribly complex.
Michael Catanzaro
Comment 16 2024-09-02 09:29:15 PDT
If it looks like the GTK API might land soon, then I think it's best to wait for and depend on that. Theme-adjacent settings are too confusing already. But if it's going to be a while, then the libadwaita solution seems pragmatic.
Note You need to log in before you can comment on or make changes to this bug.