]> Dogcows Code - chaz/openbox/commitdiff
keep track of transients. however not group transients yet
authorDana Jansens <danakj@orodu.net>
Sun, 5 Jan 2003 02:24:27 +0000 (02:24 +0000)
committerDana Jansens <danakj@orodu.net>
Sun, 5 Jan 2003 02:24:27 +0000 (02:24 +0000)
src/client.cc
src/client.hh

index 8c259db3ca3d66e8a4e5e821b62883b5b7f64c85..b4015aae63227c877d492dffac86f4cb03d87799 100644 (file)
@@ -46,44 +46,13 @@ OBClient::OBClient(int screen, Window window)
   
   getArea();
   getDesktop();
+
   updateTransientFor();
   getType();
+  getMwmHints();
 
-  // XXX: changeAllowedActions();
-
-  // set the decorations and functions
-  _decorations = Decor_Titlebar | Decor_Handle | Decor_Border |
-    Decor_Iconify | Decor_Maximize;
-  _functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
-  switch (_type) {
-  case Type_Normal:
-    // normal windows retain all of the possible decorations and
-    // functionality
-
-  case Type_Dialog:
-    // dialogs cannot be maximized
-    _decorations &= ~Decor_Maximize;
-    _functions &= ~Func_Maximize;
-    break;
-
-  case Type_Menu:
-  case Type_Toolbar:
-  case Type_Utility:
-    // these windows get less functionality
-    _decorations &= ~(Decor_Iconify | Decor_Handle);
-    _functions &= ~(Func_Iconify | Func_Resize);
-    break;
-
-  case Type_Desktop:
-  case Type_Dock:
-  case Type_Splash:
-    // none of these windows are manipulated by the window manager
-    _decorations = 0;
-    _functions = 0;
-    break;
-  }
+  setupDecorAndFunctions();
   
-  getMwmHints(); // this fucks (in good ways) with the decors and functions
   getState();
   getShaped();
 
@@ -95,7 +64,6 @@ OBClient::OBClient(int screen, Window window)
   updateClass();
   updateStrut();
 
-  calcLayer();
   changeState();
 }
 
@@ -183,57 +151,99 @@ void OBClient::getType()
 }
 
 
