GNOME Bugzilla – Bug 777690
_NET_WM_STATE ignored when mapping window with WM_HINTS initial_state=IconicState
Last modified: 2021-07-05 13:52:22 UTC
Created attachment 344107 [details] Compile with g++ -std=c++14 -Wall -g $(pkg-config --cflags --libs Qt5Core Qt5Gui) -fPIC -lX11 -o x11-minimal x11-minimal.cc Initial value of _NET_WM_STATE is ignored by gnome-session/mutter when mapping window with WM_HINTS initial_state=IconicState. This means it is not possible to create a window that is initially shown minimized (IconicState) that will become maximized when the user clicks on the windows button in the window list. The netwm-spec has this to say on the subject of _NET_WM_STATE when a window is mapped: "The Window Manager SHOULD honor _NET_WM_STATE whenever a withdrawn window requests to be mapped." I've tested how gnome-session/mutter, metacity, kwin and xfwm behaves with _NET_WM_STATE=_NET_WM_STATE_MAXIMIZED_HORZ,_NET_WM_STATE_MAXIMIZED_VERT and WM_HINTS initial_state=IconicState when the window is mapped: gnome-session/mutter: Ignores existing _NET_WM_STATE and sets it to _NET_WM_STATE=_NET_WM_STATE_HIDDEN. When user unminimize via taskbar/window list the window is shown in normal mode metacity (3.12.0-4.fc24): Overwrites _NET_WM_STATE to _NET_WM_STATE_HIDDEN, but when the user unminimize via taskbar the window becomes maximized and _NET_WM_STATE=_NET_WM_STATE_MAXIMIZED_HORZ,_NET_WM_STATE_MAXIMIZED_VERT again. If the user minimizes the window the state becomes becomes _NET_WM_STATE=_NET_WM_STATE_MAXIMIZED_HORZ,_NET_WM_STATE_MAXIMIZED_VERT,_NET_WM_STATE_HIDDEN, so metacity remembers this state somewhere else. kwin: Works as I would expect. State becomes _NET_WM_STATE=_NET_WM_STATE_MAXIMIZED_HORZ,_NET_WM_STATE_MAXIMIZED_VERT,_NET_WM_STATE_HIDDEN after the window is mapped. When the user unminimize and minimize the window the maximized state is retained in _NET_WM_STATE. xfwm: Works exactly like kwin.
The interactions between WM_HINTS and _NET_WM_STATE regarding minimization aren't at all clear unfortunately, but it seems that released versions of mutter don't behave well indeed. In master, after bug 774333, it seems we behave a little better but your test case here still doesn't do what you want, i.e. after that patch from bug 774333, the window is initially maximized but not minimized at all. FWIW, if you add _NET_WM_STATE_HIDDEN to your initial _NET_WM_STATE it behaves as you intend. At this point, I'm wondering if we should revert bug 774333 and label it as an issue that wine should deal with. Carlos?
> The interactions between WM_HINTS and _NET_WM_STATE regarding minimization aren't at all clear unfortunately, [...] Okay. That makes me feel better as I have spent a few hours today reading the netwm spec and the icccm documentation and now feel quite confused ;-) > FWIW, if you add _NET_WM_STATE_HIDDEN to your initial _NET_WM_STATE it behaves as you intend. This goes against the netwm-spec which says "Implementation note: if an Application asks to toggle _NET_WM_STATE_HIDDEN the Window Manager should probably just ignore the request, since _NET_WM_STATE_HIDDEN is a function of some other aspect of the window such as minimization, rather than an independent state."
(In reply to Thomas Sondergaard from comment #2) > > FWIW, if you add _NET_WM_STATE_HIDDEN to your initial _NET_WM_STATE it behaves as you intend. > > This goes against the netwm-spec which says "Implementation note: if an > Application asks to toggle _NET_WM_STATE_HIDDEN the Window Manager should > probably just ignore the request, since _NET_WM_STATE_HIDDEN is a function > of some other aspect of the window such as minimization, rather than an > independent state." "Implementation note" and "should probably" isn't what I'd consider proper specification... in any case I think that note doesn't apply to the initial _NET_WM_STATE when the window is mapped, in that case _NET_WM_STATE should be honored by the WM: "The Window Manager SHOULD honor _NET_WM_STATE whenever a withdrawn window requests to be mapped." By toggling I think the note is talking about the application changing _NET_WM_STATE after the window is mapped via the client message to the root window mechanism.
(In reply to Rui Matos from comment #3) > "Implementation note" and "should probably" isn't what I'd consider proper > specification... Hard to disagree with. > in any case I think that note doesn't apply to the initial > _NET_WM_STATE when the window is mapped, in that case _NET_WM_STATE should > be honored by the WM: > > "The Window Manager SHOULD honor _NET_WM_STATE whenever a withdrawn window > requests to be mapped." > > By toggling I think the note is talking about the application changing > _NET_WM_STATE after the window is mapped via the client message to the root > window mechanism. I'm not a WM developer, but that is not how I understood the text. I interpret the first part that the WM should remember to respect _NET_WM_STATE upon mapping, but for _NET_WM_STATE_HIDDEN it says "should be set by the Window Manager". I've dug through some of the popular GUI toolkits to see what they do: Qt 4 and 5 don't set _NET_WM_STATE_HIDDEN before mapping a minimized window. It uses WM_HINTS initial_state = IconicState. gtk's gdk_window_x11_show()/set_initial_hints() does indeed set _NET_WM_STATE_HIDDEN in _NET_WM_STATE and it also sets WM_HINTS initial_state = IconicState. efl explicitly doesn't set _NET_WM_STATE_HIDDEN in _ecore_evas_x_state_update - it is commented out, so it is visible that it is not omitted by error.
(In reply to Thomas Sondergaard from comment #4) > (In reply to Rui Matos from comment #3) > > "Implementation note" and "should probably" isn't what I'd consider proper > > specification... > > Hard to disagree with. > > > in any case I think that note doesn't apply to the initial > > _NET_WM_STATE when the window is mapped, in that case _NET_WM_STATE should > > be honored by the WM: > > > > "The Window Manager SHOULD honor _NET_WM_STATE whenever a withdrawn window > > requests to be mapped." > > > > By toggling I think the note is talking about the application changing > > _NET_WM_STATE after the window is mapped via the client message to the root > > window mechanism. > > I'm not a WM developer, but that is not how I understood the text. I > interpret the first part that the WM should remember to respect > _NET_WM_STATE upon mapping, but for _NET_WM_STATE_HIDDEN it says "should be > set by the Window Manager". This is how I interpret it too. The description of _NET_WM_STATE_HIDDEN in wm-spec starts off as "Should be set by the WM". Given no other state has this remark, I think it's pretty clear this is WM domain. One question for you, Thomas. What mutter version did you test with? (In reply to Rui Matos from comment #1) > The interactions between WM_HINTS and _NET_WM_STATE regarding minimization > aren't at all clear unfortunately, but it seems that released versions of > mutter don't behave well indeed. Hmm, if I'm reading the bug correctly, I don't think this involves WM hints as much, but _NET_WM_STATE alone. Isn't the problem here that mutter is resetting state set by the client when setting the _NET_WM_STATE_HIDDEN state for itself? > > In master, after bug 774333, it seems we behave a little better but your > test case here still doesn't do what you want, i.e. after that patch from > bug 774333, the window is initially maximized but not minimized at all. Hmm, that's what I'd expect to happen though? I mean, window/hints creation and mapping are just an XFlush() away in the given testcase. I however fail to see how would this patch 1) be involved here and 2) actually help for the testcase :(. > FWIW, if you add _NET_WM_STATE_HIDDEN to your initial _NET_WM_STATE it > behaves as you intend. > > At this point, I'm wondering if we should revert bug 774333 and label it as > an issue that wine should deal with. Carlos? Hmm, what can they do though? they're requesting to map a window in IconicState, which is the ICCCM observed way to go from iconic to normal state. If we keep it minimized, it's arguably us who are not following it.
(In reply to Carlos Garnacho from comment #5) > > I'm not a WM developer, but that is not how I understood the text. I > > interpret the first part that the WM should remember to respect > > _NET_WM_STATE upon mapping, but for _NET_WM_STATE_HIDDEN it says "should be > > set by the Window Manager". > > This is how I interpret it too. The description of _NET_WM_STATE_HIDDEN in > wm-spec starts off as "Should be set by the WM". Given no other state has > this remark, I think it's pretty clear this is WM domain. > > One question for you, Thomas. What mutter version did you test with? I tested with the default gnome desktop session under Fedora 25 (non-wayland). I don't see a mutter process running, but I do have a gnome-session process. It is my understanding that gnome-session uses mutter internally. These are the versions that I have: mutter-3.22.2-3.fc25.x86_64 gnome-session-3.22.2-3.fc25.x86_64 > > (In reply to Rui Matos from comment #1) > > The interactions between WM_HINTS and _NET_WM_STATE regarding minimization > > aren't at all clear unfortunately, but it seems that released versions of > > mutter don't behave well indeed. > > Hmm, if I'm reading the bug correctly, I don't think this involves WM hints > as much, but _NET_WM_STATE alone. Isn't the problem here that mutter is > resetting state set by the client when setting the _NET_WM_STATE_HIDDEN > state for itself? Yes, exactly. When the WM sets _NET_WM_STATE_HIDDEN in _NET_WM_STATE after/when the window is mapped, the state set by the client is removed.
Created attachment 344333 [details] [review] window: Fix mapping of maximized windows that are initially iconic Mapping a window with initial iconic state set in WM_HINTS makes us set window->minimized on creation. Later, when calculating whether the window should be shown we force its placement in order to e.g. be able to show the window in the correct monitor on the overview (introduced in commit 3716c302649d1c0e2f34a62cb167bef620a12f7c). But since window->minimized is true, we don't actually place it in place_window_if_needed() which means we don't honor NET_WM_STATE in case it requests maximization. One way to fix this would be removing the !window->minimized condition in place_window_if_needed(). But that condition was added in commit 07e4cacf14874746453c1c4818122e899bdc4159 which introduced a way for windows to be minimized after placement when NET_WM_STATE includes _NET_WM_STATE_HIDDEN. This means, we can instead fix this issue by making initial iconic state set in WM_HINTS behave the same way as_NET_WM_STATE_HIDDEN by setting window->minimize_after_placement which results in the window being placed and then both maximized and minimized.
(In reply to Carlos Garnacho from comment #5) > > At this point, I'm wondering if we should revert bug 774333 and label it as > > an issue that wine should deal with. Carlos? > > Hmm, what can they do though? they're requesting to map a window in > IconicState, which is the ICCCM observed way to go from iconic to normal > state. If we keep it minimized, it's arguably us who are not following it. I don't follow you here. We get MapRequest for a window which happens to contain IconicState in WM_HINTS.initial_state. This seems to me like a clear request for the window to start minimized. With the patch we merged in bug 774333 we immediately unminimize such a window which seems to go against the ICCCM: "The value of the initial_state field determines the state the client wishes to be in at the time the top-level window is mapped from the Withdrawn state"
GNOME is going to shut down bugzilla.gnome.org in favor of gitlab.gnome.org. As part of that, we are mass-closing older open tickets in bugzilla.gnome.org which have not seen updates for a longer time (resources are unfortunately quite limited so not every ticket can get handled). If you can still reproduce the situation described in this ticket in a recent and supported software version, then please follow https://wiki.gnome.org/GettingInTouch/BugReportingGuidelines and create a new ticket at https://gitlab.gnome.org/GNOME/mutter/-/issues/ Thank you for your understanding and your help.