From cd93fe3b0e7eb7d8295179d01d5d14e1797f7e09 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub Date: Sun, 22 Mar 2026 10:00:27 -0600 Subject: [PATCH 1/3] Apply app theme CSS to menubar everywhere --- src/fe-gtk/theme/theme-application.c | 54 ++++++++++++++-------------- src/fe-gtk/theme/theme-css.c | 22 +++++++----- src/fe-gtk/theme/theme-manager.c | 17 ++------- src/fe-gtk/theme/theme-policy.c | 33 +---------------- 4 files changed, 43 insertions(+), 83 deletions(-) diff --git a/src/fe-gtk/theme/theme-application.c b/src/fe-gtk/theme/theme-application.c index 73da2c79..e631a6c2 100644 --- a/src/fe-gtk/theme/theme-application.c +++ b/src/fe-gtk/theme/theme-application.c @@ -26,16 +26,29 @@ #include "theme-runtime.h" #include "theme-gtk3.h" #include "../maingui.h" - -#ifdef G_OS_WIN32 #include +#if defined(__GNUC__) || defined(__clang__) +extern char *theme_css_build_toplevel_classes (void) __attribute__ ((weak)); +#else +extern char *theme_css_build_toplevel_classes (void); +#endif + +static char * +theme_application_build_toplevel_css (void) +{ + if (theme_css_build_toplevel_classes) + return theme_css_build_toplevel_classes (); + + return g_strdup (""); +} + static void -theme_application_apply_windows_theme (gboolean dark) +theme_application_apply_toplevel_theme (gboolean dark) { GtkSettings *settings = gtk_settings_get_default (); - static GtkCssProvider *win_theme_provider = NULL; - static gboolean win_theme_provider_installed = FALSE; + static GtkCssProvider *theme_provider = NULL; + static gboolean theme_provider_installed = FALSE; GdkScreen *screen; gboolean prefer_dark = dark; char *css; @@ -56,33 +69,21 @@ theme_application_apply_windows_theme (gboolean dark) if (!screen) return; - if (theme_gtk3_is_active ()) - { - if (win_theme_provider_installed && win_theme_provider) - { - gtk_style_context_remove_provider_for_screen (screen, - GTK_STYLE_PROVIDER (win_theme_provider)); - win_theme_provider_installed = FALSE; - } - return; - } + if (!theme_provider) + theme_provider = gtk_css_provider_new (); - if (!win_theme_provider) - win_theme_provider = gtk_css_provider_new (); - - css = theme_css_build_toplevel_classes (); - gtk_css_provider_load_from_data (win_theme_provider, css, -1, NULL); + css = theme_application_build_toplevel_css (); + gtk_css_provider_load_from_data (theme_provider, css, -1, NULL); g_free (css); - if (!win_theme_provider_installed) + if (!theme_provider_installed) { gtk_style_context_add_provider_for_screen (screen, - GTK_STYLE_PROVIDER (win_theme_provider), + GTK_STYLE_PROVIDER (theme_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1); - win_theme_provider_installed = TRUE; + theme_provider_installed = TRUE; } } -#endif gboolean theme_application_apply_mode (unsigned int mode, gboolean *palette_changed) @@ -91,10 +92,7 @@ theme_application_apply_mode (unsigned int mode, gboolean *palette_changed) theme_runtime_load (); dark = theme_runtime_apply_mode (mode, palette_changed); - -#ifdef G_OS_WIN32 - theme_application_apply_windows_theme (dark); -#endif + theme_application_apply_toplevel_theme (dark); theme_application_reload_input_style (); diff --git a/src/fe-gtk/theme/theme-css.c b/src/fe-gtk/theme/theme-css.c index df657ada..a294943c 100644 --- a/src/fe-gtk/theme/theme-css.c +++ b/src/fe-gtk/theme/theme-css.c @@ -361,20 +361,22 @@ theme_css_build_toplevel_classes (void) "color: #f0f0f0;" "border-color: #202020;" "}" - "window.%s menubar, window.%s menubar:backdrop, window.%s menuitem, window.%s menuitem:backdrop {" - "background-color: #202020;" - "color: #f0f0f0;" - "border-color: #202020;" + "window.%s menubar, window.%s menubar:backdrop, window.%s menubar box, window.%s menubar box:backdrop, window.%s menuitem, window.%s menuitem:backdrop {" + "background-color: @theme_bg_color;" + "background-image: none;" + "color: @theme_fg_color;" + "border-color: @theme_bg_color;" "}" "window.%s, window.%s:backdrop, .%s {" "background-color: #f6f6f6;" "color: #101010;" "border-color: #f6f6f6;" "}" - "window.%s menubar, window.%s menubar:backdrop, window.%s menuitem, window.%s menuitem:backdrop {" - "background-color: #f6f6f6;" - "color: #101010;" - "border-color: #f6f6f6;" + "window.%s menubar, window.%s menubar:backdrop, window.%s menubar box, window.%s menubar box:backdrop, window.%s menuitem, window.%s menuitem:backdrop {" + "background-color: @theme_bg_color;" + "background-image: none;" + "color: @theme_fg_color;" + "border-color: @theme_bg_color;" "}", theme_css_selector_dark_class, theme_css_selector_dark_class, @@ -383,6 +385,10 @@ theme_css_build_toplevel_classes (void) theme_css_selector_dark_class, theme_css_selector_dark_class, theme_css_selector_dark_class, + theme_css_selector_dark_class, + theme_css_selector_dark_class, + theme_css_selector_light_class, + theme_css_selector_light_class, theme_css_selector_light_class, theme_css_selector_light_class, theme_css_selector_light_class, diff --git a/src/fe-gtk/theme/theme-manager.c b/src/fe-gtk/theme/theme-manager.c index 83e873aa..36858c8e 100644 --- a/src/fe-gtk/theme/theme-manager.c +++ b/src/fe-gtk/theme/theme-manager.c @@ -216,8 +216,6 @@ theme_manager_queue_auto_refresh (GtkSettings *settings, GParamSpec *pspec, gpoi void theme_manager_init (void) { - GtkSettings *settings; - if (!theme_manager_listeners) theme_manager_listeners = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, theme_listener_free); @@ -225,21 +223,10 @@ theme_manager_init (void) if (!theme_manager_setup_listener_id) theme_manager_setup_listener_id = theme_listener_register ("setup.apply", theme_manager_setup_apply_listener, NULL); - settings = gtk_settings_get_default (); - if (settings) - fe_set_auto_dark_mode_state (theme_policy_system_prefers_dark ()); - + fe_set_auto_dark_mode_state (FALSE); theme_application_apply_mode (prefs.hex_gui_dark_mode, NULL); theme_gtk3_init (); zoitechat_set_theme_post_apply_callback (theme_manager_handle_theme_applied); - - if (settings) - { - g_signal_connect (settings, "notify::gtk-application-prefer-dark-theme", - G_CALLBACK (theme_manager_queue_auto_refresh), NULL); - g_signal_connect (settings, "notify::gtk-theme-name", - G_CALLBACK (theme_manager_queue_auto_refresh), NULL); - } } gboolean @@ -494,7 +481,6 @@ theme_manager_apply_wayland_kde_csd (GtkWidget *window) static void theme_manager_apply_platform_window_theme (GtkWidget *window) { -#ifdef G_OS_WIN32 GtkStyleContext *context; gboolean dark; @@ -516,6 +502,7 @@ theme_manager_apply_platform_window_theme (GtkWidget *window) gtk_style_context_remove_class (context, "zoitechat-light"); gtk_style_context_add_class (context, dark ? "zoitechat-dark" : "zoitechat-light"); } +#ifdef G_OS_WIN32 fe_win32_apply_native_titlebar (window, dark); #else theme_manager_apply_wayland_kde_csd (window); diff --git a/src/fe-gtk/theme/theme-policy.c b/src/fe-gtk/theme/theme-policy.c index f0ff0a08..8bf31863 100644 --- a/src/fe-gtk/theme/theme-policy.c +++ b/src/fe-gtk/theme/theme-policy.c @@ -27,38 +27,7 @@ gboolean theme_policy_system_prefers_dark (void) { - GtkSettings *settings = gtk_settings_get_default (); - gboolean prefer_dark = FALSE; - char *theme_name = NULL; -#ifdef G_OS_WIN32 - gboolean have_win_pref = FALSE; - - if (fe_win32_high_contrast_is_enabled ()) - return FALSE; - - have_win_pref = fe_win32_try_get_system_dark (&prefer_dark); - if (!have_win_pref) -#endif - if (settings && g_object_class_find_property (G_OBJECT_GET_CLASS (settings), - "gtk-application-prefer-dark-theme")) - { - g_object_get (settings, "gtk-application-prefer-dark-theme", &prefer_dark, NULL); - } - - if (settings && !prefer_dark) - { - g_object_get (settings, "gtk-theme-name", &theme_name, NULL); - if (theme_name) - { - char *lower = g_ascii_strdown (theme_name, -1); - if (g_str_has_suffix (lower, "-dark") || g_strrstr (lower, "dark")) - prefer_dark = TRUE; - g_free (lower); - g_free (theme_name); - } - } - - return prefer_dark; + return FALSE; } gboolean From d26fbb6e8944a685e1bf238555f190cfbe1a8a70 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub Date: Sun, 22 Mar 2026 10:14:49 -0600 Subject: [PATCH 2/3] Set menubar halign to start --- src/fe-gtk/maingui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-gtk/maingui.c b/src/fe-gtk/maingui.c index 7b35c5d5..207f8629 100644 --- a/src/fe-gtk/maingui.c +++ b/src/fe-gtk/maingui.c @@ -4206,7 +4206,7 @@ mg_create_menu (session_gui *gui, GtkWidget *table, int away_state) gui->menu_item); gtk_widget_set_hexpand (gui->menu, TRUE); gtk_widget_set_vexpand (gui->menu, FALSE); - gtk_widget_set_halign (gui->menu, GTK_ALIGN_FILL); + gtk_widget_set_halign (gui->menu, GTK_ALIGN_START); gtk_widget_set_valign (gui->menu, GTK_ALIGN_FILL); gtk_grid_attach (GTK_GRID (table), gui->menu, 0, 0, 3, 1); } From 33fce2af2abdd75a0569c9ae9d6dc6f7dd518d5a Mon Sep 17 00:00:00 2001 From: deepend-tildeclub Date: Sun, 22 Mar 2026 10:39:07 -0600 Subject: [PATCH 3/3] Refresh GTK3 theme changes live --- .../test-theme-preferences-gtk3-populate.c | 6 ++++++ src/fe-gtk/theme/theme-preferences.c | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c b/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c index 6f4b1059..38c43167 100644 --- a/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c +++ b/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c @@ -102,6 +102,12 @@ theme_manager_save_preferences (void) return TRUE; } +void +theme_manager_dispatch_changed (ThemeChangedReason reasons) +{ + (void)reasons; +} + ThemePaletteBehavior theme_manager_get_userlist_palette_behavior (const PangoFontDescription *font_desc) { diff --git a/src/fe-gtk/theme/theme-preferences.c b/src/fe-gtk/theme/theme-preferences.c index 9b49a43e..bc557326 100644 --- a/src/fe-gtk/theme/theme-preferences.c +++ b/src/fe-gtk/theme/theme-preferences.c @@ -1350,6 +1350,19 @@ theme_preferences_gtk3_sync_remove_state (theme_preferences_ui *ui) gtk_widget_set_sensitive (ui->gtk3_remove, source == ZOITECHAT_GTK3_THEME_SOURCE_USER); } +static gboolean +theme_preferences_gtk3_apply_and_refresh (GError **error) +{ + if (!theme_gtk3_apply_current (error)) + return FALSE; + theme_manager_dispatch_changed (THEME_CHANGED_REASON_THEME_PACK | + THEME_CHANGED_REASON_PALETTE | + THEME_CHANGED_REASON_WIDGET_STYLE | + THEME_CHANGED_REASON_USERLIST | + THEME_CHANGED_REASON_MODE); + return TRUE; +} + static void theme_preferences_gtk3_changed_cb (GtkComboBox *combo, gpointer user_data) { @@ -1380,7 +1393,7 @@ theme_preferences_gtk3_changed_cb (GtkComboBox *combo, gpointer user_data) ui->setup_prefs->hex_gui_gtk3_variant = prefs.hex_gui_gtk3_variant; } - if (selection_changed && !theme_gtk3_apply_current (&error)) + if (selection_changed && !theme_preferences_gtk3_apply_and_refresh (&error)) { theme_preferences_show_message (ui, GTK_MESSAGE_ERROR, error ? error->message : _("Failed to apply GTK3 theme.")); @@ -1557,7 +1570,7 @@ theme_preferences_populate_gtk3 (theme_preferences_ui *ui) g_free (final_id); } - if (should_apply && !theme_gtk3_apply_current (&error)) + if (should_apply && !theme_preferences_gtk3_apply_and_refresh (&error)) { theme_preferences_show_message (ui, GTK_MESSAGE_ERROR, error ? error->message : _("Failed to apply GTK3 theme."));