From 0d36ac0cba6205db198581cb36146ac1eaba4983 Mon Sep 17 00:00:00 2001 From: RustDesk <71636191+rustdesk@users.noreply.github.com> Date: Thu, 15 Oct 2026 15:33:42 +0800 Subject: [PATCH] fix(linux): stop using the window in onWindowClose once GTK destroyed it (#16561) On Linux, GTK destroys the window on a close request unless prevent-close is on. When the main window is the last active one, onActiveWindowChanged() turns prevent-close off and calls close(), yet onWindowClose() still went on to hide() the destroyed window, and the close event that close() emits re-entered onWindowClose() to save the frame through isMaximized(). The cm and install windows never turn prevent-close on, so their window is always gone by the time onWindowClose() runs. With window_manager before cf4aef05 those calls segfaulted in gtk_window_is_maximized; since then they fail with an unhandled PlatformException(window_destroyed). Return early in both places instead. Other platforms and sub windows keep the old path. Fixes #16512 Claude-Session: https://claude.ai/code/session_01WS1HTjp6UQuG43KEcQPq1R Co-authored-by: Claude Opus 5.5 --- flutter/lib/desktop/widgets/tabbar_widget.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/flutter/lib/desktop/widgets/tabbar_widget.dart b/flutter/lib/desktop/widgets/tabbar_widget.dart index 9ef7d38d9..8eddca6ee 100644 --- a/flutter/lib/desktop/widgets/tabbar_widget.dart +++ b/flutter/lib/desktop/widgets/tabbar_widget.dart @@ -418,6 +418,13 @@ class _DesktopTabState extends State } } + // On Linux, GTK destroys the window on a close request unless prevent-close + // is on. It is off for the cm and install windows, and onActiveWindowChanged() + // turns it off to quit, so the window can no longer be saved or hidden. + // https://github.com/rustdesk/rustdesk/issues/16512 + Future _isLinuxWindowClosed() async => + isLinux && isMainWindow && !await windowManager.isPreventClose(); + @override void onWindowMoved() { _saveFrame(); @@ -465,6 +472,8 @@ class _DesktopTabState extends State }); } + if (await _isLinuxWindowClosed()) return; + await _saveFrame(flush: true); // hide window on close @@ -472,6 +481,7 @@ class _DesktopTabState extends State if (rustDeskWinManager.getActiveWindows().contains(kMainWindowId)) { await rustDeskWinManager.unregisterActiveWindow(kMainWindowId); } + if (await _isLinuxWindowClosed()) return; // macOS specific workaround, the window is not hiding when in fullscreen. if (isMacOS && await windowManager.isFullScreen()) { await windowManager.setFullScreen(false);