]> Dogcows Code - chaz/openbox/commitdiff
transient window support..halfway
authorDana Jansens <danakj@orodu.net>
Sun, 5 Jan 2003 01:40:38 +0000 (01:40 +0000)
committerDana Jansens <danakj@orodu.net>
Sun, 5 Jan 2003 01:40:38 +0000 (01:40 +0000)
src/bindings.cc
src/client.cc
src/client.hh
src/openbox.i
src/openbox_wrap.cc
src/screen.cc
src/screen.hh

index 77c1dcf848e6d00a2ea88e6be4ff37c8d9ee4453..6a135b6d6821a94c4e2b812741529371af171730 100644 (file)
@@ -410,7 +410,7 @@ bool OBBindings::addButton(const std::string &but, MouseContext context,
     // grab the button on all clients
     for (int sn = 0; sn < Openbox::instance->screenCount(); ++sn) {
       OBScreen *s = Openbox::instance->screen(sn);
-      OBScreen::ClientList::iterator c_it, c_end = s->clients.end();
+      OBClient::List::iterator c_it, c_end = s->clients.end();
       for (c_it = s->clients.begin(); c_it != c_end; ++c_it) {
         grabButton(true, bind->binding, context, *c_it);
       }
@@ -435,7 +435,7 @@ void OBBindings::removeAllButtons()
       // ungrab the button on all clients
       for (int sn = 0; sn < Openbox::instance->screenCount(); ++sn) {
         OBScreen *s = Openbox::instance->screen(sn);
-        OBScreen::ClientList::iterator c_it, c_end = s->clients.end();
+        OBClient::List::iterator c_it, c_end = s->clients.end();
         for (c_it = s->clients.begin(); c_it != c_end; ++c_it) {
           grabButton(false, (*it)->binding, (MouseContext)i, *c_it);
         }
index 7b846729e86a60ddc313f32e1e235533edec8dcd..8c259db3ca3d66e8a4e5e821b62883b5b7f64c85 100644 (file)
@@ -41,12 +41,16 @@ OBClient::OBClient(int screen, Window window)
   _decorations = _functions = 0;
   // start unfocused
   _focused = false;
+  // not a transient by default of course
+  _transient_for = 0;
   
   getArea();
   getDesktop();
-  // XXX: updateTransientFor();
+  updateTransientFor();
   getType();
 
+  // XXX: changeAllowedActions();
+
   // set the decorations and functions
   _decorations = Decor_Titlebar | Decor_Handle | Decor_Border |
     Decor_Iconify | Decor_Maximize;
@@ -171,10 +175,9 @@ void OBClient::getType()
      * the window type hint was not set, which means we either classify ourself
      * as a normal window or a dialog, depending on if we are a transient.
      */
-    // XXX: make this code work!
-    //if (isTransient())
-    //  _type = Type_Dialog;
-    //else
+    if (_transient_for)
+      _type = Type_Dialog;
+    else
       _type = Type_Normal;
   }
 }
@@ -315,16 +318,16 @@ void OBClient::getShaped()
 
 
 void OBClient::calcLayer() {
-  if (_iconic) _layer = OBScreen::Layer_Icon;
-  else if (_fullscreen) _layer = OBScreen::Layer_Fullscreen;
-  else if (_type == Type_Desktop) _layer = OBScreen::Layer_Desktop;
+  if (_iconic) _layer = Layer_Icon;
+  else if (_fullscreen) _layer = Layer_Fullscreen;
+  else if (_type == Type_Desktop) _layer = Layer_Desktop;
   else if (_type == Type_Dock) {
-    if (!_below) _layer = OBScreen::Layer_Top;
-    else _layer = OBScreen::Layer_Normal;
+    if (!_below) _layer = Layer_Top;
+    else _layer = Layer_Normal;
   }
-  else if (_above) _layer = OBScreen::Layer_Above;
-  else if (_below) _layer = OBScreen::Layer_Below;
-  else _layer = OBScreen::Layer_Normal;
+  else if (_above) _layer = Layer_Above;
+  else if (_below) _layer = Layer_Below;
+  else _layer = Layer_Normal;
 }
 
 
@@ -521,6 +524,41 @@ void OBClient::updateStrut()
 }
 
 