-void OBClient::getMwmHints()
+void OBClient::setupDecorAndFunctions()
 {
-  const otk::OBProperty *property = Openbox::instance->property();
+  // start with everything
+  _decorations = Decor_Titlebar | Decor_Handle | Decor_Border |
+    Decor_Iconify | Decor_Maximize;
+  _functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
+  
+  switch (_type) {
+  case Type_Normal:
+    // normal windows retain all of the possible decorations and
+    // functionality
 
-  unsigned long num;
-  MwmHints *hints;
+  case Type_Dialog:
+    // dialogs cannot be maximized
+    _decorations &= ~Decor_Maximize;
+    _functions &= ~Func_Maximize;
+    break;
 
-  num = MwmHints::elements;
-  if (!property->get(_window, otk::OBProperty::motif_wm_hints,
-                     otk::OBProperty::motif_wm_hints, &num,
-                     (unsigned long **)&hints))
-    return;
-  
-  if (num < MwmHints::elements) {
-    delete [] hints;
-    return;
+  case Type_Menu:
+  case Type_Toolbar:
+  case Type_Utility:
+    // these windows get less functionality
+    _decorations &= ~(Decor_Iconify | Decor_Handle);
+    _functions &= ~(Func_Iconify | Func_Resize);
+    break;
+
+  case Type_Desktop:
+  case Type_Dock:
+  case Type_Splash:
+    // none of these windows are manipulated by the window manager
+    _decorations = 0;
+    _functions = 0;
+    break;
   }
 
-  // retrieved the hints
   // Mwm Hints are applied subtractively to what has already been chosen for
   // decor and functionality
-
-  if (hints->flags & MwmFlag_Decorations) {
-    if (! (hints->decorations & MwmDecor_All)) {
-      if (! (hints->decorations & MwmDecor_Border))
+  if (_mwmhints.flags & MwmFlag_Decorations) {
+    if (! (_mwmhints.decorations & MwmDecor_All)) {
+      if (! (_mwmhints.decorations & MwmDecor_Border))
         _decorations &= ~Decor_Border;
-      if (! (hints->decorations & MwmDecor_Handle))
+      if (! (_mwmhints.decorations & MwmDecor_Handle))
         _decorations &= ~Decor_Handle;
-      if (! (hints->decorations & MwmDecor_Title))
+      if (! (_mwmhints.decorations & MwmDecor_Title))
         _decorations &= ~Decor_Titlebar;
-      if (! (hints->decorations & MwmDecor_Iconify))
+      if (! (_mwmhints.decorations & MwmDecor_Iconify))
         _decorations &= ~Decor_Iconify;
-      if (! (hints->decorations & MwmDecor_Maximize))
+      if (! (_mwmhints.decorations & MwmDecor_Maximize))
         _decorations &= ~Decor_Maximize;
     }
   }
 
-  if (hints->flags & MwmFlag_Functions) {
-    if (! (hints->functions & MwmFunc_All)) {
-      if (! (hints->functions & MwmFunc_Resize))
+  if (_mwmhints.flags & MwmFlag_Functions) {
+    if (! (_mwmhints.functions & MwmFunc_All)) {
+      if (! (_mwmhints.functions & MwmFunc_Resize))
         _functions &= ~Func_Resize;
-      if (! (hints->functions & MwmFunc_Move))
+      if (! (_mwmhints.functions & MwmFunc_Move))
         _functions &= ~Func_Move;
-      if (! (hints->functions & MwmFunc_Iconify))
+      if (! (_mwmhints.functions & MwmFunc_Iconify))
         _functions &= ~Func_Iconify;
-      if (! (hints->functions & MwmFunc_Maximize))
+      if (! (_mwmhints.functions & MwmFunc_Maximize))
         _functions &= ~Func_Maximize;
-      //if (! (hints->functions & MwmFunc_Close))
+      // dont let mwm hints kill the close button
+      //if (! (_mwmhints.functions & MwmFunc_Close))
       //  _functions &= ~Func_Close;
     }
   }
+
+  // XXX: changeAllowedActions();
+}
+
+
+void OBClient::getMwmHints()
+{
+  const otk::OBProperty *property = Openbox::instance->property();
+
+  unsigned long num = MwmHints::elements;
+  unsigned long *hints;
+
+  _mwmhints.flags = 0; // default to none
+  
+  if (!property->get(_window, otk::OBProperty::motif_wm_hints,
+                     otk::OBProperty::motif_wm_hints, &num,
+                     (unsigned long **)&hints))
+    return;
+  
+  if (num == MwmHints::elements) {
+    // retrieved the hints
+    _mwmhints.flags = hints[0];
+    _mwmhints.functions = hints[1];
+    _mwmhints.decorations = hints[2];
+  }
+
   delete [] hints;
 }
 
@@ -318,16 +328,29 @@ void OBClient::getShaped()
 
 
 void OBClient::calcLayer() {
-  if (_iconic) _layer = Layer_Icon;
-  else if (_fullscreen) _layer = Layer_Fullscreen;
-  else if (_type == Type_Desktop) _layer = Layer_Desktop;
+  StackLayer l;
+
+  if (_iconic) l = Layer_Icon;
+  else if (_fullscreen) l = Layer_Fullscreen;
+  else if (_type == Type_Desktop) l = Layer_Desktop;
   else if (_type == Type_Dock) {
-    if (!_below) _layer = Layer_Top;
-    else _layer = Layer_Normal;
+    if (!_below) l = Layer_Top;
+    else l = Layer_Normal;
+  }
+  else if (_above) l = Layer_Above;
+  else if (_below) l = Layer_Below;
+  else l = Layer_Normal;
+
+  if (l != _layer) {
+    _layer = l;
+    if (frame) {
+      /*
+        if we don't have a frame, then we aren't mapped yet (and this would
+        SIGSEGV :)
+      */
+      Openbox::instance->screen(_screen)->restack(true, this); // raise
+    }
   }
-  else if (_above) _layer = Layer_Above;
-  else if (_below) _layer = Layer_Below;
-  else _layer = Layer_Normal;
 }
 
 
@@ -580,8 +603,12 @@ void OBClient::propertyHandler(const XPropertyEvent &e)
     updateNormalHints();
   else if (e.atom == XA_WM_HINTS)
     updateWMHints();
-  else if (e.atom == XA_WM_TRANSIENT_FOR)
+  else if (e.atom == XA_WM_TRANSIENT_FOR) {
     updateTransientFor();
+    getType();
+    calcLayer(); // type may have changed, so update the layer
+    setupDecorAndFunctions();
+  }
   else if (e.atom == property->atom(otk::OBProperty::net_wm_name) ||
            e.atom == property->atom(otk::OBProperty::wm_name))
     updateTitle();
@@ -627,7 +654,7 @@ void OBClient::setDesktop(long target)
 void OBClient::setState(StateAction action, long data1, long data2)
 {
   const otk::OBProperty *property = Openbox::instance->property();
-  bool restack = false, shadestate = _shaded;
+  bool shadestate = _shaded;
 
   if (!(action == State_Add || action == State_Remove ||
         action == State_Toggle))
@@ -695,17 +722,14 @@ void OBClient::setState(StateAction action, long data1, long data2)
                  property->atom(otk::OBProperty::net_wm_state_fullscreen)) {
         if (_fullscreen) continue;
         _fullscreen = true;
-        restack = false;
       } else if (state ==
                  property->atom(otk::OBProperty::net_wm_state_above)) {
         if (_above) continue;
         _above = true;
-        restack = true;
       } else if (state ==
                  property->atom(otk::OBProperty::net_wm_state_below)) {
         if (_below) continue;
         _below = true;
-        restack = true;
       }
 
     } else { // action == State_Remove
@@ -737,26 +761,20 @@ void OBClient::setState(StateAction action, long data1, long data2)
                  property->atom(otk::OBProperty::net_wm_state_fullscreen)) {
         if (!_fullscreen) continue;
         _fullscreen = false;
-        restack = true;
       } else if (state ==
                  property->atom(otk::OBProperty::net_wm_state_above)) {
         if (!_above) continue;
         _above = false;
-        restack = true;
       } else if (state ==
                  property->atom(otk::OBProperty::net_wm_state_below)) {
         if (!_below) continue;
         _below = false;
-        restack = true;
       }
     }
   }
   if (shadestate != _shaded)
     shade(shadestate);
-  if (restack) {
-    calcLayer();
-    Openbox::instance->screen(_screen)->restack(true, this); // raise
-  }
+  calcLayer();
 }
 
 
@@ -1011,7 +1029,8 @@ void OBClient::changeState()
     netstate[num++] = property->atom(otk::OBProperty::net_wm_state_below);
   property->set(_window, otk::OBProperty::net_wm_state,
                 otk::OBProperty::Atom_Atom, netstate, num);
-  
+
+  calcLayer();
 }
 
 
