+ _iconic = iconic;
+
+ if (_iconic) {
+ _wmstate = IconicState;
+ ignore_unmaps++;
+ // we unmap the client itself so that we can get MapRequest events, and
+ // because the ICCCM tells us to!
+ XUnmapWindow(**otk::display, _window);
+ } else {
+ if (curdesk)
+ setDesktop(openbox->screen(_screen)->desktop());
+ _wmstate = NormalState;
+ XMapWindow(**otk::display, _window);
+ }
+ changeState();
+ showhide();
+ openbox->screen(_screen)->updateStruts();
+}
+
+void Client::disableDecorations(DecorationFlags flags)
+{
+ _disabled_decorations = flags;
+ setupDecorAndFunctions();
+}
+
+void Client::installColormap(bool install) const
+{
+ XWindowAttributes wa;
+ if (XGetWindowAttributes(**otk::display, _window, &wa)) {
+ if (install)
+ XInstallColormap(**otk::display, wa.colormap);
+ else
+ XUninstallColormap(**otk::display, wa.colormap);
+ }
+}
+
+Client *Client::searchModalTree(Client *node, Client *skip)
+{
+ List::const_iterator it, end = node->_transients.end();
+ Client *ret;
+
+ for (it = node->_transients.begin(); it != end; ++it) {
+ if (*it == skip) continue; // circular?
+ if ((ret = searchModalTree(*it, skip))) return ret; // got one
+ if ((*it)->_modal) return *it; // got one
+ }
+ return 0;
+}
+
+Client *Client::findModalChild()
+{
+ return searchModalTree(this, this);
+}
+
+
+bool Client::focus()
+{
+ // if we have a modal child, then focus it, not us
+ Client *c = findModalChild();
+ if (c) return c->focus();
+
+ // won't try focus if the client doesn't want it, or if the window isn't
+ // visible on the screen
+ if (!(frame->visible() && (_can_focus || _focus_notify))) return false;
+
+ // do a check to see if the window has already been unmapped or destroyed
+ // do this intelligently while watching out for unmaps we've generated
+ // (ignore_unmaps > 0)
+ XEvent ev;
+ if (XCheckTypedWindowEvent(**otk::display, _window, DestroyNotify, &ev)) {
+ XPutBackEvent(**otk::display, &ev);
+ return false;
+ }
+ while (XCheckTypedWindowEvent(**otk::display, _window, UnmapNotify, &ev)) {
+ if (ignore_unmaps) {
+ unmapHandler(ev.xunmap);
+ } else {
+ XPutBackEvent(**otk::display, &ev);
+ return false;
+ }
+ }
+
+ if (_can_focus)
+ XSetInputFocus(**otk::display, _window,
+ RevertToNone, CurrentTime);
+
+ if (_focus_notify) {
+ XEvent ce;
+ ce.xclient.type = ClientMessage;
+ ce.xclient.message_type = otk::Property::atoms.wm_protocols;
+ ce.xclient.display = **otk::display;
+ ce.xclient.window = _window;
+ ce.xclient.format = 32;
+ ce.xclient.data.l[0] = otk::Property::atoms.wm_take_focus;
+ ce.xclient.data.l[1] = openbox->lastTime();
+ ce.xclient.data.l[2] = 0l;
+ ce.xclient.data.l[3] = 0l;
+ ce.xclient.data.l[4] = 0l;
+ XSendEvent(**otk::display, _window, False, NoEventMask, &ce);
+ }
+
+ XSync(**otk::display, False);
+ return true;
+}
+
+
+void Client::unfocus() const
+{
+ assert(openbox->focusedClient() == this);
+ openbox->setFocusedClient(0);
+}
+
+
+void Client::focusHandler(const XFocusChangeEvent &e)