]> Dogcows Code - chaz/openbox/blobdiff - src/client.cc
add an app to display the icons for a window
[chaz/openbox] / src / client.cc
index 254345730a84e9bbf1c22dbb9b6113a139303d6a..33e11ce07e1e596621acb3c61fe5070e8feabc38 100644 (file)
@@ -44,7 +44,6 @@ Client::Client(int screen, Window window)
   _urgent = false;
   _positioned = false;
   _disabled_decorations = 0;
-  _modal_child = 0;
   _group = None;
   _desktop = 0;
   
@@ -639,7 +638,7 @@ void Client::updateStrut()
     // updating here is pointless while we're being mapped cuz we're not in
     // the screen's client list yet
     if (frame)
-      openbox->screen(_screen)->updateStrut();
+      openbox->screen(_screen)->updateStruts();
   }
 
   delete [] data;
@@ -670,18 +669,11 @@ void Client::updateTransientFor()
 
   // if anything has changed...
   if (c != _transient_for) {
-    bool m = _modal;
-    if (_modal)
-      setModal(false);
-    
     if (_transient_for)
       _transient_for->_transients.remove(this); // remove from old parent
     _transient_for = c;
     if (_transient_for)
       _transient_for->_transients.push_back(this); // add to new parent
-
-    if (m)
-      setModal(true);
   }
 }
 
@@ -738,111 +730,51 @@ void Client::setWMState(long state)
   
   switch (state) {
   case IconicState:
-    setDesktop(ICONIC_DESKTOP);
+    iconify(true);
     break;
   case NormalState:
-    setDesktop(openbox->screen(_screen)->desktop());
+    iconify(false);
     break;
   }
 }
 
 
-void Client::setDesktop(long target)
+void Client::setDesktop(unsigned int target)
 {
   if (target == _desktop) return;
   
-  printf("Setting desktop %ld\n", target);
+  printf("Setting desktop %u\n", target);
 
-  if (!(target >= 0 || target == (signed)0xffffffff ||
-        target == ICONIC_DESKTOP))
+  if (!(target < openbox->screen(_screen)->numDesktops() ||
+        target == 0xffffffff))
     return;
-  
+
   _desktop = target;
 
-  // set the desktop hint, but not if we're iconifying
-  if (_desktop != ICONIC_DESKTOP)
-    otk::Property::set(_window, otk::Property::atoms.net_wm_desktop,
-                       otk::Property::atoms.cardinal, (unsigned)_desktop);
+  // set the desktop hint
+  otk::Property::set(_window, otk::Property::atoms.net_wm_desktop,
+                     otk::Property::atoms.cardinal, _desktop);
   
   // 'move' the window to the new desktop
-  if (_desktop == openbox->screen(_screen)->desktop() ||
-      _desktop == (signed)0xffffffff)
-    frame->show();
-  else
-    frame->hide();
-
-  // Handle Iconic state. Iconic state is maintained by the client being a
-  // member of the ICONIC_DESKTOP, so this is where we make iconifying and
-  // uniconifying happen.
-  bool i = _desktop == ICONIC_DESKTOP;
-  if (i != _iconic) { // has the state changed?
-    _iconic = i;
-    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 {
-      _wmstate = NormalState;
-      XMapWindow(**otk::display, _window);
-    }
-    changeState();
-  }
-  
-  frame->adjustState();
+  showhide();
+
+  openbox->screen(_screen)->updateStruts();
 }
 
 
-Client *Client::findModalChild(Client *skip) const
+void Client::showhide()
 {
-  Client *ret = 0;
-  
-  // find a modal child recursively and try focus it
-  List::const_iterator it, end = _transients.end();
-  for (it = _transients.begin(); it != end; ++it)
-    if ((*it)->_modal && *it != skip)
-      return *it; // got one
-  // none of our direct children are modal, let them try check
-  for (it = _transients.begin(); it != end; ++it)
-    if ((ret = (*it)->findModalChild()))
-      return ret; // got one
-  return ret;
-}
+  bool show;
+  Screen *s = openbox->screen(_screen);
 
+  if (_iconic) show = false;
+  else if (!(_desktop == s->desktop() ||
+             _desktop == 0xffffffff)) show = false;
+  else if (normal() && s->showingDesktop()) show = false;
+  else show = true;
 
-void Client::setModal(bool modal)
-{
-  if (modal == _modal) return;
-  
-  if (modal) {
-    Client *c = this;
-    while (c->_transient_for) {
-      c = c->_transient_for;
-      if (c == this) break; // circular?
-      if (c->_modal_child) break; // already has a modal child
-      c->_modal_child = this;
-    }
-  } else {
-    // try find a replacement modal dialog
-    Client *replacement = 0;
-    
-    Client *c = this;
-    while (c->_transient_for) // go up the tree
-      c = c->_transient_for;
-    replacement = c->findModalChild(this); // find a modal child, skipping this
-    assert(replacement != this);
-
-    c = this;
-    while (c->_transient_for) {
-      c = c->_transient_for;
-      if (c == this) break; // circular?
-      if (c->_modal_child != this) break; // has a different modal child
-      if (c == replacement) break; // found the replacement itself
-      c->_modal_child = replacement;
-    }
-  }
-  _modal = modal;
+  if (show) frame->show();
+  else      frame->hide();
 }
 
 
@@ -852,7 +784,6 @@ void Client::setState(StateAction action, long data1, long data2)
   bool fsstate = _fullscreen;
   bool maxh = _max_horz;
   bool maxv = _max_vert;