@@ -1027,8 +1046,6 @@ void OBClient::setStackLayer(int l)
     _below = true;  // below
   }
   changeState();
-  calcLayer();
-  Openbox::instance->screen(_screen)->restack(true, this); // raise
 }
 
 
index 1726ce4415dec8de1103a465f46f8c41a0db01f4..963cff52ea8525f68d5f804ddf70c01dd60deade 100644 (file)
@@ -34,11 +34,11 @@ class OBFrame;
   structure contains 5. We only use the first 3, so that is all gets defined.
 */
 struct MwmHints {
-  //! The number of elements in the OBClient::MwmHints struct
-  static const unsigned int elements = 3;
   unsigned long flags;      //!< A bitmask of OBClient::MwmFlags values
   unsigned long functions;  //!< A bitmask of OBClient::MwmFunctions values
   unsigned long decorations;//!< A bitmask of OBClient::MwmDecorations values
+  //! The number of elements in the OBClient::MwmHints struct
+  static const unsigned int elements = 3;
 };
 
 //! Maintains the state of a client window.
@@ -246,6 +246,9 @@ private:
   */
   otk::Point _base_size;
 
+  //! Window decoration and functionality hints
+  MwmHints _mwmhints;
+  
   //! Where to place the decorated window in relation to the undecorated window
   int _gravity;
 
@@ -323,6 +326,13 @@ private:
   //! OBClient::_shaped
   void getShaped();
 
+  //! Set up what decor should be shown on the window and what functions should
+  //! be allowed (OBClient::_decorations and OBClient::_functions).
+  /*!
+    This also updates the NET_WM_ALLOWED_ACTIONS hint.
+  */
+  void setupDecorAndFunctions();
+  
   //! Sets the wm_state to the specified value
   void setWMState(long state);
   //! Sends the window to the specified desktop
This page took 0.035729 seconds and 4 git commands to generate.