+void OBClient::updateTransientFor()
+{
+  Window t = 0;
+  OBClient *c = 0;
+
+  if (XGetTransientForHint(otk::OBDisplay::display, _window, &t) &&
+      t != _window) { // cant be transient to itself!
+    c = Openbox::instance->findClient(t);
+    assert(c != this); // if this happens then we need to check for it
+
+    if (!c /*XXX: && _group*/) {
+      // not transient to a client, see if it is transient for a group
+      if (//t == _group->leader() ||
+        t == None ||
+        t == otk::OBDisplay::screenInfo(_screen)->rootWindow()) {
+        // window is a transient for its group!
+        // XXX: for now this is treated as non-transient.
+        //      this needs to be fixed!
+      }
+    }
+  }
+
+  // if anything has changed...
+  if (c != _transient_for) {
+    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
+
+    // XXX: change decor status?
+  }
+}
+
+
 void OBClient::propertyHandler(const XPropertyEvent &e)
 {
   otk::OtkEventHandler::propertyHandler(e);
@@ -542,6 +580,8 @@ void OBClient::propertyHandler(const XPropertyEvent &e)
     updateNormalHints();
   else if (e.atom == XA_WM_HINTS)
     updateWMHints();
+  else if (e.atom == XA_WM_TRANSIENT_FOR)
+    updateTransientFor();
   else if (e.atom == property->atom(otk::OBProperty::net_wm_name) ||
            e.atom == property->atom(otk::OBProperty::wm_name))
     updateTitle();
@@ -552,10 +592,8 @@ void OBClient::propertyHandler(const XPropertyEvent &e)
     updateClass();
   else if (e.atom == property->atom(otk::OBProperty::wm_protocols))
     updateProtocols();
-  // XXX: transient for hint
   else if (e.atom == property->atom(otk::OBProperty::net_wm_strut))
     updateStrut();
-  // XXX: strut hint
 }
 
 
