detached f8645de

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.
3434 - Cache build time reduced to ~300μs for typical history datasets
3535
3636 ### 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`
3738 - Eliminated O(n log n) sorting bottleneck on every dmenu call
3839 - Memory-efficient compact entry storage with minimal footprint
3940 - 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 datasets34 - Cache build time reduced to ~300μs for typical history datasets
35 35
36 ### Fixed36 ### 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 call38 - Eliminated O(n log n) sorting bottleneck on every dmenu call
38 - Memory-efficient compact entry storage with minimal footprint39 - Memory-efficient compact entry storage with minimal footprint
39 - Concurrent cache access with proper read/write locking40 - Concurrent cache access with proper read/write locking
M pkg/webkit/webview_cgo.go +32 -4
@@ -5,6 +5,7 @@ package webkit
55 /*
66 #cgo pkg-config: webkitgtk-6.0 gtk4 javascriptcoregtk-6.0
77 #include <stdlib.h>
8+#include <string.h>
89 #include <gtk/gtk.h>
910 #include <webkit/webkit.h>
1011 #include <glib-object.h>
@@ -72,11 +73,38 @@ static GtkWidget* new_webview_with_ucm_and_session(const char* data_dir, const c
7273 }
7374
7475 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
7590 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;
80108 }
81109
82110 // 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.06 #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 support110 // Note: preferred color scheme is handled via a user script injection to support

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close