fix(webkit): improve dark theme detection with GNOME color-scheme support
- Primary: Check org.gnome.desktop.interface color-scheme setting - Fallback 1: Check GTK theme name for -dark suffix variants - Fallback 2: Check gtk-application-prefer-dark-theme (original method) This properly detects dark mode when GNOME's color-scheme is set to 'prefer-dark' while theme remains 'Adwaita' (modern GNOME behavior).
- commit
- f8645de9f4b8cfa460e1f2ec47f6fb7b261c9ef3
- author
- Brice · · 2025-09-10 20:55 UTC
- parent
- 79d72a8
- signature
- unsigned
2 files · +33 -4
M CHANGELOG.md +1 -0
| @@ -34,6 +34,7 @@ All notable changes to this project will be documented in this file. | |||
| 34 | 34 | - Cache build time reduced to ~300μs for typical history datasets | |
| 35 | 35 | ||
| 36 | 36 | ### Fixed | |
| 37 | + | - Dark theme detection now properly reads GNOME desktop interface color-scheme setting (`org.gnome.desktop.interface color-scheme`) instead of only checking `gtk-application-prefer-dark-theme` | |
| 37 | 38 | - Eliminated O(n log n) sorting bottleneck on every dmenu call | |
| 38 | 39 | - Memory-efficient compact entry storage with minimal footprint | |
| 39 | 40 | - Concurrent cache access with proper read/write locking | |
| @@ -34,6 +34,7 @@ All notable changes to this project will be documented in this file. | |||||
| 34 | - Cache build time reduced to ~300μs for typical history datasets | 34 | - Cache build time reduced to ~300μs for typical history datasets | ||
| 35 | 35 | ||||
| 36 | ### Fixed | 36 | ### Fixed | ||
| 37 | + | - Dark theme detection now properly reads GNOME desktop interface color-scheme setting (`org.gnome.desktop.interface color-scheme`) instead of only checking `gtk-application-prefer-dark-theme` | |||
| 37 | - Eliminated O(n log n) sorting bottleneck on every dmenu call | 38 | - Eliminated O(n log n) sorting bottleneck on every dmenu call | ||
| 38 | - Memory-efficient compact entry storage with minimal footprint | 39 | - Memory-efficient compact entry storage with minimal footprint | ||
| 39 | - Concurrent cache access with proper read/write locking | 40 | - Concurrent cache access with proper read/write locking | ||
M pkg/webkit/webview_cgo.go +32 -4
| @@ -5,6 +5,7 @@ package webkit | |||
| 5 | 5 | /* | |
| 6 | 6 | #cgo pkg-config: webkitgtk-6.0 gtk4 javascriptcoregtk-6.0 | |
| 7 | 7 | #include <stdlib.h> | |
| 8 | + | #include <string.h> | |
| 8 | 9 | #include <gtk/gtk.h> | |
| 9 | 10 | #include <webkit/webkit.h> | |
| 10 | 11 | #include <glib-object.h> | |
| @@ -72,11 +73,38 @@ static GtkWidget* new_webview_with_ucm_and_session(const char* data_dir, const c | |||
| 72 | 73 | } | |
| 73 | 74 | ||
| 74 | 75 | static gboolean gtk_prefers_dark() { | |
| 76 | + | // Method 1: Check GNOME desktop interface color-scheme (primary method) | |
| 77 | + | GSettings* desktop_settings = g_settings_new("org.gnome.desktop.interface"); | |
| 78 | + | if (desktop_settings) { | |
| 79 | + | gchar* color_scheme = g_settings_get_string(desktop_settings, "color-scheme"); | |
| 80 | + | if (color_scheme) { | |
| 81 | + | gboolean prefer_dark = (g_strcmp0(color_scheme, "prefer-dark") == 0); | |
| 82 | + | g_free(color_scheme); | |
| 83 | + | g_object_unref(desktop_settings); | |
| 84 | + | if (prefer_dark) return TRUE; | |
| 85 | + | } | |
| 86 | + | g_object_unref(desktop_settings); | |
| 87 | + | } | |
| 88 | + | ||
| 89 | + | // Method 2: Check GTK theme name for dark variants | |
| 75 | 90 | GtkSettings* settings = gtk_settings_get_default(); | |
| 76 | - | if (!settings) return FALSE; | |
| 77 | - | gboolean prefer = FALSE; | |
| 78 | - | g_object_get(settings, "gtk-application-prefer-dark-theme", &prefer, NULL); | |
| 79 | - | return prefer; | |
| 91 | + | if (settings) { | |
| 92 | + | gchar* theme_name = NULL; | |
| 93 | + | g_object_get(settings, "gtk-theme-name", &theme_name, NULL); | |
| 94 | + | if (theme_name) { | |
| 95 | + | gboolean is_dark = (strstr(theme_name, "-dark") != NULL || | |
| 96 | + | strstr(theme_name, "-Dark") != NULL); | |
| 97 | + | g_free(theme_name); | |
| 98 | + | if (is_dark) return TRUE; | |
| 99 | + | } | |
| 100 | + | ||
| 101 | + | // Method 3: Check gtk-application-prefer-dark-theme (fallback) | |
| 102 | + | gboolean prefer = FALSE; | |
| 103 | + | g_object_get(settings, "gtk-application-prefer-dark-theme", &prefer, NULL); | |
| 104 | + | if (prefer) return TRUE; | |
| 105 | + | } | |
| 106 | + | ||
| 107 | + | return FALSE; | |
| 80 | 108 | } | |
| 81 | 109 | ||
| 82 | 110 | // Note: preferred color scheme is handled via a user script injection to support | |
| @@ -5,6 +5,7 @@ package webkit | |||||
| 5 | /* | 5 | /* | ||
| 6 | #cgo pkg-config: webkitgtk-6.0 gtk4 javascriptcoregtk-6.0 | 6 | #cgo pkg-config: webkitgtk-6.0 gtk4 javascriptcoregtk-6.0 | ||
| 7 | #include <stdlib.h> | 7 | #include <stdlib.h> | ||
| 8 | + | #include <string.h> | |||
| 8 | #include <gtk/gtk.h> | 9 | #include <gtk/gtk.h> | ||
| 9 | #include <webkit/webkit.h> | 10 | #include <webkit/webkit.h> | ||
| 10 | #include <glib-object.h> | 11 | #include <glib-object.h> | ||
| @@ -72,11 +73,38 @@ static GtkWidget* new_webview_with_ucm_and_session(const char* data_dir, const c | |||||
| 72 | } | 73 | } | ||
| 73 | 74 | ||||
| 74 | static gboolean gtk_prefers_dark() { | 75 | static gboolean gtk_prefers_dark() { | ||
| 76 | + | // Method 1: Check GNOME desktop interface color-scheme (primary method) | |||
| 77 | + | GSettings* desktop_settings = g_settings_new("org.gnome.desktop.interface"); | |||
| 78 | + | if (desktop_settings) { | |||
| 79 | + | gchar* color_scheme = g_settings_get_string(desktop_settings, "color-scheme"); | |||
| 80 | + | if (color_scheme) { | |||
| 81 | + | gboolean prefer_dark = (g_strcmp0(color_scheme, "prefer-dark") == 0); | |||
| 82 | + | g_free(color_scheme); | |||
| 83 | + | g_object_unref(desktop_settings); | |||
| 84 | + | if (prefer_dark) return TRUE; | |||
| 85 | + | } | |||
| 86 | + | g_object_unref(desktop_settings); | |||
| 87 | + | } | |||
| 88 | + | ||||
| 89 | + | // Method 2: Check GTK theme name for dark variants | |||
| 75 | GtkSettings* settings = gtk_settings_get_default(); | 90 | GtkSettings* settings = gtk_settings_get_default(); | ||
| 76 | - | if (!settings) return FALSE; | 91 | + | if (settings) { |
| 77 | - | gboolean prefer = FALSE; | 92 | + | gchar* theme_name = NULL; |
| 78 | - | g_object_get(settings, "gtk-application-prefer-dark-theme", &prefer, NULL); | 93 | + | g_object_get(settings, "gtk-theme-name", &theme_name, NULL); |
| 79 | - | return prefer; | 94 | + | if (theme_name) { |
| 95 | + | gboolean is_dark = (strstr(theme_name, "-dark") != NULL || | |||
| 96 | + | strstr(theme_name, "-Dark") != NULL); | |||
| 97 | + | g_free(theme_name); | |||
| 98 | + | if (is_dark) return TRUE; | |||
| 99 | + | } | |||
| 100 | + | ||||
| 101 | + | // Method 3: Check gtk-application-prefer-dark-theme (fallback) | |||
| 102 | + | gboolean prefer = FALSE; | |||
| 103 | + | g_object_get(settings, "gtk-application-prefer-dark-theme", &prefer, NULL); | |||
| 104 | + | if (prefer) return TRUE; | |||
| 105 | + | } | |||
| 106 | + | ||||
| 107 | + | return FALSE; | |||
| 80 | } | 108 | } | ||
| 81 | 109 | ||||
| 82 | // Note: preferred color scheme is handled via a user script injection to support | 110 | // Note: preferred color scheme is handled via a user script injection to support | ||