diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index 6c1b381a40f..bc159087b32 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -686,6 +686,7 @@ public WindowState WindowState ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_FULLSCREEN); ChangeWMAtoms(true, _x11.Atoms._NET_WM_STATE_MAXIMIZED_VERT, _x11.Atoms._NET_WM_STATE_MAXIMIZED_HORZ); + MapOrActiveWindow(); } else if (value == WindowState.FullScreen) { @@ -693,6 +694,7 @@ public WindowState WindowState ChangeWMAtoms(true, _x11.Atoms._NET_WM_STATE_FULLSCREEN); ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_MAXIMIZED_VERT, _x11.Atoms._NET_WM_STATE_MAXIMIZED_HORZ); + MapOrActiveWindow(); } else { @@ -700,8 +702,7 @@ public WindowState WindowState 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); + MapOrActiveWindow(); } WindowStateChanged?.Invoke(value); } @@ -1205,6 +1206,40 @@ private void SendNetWMMessage(IntPtr message_type, IntPtr l0, } + private void MapOrActiveWindow() + { + if (_wasMappedAtLeastOnce) + { + // If the window has been mapped at least once, we should use XMapRequestEvent instead of XMapWindow or SendNetWMMessage. + // See details at https://github.com/AvaloniaUI/Avalonia/pull/16922 + var e = new XEvent + { + MapRequestEvent = new XMapRequestEvent + { + type = XEventName.MapRequest, + serial = new IntPtr(0), + display = _x11.Display, + send_event = 1, + parent = _x11.RootWindow, + window = _handle, + }, + }; + XSendEvent( + _x11.Display, + _x11.RootWindow, + false, + new IntPtr((int)EventMask.SubstructureRedirectMask), + ref e); + } + else + { + // If the window has never been mapped, we should send _NET_ACTIVE_WINDOW message. + // Otherwise, the window will show too early so that content that not been layouted or rendered will be shown. + SendNetWMMessage(_x11.Atoms._NET_ACTIVE_WINDOW, (IntPtr)1, _x11.LastActivityTimestamp, + IntPtr.Zero); + } + } + private void BeginMoveResize(NetWmMoveResize side, PointerPressedEventArgs e) { var pos = GetCursorPos(_x11);