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 <noreply@anthropic.com>
This commit is contained in:
RustDesk
2026-10-15 15:33:42 +08:00
committed by GitHub
co-authored by Claude Opus 5.5
parent f1fa432bc8
commit 0d36ac0cba
@@ -418,6 +418,13 @@ class _DesktopTabState extends State<DesktopTab>
}
}
// 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<bool> _isLinuxWindowClosed() async =>
isLinux && isMainWindow && !await windowManager.isPreventClose();
@override
void onWindowMoved() {
_saveFrame();
@@ -465,6 +472,8 @@ class _DesktopTabState extends State<DesktopTab>
});
}
if (await _isLinuxWindowClosed()) return;
await _saveFrame(flush: true);
// hide window on close
@@ -472,6 +481,7 @@ class _DesktopTabState extends State<DesktopTab>
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);