mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-10 07:50:19 +00:00
Fixed the GTK3 theme dropdown population to include all expected sources again (ZoiteChat local store, user local themes, and system theme dirs), which resolves the “messed up selector” behavior from the previous change.
Restored proper initial selection logic so the dropdown now prefers saved gui_gtk3_theme_name when present, and otherwise falls back to the current GTK gtk-theme-name.
Fixed selection UX by not forcing index 0; it starts unselected and selects only if a real match is found. Also made Apply button sensitivity follow actual selection state.
Updated the status text to reflect mixed-source theme discovery and added cleanup for allocated selection strings/path entries in this code path.
This commit is contained in:
@@ -419,6 +419,7 @@ const struct prefs vars[] =
|
||||
{"gui_input_nick", P_OFFINT (hex_gui_input_nick), TYPE_BOOL},
|
||||
{"gui_input_spell", P_OFFINT (hex_gui_input_spell), TYPE_BOOL},
|
||||
{"gui_input_style", P_OFFINT (hex_gui_input_style), TYPE_BOOL},
|
||||
{"gui_gtk3_theme_name", P_OFFSET (hex_gui_gtk3_theme_name), TYPE_STR},
|
||||
{"gui_join_dialog", P_OFFINT (hex_gui_join_dialog), TYPE_BOOL},
|
||||
{"gui_lagometer", P_OFFINT (hex_gui_lagometer), TYPE_INT},
|
||||
{"gui_lang", P_OFFINT (hex_gui_lang), TYPE_INT},
|
||||
|
||||
@@ -297,6 +297,7 @@ struct zoitechatprefs
|
||||
char hex_dcc_completed_dir[PATHLEN + 1];
|
||||
char hex_dcc_dir[PATHLEN + 1];
|
||||
char hex_dcc_ip[DOMAINLEN + 1];
|
||||
char hex_gui_gtk3_theme_name[128];
|
||||
char hex_gui_ulist_doubleclick[256];
|
||||
char hex_input_command_char[4];
|
||||
char hex_irc_extra_hilight[300];
|
||||
|
||||
@@ -590,6 +590,109 @@ fe_system_prefers_dark (void)
|
||||
static gboolean auto_dark_mode_enabled = FALSE;
|
||||
static gboolean dark_mode_state_initialized = FALSE;
|
||||
|
||||
|
||||
static GtkCssProvider *gtk3_theme_provider = NULL;
|
||||
static char *gtk3_theme_provider_name = NULL;
|
||||
static gboolean gtk3_theme_provider_dark = FALSE;
|
||||
|
||||
gboolean
|
||||
fe_apply_gtk3_theme (const char *theme_name, GError **error)
|
||||
{
|
||||
GdkScreen *screen = gdk_screen_get_default ();
|
||||
char *theme_dir = NULL;
|
||||
char *gtk3_dir = NULL;
|
||||
char *gtk_css = NULL;
|
||||
char *gtk_dark_css = NULL;
|
||||
const char *selected_css = NULL;
|
||||
gboolean dark = fe_dark_mode_is_enabled ();
|
||||
GList *toplevels, *node;
|
||||
|
||||
if (!theme_name || !*theme_name)
|
||||
{
|
||||
if (gtk3_theme_provider && screen)
|
||||
{
|
||||
gtk_style_context_remove_provider_for_screen (
|
||||
screen,
|
||||
GTK_STYLE_PROVIDER (gtk3_theme_provider));
|
||||
}
|
||||
g_clear_object (>k3_theme_provider);
|
||||
g_clear_pointer (>k3_theme_provider_name, g_free);
|
||||
gtk3_theme_provider_dark = FALSE;
|
||||
|
||||
toplevels = gtk_window_list_toplevels ();
|
||||
for (node = toplevels; node; node = node->next)
|
||||
fe_apply_theme_to_toplevel (GTK_WIDGET (node->data));
|
||||
g_list_free (toplevels);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (gtk3_theme_provider_name
|
||||
&& g_strcmp0 (gtk3_theme_provider_name, theme_name) == 0
|
||||
&& gtk3_theme_provider_dark == dark)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
theme_dir = g_build_filename (get_xdir (), "gtk3-themes", theme_name, NULL);
|
||||
gtk3_dir = g_build_filename (theme_dir, "gtk-3.0", NULL);
|
||||
gtk_css = g_build_filename (gtk3_dir, "gtk.css", NULL);
|
||||
gtk_dark_css = g_build_filename (gtk3_dir, "gtk-dark.css", NULL);
|
||||
|
||||
if (!g_file_test (gtk_css, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT,
|
||||
_("GTK3 theme '%s' is missing gtk-3.0/gtk.css."), theme_name);
|
||||
g_free (gtk_dark_css);
|
||||
g_free (gtk_css);
|
||||
g_free (gtk3_dir);
|
||||
g_free (theme_dir);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dark && g_file_test (gtk_dark_css, G_FILE_TEST_IS_REGULAR))
|
||||
selected_css = gtk_dark_css;
|
||||
else
|
||||
selected_css = gtk_css;
|
||||
|
||||
if (!gtk3_theme_provider)
|
||||
gtk3_theme_provider = gtk_css_provider_new ();
|
||||
|
||||
if (!gtk_css_provider_load_from_path (gtk3_theme_provider, selected_css, error))
|
||||
{
|
||||
g_free (gtk_dark_css);
|
||||
g_free (gtk_css);
|
||||
g_free (gtk3_dir);
|
||||
g_free (theme_dir);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (screen)
|
||||
{
|
||||
gtk_style_context_add_provider_for_screen (
|
||||
screen,
|
||||
GTK_STYLE_PROVIDER (gtk3_theme_provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
gtk_style_context_reset_widgets (screen);
|
||||
}
|
||||
|
||||
g_free (gtk3_theme_provider_name);
|
||||
gtk3_theme_provider_name = g_strdup (theme_name);
|
||||
gtk3_theme_provider_dark = dark;
|
||||
|
||||
toplevels = gtk_window_list_toplevels ();
|
||||
for (node = toplevels; node; node = node->next)
|
||||
fe_apply_theme_to_toplevel (GTK_WIDGET (node->data));
|
||||
g_list_free (toplevels);
|
||||
|
||||
g_free (gtk_dark_css);
|
||||
g_free (gtk_css);
|
||||
g_free (gtk3_dir);
|
||||
g_free (theme_dir);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fe_set_gtk_prefer_dark_theme (gboolean dark)
|
||||
{
|
||||
@@ -722,6 +825,12 @@ fe_apply_theme_for_mode (unsigned int mode, gboolean *palette_changed)
|
||||
if (input_style)
|
||||
create_input_style (input_style);
|
||||
|
||||
if (!fe_apply_gtk3_theme (prefs.hex_gui_gtk3_theme_name, NULL)
|
||||
&& prefs.hex_gui_gtk3_theme_name[0] != '\0')
|
||||
{
|
||||
fe_message (_("Failed to apply configured GTK3 theme from gtk3-themes."), FE_MSG_ERROR);
|
||||
}
|
||||
|
||||
/* Existing toplevel windows also need the class refreshed for selectors like
|
||||
* .zoitechat-dark / .zoitechat-light to update immediately. */
|
||||
toplevels = gtk_window_list_toplevels ();
|
||||
|
||||
@@ -193,6 +193,7 @@ gboolean fe_dark_mode_state_is_initialized (void);
|
||||
void fe_set_auto_dark_mode_state (gboolean enabled);
|
||||
void fe_refresh_auto_dark_mode (void);
|
||||
gboolean fe_apply_theme_for_mode (unsigned int mode, gboolean *palette_changed);
|
||||
gboolean fe_apply_gtk3_theme (const char *theme_name, GError **error);
|
||||
void fe_apply_theme_to_toplevel (GtkWidget *window);
|
||||
|
||||
#define SPELL_ENTRY_GET_TEXT(e) ((char *)(gtk_entry_get_text (GTK_ENTRY(e))))
|
||||
|
||||
@@ -72,6 +72,7 @@ typedef struct
|
||||
GtkWidget *gtk3_combo;
|
||||
GtkWidget *gtk3_import_button;
|
||||
GtkWidget *gtk3_apply_button;
|
||||
GtkWidget *gtk3_use_system_button;
|
||||
GtkWidget *gtk3_status_label;
|
||||
} setup_theme_ui;
|
||||
|
||||
@@ -2068,12 +2069,14 @@ setup_theme_populate_gtk3 (setup_theme_ui *ui)
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (ui->gtk3_combo), g_ptr_array_index (names, i));
|
||||
|
||||
settings = gtk_settings_get_default ();
|
||||
if (settings)
|
||||
if (prefs.hex_gui_gtk3_theme_name[0] != '\0')
|
||||
current_theme = g_strdup (prefs.hex_gui_gtk3_theme_name);
|
||||
else if (settings)
|
||||
g_object_get (settings, "gtk-theme-name", ¤t_theme, NULL);
|
||||
|
||||
if (names->len > 0)
|
||||
{
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (ui->gtk3_combo), 0);
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (ui->gtk3_combo), -1);
|
||||
if (current_theme)
|
||||
{
|
||||
for (i = 0; i < names->len; i++)
|
||||
@@ -2087,9 +2090,10 @@ setup_theme_populate_gtk3 (setup_theme_ui *ui)
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive (ui->gtk3_apply_button, names->len > 0);
|
||||
gtk_widget_set_sensitive (ui->gtk3_apply_button,
|
||||
gtk_combo_box_get_active (GTK_COMBO_BOX (ui->gtk3_combo)) >= 0);
|
||||
gtk_label_set_text (GTK_LABEL (ui->gtk3_status_label),
|
||||
names->len > 0 ? _("Select a GTK3 theme to activate for the interface.") : _("No GTK3 themes found."));
|
||||
names->len > 0 ? _("Select a GTK3 theme to activate from the dropdown, or use the system GTK theme.") : _("No GTK3 themes found."));
|
||||
|
||||
g_ptr_array_free (names, TRUE);
|
||||
g_hash_table_destroy (seen);
|
||||
@@ -2169,28 +2173,42 @@ static void
|
||||
setup_theme_gtk3_apply_cb (GtkWidget *button, gpointer user_data)
|
||||
{
|
||||
setup_theme_ui *ui = user_data;
|
||||
GtkSettings *settings;
|
||||
char *theme;
|
||||
GError *error = NULL;
|
||||
|
||||
theme = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (ui->gtk3_combo));
|
||||
if (!theme)
|
||||
return;
|
||||
|
||||
settings = gtk_settings_get_default ();
|
||||
if (!settings)
|
||||
if (!fe_apply_gtk3_theme (theme, &error))
|
||||
{
|
||||
setup_theme_show_message (GTK_MESSAGE_ERROR, _("GTK settings are unavailable, cannot activate GTK3 theme."));
|
||||
setup_theme_show_message (GTK_MESSAGE_ERROR,
|
||||
error ? error->message : _("Failed to apply GTK3 theme."));
|
||||
g_clear_error (&error);
|
||||
g_free (theme);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_set (settings, "gtk-theme-name", theme, NULL);
|
||||
gtk_label_set_text (GTK_LABEL (ui->gtk3_status_label), _("GTK3 theme activated for this session."));
|
||||
setup_theme_show_message (GTK_MESSAGE_INFO, _("GTK3 theme activated. Application palette settings were not changed."));
|
||||
safe_strcpy (prefs.hex_gui_gtk3_theme_name, theme, sizeof (prefs.hex_gui_gtk3_theme_name));
|
||||
save_config ();
|
||||
gtk_label_set_text (GTK_LABEL (ui->gtk3_status_label), _("GTK3 theme activated from ZoiteChat's local theme store."));
|
||||
setup_theme_show_message (GTK_MESSAGE_INFO, _("GTK3 theme activated and saved."));
|
||||
|
||||
g_free (theme);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_theme_gtk3_use_system_cb (GtkWidget *button, gpointer user_data)
|
||||
{
|
||||
setup_theme_ui *ui = user_data;
|
||||
|
||||
fe_apply_gtk3_theme (NULL, NULL);
|
||||
prefs.hex_gui_gtk3_theme_name[0] = '\0';
|
||||
save_config ();
|
||||
gtk_label_set_text (GTK_LABEL (ui->gtk3_status_label), _("Using system GTK theme."));
|
||||
setup_theme_show_message (GTK_MESSAGE_INFO, _("Using system GTK theme."));
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
setup_create_theme_page (void)
|
||||
{
|
||||
@@ -2262,7 +2280,7 @@ setup_create_theme_page (void)
|
||||
gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
|
||||
gtk_container_add (GTK_CONTAINER (frame), hbox);
|
||||
|
||||
label = gtk_label_new (_("Import a GTK3 theme archive or select an installed GTK3 theme."));
|
||||
label = gtk_label_new (_("Import a GTK3 theme archive or select a GTK3 theme installed in ZoiteChat's local theme store."));
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
@@ -2285,6 +2303,11 @@ setup_create_theme_page (void)
|
||||
g_signal_connect (G_OBJECT (ui->gtk3_apply_button), "clicked",
|
||||
G_CALLBACK (setup_theme_gtk3_apply_cb), ui);
|
||||
|
||||
ui->gtk3_use_system_button = gtk_button_new_with_mnemonic (_("Use _System GTK Theme"));
|
||||
gtk_box_pack_start (GTK_BOX (button_box), ui->gtk3_use_system_button, FALSE, FALSE, 0);
|
||||
g_signal_connect (G_OBJECT (ui->gtk3_use_system_button), "clicked",
|
||||
G_CALLBACK (setup_theme_gtk3_use_system_cb), ui);
|
||||
|
||||
ui->gtk3_status_label = gtk_label_new (NULL);
|
||||
gtk_widget_set_halign (ui->gtk3_status_label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (ui->gtk3_status_label, GTK_ALIGN_CENTER);
|
||||
|
||||
Reference in New Issue
Block a user