]> Dogcows Code - chaz/openbox/blobdiff - src/client.cc
set the desktop number before the number of desktops
[chaz/openbox] / src / client.cc
index e9418cb34a8dc5bb31abe8c8af88b0f094cc32ad..2f8cfe8d7efb7dfb769c3e5cfeebc7f879824a1f 100644 (file)
@@ -58,8 +58,8 @@ Client::Client(int screen, Window window)
   getDesktop();
 
   updateTransientFor();
-  getType();
   getMwmHints();
+  getType(); // this can change the mwmhints for special cases
 
   getState();
   getShaped();
@@ -188,9 +188,12 @@ void Client::getType()
         _type = Type_Dialog;
       else if (val[i] == otk::Property::atoms.net_wm_window_type_normal)
         _type = Type_Normal;
-//    XXX: make this work again
-//    else if (val[i] == otk::Property::atoms.kde_net_wm_window_type_override)
-//      mwm_decorations = 0; // prevent this window from getting any decor
+      else if (val[i] == otk::Property::atoms.kde_net_wm_window_type_override){
+        // prevent this window from getting any decor or functionality
+        _mwmhints.flags &= MwmFlag_Functions | MwmFlag_Decorations;
+        _mwmhints.decorations = 0;
+        _mwmhints.functions = 0;
+      }
       if (_type != (WindowType) -1)
         break; // grab the first known type
     }
@@ -481,9 +484,6 @@ void Client::updateNormalHints()
   _min_size.setPoint(0, 0);
   _max_size.setPoint(INT_MAX, INT_MAX);
 
-  // XXX: might want to cancel any interactive resizing of the window at this
-  // point..
-
   // get the hints from the window
   if (XGetWMNormalHints(**otk::display, _window, &size, &ret)) {
     _positioned = (size.flags & (PPosition|USPosition));
@@ -495,7 +495,7 @@ void Client::updateNormalHints()
       // changing its gravity
       if (frame && _gravity != oldgravity) {
         // move our idea of the client's position based on its new gravity
-        int x, y;
+        int x = frame->rect().x(), y = frame->rect().y();
         frame->frameGravity(x, y);
         _area.setPos(x, y);
       }
@@ -679,8 +679,6 @@ void Client::updateTransientFor()
     _transient_for = c;
     if (_transient_for)
       _transient_for->_transients.push_back(this); // add to new parent
-
-    // XXX: change decor status?
   }
 }
 
@@ -841,7 +839,6 @@ void Client::setState(StateAction action, long data1, long data2)
       } else if (state == otk::Property::atoms.net_wm_state_maximized_horz) {
         if (_max_horz) continue;
         maxh = true;
-        // XXX: resize the window etc
       } else if (state == otk::Property::atoms.net_wm_state_shaded) {
         shadestate = true;
       } else if (state == otk::Property::atoms.net_wm_state_skip_taskbar) {
@@ -895,7 +892,7 @@ void Client::setState(StateAction action, long data1, long data2)
       if (maxh != _max_horz)
         maximize(maxh, 1, true);
       else
-        maximize(maxv, 1, true);
+        maximize(maxv, 2, true);
     }
   }
   // change fullscreen state before shading, as it will affect if the window
