AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
26.19k stars 2.27k forks source link

X11 Atoms will be lost after the window is unmapped #16115

Open walterlv opened 5 months ago

walterlv commented 5 months ago

Describe the bug

I don't know whether it's a bug or not, so I think I should discuss the solution here.

Related links:

Assume that we're setting such properties on a window:

public MainWindow()
{
    InitializeComponent();

    ShowInTaskbar = false;
    Topmost = true;
    WindowState = WindowState.FullScreen;
}

We're expecting that the window will be shown in full screen mode, topmost, and not shown in the taskbar. However, after Hide and Show the window, all the properties are lost. The window is shown in maximized mode, not topmost, and shown in the taskbar. This behavior is quitely different from the behavior running on Windows.

Let's see deeper.

The properties above emit the following X11 atoms:

After the XUnmapWindow is called, all the atoms are lost. Furthermore, after the XMapWindow is called, two new atoms are added:

As a result, the window is shown in maximized mode(not fullscreen), not topmost, and shown in the taskbar.

To Reproduce

  1. Set the properties on a window as above.
  2. Call Hide and Show on the window.
  3. The window is shown in maximized mode, not topmost, and shown in the taskbar.

Expected behavior

The window should be shown in full screen mode, topmost, and not shown in the taskbar even after Hide and Show which is the same behavior as running on Windows.

Avalonia version

11.0.10, 11.0.11, 11.1.0-beta1, 11.1.0-beta2, 11.1.0-rc1

OS

Linux

Additional context

See the link here and search for _NET_WM_STATE section:

The Window Manager should remove the property whenever a window is withdrawn, but it should leave the property in place when it is shutting down

I can't understand the meaning of "withdrawn" here. But after several debugging on the ControlCatalog.NetCore project, I think it's very likely that it means the window is unmapped which means that the Window Manager should remove the atoms properties whenever a window is unmapped.

See another link here:

The author of the topic is suffering from the same problem as what Avalonia UI is facing.

walterlv commented 5 months ago

I have two naive solutions:

Solution 1:

  1. Add a HashSet<nint> into the X11Window class to store the atoms.
  2. Whenever any properties which affect the atoms are set, change the atoms of the HashSet.
  3. Every time before the XMapWindow is called, set the atoms in the HashSet to the window.

Solution 2:

  1. Store the atoms in the X11Window class before the XUnmapWindow is called.
  2. Every time before the XMapWindow is called, set the atoms back to the window.

The two solutions are both not perfect.

For solution 1, if the developer add some Atoms themselves, we will drop them after the window is mapped. For solution 2, if the developer set some properties when the window is invisible, the properties will be lost after the window is mapped.

I think we should discuss a better solution here. Thanks.

lindexi commented 5 months ago

I prefer Solution one.

AlexeyTliss commented 2 months ago

I also think solution 1 is good enough. Hope this gets fixed soon :)