[Initiatives.wiki] Create Dark Style Preference
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [Initiatives.wiki] Create Dark Style Preference
- Date: Wed, 29 Sep 2021 10:31:38 +0000 (UTC)
commit 83fbdedcea3abfe1f0054bed3e181c777ad030d0
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Wed Sep 29 10:31:37 2021 +0000
Create Dark Style Preference
Dark-Style-Preference.md | 155 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 155 insertions(+)
---
diff --git a/Dark-Style-Preference.md b/Dark-Style-Preference.md
new file mode 100644
index 0000000..f962d15
--- /dev/null
+++ b/Dark-Style-Preference.md
@@ -0,0 +1,155 @@
+# Design
+1. Apps that didn't have their own appearance preference (e.g. **Contacts** or **Clocks**) should normally
be light and become dark if the system prefers that.
+ * Apps that synchronized their appearance with the system night light mode (e.g. **Calendar** or
**Builder**), should stop doing that, this will be done system-wide instead.
+2. Apps that didn't have a preference but used dark appearance by default (e.g. **Photos** or **Videos**)
should be dark unless the system prefers light appearance, such as for the high contrast mode. If it's not
possible to support light appearance, they can be always dark.
+3. Apps that had provided a preference, but only because there wasn't a system-wide one (e.g. **Shortwave**
or **dconf-editor**) should drop their preference for GNOME 42. They can still show it when running on older
systems.
+4. Apps that had provided a prominent preference and want to keep it going forward (e.g. **Apostrophe**,
[**Text Editor**](https://gitlab.gnome.org/GNOME/gnome-text-editor) or **Builder**) should add a state where
the application follows the system preference, for example like on [this
mockup](https://gitlab.gnome.org/Teams/Design/os-mockups/-/blob/master/prefer-dark/prefer-dark.png). That
state may be omitted when running on older systems.
+5. Apps that use completely custom styles (e.g. **Contrast**) shouldn't try to follow the preference at all
if it doesn't make sense for them.
+6. Libraries that provide widgets should try to follow the app's appearance if possible and makes sense -
for example, **WebKitGTK** should use dark color scheme for pages that support it when the application it's
embedded into is dark — either automatically, or via API that the app would use. They should not follow the
system preference directly, as there's no guarantee the application follows it.
+
+# Implementation
+## GTK4 + libadwaita
+Applications follow the preference by default, so design 1 doesn't require any changes.
+
+To implement design 2 can use the following snippet to request dark variant and still support light
appearance:
+
+```c
+adw_style_manager_set_color_scheme (adw_style_manager_get_default (),
+ ADW_COLOR_SCHEME_PREFER_DARK);
+```
+
+or the following one otherwise:
+
+```c
+adw_style_manager_set_color_scheme (adw_style_manager_get_default (),
+ ADW_COLOR_SCHEME_FORCE_DARK);
+```
+
+A good place to do that would be the `startup()` handler of your `GApplication`.
+
+Applications that provide color scheme preferences as per designs 3 and 4 should use
`ADW_COLOR_SCHEME_FORCE_LIGHT` and `ADW_COLOR_SCHEME_FORCE_DARK` color schemes, as they will ignore the
system preference. The "follow system" state can be implemented as `ADW_COLOR_SCHEME_PREFER_LIGHT`.
+
+See [`AdwStyleManager:color-scheme`](color-scheme) for more details.
+
+Important: Don't use [`GtkSettings:gtk-application-prefer-dark-theme`](prefer-dark-theme) or
[`GtkSettings:gtk-theme-name`](gtk-theme-name) for checking if the application is currently using dark
appearance! Neither of them will change in this case.
+
+Instead, if you need to vary other aspects of the UI (e.g. the `GtkSourceView` color scheme), use the
[`AdwStyleManager:dark`](dark) property, and to check for the high contrast mode, use
[`AdwStyleManager:high-contrast`](high-contrast).
+
+To only show a switch when running on an system without a system-wide preference, the
[`AdwStyleManager:system-supports-color-schemes`](supports-color-schemes) property can be used; libadwaita
demo has [an
example](https://gitlab.gnome.org/GNOME/libadwaita/-/blob/2bf94101/examples/adw-demo-window.c#L41-62).
+
+If the application bundles custom CSS which needs changes for dark appearance or vice versa,
[`AdwApplication`](AdwApplication) provides an easy way to do that via `style.css` and `style-dark.css`
resoures.
+
+## GTK3 + libhandy
+If possible, consider porting to GTK4 and libadwaita first. libadwaita has a significant amount of changes
in its stylesheet, aimed to improve the contrast in dark variant. For example:
+
+| GTK3 | GTK4 + libadwaita |
+| :--: | :---------------: |
+| ![libhandy example](uploads/81af07e893f68272b4d676757ffc05a8/Screenshot_from_2021-09-29_02-38-52.png) |
![libadwaita example](uploads/f00ae6c5923bd0e056d3ad7ce0bee62d/Screenshot_from_2021-09-29_02-38-56.png)|
+
+Cases like this will need custom styles in the application.
+
+Other than that, the steps mostly match libadwaita, with one exception: applications don't follow the
preference by default, so design 1 requires apps to opt in using the following snippet:
+
+```c
+hdy_style_manager_set_color_scheme (hdy_style_manager_get_default (),
+ HDY_COLOR_SCHEME_PREFER_LIGHT);
+```
+
+Additionally, since `AdwApplication` is not available, loading a CSS snippet only for dark appearance is
instead done as follows:
+
+```c
+struct _MyApplication
+{
+ ...
+
+ GtkStyleProvider *dark_provider;
+};
+
+...
+
+static void
+update_dark_style (MyApplication *self)
+{
+ HdyStyleManager *manager = hdy_style_manager_get_default ();
+ GdkScreen *screen = gdk_screen_get_default ();
+
+ if (hdy_style_manager_get_dark (manager))
+ gtk_style_context_add_provider_for_screen (screen,
+ self->dark_provider,
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
+ else
+ gtk_style_context_remove_provider_for_screen (screen,
+ self->dark_provider);
+}
+
+...
+
+static void
+my_application_dispose (GObject *self)
+{
+ ...
+
+ g_clear_object (&self->dark_provider);
+}
+
+...
+
+static void
+my_application_startup (MyApplication *self)
+{
+ ...
+
+ self->dark_provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
+
+ gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (self->dark_provider),
+ "/my/application/style-dark.css");
+
+ update_dark_style (self);
+
+ g_signal_connect_object (hdy_style_manager_get_default (),
+ "notify::dark",
+ G_CALLBACK (update_dark_style),
+ self,
+ G_CONNECT_SWAPPED);
+}
+```
+
+## Other
+If it's not possible to use libadwaita or libhandy, use DBus to manually access the settings portal and
fetch the preference.
+
+Do _not_ use the gsettings key backing the settings portal implementation other than as a fallback if the
portal isn't present: that key only exists on GNOME and is an implementation detail.
+
+Don't add any animation for the transition; the whole screen will be animated on the compositor side instead.
+
+A self-contained SDL+GDBus example that supports the dark style preference:
[hello.c](uploads/76dfcc9b07d234cb8922cf800e743f02/hello.c)
+
+Building: `gcc $(pkg-config --libs --cflags sdl2 gio-2.0) hello.c -o hello"`
+
+Screenshots:
+
+![Screenshot_from_2021-09-29_03-54-35](uploads/a6b95700ea1e2b9487131b6d399998e6/Screenshot_from_2021-09-29_03-54-35.png)
+
+![Screenshot_from_2021-09-29_03-54-40](uploads/7ebfb46ec97d191ceef36c217eea554e/Screenshot_from_2021-09-29_03-54-40.png)
+
+# Testing
+## GNOME 42
+If you have a GNOME 42 system, for example a jhbuild session or a GNOME OS VM, use dconf-editor or
`gsettings` CLI to edit the following preference: `org.gnome.desktop.interface.color-scheme`.
+
+## libadwaita
+Libadwaita provides a `GtkInspector` page. If libadwaita is present in the SDK, it should work out of the
box, and for apps that bundle libadwaita, it can be enabled via `"--env=GTK_PATH=/app/lib/gtk-4.0"` in
`finish-args` in their manifest.
+
+If it's set up correctly, open inspector with `Ctrl+Shift+D` and there should be a libadwaita page providing
toggles for the system color scheme, high contrast and emulating an older system without color schemes.
+
+## Other
+The following project can be used to test the preference:
https://gitlab.gnome.org/exalm/color-scheme-simulator
+
+It provides a settings portal implementation (providing `color-scheme` and nothing else) that can run on
older GNOME versions together with `xdg-desktop-portal-gnome/gtk`, and a simple GUI for changing the
preference.
+
+[AdwApplication]: https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.Application.html
+[AdwStyleManager]: https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StyleManager.html
+[prefer-dark-theme]: https://docs.gtk.org/gtk4/property.Settings.gtk-application-prefer-dark-theme.html
+[gtk-theme-name]: https://docs.gtk.org/gtk4/property.Settings.gtk-theme-name.html
+[color-scheme]:
https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/property.StyleManager.color-scheme.html
+[supports-color-schemes]:
https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/property.StyleManager.system-supports-color-schemes.html
+[dark]: https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/property.StyleManager.dark.html
+[high-contrast]:
https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/property.StyleManager.high-contrast.html
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]