@@ -1071,12 +1068,19 @@ void Client::internal_resize(Corner anchor, int w, int h, bool user,
   w -= _base_size.x(); 
   h -= _base_size.y();
 
-  // for interactive resizing. have to move half an increment in each
-  // direction.
-  w += _size_inc.x() / 2;
-  h += _size_inc.y() / 2;
-
   if (user) {
+    // for interactive resizing. have to move half an increment in each
+    // direction.
+    int mw = w % _size_inc.x(); // how far we are towards the next size inc
+    int mh = h % _size_inc.y();
+    int aw = _size_inc.x() / 2; // amount to add
+    int ah = _size_inc.y() / 2;
+    // don't let us move into a new size increment
+    if (mw + aw >= _size_inc.x()) aw = _size_inc.x() - mw - 1;
+    if (mh + ah >= _size_inc.y()) ah = _size_inc.y() - mh - 1;
+    w += aw;
+    h += ah;
+    
     // if this is a user-requested resize, then check against min/max sizes
     // and aspect ratios
 
@@ -1142,6 +1146,8 @@ void Client::internal_resize(Corner anchor, int w, int h, bool user,
 void Client::move(int x, int y)
 {
   if (!(_functions & Func_Move)) return;
+  frame->frameGravity(x, y); // get the client's position based on x,y for the
+                             // frame
   internal_move(x, y);
 }
 
@@ -1277,6 +1283,22 @@ void Client::changeAllowedActions(void)
 }
 
 
+void Client::remaximize()
+{
+  int dir;
+  if (_max_horz && _max_vert)
+    dir = 0;
+  else if (_max_horz)
+    dir = 1;
+  else if (_max_vert)
+    dir = 2;
+  else
+    return; // not maximized
+  _max_horz = _max_vert = false;
+  maximize(true, dir, false);
+}
+
+
 void Client::applyStartupState()
 {
   // these are in a carefully crafted order..
@@ -1353,21 +1375,39 @@ void Client::maximize(bool max, int dir, bool savearea)
     if (dir == 2 && !_max_vert) return;
   }
 
-  int g = _gravity;
-  
   const otk::Rect &a = openbox->screen(_screen)->area();
-  int x = _area.x(), y = _area.y(), w = _area.width(), h = _area.height();
+  int x = frame->rect().x(), y = frame->rect().y(),
+    w = _area.width(), h = _area.height();
   
   if (max) {
-    // when maximizing, put the client where we want, NOT the frame!
-    _gravity = StaticGravity;
-
     if (savearea) {
       long dimensions[4];
+      long *readdim;
+      unsigned long n = 4;
+
       dimensions[0] = x;
       dimensions[1] = y;
       dimensions[2] = w;
       dimensions[3] = h;
+
+      // get the property off the window and use it for the dimentions we are
+      // already maxed on
+      if (otk::Property::get(_window, otk::Property::atoms.openbox_premax,
+                             otk::Property::atoms.cardinal, &n,
+                             (long unsigned**) &readdim)) {
+        if (n >= 4) {
+          if (_max_horz) {
+            dimensions[0] = readdim[0];
+            dimensions[2] = readdim[2];
+          }
+          if (_max_vert) {
+            dimensions[1] = readdim[1];
+            dimensions[3] = readdim[3];
+          }
+        }
+        delete readdim;
+      }
+      
       otk::Property::set(_window, otk::Property::atoms.openbox_premax,
                          otk::Property::atoms.cardinal,
                          (long unsigned*)dimensions, 4);
@@ -1377,7 +1417,7 @@ void Client::maximize(bool max, int dir, bool savearea)
       w = a.width();
     }
     if (dir == 0 || dir == 2) { // vert
-      y = a.y() + frame->size().top;
+      y = a.y();
       h = a.height() - frame->size().top - frame->size().bottom;
     }
   } else {
@@ -1409,26 +1449,20 @@ void Client::maximize(bool max, int dir, bool savearea)
         h = a.height() / 2;
       }
     }
-    otk::Property::erase(_window, otk::Property::atoms.openbox_premax);
   }
 
   if (dir == 0 || dir == 1) // horz
     _max_horz = max;
   if (dir == 0 || dir == 2) // vert
     _max_vert = max;
+
+  if (!_max_horz && !_max_vert)
+    otk::Property::erase(_window, otk::Property::atoms.openbox_premax);
+
   changeState(); // change the state hints on the client
 
+  frame->frameGravity(x, y); // figure out where the client should be going
   internal_resize(TopLeft, w, h, true, x, y);
-  printf("before x %d y %d w %d h %d\n", x, y, w, h);
-  _gravity = g;
-  if (max) {
-    // because of my little gravity trick in here, we have to set the position
-    // of the client to what it really is
-    int x, y;
-    frame->frameGravity(x, y);
-    _area.setPos(x, y);
-    printf("after x %d y %d w %d h %d\n", x, y, w, h);
-  }
 }
 
 
@@ -1514,6 +1548,21 @@ void Client::disableDecorations(DecorationFlags flags)
 }
 
 
+bool Client::focusModalChild()
+{
+  // find a modal child recursively and try focus it
+  List::iterator it, end = _transients.end();
+  for (it = _transients.begin(); it != end; ++it)
+    if ((*it)->focusModalChild())
+      return true; // got one
+  // none of our grand-children are modal, try our direct children
+  for (it = _transients.begin(); it != end; ++it)
+    if ((*it)->modal() && (*it)->focus())
+      return true; // got one
+  return false;
+}
+
+
 bool Client::focus()
 {
   // won't try focus if the client doesn't want it, or if the window isn't
@@ -1522,6 +1571,10 @@ bool Client::focus()
 
   if (_focused) return true;
 
+  if (!_modal)
+    if (focusModalChild())
+      return true;
+
   // 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)
This page took 0.02933 seconds and 4 git commands to generate.