1 Commits

Author SHA1 Message Date
364e52f7d9 Fix Win tray hidden-state toggle logic 2026-03-21 03:28:38 -06:00
14 changed files with 151 additions and 190 deletions

View File

@@ -1,28 +1,6 @@
ZoiteChat ChangeLog ZoiteChat ChangeLog
================= =================
2.18.0~pre5 (2026-03-22)
------------------------
- Overhauled preferences/config saving: fully staged and transactional, debounced
with flush on close, write failures now surfaced.
- Overhauled GTK theme handling: live preview, correct colour reset persistence,
proper file:// import paths, consistent menubar CSS.
- Fixed GTK entry scroll artifact in the input box.
- Hardened tray menu lifetime; fixed stale pointer crash on menu destruction.
- Fixed AppIndicator tray init for Wayland/source builds; skip redundant X11
tray probe for AppIndicator builds.
- Split topic/mode rows in channel bar, tighten spacing, persist userlist column widths.
- Preserve saved right-pane size on first layout.
- Fixed sounds prefs section.
- Fixed chanview tree layout and header alignment; tighten topic URL hit-testing.
- Dropped realpath() in favour of GLib-only absolute path build.
- Made About dialog links explicit; added GPL licence URL.
- Added licence headers to new source files.
- Windows installer: fixed VC++ redist URL, added non-plugin download fallback,
switched to registry-based runtime detection.
- Made libayatana-appindicator a required dep in PKGBUILD.
- Cleaned up Meson libperl detection.
2.18.0~pre4 (2026-03-15) 2.18.0~pre4 (2026-03-15)
------------------------ ------------------------

View File

@@ -29,45 +29,6 @@
<id>zoitechat.desktop</id> <id>zoitechat.desktop</id>
</provides> </provides>
<releases> <releases>
<release date="2026-03-22" version="2.18.0~pre5">
<description>
<p>Preferences and config saving:</p>
<ul>
<li>Overhauled preferences/config saving: fully staged and transactional, debounced with flush on close, write failures now surfaced.</li>
</ul>
<p>GTK theme and UI:</p>
<ul>
<li>Overhauled GTK theme handling: live preview, correct colour reset persistence, proper <code>file://</code> import paths, consistent menubar CSS.</li>
<li>Fixed GTK entry scroll artifact in the input box.</li>
<li>Split topic/mode rows in channel bar, tighten spacing, persist userlist column widths.</li>
<li>Preserve saved right-pane size on first layout.</li>
<li>Fixed sounds prefs section.</li>
<li>Fixed chanview tree layout and header alignment; tighten topic URL hit-testing.</li>
</ul>
<p>Tray:</p>
<ul>
<li>Hardened tray menu lifetime; fixed stale pointer crash on menu destruction.</li>
<li>Fixed AppIndicator tray init for Wayland/source builds; skip redundant X11 tray probe for AppIndicator builds.</li>
</ul>
<p>Build and packaging:</p>
<ul>
<li>Dropped <code>realpath()</code> in favour of GLib-only absolute path build.</li>
<li>Made About dialog links explicit; added GPL licence URL.</li>
<li>Added licence headers to new source files.</li>
<li>Windows installer: fixed VC++ redist URL, added non-plugin download fallback, switched to registry-based runtime detection.</li>
<li>Made <code>libayatana-appindicator</code> a required dep in PKGBUILD.</li>
<li>Cleaned up Meson libperl detection.</li>
</ul>
</description>
</release>
<release date="2026-03-22" version="2.18.0~pre5">
<description>
<p>Version metadata update:</p>
<ul>
<li>Bumped release version references to <code>2.18.0~pre5</code> across build and packaging files.</li>
</ul>
</description>
</release>
<release date="2026-03-14" version="2.18.0~pre4"> <release date="2026-03-14" version="2.18.0~pre4">
<description> <description>
<p>UI fixes, topic bar improvements, and selection styling updates:</p> <p>UI fixes, topic bar improvements, and selection styling updates:</p>