@@ -563,7 +601,8 @@ void OBClient::setWMState(long state)
 {
   if (state == _wmstate) return; // no change
   
-  switch (state) {
+  _wmstate = state;
+  switch (_wmstate) {
   case IconicState:
     // XXX: cause it to iconify
     break;
@@ -571,7 +610,6 @@ void OBClient::setWMState(long state)
     // XXX: cause it to uniconify
     break;
   }
-  _wmstate = state;
 }
 
 
index 724cf5189ae23919436a42d43923834d4f4cc5b2..1726ce4415dec8de1103a465f46f8c41a0db01f4 100644 (file)
@@ -7,6 +7,12 @@
   property changes on the window and some client messages
 */
 
+#include "widget.hh"
+#include "otk/point.hh"
+#include "otk/strut.hh"
+#include "otk/rect.hh"
+#include "otk/eventhandler.hh"
+
 extern "C" {
 #include <X11/Xlib.h>
 
@@ -16,13 +22,7 @@ extern "C" {
 }
 
 #include <string>
-
-#include "screen.hh"
-#include "widget.hh"
-#include "otk/point.hh"
-#include "otk/strut.hh"
-#include "otk/rect.hh"
-#include "otk/eventhandler.hh"
+#include <list>
 
 namespace ob {
 
@@ -41,7 +41,6 @@ struct MwmHints {
   unsigned long decorations;//!< A bitmask of OBClient::MwmDecorations values
 };
 
-
 //! Maintains the state of a client window.
 /*!
   OBClient maintains the state of a client window. The state consists of the
@@ -63,6 +62,22 @@ public:
   */
   OBFrame *frame;
 
+  //! Holds a list of OBClients
+  typedef std::list<OBClient*> List;
+
+  //! The possible stacking layers a client window can be a part of
+  enum StackLayer {
+    Layer_Icon,       //!< 0 - iconified windows, in any order at all
+    Layer_Desktop,    //!< 1 - desktop windows
+    Layer_Below,      //!< 2 - normal windows w/ below
+    Layer_Normal,     //!< 3 - normal windows
+    Layer_Above,      //!< 4 - normal windows w/ above
+    Layer_Top,        //!< 5 - always-on-top-windows (docks?)
+    Layer_Fullscreen, //!< 6 - fullscreeen windows
+    Layer_Internal,   //!< 7 - openbox windows/menus
+    NUM_LAYERS
+  };
+
   //! Corners of the client window, used for anchor positions
   enum Corner { TopLeft,
                 TopRight,
@@ -157,7 +172,11 @@ private:
   //! The id of the group the window belongs to
   Window   _group;
 
-  // XXX: transient_for, transients
+  //! The client which this client is a transient (child) for
+  OBClient *_transient_for;
+
+  //! The clients which are transients (children) of this client
+  OBClient::List _transients;
 
   //! The desktop on which the window resides (0xffffffff for all desktops)
   unsigned long _desktop;
@@ -272,7 +291,7 @@ private:
   //! The window should be underneath other windows of the same type
   bool _below;
 
-  OBScreen::StackLayer _layer;
+  StackLayer _layer;
 
   //! A bitmask of values in the OBClient::Decoration enum
   /*!
@@ -327,9 +346,10 @@ private:
   void updateIconTitle();
   //! Updates the window's application name and class
   void updateClass();
-  // XXX: updateTransientFor();
   //! Updates the strut for the client
   void updateStrut();
+  //! Updates the window's transient status, and any parents of it
+  void updateTransientFor();
 
   //! Change the client's state hints to match the class' data
   void changeState();
@@ -435,7 +455,7 @@ public:
   //! Returns if the window is maximized horizontally
   inline bool maxHorz() const { return _max_horz; }
   //! Returns the window's stacking layer
-  inline OBScreen::StackLayer layer() const { return _layer; }
+  inline StackLayer layer() const { return _layer; }
 
   //! Removes or reapplies the client's border to its window
   /*!
index 1b2275689471bb768f9f6a34943284c30b19b617..508b678cf990274fb188d3bf4ae8e057ad41dc8d 100644 (file)
@@ -32,7 +32,7 @@
   OBClient *client(int i) {
     if (i >= (int)self->clients.size())
       return NULL;
-    ob::OBScreen::ClientList::iterator it = self->clients.begin();
+    ob::OBClient::List::iterator it = self->clients.begin();
     std::advance(it,i);
     return *it;
   }
index 6f2697067c41ca24ccf50ea694e42f0b0f8b7507..8201bb762890dbabd67b7943377044d3c68c83cc 100644 (file)
@@ -783,7 +783,7 @@ static std::string SwigString_AsString(PyObject* o) {
 ob::OBClient *ob_OBScreen_client(ob::OBScreen *self,int i){
     if (i >= (int)self->clients.size())
       return NULL;
-    ob::OBScreen::ClientList::iterator it = self->clients.begin();
+    ob::OBClient::List::iterator it = self->clients.begin();
     std::advance(it,i);
     return *it;
   }
@@ -2911,16 +2911,16 @@ static swig_const_info swig_const_table[] = {
 { SWIG_PY_INT,     (char *)"Openbox_State_Normal", (long) ob::Openbox::State_Normal, 0, 0, 0},
 { SWIG_PY_INT,     (char *)"Openbox_State_Exiting", (long) ob::Openbox::State_Exiting, 0, 0, 0},
 { SWIG_PY_INT,     (char *)"OBScreen_event_mask", (long) ob::OBScreen::event_mask, 0, 0, 0},
-{ SWIG_PY_INT,     (char *)"OBScreen_Layer_Icon", (long) ob::OBScreen::Layer_Icon, 0, 0, 0},
-{ SWIG_PY_INT,     (char *)"OBScreen_Layer_Desktop", (long) ob::OBScreen::Layer_Desktop, 0, 0, 0},
-{ SWIG_PY_INT,     (char *)"OBScreen_Layer_Below", (long) ob::OBScreen::Layer_Below, 0, 0, 0},
-{ SWIG_PY_INT,     (char *)"OBScreen_Layer_Normal", (long) ob::OBScreen::Layer_Normal, 0, 0, 0},
-{ SWIG_PY_INT,     (char *)"OBScreen_Layer_Above", (long) ob::OBScreen::Layer_Above, 0, 0, 0},
-{ SWIG_PY_INT,     (char *)"OBScreen_Layer_Top", (long) ob::OBScreen::Layer_Top, 0, 0, 0},
-{ SWIG_PY_INT,     (char *)"OBScreen_Layer_Fullscreen", (long) ob::OBScreen::Layer_Fullscreen, 0, 0, 0},
-{ SWIG_PY_INT,     (char *)"OBScreen_Layer_Internal", (long) ob::OBScreen::Layer_Internal, 0, 0, 0},
-{ SWIG_PY_INT,     (char *)"OBScreen_NUM_LAYERS", (long) ob::OBScreen::NUM_LAYERS, 0, 0, 0},
 { SWIG_PY_INT,     (char *)"MwmHints_elements", (long) ob::MwmHints::elements, 0, 0, 0},
+{ SWIG_PY_INT,     (char *)"OBClient_Layer_Icon", (long) ob::OBClient::Layer_Icon, 0, 0, 0},
+{ SWIG_PY_INT,     (char *)"OBClient_Layer_Desktop", (long) ob::OBClient::Layer_Desktop, 0, 0, 0},
+{ SWIG_PY_INT,     (char *)"OBClient_Layer_Below", (long) ob::OBClient::Layer_Below, 0, 0, 0},
+{ SWIG_PY_INT,     (char *)"OBClient_Layer_Normal", (long) ob::OBClient::Layer_Normal, 0, 0, 0},
+{ SWIG_PY_INT,     (char *)"OBClient_Layer_Above", (long) ob::OBClient::Layer_Above, 0, 0, 0},
+{ SWIG_PY_INT,     (char *)"OBClient_Layer_Top", (long) ob::OBClient::Layer_Top, 0, 0, 0},
+{ SWIG_PY_INT,     (char *)"OBClient_Layer_Fullscreen", (long) ob::OBClient::Layer_Fullscreen, 0, 0, 0},
+{ SWIG_PY_INT,     (char *)"OBClient_Layer_Internal", (long) ob::OBClient::Layer_Internal, 0, 0, 0},
+{ SWIG_PY_INT,     (char *)"OBClient_NUM_LAYERS", (long) ob::OBClient::NUM_LAYERS, 0, 0, 0},
 { SWIG_PY_INT,     (char *)"OBClient_TopLeft", (long) ob::OBClient::TopLeft, 0, 0, 0},
 { SWIG_PY_INT,     (char *)"OBClient_TopRight", (long) ob::OBClient::TopRight, 0, 0, 0},
 { SWIG_PY_INT,     (char *)"OBClient_BottomLeft", (long) ob::OBClient::BottomLeft, 0, 0, 0},
index 8ea1b49ea8a0432f48bf86ed50278a9434cbb880..307404ffce87aa48629f585a7b271100367f8880 100644 (file)
@@ -196,7 +196,7 @@ void OBScreen::updateStrut()
 {
   _strut.left = _strut.right = _strut.top = _strut.bottom = 0;
 
-  ClientList::iterator it, end = clients.end();
+  OBClient::List::iterator it, end = clients.end();
   for (it = clients.begin(); it != end; ++it) {
     const otk::Strut &s = (*it)->strut();
     _strut.left = std::max(_strut.left, s.left);
@@ -364,8 +364,8 @@ void OBScreen::setClientList()
     
     windows = new Window[size];
     win_it = windows;
-    ClientList::const_iterator it = clients.begin();
-    const ClientList::const_iterator end = clients.end();
+    OBClient::List::const_iterator it = clients.begin();
+    const OBClient::List::const_iterator end = clients.end();
     for (; it != end; ++it, ++win_it)
       *win_it = (*it)->window();
   } else
@@ -397,8 +397,8 @@ void OBScreen::setStackingList()
     
     windows = new Window[size];
     win_it = windows;
-    ClientList::const_iterator it = _stacking.begin();
-    const ClientList::const_iterator end = _stacking.end();
+    OBClient::List::const_iterator it = _stacking.begin();
+    const OBClient::List::const_iterator end = _stacking.end();
     for (; it != end; ++it, ++win_it)
       *win_it = (*it)->window();
   } else
@@ -547,7 +547,7 @@ void OBScreen::unmanageWindow(OBClient *client)
   // pass around focus if this window was focused XXX do this better!
   if (Openbox::instance->focusedClient() == client) {
     OBClient *newfocus = 0;
-    ClientList::iterator it, end = _stacking.end();
+    OBClient::List::iterator it, end = _stacking.end();
     for (it = _stacking.begin(); it != end; ++it)
       if ((*it)->normal() && (*it)->focus()) {
         newfocus = *it;
@@ -604,7 +604,7 @@ void OBScreen::restack(bool raise, OBClient *client)
 
   // the stacking list is from highest to lowest
   
-  ClientList::iterator it = _stacking.begin(), end = _stacking.end();
+  OBClient::List::iterator it = _stacking.begin(), end = _stacking.end();
   // insert the windows above this window
   for (; it != end; ++it) {
     if ((*it)->layer() < layer || (raise && (*it)->layer() == layer))
index cb078082a28be8ef906389efa9700c278ecaf0ba..e57ab2edbcb679ce87313144f9ca0afeae6ed561 100644 (file)
@@ -10,6 +10,7 @@ extern "C" {
 #include <X11/Xlib.h>
 }
 
+#include "client.hh"
 #include "rootwindow.hh"
 #include "otk/image.hh"
 #include "otk/strut.hh"
@@ -29,8 +30,6 @@ class OBRootWindow;
 */
 class OBScreen {
 public:
-  //! Holds a list of OBClient objects
-  typedef std::list<OBClient*> ClientList;
   //! Holds a list of otk::Strut objects
   typedef std::list<otk::Strut*> StrutList;
 
@@ -43,20 +42,8 @@ public:
                                           ButtonPressMask |
                                           ButtonReleaseMask;
 
-  enum StackLayer {
-    Layer_Icon,       // 0 - iconified windows, in any order at all
-    Layer_Desktop,    // 1 - desktop windows
-    Layer_Below,      // 2 - normal windows w/ below
-    Layer_Normal,     // 3 - normal windows
-    Layer_Above,      // 4 - normal windows w/ above
-    Layer_Top,        // 5 - always-on-top-windows (docks?)
-    Layer_Fullscreen, // 6 - fullscreeen windows
-    Layer_Internal,   // 7 - openbox windows/menus
-    NUM_LAYERS
-  };
-
   //! All managed clients on the screen (in order of being mapped)
-  ClientList clients;
+  OBClient::List clients;
   
 private:
   //! Was %Openbox able to manage the screen?
@@ -94,7 +81,7 @@ private:
   Window _supportwindow;
 
   //! A list of all managed clients on the screen, in their stacking order
-  ClientList _stacking;
+  OBClient::List _stacking;
 
   //! Calculate the OBScreen::_area member
   void calcArea();
This page took 0.040122 seconds and 4 git commands to generate.