diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index 6926758fe3..ef644e2c72 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -62,6 +62,7 @@ namespace Avalonia.X11 private XSyncState _xSyncState = 0; private bool _mapped; private bool _wasMappedAtLeastOnce = false; + private bool _shown; private double? _scalingOverride; private bool _disabled; private TransparencyHelper? _transparencyHelper; @@ -797,13 +798,21 @@ namespace Avalonia.X11 get => _lastWindowState; set { - if(_lastWindowState == value) + var previousState = _lastWindowState; + if (previousState == value) return; + if (value == WindowState.Minimized) { XIconifyWindow(_x11.Display, _handle, _x11.DefaultScreen); + return; } - else if (value == WindowState.Maximized) + + // When going from Minimized to any other state programatically, we might need to re-map the window. + // Not doing that will leave the window invisible. + var needsRemap = _shown && previousState == WindowState.Minimized && !_mapped; + + if (value == WindowState.Maximized) { ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_HIDDEN); ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_FULLSCREEN); @@ -823,9 +832,13 @@ namespace Avalonia.X11 ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_FULLSCREEN); ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_MAXIMIZED_VERT, _x11.Atoms._NET_WM_STATE_MAXIMIZED_HORZ); - SendNetWMMessage(_x11.Atoms._NET_ACTIVE_WINDOW, (IntPtr)1, _x11.LastActivityTimestamp, - IntPtr.Zero); } + + if (needsRemap) + XMapWindow(_x11.Display, _handle); + + if (_shown) + SendNetWMMessage(_x11.Atoms._NET_ACTIVE_WINDOW, 1, _x11.LastActivityTimestamp, 0); } } diff --git a/src/Avalonia.X11/X11WindowModes/DefaultWindowMode.cs b/src/Avalonia.X11/X11WindowModes/DefaultWindowMode.cs index af7b56788d..b2a8910d76 100644 --- a/src/Avalonia.X11/X11WindowModes/DefaultWindowMode.cs +++ b/src/Avalonia.X11/X11WindowModes/DefaultWindowMode.cs @@ -30,7 +30,9 @@ partial class X11Window } public override void Show(bool activate, bool isDialog) - { + { + base.Show(activate, isDialog); + Window._wasMappedAtLeastOnce = true; if (!activate) @@ -42,7 +44,6 @@ partial class X11Window XMapWindow(X11.Display, Handle); XFlush(X11.Display); - base.Show(activate, isDialog); } public override void Hide() diff --git a/src/Avalonia.X11/X11WindowModes/WindowMode.cs b/src/Avalonia.X11/X11WindowModes/WindowMode.cs index 20df7d93e9..868592cf45 100644 --- a/src/Avalonia.X11/X11WindowModes/WindowMode.cs +++ b/src/Avalonia.X11/X11WindowModes/WindowMode.cs @@ -47,7 +47,7 @@ partial class X11Window public virtual void Show(bool activate, bool isDialog) { - + Window._shown = true; } public abstract PixelPoint PointToScreen(Point pt); @@ -55,6 +55,7 @@ partial class X11Window public virtual void Hide() { + Window._shown = false; } } }