GNOME Bugzilla – Bug 450055
Mapping a previously iconified window restores the window
Last modified: 2007-06-30 17:01:13 UTC
Consider the following sequence of actions: 1. A window is mapped. 2. The window is iconified. 3. The window is unmapped. 4. The window gets mapped again In this scenario it is expected that after step #4 the window is still shown in iconified state (i.e. just the button on the taskbar is expected to be shown, not the window itself). Indeed, implementing this scenario works perfectly while run on KDE or CDE (dtwm). However, running such a scenario on a GNOME system with Metacity WM brings the window back in restored state after the step #4. We feel it is a bug in Metacity WM. The following test case demonstrates the problem. Run the test, if the window is finally shown in iconified state, the bug is NOT reproduced, but if the window is shown in NORMAL state, the bug IS reproduced then. #include <X11/X.h> #include <X11/Xlib.h> #include <X11/Xos.h> #include <X11/Xutil.h> #include <stdio.h> Display *display; int screen_num; Window root; Window create_window(char * name, int x, int y, int width, int height) { XSizeHints sh; XWMHints wmh; Window win = XCreateSimpleWindow(display, root, x, y, width, height, 2, // border width BlackPixel(display, screen_num), WhitePixel(display, screen_num)); XStoreName(display, win, name); XSelectInput(display, win, ButtonPressMask | KeyPressMask); sh.width = width; sh.height = height; sh.x = x; sh.y = y; sh.flags = USPosition | USSize; XSetWMNormalHints(display, win, &sh); return win; } int main(int argc, char **argv) { Window f1; XEvent ev; XButtonEvent bev; int i, k; char *display_name = NULL; if ((display = XOpenDisplay(display_name)) == NULL) { fprintf(stderr, "Couldn't open %s\n", XDisplayName(display_name)); return -1; } screen_num = DefaultScreen(display); root = RootWindow(display, screen_num); f1 = create_window("Frame 1", 100, 100, 200, 200); // Show in NORMAL state XMapWindow(display, f1); XFlush(display); XSync(display, False); // Iconify XIconifyWindow(display, f1, 0); XFlush(display); XSync(display, False); // Hide the window XUnmapWindow(display, f1); XFlush(display); XSync(display, False); // Restore back... // An iconified window is expected to be shown on the taskbar. XMapWindow(display, f1); XFlush(display); XSync(display, False); while (1) { XNextEvent(display, &ev); if (ev.type == ButtonPress) { fprintf(stderr, "Hello, world!\n"); exit(0); } } }
ICCCM quote: Newly created top-level windows are in the Withdrawn state. Once the window has been provided with suitable properties, the client is free to change its state as follows: Withdrawn -> Normal - The client should map the window with WM_HINTS.initial_state being NormalState . Withdrawn -> Iconic - The client should map the window with WM_HINTS.initial_state being IconicState . Normal -> Iconic - The client should send a ClientMessage event as described later in this section. Normal -> Withdrawn - The client should unmap the window and follow it with a synthetic UnmapNotify event as described later in this section. Iconic -> Normal - The client should map the window. The contents of WM_HINTS.initial_state are irrelevant in this case. Iconic -> Withdrawn - The client should unmap the window and follow it with a synthetic UnmapNotify event as described later in this section.
The test code does four things: - maps window, Withdrawn -> Normal - sends iconify client message, Normal -> Iconic * Note that this should cause metacity to unmap the window - makes an Unmap request, which does nothing (metacity already unmapped as part of the iconification. If it had not, then this unmap would result in withdrawing the window. If the client wants to reliably withdraw, a synthetic UnmapNotify is required as well as the real one, to handle the already-unmapped case - use XWithdrawWindow() instead of XUnmapWindow()) - makes a Map request, which should trigger Iconic->Normal per the ICCCM as quoted above if the window is in Iconic state. If the window had been successfully withdrawn, then this would go back to the NormalState or IconicState depending on WM_HINTS.initial_state as set by the client during the withdraw. This seems right to me...
If the window had been withdrawn in step 3, then this would be bug 360900 (metacity ignores the iconic state for windows leaving the withdrawn state).
Yes, thanks for the point. Our software actually does set the WM_HINTS.initial_state property to IconicState just before mapping the window. I'm sorry that I provided you with incomplete test case. (Though I wonder that even the provided test case lacking the WM_HINTS.initial_state setting works pretty well on other window managers. Why?) Taking this into account, I confirm that this bug is actually a duplicate of bug 440691 filed by me, that in turn is a duplicate of bug 360900. Is it possible to somehow slightly rise the priority of the latter one, as it is now the second time when we run into it? Thanks in advance!
Yeah, I'll bump the priority on the bug. Sorry for the inconvenience. *** This bug has been marked as a duplicate of 360900 ***