6

I've managed to iconify a window using XIconifyWindow, but haven't managed to later restore it. I tried the following:

XMapRaised (display, window);

And:

XMapWindow (display, window);

And:

XClientMessageEvent ev;
std::memset (&ev, 0, sizeof ev);
ev.type = ClientMessage;
ev.window = window;
ev.message_type = XInternAtom(display, "WM_CHANGE_STATE", False);
ev.format = 32;
ev.data.l[0] = NormalState;
XSendEvent (display, RootWindow(display, XDefaultScreen(display)), False,
  SubstructureRedirectMask |SubstructureNotifyMask, (XEvent*)&ev);
XFlush (display);

To no success. I'm using Debian Jessie with GNOME 3.14.0.

Yaron Cohen-Tal
  • 2,005
  • 1
  • 15
  • 26
  • Have you tried sending a `WM_CHANGE_STATE` message with data element of `NormalState`? (Though I would have assumed that `XMapRaised` would have un-iconified the window correctly are you sure you flushed the calls/waited for the server? Have you also made sure that you called that on the correct toplevel window and didn't leave an ancestor iconified/withdrawn?) – Etan Reisner May 12 '15 at 13:58
  • No, but now I've tried it and unfortunately it doesn't work. I have only one window so obviously it's top-level. I also tried to add "XFlush" without success. I hope I don't have to use WM-specific code eventually. – Yaron Cohen-Tal May 12 '15 at 14:30
  • Can you post the relevant portions of your code here? Including the various attempts you've made? – Etan Reisner May 12 '15 at 14:40
  • @Etan: Sure, I've editted my post and added code snippets. – Yaron Cohen-Tal May 12 '15 at 19:47
  • And you called `XIconifyWindow(display, window)` on identical values for `display` and `window`? – Etan Reisner May 12 '15 at 19:49
  • @Etan: Yes, that's true. – Yaron Cohen-Tal May 12 '15 at 20:20

1 Answers1

7

After a lot of stuggles, finally solved!

In GNOME 3, windows have no "iconify/minimize" button. It appears that a window can't be minimized, neither by the user nor from code. When I called XIconifyWindow, the window wasn't minimized. If it had been minimized, I'd have gotten an "UnmapNotify" event, which I didn't. What did happen is, the window was hidden (" _NET_WM_STATE_HIDDEN" was added to the window's "_NET_WM_STATE" property), and another window was activated. So all I had to do to "unminimize" the window was to activate it:

XClientMessageEvent ev;
std::memset (&ev, 0, sizeof ev);
ev.type = ClientMessage;
ev.window = window;
ev.message_type = XInternAtom(display, "_NET_ACTIVE_WINDOW", True);
ev.format = 32;
ev.data.l[0] = 1;
ev.data.l[1] = CurrentTime;
ev.data.l[2] = ev.data.l[3] = ev.data.l[4] = 0;
XSendEvent (display, RootWindow(display, XDefaultScreen(display)), False,
  SubstructureRedirectMask |SubstructureNotifyMask, (XEvent*)&ev);
XFlush (display);

Btw calling XRaiseWindow instead didn't work, it seems like it had to be activated.

Yaron Cohen-Tal
  • 2,005
  • 1
  • 15
  • 26
  • Nicely found. That seems a bit broken to me though. Sending `_NET_ACTIVE_WINDOW` is different then "unhiding" a window (though it should unhide a window) but it also implies a request for that window becoming the active window (which may or may not actually be desired). I would have expected that `XMapRaised` or similar would have worked but possibly not. And I'm not seeing anything obvious in the wm-spec for how to undo `HIDDEN`. – Etan Reisner May 15 '15 at 12:39