diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 366a7b6ba..302c507e4 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -1779,15 +1779,29 @@ Future 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: diff --git a/flutter/lib/desktop/widgets/tabbar_widget.dart b/flutter/lib/desktop/widgets/tabbar_widget.dart index 9ef7d38d9..6d57fd46e 100644 --- a/flutter/lib/desktop/widgets/tabbar_widget.dart +++ b/flutter/lib/desktop/widgets/tabbar_widget.dart @@ -432,7 +432,16 @@ class _DesktopTabState extends State @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");