]> Dogcows Code - chaz/openbox/blobdiff - src/client.cc
add DONT_DUPLICATE option
[chaz/openbox] / src / client.cc
index 68653c31f462a8a3e007f466f789fe186102b268..091b095e64767bcccf13ca9d7c9af98109667235 100644 (file)
@@ -1,8 +1,6 @@
 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
 
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#endif
+#include "config.h"
 
 #include "client.hh"
 #include "frame.hh"
@@ -29,7 +27,6 @@ namespace ob {
 
 Client::Client(int screen, Window window)
   : otk::EventHandler(),
-    WidgetBase(WidgetBase::Type_Client),
     frame(0), _screen(screen), _window(window)
 {
   assert(screen >= 0);
@@ -47,7 +44,6 @@ Client::Client(int screen, Window window)
   _urgent = false;
   _positioned = false;
   _disabled_decorations = 0;
-  _modal_child = 0;
   _group = None;
   _desktop = 0;
   
@@ -481,7 +477,7 @@ void Client::updateNormalHints()
   _size_inc = otk::Size(1, 1);
   _base_size = otk::Size(0, 0);
   _min_size = otk::Size(0, 0);
-  _max_size = otk::Size(UINT_MAX, UINT_MAX);
+  _max_size = otk::Size(INT_MAX, INT_MAX);
 
   // get the hints from the window
   if (XGetWMNormalHints(**otk::display, _window, &size, &ret)) {
@@ -581,7 +577,7 @@ void Client::updateTitle()
     _title = _("Unnamed Window");
 
   if (frame)
-    frame->setTitle(_title);
+    frame->adjustTitle();
 }
 
 
@@ -673,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);
   }
 }
 
@@ -797,61 +786,12 @@ void Client::setDesktop(long target)
 }
 
 
-Client *Client::findModalChild(Client *skip) const
-{
-  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;
-}
-
-
-void Client::setModal(bool modal)
-{
-  if (modal == _modal) return;
-  
-  if (modal) {
-    Client *c = this;
-    while (c->_transient_for) {
-      c = c->_transient_for;
-      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
-
-    c = this;
-    while (c->_transient_for) {
-      c = c->_transient_for;
-      if (c->_modal_child != this) break; // has a different modal child
-      c->_modal_child = replacement;
-    }
-  }
-  _modal = modal;
-}
-
-
 void Client::setState(StateAction action, long data1, long data2)
 {
   bool shadestate = _shaded;
   bool fsstate = _fullscreen;
   bool maxh = _max_horz;
   bool maxv = _max_vert;
-  bool modal = _modal;
 
   if (!(action == State_Add || action == State_Remove ||
         action == State_Toggle))
@@ -887,7 +827,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) {
@@ -912,7 +852,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) {
@@ -949,8 +889,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)
@@ -1118,27 +1056,26 @@ void Client::shapeHandler(const XShapeEvent &e)
 #endif
 
 
-void Client::resize(Corner anchor, unsigned int w, unsigned int h)
+void Client::resize(Corner anchor, int w, int h)
 {
   if (!(_functions & Func_Resize)) return;
   internal_resize(anchor, w, h);
 }
 
 
-void Client::internal_resize(Corner anchor, unsigned int w, unsigned int h,
+void Client::internal_resize(Corner anchor, int w, int h,
                              bool user, int x, int y)
 {
-  w -= _base_size.width(); 
+  w -= _base_size.width();
   h -= _base_size.height();
 
   if (user) {
     // for interactive resizing. have to move half an increment in each
     // direction.
-    unsigned int mw = w % _size_inc.width(); // how far we are towards the next
-                                             // size inc
-    unsigned int mh = h % _size_inc.height();
-    unsigned int aw = _size_inc.width() / 2; // amount to add
-    unsigned int ah = _size_inc.height() / 2;
+    int mw = w % _size_inc.width(); // how far we are towards the next size inc
+    int mh = h % _size_inc.height();
+    int aw = _size_inc.width() / 2; // amount to add
+    int ah = _size_inc.height() / 2;
     // don't let us move into a new size increment
     if (mw + aw >= _size_inc.width()) aw = _size_inc.width() - mw - 1;
     if (mh + ah >= _size_inc.height()) ah = _size_inc.height() - mh - 1;
@@ -1149,10 +1086,10 @@ void Client::internal_resize(Corner anchor, unsigned int w, unsigned 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,11 +1319,6 @@ void Client::applyStartupState()
 {
   // these are in a carefully crafted order..
 
-  if (_modal) {
-    _modal = false;
-    setModal(true);
-  }
-  
   if (_iconic) {
     _iconic = false;
     setDesktop(ICONIC_DESKTOP);
@@ -1644,11 +1576,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
@@ -1714,8 +1667,8 @@ void Client::focusHandler(const XFocusChangeEvent &e)
   
   otk::EventHandler::focusHandler(e);
 
-  frame->focus();
   _focused = true;
+  frame->adjustFocus();
 
   openbox->setFocusedClient(this);
 }
@@ -1729,26 +1682,29 @@ void Client::unfocusHandler(const XFocusChangeEvent &e)
   
   otk::EventHandler::unfocusHandler(e);
 
-  frame->unfocus();
   _focused = false;
+  frame->adjustFocus();
 
   if (openbox->focusedClient() == this)
     openbox->setFocusedClient(0);
 }
 
 
-void Client::configureRequestHandler(const XConfigureRequestEvent &e)
+void Client::configureRequestHandler(const XConfigureRequestEvent &ec)
 {
 #ifdef    DEBUG
-  printf("ConfigureRequest for 0x%lx\n", e.window);
+  printf("ConfigureRequest for 0x%lx\n", ec.window);
 #endif // DEBUG
   
-  otk::EventHandler::configureRequestHandler(e);
+  otk::EventHandler::configureRequestHandler(ec);
 
   // compress these
+  XConfigureRequestEvent e = ec;
   XEvent ev;
   while (XCheckTypedWindowEvent(**otk::display, window(), ConfigureRequest,
                                 &ev)) {
+    // XXX if this causes bad things.. we can compress config req's with the
+    //     same mask.
     e.value_mask |= ev.xconfigurerequest.value_mask;
     if (ev.xconfigurerequest.value_mask & CWX)
       e.x = ev.xconfigurerequest.x;
This page took 0.031768 seconds and 4 git commands to generate.