-  bool modal = _modal;
 
   if (!(action == State_Add || action == State_Remove ||
         action == State_Toggle))
@@ -888,7 +819,7 @@ void Client::setState(StateAction action, long data1, long data2)
     if (action == State_Add) {
       if (state == otk::Property::atoms.net_wm_state_modal) {
         if (_modal) continue;
-        modal = true;
+        _modal = true;
       } else if (state == otk::Property::atoms.net_wm_state_maximized_vert) {
         maxv = true;
       } else if (state == otk::Property::atoms.net_wm_state_maximized_horz) {
@@ -913,7 +844,7 @@ void Client::setState(StateAction action, long data1, long data2)
     } else { // action == State_Remove
       if (state == otk::Property::atoms.net_wm_state_modal) {
         if (!_modal) continue;
-        modal = false;
+        _modal = false;
       } else if (state == otk::Property::atoms.net_wm_state_maximized_vert) {
         maxv = false;
       } else if (state == otk::Property::atoms.net_wm_state_maximized_horz) {
@@ -950,8 +881,6 @@ void Client::setState(StateAction action, long data1, long data2)
         maximize(maxv, 2, true);
     }
   }
-  if (modal != _modal)
-    setModal(modal);
   // change fullscreen state before shading, as it will affect if the window
   // can shade or not
   if (fsstate != _fullscreen)
@@ -1088,15 +1017,23 @@ void Client::clientMessageHandler(const XClientMessageEvent &e)
 #ifdef DEBUG
     printf("net_active_window for 0x%lx\n", _window);
 #endif
+    if (openbox->screen(_screen)->showingDesktop())
+      openbox->screen(_screen)->showDesktop(false);
     if (_iconic)
-      setDesktop(openbox->screen(_screen)->desktop());
+      iconify(false);
+    else if (!frame->visible()) // if its not visible for other reasons, then
+      return;                   // don't mess with it
     if (_shaded)
       shade(false);
     focus();
     openbox->screen(_screen)->raiseWindow(this);
   } else if (e.message_type == otk::Property::atoms.openbox_active_window) {
+    if (openbox->screen(_screen)->showingDesktop())
+      openbox->screen(_screen)->showDesktop(false);
     if (_iconic)
-      setDesktop(openbox->screen(_screen)->desktop());
+      iconify(false);
+    else if (!frame->visible()) // if its not visible for other reasons, then
+      return;                   // don't mess with it
     if (e.data.l[0] && _shaded)
       shade(false);
     focus();
@@ -1149,10 +1086,10 @@ void Client::internal_resize(Corner anchor, int w, int h,
     // and aspect ratios
 
     // smaller than min size or bigger than max size?
+    if (w > _max_size.width()) w = _max_size.width();
     if (w < _min_size.width()) w = _min_size.width();
-    else if (w > _max_size.width()) w = _max_size.width();
+    if (h > _max_size.height()) h = _max_size.height();
     if (h < _min_size.height()) h = _min_size.height();
-    else if (h > _max_size.height()) h = _max_size.height();
 
     // adjust the height ot match the width for the aspect ratios
     if (_min_ratio)
@@ -1382,14 +1319,9 @@ void Client::applyStartupState()
 {
   // these are in a carefully crafted order..
 
-  if (_modal) {
-    _modal = false;
-    setModal(true);
-  }
-  
   if (_iconic) {
     _iconic = false;
-    setDesktop(ICONIC_DESKTOP);
+    iconify(true);
   }
   if (_fullscreen) {
     _fullscreen = false;
@@ -1459,7 +1391,7 @@ void Client::maximize(bool max, int dir, bool savearea)
     if (dir == 2 && !_max_vert) return;
   }
 
-  const otk::Rect &a = openbox->screen(_screen)->area();
+  const otk::Rect &a = openbox->screen(_screen)->area(_desktop);
   int x = frame->area().x(), y = frame->area().y(),
     w = _area.width(), h = _area.height();
   
@@ -1604,7 +1536,7 @@ void Client::fullscreen(bool fs, bool savearea)
       delete dimensions;
     } else {
       // pick some fallbacks...
-      const otk::Rect &a = openbox->screen(_screen)->area();
+      const otk::Rect &a = openbox->screen(_screen)->area(_desktop);
       x = a.x() + a.width() / 4;
       y = a.y() + a.height() / 4;
       w = a.width() / 2;
@@ -1625,6 +1557,36 @@ void Client::fullscreen(bool fs, bool savearea)
 }
 
 
+void Client::iconify(bool iconic, bool curdesk)
+{
+  if (_iconic == iconic) return; // nothing to do
+
+#ifdef DEBUG
+    printf("%sconifying window: 0x%lx\n", (iconic ? "I" : "Uni"), _window);
+#endif
+
+  _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;
@@ -1644,11 +1606,32 @@ void Client::installColormap(bool install) const
 }
 
 
+// recursively searches the client 'tree' for a modal client, always skips the
+// topmost node (the window you're starting with)
+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
-  if (_modal_child)
-    return _modal_child->focus();
+  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
@@ -1896,7 +1879,7 @@ void Client::mapRequestHandler(const XMapRequestEvent &e)
   assert(_iconic); // we shouldn't be able to get this unless we're iconic
 
   // move to the current desktop (uniconify)
-  setDesktop(openbox->screen(_screen)->desktop());
+  iconify(false);
   // XXX: should we focus/raise the window? (basically a net_wm_active_window)
 }
 
This page took 0.027616 seconds and 4 git commands to generate.