Fixed GTK3 theme activation on Win32 so fallback window CSS is disabled immediately after loading an imported GTK3 theme, preventing mixed styling (like unthemed buttons/chat areas) during runtime theme changes
Added cleanup for previously-added fallback CSS providers (with widget style reset) when a GTK3 theme is active, so the imported theme can fully control styling consistently.
Kept the original Windows fallback CSS behavior for cases where no imported GTK3 theme is set, so non-GTK3-theme behavior remains unchanged.
Updated theme application to load CSS/resources from the resolved gtk-3.x folder and updated the error path/message when a valid gtk-3.x/gtk.css layout is missing.
Exposed the resolver in the GTK frontend header so other GTK UI code can validate theme layouts consistently.
Updated the Preferences GTK3 theme picker to validate themes via the resolver (so themes with e.g. gtk-3.24/gtk.css now appear as valid).
Updated archive import validation to recognize gtk-3.x directories (not just gtk-3.0) and adjusted user-facing validation messages accordingly.
Extended fe_apply_gtk3_theme_with_reload to:
detect gtk.gresource,
register it before applying CSS,
unregister resources when no resource file is present or when switching back to system theme,
and clean up allocated paths consistently on error paths
Updated the same-theme early return so it is bypassed when reload is requested, while preserving the existing provider reset/replacement flow, gtk_style_context_reset_widgets, and top-level reapply behavior.
Wired setup import/apply flow to force a reload on the next apply after successful archive import, ensuring same-name imported themes are reloaded from disk; the flag is cleared after apply and when switching back to system theme.
Added the same short explanatory comment style already used in setup_theme_show_message (“Window classes are required for GTK CSS selectors like .zoitechat-dark / .zoitechat-light.”), keeping behavior/style aligned with existing code conventions.
Verified the open/cancel/import flow is unchanged: the same GTK_RESPONSE_ACCEPT gate, early return on cancel, file extraction path retrieval, and import success/error handling remain intact.
Fixed the same persistence path for “Use System GTK Theme” by clearing both prefs and setup_prefs, preventing the theme from reverting after the dialog closes.
Reverted GTK3 provider priority back to GTK_STYLE_PROVIDER_PRIORITY_THEME (from application priority), which addresses the dropdown/menu rendering regression introduced by the previous commit.
Changed imported GTK3 theme provider registration from GTK_STYLE_PROVIDER_PRIORITY_APPLICATION to GTK_STYLE_PROVIDER_PRIORITY_THEME, so GTK3 theme rules apply correctly across themed controls (including menu/dropdown-related GTK theme elements) instead of being overly overridden by app-priority styling.
Deleted the old ZoiteChat palette/event theme import/apply implementation and kept GTK3 archive import as the sole theme import backend; the GTK3 import API now optionally returns the imported theme name for better caller messaging.
Updated startup and /URL handling so theme archives are imported into gtk3-themes and users are prompted to apply them via Theme settings, instead of auto-applying old ZoiteChat themes.
Simplified the Theme Manager UI/data model to GTK3-only by removing the old “ZoiteChat Theme” controls and keeping the GTK3 import/apply/use-system workflow.
Kept GTK3 discovery restricted to the app-local install directory (get_xdir()/gtk3-themes) and only included directories containing gtk-3.0/gtk.css.
Ensured theme selection is restored/saved correctly by matching saved pref name against discovered entries and applying via the selected internal path, then persisting prefs.hex_gui_gtk3_theme_name with save_config().
Preserved/updated empty-invalid status behavior to show “No valid GTK3 themes found.” when no usable themes exist (or saved selection is invalid).
Added proper cleanup for the new internal mapping via setup_theme_ui_free and wired it into g_object_set_data_full.
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.
Updated the GTK3 import callback in setup.c to:
open a file chooser titled Import GTK3 Theme ZIP,
enforce a ZIP-focused chooser filter (*.zip, *.ZIP),
call the new backend function,
show success/failure dialogs through setup_theme_show_message,
refresh the GTK3 theme list immediately after successful import.
Updated the GTK3 section button label to Import GTK3 Theme ZIP and added/used new translatable strings for the new button text and import messages.
Expanded setup_theme_ui to track separate widget state for ZoiteChat controls and GTK3 controls (zoitechat_* and gtk3_* fields), so the two flows are no longer sharing ambiguous UI pointers.
Kept the existing ZoiteChat apply path using zoitechat_apply_theme, but updated selection/status/apply messaging so it clearly indicates palette/event updates rather than GTK theme activation.
Added GTK3 theme management behavior:
discovery/population from standard theme directories,
import from archive via file chooser into ~/.themes/<basename>,
apply via GtkSettings (gtk-theme-name),
status/info messages that explicitly say GTK3 activation does not change ZoiteChat palette settings.
Kept native titlebar dark-mode behavior intact by leaving the existing Win32 titlebar flow untouched and continuing to call theme preference updates in fe_apply_windows_theme.
Ensured theme/palette apply paths refresh CSS by routing both FE_GUI_APPLY and setup theme apply through fe_apply_theme_for_mode(...), which re-runs Win32 CSS application and re-applies classes to toplevel windows.
Added gtkutil_menu_icon_exists to gtkutil.c and declared it in gtkutil.h. The implementation uses a shared helper that resolves menu icon resources with theme-variant-aware lookup (variant first, then light fallback) for both png and svg, so probing behavior now lives in the same subsystem as gtkutil_image_new_from_stock.
Kept gtkutil_menu_icon_image_new as the single menu-icon loading path, which already contains the requested theme variant selection and light-variant fallback behavior for both PNG and SVG assets.
Added theming to setup_browsefont_cb() immediately after gtk_font_chooser_dialog_new(...) by calling fe_apply_theme_to_toplevel (dialog);, plus the same short comment for consistency/discoverability.
Added theming to setup_color_cb() immediately after gtk_color_chooser_dialog_new(...) by calling fe_apply_theme_to_toplevel (dialog);, again with the matching comment.
Added an inline regression-prevention comment noting this path should stay in parity with setup_theme_apply_cb.
Verified palette.h is already included in src/fe-gtk/fe-gtk.c (no include changes required).
Standard GTK file chooser fallback dialog in src/fe-gtk/gtkutil.c
Font chooser dialog in src/fe-gtk/setup.c
Color chooser dialog in src/fe-gtk/setup.c
About dialog in src/fe-gtk/menu.c
Updated edit-target and dark-mode combo callbacks on the color page to stop applying global palette mode directly; they now only switch/refresh the Preferences page source palette.
Changed color-chooser behavior so setup_color_response_cb() writes edits to the selected target snapshot via palette_user_set_color / palette_dark_set_color, then refreshes only page widgets (no runtime palette apply). Also updated dialog initialization to read from the current edit-source snapshot.
Added palette snapshot accessors (palette_user_colors, palette_dark_colors) in the palette API and implementation so Preferences can render from light/dark snapshots safely without mutating runtime palette state.
Runtime palette changes remain on the real apply paths (theme/dark-mode application), not edit-target toggles.
Added deterministic dark-mode precedence by combining explicit signals (theme_name_prefers_dark || property_prefers_dark), while preserving Windows system preference as another dark-enabling signal when available. This ensures “dark if any explicit dark signal is true.”
Re-checked the relevant callers (fe_auto_dark_mode_changed() and fe_apply_theme_for_mode()): they consume fe_system_prefers_dark() output and do not depend on the removed !has_theme_name conditional behavior.
Added a new frontend helper declaration fe_dark_mode_state_is_initialized() in the GTK frontend header so callers can check whether dark-mode state is ready.
Implemented dark-mode initialization tracking in fe-gtk.c via a new static flag, set when auto mode state is externally set and during fe_init(), and exposed it through fe_dark_mode_state_is_initialized().
Added a guarded fallback path that only uses theme lookup/string conversion when palette selection components are invalid (isfinite checks fail), with palette values as secondary fallback there too. This keeps theme colors out of the primary path while preserving robustness for malformed data.
Kept needs_reload dependent on last_sel_* tracking, so changing selection colors in Preferences still triggers immediate CSS regeneration (including across light/dark mode).
Added a new Editing: combo control near the dark-mode selector in setup_create_color_page, with a callback that switches between Light/Dark palette targets and refreshes swatches immediately using the same refresh path as dark-mode UI updates.
Updated the dark-mode combo callback to refresh color swatches based on the explicit editing target (not runtime dark-mode detection), preserving existing runtime theme behavior while editing persisted overrides.
Updated setup_color_response_cb to write color changes to palette_dark_set_color vs palette_user_set_color based on the new edit-target state.
Initialized the editing target in setup_create_color_page from explicit Dark mode selection only (hex_gui_dark_mode == ZOITECHAT_DARK_MODE_DARK), avoiding AUTO runtime detection for editing context.
Added setup_refresh_color_selector_widgets() to iterate color_selector_widgets, resolve each button’s stored color index, and re-run setup_color_button_apply against colors[] so all selectors repaint to the active palette.
Updated setup_create_color_button to register each widget’s palette index (zoitechat-color-index), enabling correct per-button repaint during mode switches.
Preserved existing persistence behavior in setup_color_response_cb (palette_dark_set_color vs palette_user_set_color) so changes remain non-destructive until existing OK/Save flow persists them.
Added a fallback path that derives selection colors from palette values (COL_MARK_FG/COL_MARK_BG) and then samples selected-state colors from a GTK style context when possible, emitting explicit color strings for CSS.
Ensured fallback regeneration is tied to the same reload flow by extending needs_reload tracking with selection palette channels and persisting those last-seen values.
Kept Preferences > Colors foreground/background behavior intact for normal input rendering; only selection-specific CSS is conditionally overridden. Base text/background/caret rules remain unchanged while only text selection uses the new selection logic.
Added/kept lifecycle call sites for main and detached/channel windows, with comments explaining that .zoitechat-dark / .zoitechat-light classes are required for GTK CSS selectors. This includes top/tab windows and server list/edit windows.
Wired dialog/toplevel creation paths in src/fe-gtk/ to call fe_apply_theme_to_toplevel() (without duplicating platform logic), including common prompt/message dialogs and feature-specific dialogs (join, notify, setup, ignore/ban, etc.), each with the requested brief comment near the new call site.
Added a short in-code comment explaining why app-written GTK property state must not permanently block future reads in AUTO mode.
Removed the now-unneeded app_set_prefer_dark tracking behavior from fe_set_gtk_prefer_dark_theme(), so writes no longer disable later fallback reads.
Confirmed fe_auto_dark_mode_changed() still prevents reapply loops by early-returning when enabled == auto_dark_mode_enabled before calling theme/apply logic.
Updated Preferences window creation to explicitly apply the toplevel theme after gtk_widget_show_all() in setup_window_open(), matching your requested timing there.
Added explicit theme application for non-session windows that bypass gtkutil_window_new() and use direct gtk_window_new() in server list UI (editserv and servlist).
Extended mg_apply_setup() to iterate all current GTK toplevels (gtk_window_list_toplevels()) and reapply fe_apply_theme_to_toplevel() during setup/theme reapply flows, ensuring existing windows stay consistent after theme changes. Palette override widgets were not touched.
Preserved font handling exactly as before (input_style->font_desc when available).
Added inline rationale comment clarifying that AUTO/light should continue using palette-managed colors and should not revert to GTK theme defaults in a way that clears custom colors.
Reworked fe_system_prefers_dark() to prioritize non-app-written sources in AUTO flow:
first: gtk-theme-name dark-variant heuristic,
then (Windows): native platform detection via fe_win32_try_get_system_dark,
only then fallback to gtk-application-prefer-dark-theme when no theme-name signal was available and the app has not written that property.
Kept manual LIGHT/DARK behavior unchanged by preserving the existing mode application path (fe_apply_theme_for_mode() still drives fe_set_gtk_prefer_dark_theme() directly).
Verified fe_auto_dark_mode_changed() and fe_init() signal wiring still trigger AUTO palette/theme refreshes on system theme changes (notify::gtk-theme-name and existing notify callback flow remain in place).
Kept user override support for baseline text color and caret color on the input’s text node (#zoitechat-inputbox text).
Added targeted state-aware text rules for :focus and :backdrop (to preserve readability when theme state styling changes), plus a softened :disabled text rule instead of broad global color forcing.
Added explicit selection-node handling (#zoitechat-inputbox text selection) using theme selection tokens so selected text remains readable and aligned with Adwaita/Yaru-style theme behavior.
Preserved the existing Adwaita/Yaru background-image workaround logic, so fallback behavior remains compatible with those themes.
Removed a redundant inline comment in the Windows sysinfo volume-name guard path, with no functional impact.
Removed a redundant inline comment in WinRT toast setup while keeping the same notification/audio attribute behavior.
Added monitor-aware work-area adjustment when maximized (MonitorFromWindow + GetMonitorInfo) and shrink by 1px on the detected taskbar edge (including bottom edge), then apply that rectangle with SetWindowPos. This addresses the “mouse at bottom edge should unhide taskbar” behavior.
Kept the existing HWND_NOTOPMOST safeguard in place after the adjustment, preserving prior not-topmost behavior.
Hooked that helper into mg_windowstate_cb so it runs whenever the main window state changes (while preserving existing maximize/fullscreen preference handling).