Added gtkutil_native_file_req_response() to keep completion semantics consistent: process selected files on accept, send the trailing callback(..., NULL) completion notification, free request state, and defer dialog unref to idle.
Updated the native chooser code path to replace immediate unref with deferred unref via g_idle_add(...) after gtk_native_dialog_run, while preserving the existing accept-only file handling behavior.
Updated gtkutil_file_req() to resolve an effective_parent (fallback to global parent_window when no parent is passed), which ensures consistent transient parenting and modal assertions in this code path.
Added a Windows GTK3-specific path that uses GtkFileChooserNative (instead of the GTK file chooser dialog widget path implicated by your stack trace), while preserving existing behavior for initial folder/name, filters, multi-select, and overwrite confirmation before invoking the same file-check callback flow.
Left the existing non-Windows / non-GTK3 dialog flow in place unchanged in behavior, so platforms outside the crash scenario continue using the prior implementation.
zoitechat-common (desktop integration, dbus service, icons, locales, appdata, mime).
zoitechat-dev (plugin development header + pkg-config file).
zoitechat-lua, zoitechat-perl, zoitechat-plugins, and zoitechat-python3 (plugin/shared module payloads).
Simplified zoitechat.install to only the core executable + man page, with shared data moved to zoitechat-common to match package split intent.
Updated user list creation to apply the current input font in GTK3 when palette styling is applied, so the user list reflects font changes consistently.
Updated channel view creation in GTK3 to always pass the current input font to chanview_new, ensuring channel list typography starts with the configured font.
Updated settings re-apply logic to always include the current input font for the user list in GTK3, so runtime font updates take effect there as well.
Added a Windows-specific guard in waitline() that checks _get_osfhandle(sok) before calling read() in non-socket mode; if the CRT file descriptor is invalid, it now fails gracefully with -1 instead of hitting the debug CRT assertion you reported.
Wrapped shortcut-folder setup with existence checks and explicit GError handling so invalid config paths don’t propagate into GTK chooser failures/crashes on Windows.
Removed an unused get_xdir_fs extern declaration from this function while introducing a single xdir value reused across chooser setup logic.
Added type guards before using the stored plugin view/model (GTK_IS_TREE_VIEW, GTK_IS_LIST_STORE) so stale or unexpected object data doesn’t get dereferenced.
Switched plugin list population to always pass non-null strings for name/version/description via plugingui_safe_string, preventing null string propagation into GTK model setters.
Added an unload guard for empty/null modname before calling unload logic, preventing unsafe calls into plugin teardown paths with invalid identifiers.
fe_pluginlist_update() now guards against pl == NULL, pl->version == NULL, and pl->filename == NULL before dereferencing, and uses safe empty-string fallbacks for filename-backed columns. This prevents null dereferences from malformed or partially-populated plugin entries.
plugingui_unload() now early-returns when the selected plugin filepath is NULL/empty before suffix checks and command formatting, preventing invalid string operations in unload flow.
Updated plugin Unload and Reload callbacks to use the guarded session helper before issuing command-based unload/reload for script plugins, and to exit cleanly when no session is available.
Fixed plugin list layout sizing by forcing the tree view’s scrolled container to expand/fill inside the plugin window’s vbox, so the loaded-plugins list now uses full available height above the button row.
Added a defensive check that reports a user-facing error ("No active session available for loading addons.") and exits early when no valid session exists, instead of calling handle_command() with invalid state.
Updated the file request call to pass NULL userdata for load operations, so the callback no longer retains a stale session pointer while the chooser is open.
Fixed the single-file open path in gtkutil_file_req_done() to fetch the filename once and only call gtkutil_check_file() when a non-NULL filename is returned, preventing the crash path when GTK returns no file on accept/load.
Fixed the top-level preferences window layout so the central horizontal content area expands within the main vertical container, instead of staying at natural height.
Updated Run Command to use the shared decoder instead of its previous newline-only parser, so it now supports the same escape set consistently.
Updated Insert in Buffer to decode escapes before insertion, so \xNN inserts raw bytes rather than literal text.
Updated key action help text to document the supported escape syntax for both Run Command and Insert in Buffer.
Updated the Windows build to prefer glib-genmarshal executables with a Python fallback for marshal generation.
Made GTK link dependencies more robust by selecting available ATK library names before assembling GTK libs.
Added compile-time selection to use AppIndicator when available and fall back to GtkStatusIcon otherwise, keeping the status-icon backend available for non-AppIndicator builds (including GTK3 fallback).
Updated multiple GTK UI layout paths (setup, server list, notify, ban list, join dialog, and menu) to use the new helpers for GTK3-safe box/grid creation and attachment behavior.
Added GTK3-safe attach option definitions and updated helper signatures to avoid GTK2-only types/macros in public headers.
Updated gtkutil grid-attachment helpers to use the new attach option type in alignment/expansion logic.
Switched banlist grid attachments to the new helper option flags for GTK3 builds.
Added a fallback in the GTK frontend header to derive HAVE_GTK3 from GTK_MAJOR_VERSION when the macro is missing, so Windows GTK3 builds don’t compile GTK2-only code paths by mistake.