From d50b4cbf3d05e3d3fe7d6f078a9719f90ca01e5f Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 4 Mar 2026 22:29:27 +0800 Subject: [PATCH 1/4] Improves usability on Linux. No more double title bar (#12600) * Fix double title bar on Linux by removing WM decorations for GTK * wip * fix * finish * address review comment --- src/slic3r/GUI/BBLTopbar.cpp | 34 +++++++- src/slic3r/GUI/MainFrame.cpp | 156 +++++++++++++++++++++++++++++++++++ src/slic3r/GUI/MainFrame.hpp | 5 ++ task.md | 12 --- 4 files changed, 191 insertions(+), 16 deletions(-) delete mode 100644 task.md diff --git a/src/slic3r/GUI/BBLTopbar.cpp b/src/slic3r/GUI/BBLTopbar.cpp index 151f601e2c..4ac9a7aa29 100644 --- a/src/slic3r/GUI/BBLTopbar.cpp +++ b/src/slic3r/GUI/BBLTopbar.cpp @@ -13,6 +13,10 @@ #include +#ifdef __WXGTK__ +#include +#endif + #define TOPBAR_ICON_SIZE 18 #define TOPBAR_TITLE_WIDTH 300 @@ -532,6 +536,18 @@ void BBLTopbar::OnIconize(wxAuiToolBarEvent& event) void BBLTopbar::OnFullScreen(wxAuiToolBarEvent& event) { +#ifdef __WXGTK__ + GtkWindow* gtk_window = GTK_WINDOW(m_frame->m_widget); + if (gtk_window_is_maximized(gtk_window)) { + gtk_window_unmaximize(gtk_window); + } + else { + m_normalRect = m_frame->GetRect(); + gtk_window_maximize(gtk_window); + } + return; +#endif + if (m_frame->IsMaximized()) { m_frame->Restore(); } @@ -621,17 +637,27 @@ void BBLTopbar::OnMouseLeftDown(wxMouseEvent& event) wxPoint frame_pos = m_frame->GetScreenPosition(); m_delta = mouse_pos - frame_pos; - if (FindToolByCurrentPosition() == NULL + if (FindToolByCurrentPosition() == NULL || this->FindToolByCurrentPosition() == m_title_item) { - CaptureMouse(); #ifdef __WXMSW__ + CaptureMouse(); ReleaseMouse(); ::PostMessage((HWND) m_frame->GetHandle(), WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(mouse_pos.x, mouse_pos.y)); return; -#endif // __WXMSW__ +#elif defined(__WXGTK__) + // Use WM-integrated drag for smoother window movement on Linux. + gtk_window_begin_move_drag( + GTK_WINDOW(m_frame->m_widget), + 1, // left mouse button + mouse_pos.x, mouse_pos.y, + gtk_get_current_event_time()); + return; +#else + CaptureMouse(); +#endif } - + event.Skip(); } diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index c279d0ebb9..d7c0da0127 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -71,6 +71,10 @@ #include #include #endif // _WIN32 + +#ifdef __WXGTK__ +#include +#endif // __WXGTK__ #include @@ -100,6 +104,142 @@ enum class ERescaleTarget SettingsDialog }; +#ifdef __WXGTK__ +// Intercepts mouse events globally to provide resize handles for the +// borderless (CSD) window. When the cursor is within BORDER_PX of a +// window edge, a resize cursor is shown and left-click initiates a +// WM-integrated resize via gtk_window_begin_resize_drag(). +class MainFrame::GtkResizeBorderHandler : public wxEventFilter +{ +public: + static constexpr int BORDER_PX = 8; + + explicit GtkResizeBorderHandler(MainFrame* frame) + : m_frame(frame) + { + wxEvtHandler::AddFilter(this); + } + + ~GtkResizeBorderHandler() override + { + wxEvtHandler::RemoveFilter(this); + } + + int FilterEvent(wxEvent& event) override + { + const wxEventType t = event.GetEventType(); + if (t != wxEVT_MOTION && t != wxEVT_LEFT_DOWN) + return Event_Skip; + + if (!m_frame || !m_frame->IsShown() || m_frame->IsMaximized() || m_frame->IsFullScreen()) + return Event_Skip; + + if (!gtk_widget_get_realized(m_frame->m_widget) || gtk_widget_get_window(m_frame->m_widget) == nullptr) + return Event_Skip; + + wxPoint mouse = ::wxGetMousePosition(); + wxRect rect = m_frame->GetScreenRect(); + + // Don't steal interactions from the custom top bar area. + // Keep corner resizing available by only excluding the pure top edge. + if (m_frame->topbar() != nullptr) { + const wxRect topbar_rect = m_frame->topbar()->GetScreenRect(); + if (topbar_rect.Contains(mouse)) { + const bool near_left_corner = mouse.x < rect.x + BORDER_PX; + const bool near_right_corner = mouse.x > rect.x + rect.width - BORDER_PX; + if (!near_left_corner && !near_right_corner) + return Event_Skip; + } + } + + GdkWindowEdge edge; + if (!hit_test(mouse, rect, edge)) { + // Cursor is not near any edge — restore default cursor if we changed it. + if (m_cursor_set) { + gdk_window_set_cursor(gtk_widget_get_window(m_frame->m_widget), NULL); + m_cursor_set = false; + m_last_edge_valid = false; + } + return Event_Skip; + } + + // Set the appropriate resize cursor. + set_cursor_for_edge(edge); + + if (t == wxEVT_LEFT_DOWN) { + gtk_window_begin_resize_drag( + GTK_WINDOW(m_frame->m_widget), + edge, + 1, // left mouse button + mouse.x, mouse.y, + gtk_get_current_event_time()); + return Event_Processed; + } + + // For motion, keep app interaction working (menus, hover, etc.). + return Event_Skip; + } + +private: + bool hit_test(const wxPoint& mouse, const wxRect& rect, GdkWindowEdge& edge) const + { + bool left = mouse.x >= rect.x && mouse.x < rect.x + BORDER_PX; + bool right = mouse.x > rect.x + rect.width - BORDER_PX && mouse.x <= rect.x + rect.width; + bool top = mouse.y >= rect.y && mouse.y < rect.y + BORDER_PX; + bool bottom = mouse.y > rect.y + rect.height - BORDER_PX && mouse.y <= rect.y + rect.height; + + if (!left && !right && !top && !bottom) + return false; + + if (top && left) edge = GDK_WINDOW_EDGE_NORTH_WEST; + else if (top && right) edge = GDK_WINDOW_EDGE_NORTH_EAST; + else if (bottom && left) edge = GDK_WINDOW_EDGE_SOUTH_WEST; + else if (bottom && right) edge = GDK_WINDOW_EDGE_SOUTH_EAST; + else if (top) edge = GDK_WINDOW_EDGE_NORTH; + else if (bottom) edge = GDK_WINDOW_EDGE_SOUTH; + else if (left) edge = GDK_WINDOW_EDGE_WEST; + else edge = GDK_WINDOW_EDGE_EAST; + return true; + } + + void set_cursor_for_edge(GdkWindowEdge edge) + { + if (m_last_edge_valid && m_cursor_set && edge == m_last_edge) + return; + + const char* cursor_name = nullptr; + switch (edge) { + case GDK_WINDOW_EDGE_NORTH: cursor_name = "n-resize"; break; + case GDK_WINDOW_EDGE_SOUTH: cursor_name = "s-resize"; break; + case GDK_WINDOW_EDGE_WEST: cursor_name = "w-resize"; break; + case GDK_WINDOW_EDGE_EAST: cursor_name = "e-resize"; break; + case GDK_WINDOW_EDGE_NORTH_WEST: cursor_name = "nw-resize"; break; + case GDK_WINDOW_EDGE_NORTH_EAST: cursor_name = "ne-resize"; break; + case GDK_WINDOW_EDGE_SOUTH_WEST: cursor_name = "sw-resize"; break; + case GDK_WINDOW_EDGE_SOUTH_EAST: cursor_name = "se-resize"; break; + default: return; + } + + GdkDisplay* display = gtk_widget_get_display(m_frame->m_widget); + GdkCursor* cursor = gdk_cursor_new_from_name(display, cursor_name); + if (!cursor) + return; + + gdk_window_set_cursor(gtk_widget_get_window(m_frame->m_widget), cursor); + g_object_unref(cursor); + + m_cursor_set = true; + m_last_edge = edge; + m_last_edge_valid = true; + } + + MainFrame* m_frame; + bool m_cursor_set{false}; + GdkWindowEdge m_last_edge{}; + bool m_last_edge_valid{false}; +}; +#endif // __WXGTK__ + #ifdef __APPLE__ class OrcaSlicerTaskBarIcon : public wxTaskBarIcon { @@ -191,6 +331,18 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ set_miniaturizable(GetHandle()); #endif +#ifdef __WXGTK__ + // Zero out the decoration hints that wxGTK computed from the window style. + // When GTKHandleRealized() later calls gdk_window_set_decorations(), it + // will apply zero decorations (no WM title bar). + m_gdkDecor = 0; + + // Install app-level resize border handler as a fallback. + // This keeps resize behavior for undecorated windows without using GTK CSD, + // avoiding CSD repaint/maximize artifacts on some WMs. + m_resize_border_handler = new GtkResizeBorderHandler(this); +#endif + if (!wxGetApp().app_config->has("user_mode")) { wxGetApp().app_config->set("user_mode", "simple"); wxGetApp().app_config->set_bool("developer_mode", false); @@ -937,6 +1089,10 @@ void MainFrame::update_layout() void MainFrame::shutdown() { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "MainFrame::shutdown enter"; +#ifdef __WXGTK__ + delete m_resize_border_handler; + m_resize_border_handler = nullptr; +#endif // BBS: backup Slic3r::set_backup_callback(nullptr); #ifdef _WIN32 diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index faa6e10708..8fa5454cae 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -422,6 +422,11 @@ public: uint32_t m_ulSHChangeNotifyRegister { 0 }; static constexpr int WM_USER_MEDIACHANGED { 0x7FFF }; // WM_USER from 0x0400 to 0x7FFF, picking the last one to not interfere with wxWidgets allocation #endif // _WIN32 + +#ifdef __WXGTK__ + class GtkResizeBorderHandler; + GtkResizeBorderHandler* m_resize_border_handler{nullptr}; +#endif // __WXGTK__ }; wxDECLARE_EVENT(EVT_HTTP_ERROR, wxCommandEvent); diff --git a/task.md b/task.md deleted file mode 100644 index 10fc9ac724..0000000000 --- a/task.md +++ /dev/null @@ -1,12 +0,0 @@ -Analyze the bug that it failed to load project(3mf) from old version. -It failed pass below check in PresetBundle::load_config_file_config function, hence throw error. - if (config.option("extruder_variant_list")) { - //3mf support multiple extruder logic - size_t extruder_count = config.option("nozzle_diameter")->values.size(); - extruder_variant_count = config.option("filament_extruder_variant", true)->size(); - if ((extruder_variant_count != filament_self_indice.size()) - || (extruder_variant_count < num_filaments)) { - assert(false); - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": invalid config file %1%, can not find suitable filament_extruder_variant or filament_self_index") % name_or_path; - throw Slic3r::RuntimeError(std::string("Invalid configuration file: ") + name_or_path); - } \ No newline at end of file From 008cfd1f8657c0e266a7a741920d7e9f7e187baa Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 4 Mar 2026 22:48:40 +0800 Subject: [PATCH 2/4] Linux: prefer discrete GPU on dual-GPU systems via PRIME environment variables (#12602) * Linux: prefer discrete GPU on dual-GPU systems via PRIME environment variables Set DRI_PRIME=1 for AMD/nouveau PRIME setups and __NV_PRIME_RENDER_OFFLOAD/__GLX_VENDOR_LIBRARY_NAME for NVIDIA proprietary driver, only when the NVIDIA kernel module is detected. Uses replace=false to respect user overrides. * Improves usability on Linux. No more double title bar (#12600) * Fix double title bar on Linux by removing WM decorations for GTK * wip * fix * finish * address review comment --- src/OrcaSlicer.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index 397cd66d38..35736348a0 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -88,6 +88,7 @@ using namespace nlohmann; #ifdef __WXGTK__ #include +#include #endif #ifdef SLIC3R_GUI @@ -1191,6 +1192,17 @@ int CLI::run(int argc, char **argv) // mode forces software rendering, which works reliably on all backends. ::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", /* replace */ false); + // On Linux dual-GPU systems, request the high-performance discrete GPU. + // DRI_PRIME=1 handles AMD and nouveau (open-source NVIDIA) PRIME setups. + ::setenv("DRI_PRIME", "1", /* replace */ false); + + // For NVIDIA proprietary driver PRIME render offload, set additional variables. + // Only set if the NVIDIA kernel module is loaded to avoid breaking systems without NVIDIA. + if (::access("/proc/driver/nvidia/version", F_OK) == 0) { + ::setenv("__NV_PRIME_RENDER_OFFLOAD", "1", /* replace */ false); + ::setenv("__GLX_VENDOR_LIBRARY_NAME", "nvidia", /* replace */ false); + } + // Also on Linux, we need to tell Xlib that we will be using threads, // lest we crash when we fire up GStreamer. XInitThreads(); From 1218711adb5364d53436f674940c4d6d80319008 Mon Sep 17 00:00:00 2001 From: Vovodroid Date: Wed, 4 Mar 2026 17:25:54 +0200 Subject: [PATCH 3/4] Use non-deprecated triangulate_hole method (#12592) --- src/libslic3r/MeshBoolean.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/MeshBoolean.cpp b/src/libslic3r/MeshBoolean.cpp index 779d5a042b..c195e4358f 100644 --- a/src/libslic3r/MeshBoolean.cpp +++ b/src/libslic3r/MeshBoolean.cpp @@ -343,7 +343,7 @@ void segment(CGALMesh& src, std::vector& dst, double smoothing_alpha = std::cout << "* Number of facets in constructed patch: " << patch_facets.size() << std::endl; std::cout << " Number of vertices in constructed patch: " << patch_vertices.size() << std::endl; #else - CGAL::Polygon_mesh_processing::triangulate_hole(out, h, std::back_inserter(patch_facets)); + CGAL::Polygon_mesh_processing::triangulate_hole(out, h, CGAL::parameters::default_values().face_output_iterator(std::back_inserter(patch_facets))); #endif } From 52a2c033d3bf6d9abddf42ef850c1b76d08f41c1 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Thu, 5 Mar 2026 01:13:26 +0800 Subject: [PATCH 4/4] Remove upstreamed wxWidgets dark theme patch for Flatpak The GNOME dark style support patch has been submitted upstream to wxWidgets, so the local Flatpak patch is no longer needed. --- deps/wxWidgets/wxWidgets.cmake | 4 - .../io.github.softfever.OrcaSlicer.yml | 4 - ...ark-theme-when-Gnome-dark-style-is-s.patch | 164 ------------------ 3 files changed, 172 deletions(-) delete mode 100644 scripts/flatpak/patches/0001-Enable-using-a-dark-theme-when-Gnome-dark-style-is-s.patch diff --git a/deps/wxWidgets/wxWidgets.cmake b/deps/wxWidgets/wxWidgets.cmake index cb25f0eb45..e1c40cc287 100644 --- a/deps/wxWidgets/wxWidgets.cmake +++ b/deps/wxWidgets/wxWidgets.cmake @@ -1,8 +1,6 @@ set(_wx_toolkit "") set(_wx_debug_postfix "") set(_wx_shared -DwxBUILD_SHARED=OFF) -set(_wx_flatpak_patch "") - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(_gtk_ver 2) @@ -14,7 +12,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") if (FLATPAK) set(_wx_debug_postfix "d") set(_wx_shared -DwxBUILD_SHARED=ON -DBUILD_SHARED_LIBS:BOOL=ON) - set(_wx_flatpak_patch PATCH_COMMAND ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/0001-flatpak.patch) endif () endif() @@ -37,7 +34,6 @@ orcaslicer_add_cmake_project( GIT_REPOSITORY "https://github.com/SoftFever/Orca-deps-wxWidgets" GIT_SHALLOW ON DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} ${JPEG_PKG} - ${_wx_flatpak_patch} CMAKE_ARGS ${_wx_opengl_override} -DwxBUILD_PRECOMP=ON diff --git a/scripts/flatpak/io.github.softfever.OrcaSlicer.yml b/scripts/flatpak/io.github.softfever.OrcaSlicer.yml index 9fa5b7d8b8..1b36f06481 100755 --- a/scripts/flatpak/io.github.softfever.OrcaSlicer.yml +++ b/scripts/flatpak/io.github.softfever.OrcaSlicer.yml @@ -95,10 +95,6 @@ modules: path: ../../deps dest: deps - - type: file - path: patches/0001-Enable-using-a-dark-theme-when-Gnome-dark-style-is-s.patch - dest: deps/wxWidgets - dest-filename: 0001-flatpak.patch - name: OrcaSlicer buildsystem: simple diff --git a/scripts/flatpak/patches/0001-Enable-using-a-dark-theme-when-Gnome-dark-style-is-s.patch b/scripts/flatpak/patches/0001-Enable-using-a-dark-theme-when-Gnome-dark-style-is-s.patch deleted file mode 100644 index 877b69b459..0000000000 --- a/scripts/flatpak/patches/0001-Enable-using-a-dark-theme-when-Gnome-dark-style-is-s.patch +++ /dev/null @@ -1,164 +0,0 @@ -From f0135d9c3faf0207f7100991ccf512f228b90570 Mon Sep 17 00:00:00 2001 -From: Paul Cornett -Date: Sat, 30 Sep 2023 16:42:58 -0700 -Subject: [PATCH] Enable using a dark theme when Gnome "dark style" is set - -The dark style setting does not cause a dark theme to be used -automatically, so request it explicitly. - -Co-authored-by: Colin Kinloch ---- - src/gtk/settings.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 117 insertions(+), 1 deletion(-) - -diff --git a/src/gtk/settings.cpp b/src/gtk/settings.cpp -index 3047247737..f13ea2ef24 100644 ---- a/src/gtk/settings.cpp -+++ b/src/gtk/settings.cpp -@@ -183,6 +183,64 @@ static void notify_gtk_font_name(GObject*, GParamSpec*, void*) - } - } - -+static bool UpdatePreferDark(GVariant* value) -+{ -+ // 0: No preference, 1: Prefer dark appearance, 2: Prefer light appearance -+ gboolean preferDark = g_variant_get_uint32(value) == 1; -+ -+ GtkSettings* settings = gtk_settings_get_default(); -+ char* themeName; -+ gboolean preferDarkPrev; -+ g_object_get(settings, -+ "gtk-theme-name", &themeName, -+ "gtk-application-prefer-dark-theme", &preferDarkPrev, nullptr); -+ -+ // We don't need to enable prefer-dark if the theme is already dark -+ if (strstr(themeName, "-dark") || strstr(themeName, "-Dark")) -+ preferDark = false; -+ g_free(themeName); -+ -+ const bool changed = preferDark != preferDarkPrev; -+ if (changed) -+ { -+ g_object_set(settings, -+ "gtk-application-prefer-dark-theme", preferDark, nullptr); -+ } -+ return changed; -+} -+ -+// "g-signal" from GDBusProxy -+extern "C" { -+static void -+proxy_g_signal(GDBusProxy*, const char*, const char* signal_name, GVariant* parameters, void*) -+{ -+ if (strcmp(signal_name, "SettingChanged") != 0) -+ return; -+ -+ const char* nameSpace; -+ const char* key; -+ GVariant* value; -+ g_variant_get(parameters, "(&s&sv)", &nameSpace, &key, &value); -+ if (strcmp(nameSpace, "org.freedesktop.appearance") == 0 && -+ strcmp(key, "color-scheme") == 0) -+ { -+ if (UpdatePreferDark(value)) -+ { -+ for (int i = wxSYS_COLOUR_MAX; i--;) -+ gs_systemColorCache[i].UnRef(); -+ -+ for (auto* win: wxTopLevelWindows) -+ { -+ wxSysColourChangedEvent event; -+ event.SetEventObject(win); -+ win->HandleWindowEvent(event); -+ } -+ } -+ } -+ g_variant_unref(value); -+} -+} -+ - // Some notes on using GtkStyleContext. Style information from a context - // attached to a non-visible GtkWidget is not accurate. The context has an - // internal visibility state, controlled by the widget, which it presumably -@@ -1124,12 +1182,68 @@ bool wxSystemSettingsNative::HasFeature(wxSystemFeature index) - class wxSystemSettingsModule: public wxModule - { - public: -- virtual bool OnInit() wxOVERRIDE { return true; } -+ virtual bool OnInit() wxOVERRIDE; - virtual void OnExit() wxOVERRIDE; -+ -+#ifdef __WXGTK3__ -+ GDBusProxy* m_proxy; -+#endif - wxDECLARE_DYNAMIC_CLASS(wxSystemSettingsModule); - }; - wxIMPLEMENT_DYNAMIC_CLASS(wxSystemSettingsModule, wxModule); - -+bool wxSystemSettingsModule::OnInit() -+{ -+#ifdef __WXGTK3__ -+ // Gnome has gone to a dark style setting rather than a selectable dark -+ // theme, available via GSettings as the 'color-scheme' key under the -+ // 'org.gnome.desktop.interface' schema. It's also available via a "portal" -+ // (https://docs.flatpak.org/en/latest/portal-api-reference.html), which -+ // has the advantage of allowing the setting to be accessed from within a -+ // virtualized environment such as Flatpak. Since the setting does not -+ // change the theme, we propagate it to the GtkSettings -+ // 'gtk-application-prefer-dark-theme' property to get a dark theme. -+ -+ m_proxy = nullptr; -+ -+ if (getenv("ORCA_SLICER_DARK_THEME") != nullptr) { -+ /* 1 for prefer dark */ -+ GVariant *value = g_variant_new_uint32(1); -+ UpdatePreferDark(value); -+ g_variant_unref(value); -+ } -+ // GTK_THEME environment variable overrides other settings -+ else if (getenv("GTK_THEME") == nullptr) -+ { -+ m_proxy = g_dbus_proxy_new_for_bus_sync( -+ G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, nullptr, -+ "org.freedesktop.portal.Desktop", -+ "/org/freedesktop/portal/desktop", -+ "org.freedesktop.portal.Settings", -+ nullptr, nullptr); -+ } -+ if (m_proxy) -+ { -+ g_signal_connect(m_proxy, "g-signal", G_CALLBACK(proxy_g_signal), nullptr); -+ -+ GVariant* ret = g_dbus_proxy_call_sync(m_proxy, "Read", -+ g_variant_new("(ss)", "org.freedesktop.appearance", "color-scheme"), -+ G_DBUS_CALL_FLAGS_NONE, -1, nullptr, nullptr); -+ if (ret) -+ { -+ GVariant* child; -+ g_variant_get(ret, "(v)", &child); -+ GVariant* value = g_variant_get_variant(child); -+ UpdatePreferDark(value); -+ g_variant_unref(value); -+ g_variant_unref(child); -+ g_variant_unref(ret); -+ } -+ } -+#endif // __WXGTK3__ -+ return true; -+} -+ - void wxSystemSettingsModule::OnExit() - { - #ifdef __WXGTK3__ -@@ -1141,6 +1255,8 @@ void wxSystemSettingsModule::OnExit() - g_signal_handlers_disconnect_by_func(settings, - (void*)notify_gtk_font_name, NULL); - } -+ if (m_proxy) -+ g_object_unref(m_proxy); - #endif - if (gs_tlw_parent) - { --- -2.49.0 -