View File

@@ -1,5 +1,5 @@
project('zoitechat', 'c', project('zoitechat', 'c',
version: '2.18.0~pre5', version: '2.18.0~pre4',
meson_version: '>= 0.55.0', meson_version: '>= 0.55.0',
default_options: [ default_options: [
'c_std=c17', 'c_std=c17',

View File

@@ -19,7 +19,7 @@ else:
if not hasattr(sys, 'argv'): if not hasattr(sys, 'argv'):
sys.argv = ['<zoitechat>'] sys.argv = ['<zoitechat>']
VERSION = b'2.18.0~pre5' VERSION = b'2.18.0~pre4'
PLUGIN_NAME = ffi.new('char[]', b'Python') PLUGIN_NAME = ffi.new('char[]', b'Python')
PLUGIN_DESC = ffi.new('char[]', b'Python %d.%d scripting interface' % (sys.version_info[0], sys.version_info[1])) PLUGIN_DESC = ffi.new('char[]', b'Python %d.%d scripting interface' % (sys.version_info[0], sys.version_info[1]))
PLUGIN_VERSION = ffi.new('char[]', VERSION) PLUGIN_VERSION = ffi.new('char[]', VERSION)

View File

@@ -4206,7 +4206,7 @@ mg_create_menu (session_gui *gui, GtkWidget *table, int away_state)
gui->menu_item); gui->menu_item);
gtk_widget_set_hexpand (gui->menu, TRUE); gtk_widget_set_hexpand (gui->menu, TRUE);
gtk_widget_set_vexpand (gui->menu, FALSE); gtk_widget_set_vexpand (gui->menu, FALSE);
gtk_widget_set_halign (gui->menu, GTK_ALIGN_START); gtk_widget_set_halign (gui->menu, GTK_ALIGN_FILL);
gtk_widget_set_valign (gui->menu, GTK_ALIGN_FILL); gtk_widget_set_valign (gui->menu, GTK_ALIGN_FILL);
gtk_grid_attach (GTK_GRID (table), gui->menu, 0, 0, 3, 1); gtk_grid_attach (GTK_GRID (table), gui->menu, 0, 0, 3, 1);
} }
@@ -4375,10 +4375,37 @@ mg_win32_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
{ {
if (strcmp (command, "__WIN32_TASKBAR_TOGGLE__") == 0) if (strcmp (command, "__WIN32_TASKBAR_TOGGLE__") == 0)
{ {
if (gtk_widget_get_visible (current_sess->gui->window)) GtkWidget *widget = current_sess->gui->window;
fe_ctrl_gui (current_sess, FE_GUI_ICONIFY, 0); GdkWindow *gdk_window = NULL;
gboolean hidden = TRUE;
if (widget)
{
hidden = !gtk_widget_get_visible (widget);
gdk_window = gtk_widget_get_window (widget);
if (!hidden && gdk_window &&
(gdk_window_get_state (gdk_window) & GDK_WINDOW_STATE_ICONIFIED))
hidden = TRUE;
}
if (hidden)
{
if (widget)
{
gtk_widget_show (widget);
gtk_window_deiconify (GTK_WINDOW (widget));
gtk_window_present (GTK_WINDOW (widget));
}
else
fe_ctrl_gui (current_sess, FE_GUI_SHOW, 0);
}
else else
fe_ctrl_gui (current_sess, FE_GUI_SHOW, 0); {
if (widget)
gtk_window_iconify (GTK_WINDOW (widget));
else
fe_ctrl_gui (current_sess, FE_GUI_ICONIFY, 0);
}
} }
else else
{ {

View File

@@ -125,7 +125,6 @@ static void tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user
static void tray_update_toggle_item_label (void); static void tray_update_toggle_item_label (void);
static gboolean tray_window_state_cb (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata); static gboolean tray_window_state_cb (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata);
static void tray_window_visibility_cb (GtkWidget *widget, gpointer userdata); static void tray_window_visibility_cb (GtkWidget *widget, gpointer userdata);
static void tray_toggle_item_destroy_cb (GtkWidget *widget, gpointer userdata);
#if HAVE_APPINDICATOR_BACKEND #if HAVE_APPINDICATOR_BACKEND
static void tray_menu_show_cb (GtkWidget *menu, gpointer userdata) G_GNUC_UNUSED; static void tray_menu_show_cb (GtkWidget *menu, gpointer userdata) G_GNUC_UNUSED;
#endif #endif
@@ -409,8 +408,7 @@ tray_app_indicator_cleanup (void)
if (tray_menu) if (tray_menu)
{ {
if (GTK_IS_WIDGET (tray_menu)) gtk_widget_destroy (tray_menu);
gtk_widget_destroy (tray_menu);
tray_menu = NULL; tray_menu = NULL;
} }
} }
@@ -584,23 +582,33 @@ tray_backend_cleanup (void)
tray_backend_active = FALSE; tray_backend_active = FALSE;
} }
static gboolean
tray_window_is_hidden (GtkWidget *widget)
{
GdkWindow *gdk_win;
if (!widget || !gtk_widget_get_visible (widget))
return TRUE;
gdk_win = gtk_widget_get_window (widget);
if (gdk_win && (gdk_window_get_state (gdk_win) & GDK_WINDOW_STATE_ICONIFIED))
return TRUE;
return FALSE;
}
static WinStatus static WinStatus
tray_get_window_status (void) tray_get_window_status (void)
{ {
GtkWindow *win; GtkWindow *win;
GtkWidget *widget; GtkWidget *widget;
GdkWindow *gdk_win;
const char *st; const char *st;
win = GTK_WINDOW (zoitechat_get_info (ph, "gtkwin_ptr")); win = GTK_WINDOW (zoitechat_get_info (ph, "gtkwin_ptr"));
if (win) if (win)
{ {
widget = GTK_WIDGET (win); widget = GTK_WIDGET (win);
if (!gtk_widget_get_visible (widget)) if (tray_window_is_hidden (widget))
return WS_HIDDEN;
gdk_win = gtk_widget_get_window (widget);
if (gdk_win && (gdk_window_get_state (gdk_win) & GDK_WINDOW_STATE_ICONIFIED))
return WS_HIDDEN; return WS_HIDDEN;
} }
@@ -855,6 +863,8 @@ tray_toggle_visibility (gboolean force_hide)
static int maximized; static int maximized;
static int fullscreen; static int fullscreen;
GtkWindow *win; GtkWindow *win;
GtkWidget *widget;
gboolean hidden;
if (!tray_backend_active) if (!tray_backend_active)
return FALSE; return FALSE;
@@ -870,7 +880,10 @@ tray_toggle_visibility (gboolean force_hide)
if (!win) if (!win)
return FALSE; return FALSE;
if (force_hide || gtk_widget_get_visible (GTK_WIDGET (win))) widget = GTK_WIDGET (win);
hidden = tray_window_is_hidden (widget);
if (force_hide || !hidden)
{ {
if (prefs.hex_gui_tray_away) if (prefs.hex_gui_tray_away)
zoitechat_command (ph, "ALLSERV AWAY"); zoitechat_command (ph, "ALLSERV AWAY");
@@ -1028,15 +1041,10 @@ blink_item (unsigned int *setting, GtkWidget *menu, char *label)
static void static void
tray_menu_destroy (GtkWidget *menu, gpointer userdata) tray_menu_destroy (GtkWidget *menu, gpointer userdata)
{ {
GtkWidget **menu_ptr = userdata; (void)userdata;
if (menu_ptr && *menu_ptr == menu) gtk_widget_destroy (menu);
*menu_ptr = NULL; g_object_unref (menu);
if (GTK_IS_WIDGET (menu))
gtk_widget_destroy (menu);
if (G_IS_OBJECT (menu))
g_object_unref (menu);
#ifdef WIN32 #ifdef WIN32
g_source_remove (tray_menu_timer); g_source_remove (tray_menu_timer);
#endif #endif
@@ -1096,8 +1104,6 @@ tray_menu_populate (GtkWidget *menu)
zoitechat_set_context (ph, zoitechat_find_context (ph, NULL, NULL)); zoitechat_set_context (ph, zoitechat_find_context (ph, NULL, NULL));
tray_toggle_item = tray_make_item (menu, _("_Hide Window"), tray_menu_restore_cb, NULL); tray_toggle_item = tray_make_item (menu, _("_Hide Window"), tray_menu_restore_cb, NULL);
g_signal_connect (G_OBJECT (tray_toggle_item), "destroy",
G_CALLBACK (tray_toggle_item_destroy_cb), NULL);
tray_update_toggle_item_label (); tray_update_toggle_item_label ();
tray_make_item (menu, NULL, tray_menu_quit_cb, NULL); tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
@@ -1138,22 +1144,12 @@ tray_menu_clear (GtkWidget *menu)
children = gtk_container_get_children (GTK_CONTAINER (menu)); children = gtk_container_get_children (GTK_CONTAINER (menu));
for (iter = children; iter; iter = iter->next) for (iter = children; iter; iter = iter->next)
if (GTK_IS_WIDGET (iter->data)) gtk_widget_destroy (GTK_WIDGET (iter->data));
gtk_widget_destroy (GTK_WIDGET (iter->data));
g_list_free (children); g_list_free (children);
tray_toggle_item = NULL; tray_toggle_item = NULL;
} }
#endif #endif
static void
tray_toggle_item_destroy_cb (GtkWidget *widget, gpointer userdata)
{
(void)userdata;
if (tray_toggle_item == widget)
tray_toggle_item = NULL;
}
static void static void
tray_update_toggle_item_label (void) tray_update_toggle_item_label (void)
{ {
@@ -1161,11 +1157,6 @@ tray_update_toggle_item_label (void)
if (!tray_toggle_item) if (!tray_toggle_item)
return; return;
if (!GTK_IS_MENU_ITEM (tray_toggle_item))
{
tray_toggle_item = NULL;
return;
}
if (tray_get_window_status () == WS_HIDDEN) if (tray_get_window_status () == WS_HIDDEN)
label = _("_Restore Window"); label = _("_Restore Window");
@@ -1218,9 +1209,10 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
(void)time; (void)time;
(void)userdata; (void)userdata;
if (menu) /* close any old menu */
if (G_IS_OBJECT (menu))
{ {
tray_menu_destroy (menu, &menu); tray_menu_destroy (menu, NULL);
} }
menu = gtk_menu_new (); menu = gtk_menu_new ();
@@ -1230,9 +1222,8 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
g_object_ref (menu); g_object_ref (menu);
g_object_ref_sink (menu); g_object_ref_sink (menu);
g_object_unref (menu); g_object_unref (menu);
g_object_add_weak_pointer (G_OBJECT (menu), (gpointer *)&menu);
g_signal_connect (G_OBJECT (menu), "selection-done", g_signal_connect (G_OBJECT (menu), "selection-done",
G_CALLBACK (tray_menu_destroy), &menu); G_CALLBACK (tray_menu_destroy), NULL);
#ifdef WIN32 #ifdef WIN32
g_signal_connect (G_OBJECT (menu), "leave-notify-event", g_signal_connect (G_OBJECT (menu), "leave-notify-event",
G_CALLBACK (tray_menu_left_cb), NULL); G_CALLBACK (tray_menu_left_cb), NULL);

View File

@@ -2197,8 +2197,8 @@ setup_ok_cb (GtkWidget *but, GtkWidget *win)
char buffer[192]; char buffer[192];
memcpy (&old_prefs, &prefs, sizeof (prefs)); memcpy (&old_prefs, &prefs, sizeof (prefs));
setup_apply (&setup_prefs);
theme_preferences_stage_apply (); theme_preferences_stage_apply ();
setup_apply (&setup_prefs);
save_result = preferences_persistence_save_all (); save_result = preferences_persistence_save_all ();
if (save_result.success) if (save_result.success)
{ {

View File

@@ -68,16 +68,6 @@ theme_get_color (ThemeSemanticToken token, GdkRGBA *color)
return TRUE; return TRUE;
} }
void
theme_get_widget_style_values_for_widget (GtkWidget *widget, ThemeWidgetStyleValues *out_values)
{
(void)widget;
if (!out_values)
return;
gdk_rgba_parse (&out_values->foreground, "#111111");
gdk_rgba_parse (&out_values->background, "#f0f0f0");
}
void void
theme_manager_set_token_color (unsigned int dark_mode, ThemeSemanticToken token, const GdkRGBA *color, gboolean *changed) theme_manager_set_token_color (unsigned int dark_mode, ThemeSemanticToken token, const GdkRGBA *color, gboolean *changed)
{ {
@@ -102,12 +92,6 @@ theme_manager_save_preferences (void)
return TRUE; return TRUE;
} }
void
theme_manager_dispatch_changed (ThemeChangedReason reasons)
{
(void)reasons;
}
ThemePaletteBehavior ThemePaletteBehavior
theme_manager_get_userlist_palette_behavior (const PangoFontDescription *font_desc) theme_manager_get_userlist_palette_behavior (const PangoFontDescription *font_desc)
{ {

View File

@@ -26,29 +26,16 @@
#include "theme-runtime.h" #include "theme-runtime.h"
#include "theme-gtk3.h" #include "theme-gtk3.h"
#include "../maingui.h" #include "../maingui.h"
#ifdef G_OS_WIN32
#include <gtk/gtk.h> #include <gtk/gtk.h>
#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 static void
theme_application_apply_toplevel_theme (gboolean dark) theme_application_apply_windows_theme (gboolean dark)
{ {
GtkSettings *settings = gtk_settings_get_default (); GtkSettings *settings = gtk_settings_get_default ();
static GtkCssProvider *theme_provider = NULL; static GtkCssProvider *win_theme_provider = NULL;
static gboolean theme_provider_installed = FALSE; static gboolean win_theme_provider_installed = FALSE;
GdkScreen *screen; GdkScreen *screen;
gboolean prefer_dark = dark; gboolean prefer_dark = dark;
char *css; char *css;
@@ -69,21 +56,33 @@ theme_application_apply_toplevel_theme (gboolean dark)
if (!screen) if (!screen)
return; return;
if (!theme_provider) if (theme_gtk3_is_active ())
theme_provider = gtk_css_provider_new (); {
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;
}
css = theme_application_build_toplevel_css (); if (!win_theme_provider)
gtk_css_provider_load_from_data (theme_provider, css, -1, NULL); 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);
g_free (css); g_free (css);
if (!theme_provider_installed) if (!win_theme_provider_installed)
{ {
gtk_style_context_add_provider_for_screen (screen, gtk_style_context_add_provider_for_screen (screen,
GTK_STYLE_PROVIDER (theme_provider), GTK_STYLE_PROVIDER (win_theme_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1); GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
theme_provider_installed = TRUE; win_theme_provider_installed = TRUE;
} }
} }
#endif
gboolean gboolean
theme_application_apply_mode (unsigned int mode, gboolean *palette_changed) theme_application_apply_mode (unsigned int mode, gboolean *palette_changed)
@@ -92,7 +91,10 @@ theme_application_apply_mode (unsigned int mode, gboolean *palette_changed)
theme_runtime_load (); theme_runtime_load ();
dark = theme_runtime_apply_mode (mode, palette_changed); dark = theme_runtime_apply_mode (mode, palette_changed);
theme_application_apply_toplevel_theme (dark);
#ifdef G_OS_WIN32
theme_application_apply_windows_theme (dark);
#endif
theme_application_reload_input_style (); theme_application_reload_input_style ();

View File

@@ -361,22 +361,20 @@ theme_css_build_toplevel_classes (void)
"color: #f0f0f0;" "color: #f0f0f0;"
"border-color: #202020;" "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 {" "window.%s menubar, window.%s menubar:backdrop, window.%s menuitem, window.%s menuitem:backdrop {"
"background-color: @theme_bg_color;" "background-color: #202020;"
"background-image: none;" "color: #f0f0f0;"
"color: @theme_fg_color;" "border-color: #202020;"
"border-color: @theme_bg_color;"
"}" "}"
"window.%s, window.%s:backdrop, .%s {" "window.%s, window.%s:backdrop, .%s {"
"background-color: #f6f6f6;" "background-color: #f6f6f6;"
"color: #101010;" "color: #101010;"
"border-color: #f6f6f6;" "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 {" "window.%s menubar, window.%s menubar:backdrop, window.%s menuitem, window.%s menuitem:backdrop {"
"background-color: @theme_bg_color;" "background-color: #f6f6f6;"
"background-image: none;" "color: #101010;"
"color: @theme_fg_color;" "border-color: #f6f6f6;"
"border-color: @theme_bg_color;"
"}", "}",
theme_css_selector_dark_class, theme_css_selector_dark_class,
theme_css_selector_dark_class, theme_css_selector_dark_class,
@@ -385,10 +383,6 @@ 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_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, theme_css_selector_light_class,
theme_css_selector_light_class, theme_css_selector_light_class,

View File

@@ -216,6 +216,8 @@ theme_manager_queue_auto_refresh (GtkSettings *settings, GParamSpec *pspec, gpoi
void void
theme_manager_init (void) theme_manager_init (void)
{ {
GtkSettings *settings;
if (!theme_manager_listeners) if (!theme_manager_listeners)
theme_manager_listeners = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, theme_manager_listeners = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
theme_listener_free); theme_listener_free);
@@ -223,10 +225,21 @@ theme_manager_init (void)
if (!theme_manager_setup_listener_id) if (!theme_manager_setup_listener_id)
theme_manager_setup_listener_id = theme_listener_register ("setup.apply", theme_manager_setup_apply_listener, NULL); theme_manager_setup_listener_id = theme_listener_register ("setup.apply", theme_manager_setup_apply_listener, NULL);
fe_set_auto_dark_mode_state (FALSE); settings = gtk_settings_get_default ();
if (settings)
fe_set_auto_dark_mode_state (theme_policy_system_prefers_dark ());
theme_application_apply_mode (prefs.hex_gui_dark_mode, NULL); theme_application_apply_mode (prefs.hex_gui_dark_mode, NULL);
theme_gtk3_init (); theme_gtk3_init ();
zoitechat_set_theme_post_apply_callback (theme_manager_handle_theme_applied); 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 gboolean
@@ -481,6 +494,7 @@ theme_manager_apply_wayland_kde_csd (GtkWidget *window)
static void static void
theme_manager_apply_platform_window_theme (GtkWidget *window) theme_manager_apply_platform_window_theme (GtkWidget *window)
{ {
#ifdef G_OS_WIN32
GtkStyleContext *context; GtkStyleContext *context;
gboolean dark; gboolean dark;
@@ -502,7 +516,6 @@ theme_manager_apply_platform_window_theme (GtkWidget *window)
gtk_style_context_remove_class (context, "zoitechat-light"); gtk_style_context_remove_class (context, "zoitechat-light");
gtk_style_context_add_class (context, dark ? "zoitechat-dark" : "zoitechat-light"); gtk_style_context_add_class (context, dark ? "zoitechat-dark" : "zoitechat-light");
} }
#ifdef G_OS_WIN32
fe_win32_apply_native_titlebar (window, dark); fe_win32_apply_native_titlebar (window, dark);
#else #else
theme_manager_apply_wayland_kde_csd (window); theme_manager_apply_wayland_kde_csd (window);

View File

@@ -27,7 +27,38 @@
gboolean gboolean
theme_policy_system_prefers_dark (void) theme_policy_system_prefers_dark (void)
{ {
return FALSE; 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;
} }
gboolean gboolean

View File

@@ -723,7 +723,6 @@ theme_preferences_manager_dialog_response_cb (GtkDialog *dialog, gint response_i
if (theme_preferences_stage.active) if (theme_preferences_stage.active)
{ {
ThemeSemanticToken token; ThemeSemanticToken token;
ThemeWidgetStyleValues style_values;
for (token = THEME_TOKEN_MIRC_0; token < THEME_TOKEN_COUNT; token++) for (token = THEME_TOKEN_MIRC_0; token < THEME_TOKEN_COUNT; token++)
{ {
@@ -734,12 +733,6 @@ theme_preferences_manager_dialog_response_cb (GtkDialog *dialog, gint response_i
theme_preferences_stage.staged[token] = rgba; theme_preferences_stage.staged[token] = rgba;
theme_preferences_stage.staged_valid[token] = TRUE; theme_preferences_stage.staged_valid[token] = TRUE;
} }
theme_get_widget_style_values_for_widget (GTK_WIDGET (dialog), &style_values);
theme_preferences_stage.staged[THEME_TOKEN_TEXT_FOREGROUND] = style_values.foreground;
theme_preferences_stage.staged_valid[THEME_TOKEN_TEXT_FOREGROUND] = TRUE;
theme_preferences_stage.staged[THEME_TOKEN_TEXT_BACKGROUND] = style_values.background;
theme_preferences_stage.staged_valid[THEME_TOKEN_TEXT_BACKGROUND] = TRUE;
theme_preferences_stage_sync_runtime_to_staged ();
theme_preferences_stage_recompute_changed (); theme_preferences_stage_recompute_changed ();
if (ui->color_change_flag) if (ui->color_change_flag)
*ui->color_change_flag = theme_preferences_stage.changed; *ui->color_change_flag = theme_preferences_stage.changed;
@@ -1350,19 +1343,6 @@ theme_preferences_gtk3_sync_remove_state (theme_preferences_ui *ui)
gtk_widget_set_sensitive (ui->gtk3_remove, source == ZOITECHAT_GTK3_THEME_SOURCE_USER); 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 static void
theme_preferences_gtk3_changed_cb (GtkComboBox *combo, gpointer user_data) theme_preferences_gtk3_changed_cb (GtkComboBox *combo, gpointer user_data)
{ {
@@ -1393,7 +1373,7 @@ theme_preferences_gtk3_changed_cb (GtkComboBox *combo, gpointer user_data)
ui->setup_prefs->hex_gui_gtk3_variant = prefs.hex_gui_gtk3_variant; ui->setup_prefs->hex_gui_gtk3_variant = prefs.hex_gui_gtk3_variant;
} }
if (selection_changed && !theme_preferences_gtk3_apply_and_refresh (&error)) if (selection_changed && !theme_gtk3_apply_current (&error))
{ {
theme_preferences_show_message (ui, GTK_MESSAGE_ERROR, theme_preferences_show_message (ui, GTK_MESSAGE_ERROR,
error ? error->message : _("Failed to apply GTK3 theme.")); error ? error->message : _("Failed to apply GTK3 theme."));
@@ -1570,7 +1550,7 @@ theme_preferences_populate_gtk3 (theme_preferences_ui *ui)
g_free (final_id); g_free (final_id);
} }
if (should_apply && !theme_preferences_gtk3_apply_and_refresh (&error)) if (should_apply && !theme_gtk3_apply_current (&error))
{ {
theme_preferences_show_message (ui, GTK_MESSAGE_ERROR, theme_preferences_show_message (ui, GTK_MESSAGE_ERROR,
error ? error->message : _("Failed to apply GTK3 theme.")); error ? error->message : _("Failed to apply GTK3 theme."));

View File

@@ -1 +1 @@
2.18.0~pre5 2.18.0~pre4