mirror of
https://github.com/rustdesk/rustdesk
synced 2026-04-21 13:27:19 +00:00
fix(linux): guard window queries during close to prevent SIGSEGV
When a RustDesk window is closing on Linux, the window_manager plugin's get_window() can return null during widget destruction. The Flutter code called saveWindowPosition/saveFrameState without checking if the window was still valid, causing SIGSEGV crashes. Changes: - Guard saveWindowPosition() and saveFrameState() calls during close - Add null checks before window geometry queries in tabbar_widget.dart - Wrap common.dart window operations with validity checks Companion PR: rustdesk-org/window_manager fix/linux-nullptr-guards-sigsegv — adds C++ nullptr guards in the plugin that this Flutter code depends on. Both PRs are needed together to fully resolve the SIGSEGV crashes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ac124c0680
commit
f249d102ea
2 changed files with 30 additions and 7 deletions
|
|
@ -1768,15 +1768,29 @@ Future<void> saveWindowPosition(WindowType type,
|
|||
// if is not resizable. The reason is unknown.
|
||||
//
|
||||
// `setResizable(!bind.isIncomingOnly());` in main.dart
|
||||
isMaximized =
|
||||
bind.isIncomingOnly() ? false : await windowManager.isMaximized();
|
||||
// On Linux, the GtkWindow may already be destroyed when this is called
|
||||
// during onWindowClose (via _saveFrame(flush: true)). Querying a destroyed
|
||||
// window causes SIGSEGV in the native plugin. Guard with try-catch and
|
||||
// fall back to the last saved position if the window is no longer available.
|
||||
try {
|
||||
isMaximized =
|
||||
bind.isIncomingOnly() ? false : await windowManager.isMaximized();
|
||||
} catch (e) {
|
||||
debugPrint('Failed to query isMaximized (window may be closing): $e');
|
||||
isMaximized = false;
|
||||
}
|
||||
if (isFullscreen || isMaximized) {
|
||||
setPreFrame();
|
||||
} else {
|
||||
position = await windowManager.getPosition(
|
||||
ignoreDevicePixelRatio: _ignoreDevicePixelRatio);
|
||||
sz = await windowManager.getSize(
|
||||
ignoreDevicePixelRatio: _ignoreDevicePixelRatio);
|
||||
try {
|
||||
position = await windowManager.getPosition(
|
||||
ignoreDevicePixelRatio: _ignoreDevicePixelRatio);
|
||||
sz = await windowManager.getSize(
|
||||
ignoreDevicePixelRatio: _ignoreDevicePixelRatio);
|
||||
} catch (e) {
|
||||
debugPrint('Failed to query window position/size (window may be closing): $e');
|
||||
setPreFrame();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -431,7 +431,16 @@ class _DesktopTabState extends State<DesktopTab>
|
|||
|
||||
@override
|
||||
void onWindowClose() async {
|
||||
mainWindowClose() async => await windowManager.hide();
|
||||
// On Linux, the GtkWindow may already be destroyed at this point.
|
||||
// Calling hide() on a destroyed window causes GTK CRITICAL assertions
|
||||
// and can contribute to SIGSEGV crashes. Guard with try-catch.
|
||||
mainWindowClose() async {
|
||||
try {
|
||||
await windowManager.hide();
|
||||
} catch (e) {
|
||||
debugPrint('Failed to hide window (may already be closing): $e');
|
||||
}
|
||||
};
|
||||
notMainWindowClose(WindowController windowController) async {
|
||||
if (controller.length != 0) {
|
||||
debugPrint("close not empty multiwindow from taskbar");
|
||||
|
|
|
|||
Loading…
Reference in a new issue