Browse Source

Fix an issue that if WindowState is been set in the constructor, the contents that not been layouted or rendered will be shown.

pull/16922/head
walterlv 2 years ago
parent
commit
e0b8da8e85
No known key found for this signature in database GPG Key ID: 59ADF4450E42FA22
  1. 59
      src/Avalonia.X11/X11Window.cs

59
src/Avalonia.X11/X11Window.cs

@ -686,7 +686,7 @@ namespace Avalonia.X11
ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_FULLSCREEN); ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_FULLSCREEN);
ChangeWMAtoms(true, _x11.Atoms._NET_WM_STATE_MAXIMIZED_VERT, ChangeWMAtoms(true, _x11.Atoms._NET_WM_STATE_MAXIMIZED_VERT,
_x11.Atoms._NET_WM_STATE_MAXIMIZED_HORZ); _x11.Atoms._NET_WM_STATE_MAXIMIZED_HORZ);
MapWindow(); MapOrActiveWindow();
} }
else if (value == WindowState.FullScreen) else if (value == WindowState.FullScreen)
{ {
@ -694,7 +694,7 @@ namespace Avalonia.X11
ChangeWMAtoms(true, _x11.Atoms._NET_WM_STATE_FULLSCREEN); ChangeWMAtoms(true, _x11.Atoms._NET_WM_STATE_FULLSCREEN);
ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_MAXIMIZED_VERT, ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_MAXIMIZED_VERT,
_x11.Atoms._NET_WM_STATE_MAXIMIZED_HORZ); _x11.Atoms._NET_WM_STATE_MAXIMIZED_HORZ);
MapWindow(); MapOrActiveWindow();
} }
else else
{ {
@ -702,7 +702,7 @@ namespace Avalonia.X11
ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_FULLSCREEN); ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_FULLSCREEN);
ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_MAXIMIZED_VERT, ChangeWMAtoms(false, _x11.Atoms._NET_WM_STATE_MAXIMIZED_VERT,
_x11.Atoms._NET_WM_STATE_MAXIMIZED_HORZ); _x11.Atoms._NET_WM_STATE_MAXIMIZED_HORZ);
MapWindow(); MapOrActiveWindow();
} }
WindowStateChanged?.Invoke(value); WindowStateChanged?.Invoke(value);
} }
@ -1206,33 +1206,38 @@ namespace Avalonia.X11
} }
/// <summary> private void MapOrActiveWindow()
/// Map the window to the screen.
/// </summary>
/// <remarks>
/// Why we map the window using XMapRequestEvent instead of XMapWindow or SendNetWMMessage?<br/>
/// See details at https://github.com/AvaloniaUI/Avalonia/pull/16922
/// </remarks>
private void MapWindow()
{ {
var e = new XEvent if (_wasMappedAtLeastOnce)
{ {
MapRequestEvent = new XMapRequestEvent // 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
{ {
type = XEventName.MapRequest, MapRequestEvent = new XMapRequestEvent
serial = new IntPtr(0), {
display = _x11.Display, type = XEventName.MapRequest,
send_event = 1, serial = new IntPtr(0),
parent = _x11.RootWindow, display = _x11.Display,
window = _handle, send_event = 1,
}, parent = _x11.RootWindow,
}; window = _handle,
XSendEvent( },
_x11.Display, };
_x11.RootWindow, XSendEvent(
false, _x11.Display,
new IntPtr((int)EventMask.SubstructureRedirectMask), _x11.RootWindow,
ref e); 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) private void BeginMoveResize(NetWmMoveResize side, PointerPressedEventArgs e)

Loading…
Cancel
Save