[PATCH] window raise/lower improvement

ManMower manmower at is.fuckingabitch.com
Thu Jan 16 13:56:18 EST 2003


This patch replaces restack() with raiseWindow() and lowerWindow()

the focus window becomes our perpetual topmost window that we never raise
above.  this allows us to do all raises and lowers with only a 2 window
array passed to XRestackWindows.

this should eliminate all flicker when raising windows, and increase the
speed of both raise/lower operations.
-------------- next part --------------
Index: scripts/builtins.py
===================================================================
RCS file: /cvs/cvsroot/openbox/scripts/builtins.py,v
retrieving revision 1.39
diff -p -u -r1.39 builtins.py
--- scripts/builtins.py	2003/01/16 09:12:07	1.39
+++ scripts/builtins.py	2003/01/16 18:34:10
@@ -93,12 +93,12 @@ def restart(data, other = ""):
 def raise_win(data):
     """Raises the window on which the event occured"""
     if not data.client: return
-    openbox.screen(data.screen).restack(1, data.client)
+    openbox.screen(data.screen).raiseWindow(data.client)
 
 def lower_win(data):
     """Lowers the window on which the event occured"""
     if not data.client: return
-    openbox.screen(data.screen).restack(0, data.client)
+    openbox.screen(data.screen).lowerWindow(data.client)
 
 def toggle_shade(data):
     """Toggles the shade status of the window on which the event occured"""
Index: src/client.cc
===================================================================
RCS file: /cvs/cvsroot/openbox/src/client.cc,v
retrieving revision 1.89
diff -p -u -r1.89 client.cc
--- src/client.cc	2003/01/16 08:44:52	1.89
+++ src/client.cc	2003/01/16 18:34:11
@@ -339,7 +339,7 @@ void Client::calcLayer() {
         if we don't have a frame, then we aren't mapped yet (and this would
         SIGSEGV :)
       */
-      openbox->screen(_screen)->restack(true, this); // raise
+      openbox->screen(_screen)->raiseWindow(this);
     }
   }
 }
@@ -856,7 +856,7 @@ void Client::clientMessageHandler(const 
       shade(false);
     // XXX: deiconify
     focus();
-    openbox->screen(_screen)->restack(true, this); // raise
+    openbox->screen(_screen)->raiseWindow(this);
   }
 }
 
@@ -1165,13 +1165,13 @@ void Client::configureRequestHandler(con
     switch (e.detail) {
     case Below:
     case BottomIf:
-      openbox->screen(_screen)->restack(false, this); // lower
+      openbox->screen(_screen)->lowerWindow(this);
       break;
 
     case Above:
     case TopIf:
     default:
-      openbox->screen(_screen)->restack(true, this); // raise
+      openbox->screen(_screen)->raiseWindow(this);
       break;
     }
   }
Index: src/openbox.py
===================================================================
RCS file: /cvs/cvsroot/openbox/src/openbox.py,v
retrieving revision 1.11
diff -p -u -r1.11 openbox.py
--- src/openbox.py	2003/01/16 08:44:52	1.11
+++ src/openbox.py	2003/01/16 18:34:12
@@ -665,7 +665,8 @@ class Screen(EventHandler,):
     def manageExisting(*args): return apply(_openbox.Screen_manageExisting,args)
     def manageWindow(*args): return apply(_openbox.Screen_manageWindow,args)
     def unmanageWindow(*args): return apply(_openbox.Screen_unmanageWindow,args)
-    def restack(*args): return apply(_openbox.Screen_restack,args)
+    def raiseWindow(*args): return apply(_openbox.Screen_raiseWindow,args)
+    def lowerWindow(*args): return apply(_openbox.Screen_lowerWindow,args)
     def setDesktopName(*args): return apply(_openbox.Screen_setDesktopName,args)
     def propertyHandler(*args): return apply(_openbox.Screen_propertyHandler,args)
     def clientMessageHandler(*args): return apply(_openbox.Screen_clientMessageHandler,args)
Index: src/screen.cc
===================================================================
RCS file: /cvs/cvsroot/openbox/src/screen.cc,v
retrieving revision 1.78
diff -p -u -r1.78 screen.cc
--- src/screen.cc	2003/01/16 08:44:52	1.78
+++ src/screen.cc	2003/01/16 18:34:19
@@ -125,7 +125,7 @@ Screen::Screen(int screen)
   _focuswindow = XCreateWindow(**otk::display, _info->rootWindow(),
                                -100, -100, 1, 1, 0, 0, InputOnly,
                                _info->visual(), CWOverrideRedirect, &attr);
-  XMapWindow(**otk::display, _focuswindow);
+  XMapRaised(**otk::display, _focuswindow);
   
   // these may be further updated if any pre-existing windows are found in
   // the manageExising() function
@@ -512,7 +512,7 @@ void Screen::manageWindow(Window window)
   clients.push_back(client);
   // this puts into the stacking order, then raises it
   _stacking.push_back(client);
-  restack(true, client);
+  raiseWindow(client);
   // update the root properties
   changeClientList();
 
@@ -527,7 +527,6 @@ void Screen::manageWindow(Window window)
 #endif
 }
 
-
 void Screen::unmanageWindow(Client *client)
 {
   Frame *frame = client->frame;
@@ -590,30 +589,59 @@ void Screen::unmanageWindow(Client *clie
   changeClientList();
 }
 
-void Screen::restack(bool raise, Client *client)
+void Screen::lowerWindow(Client *client)
 {
-  const int layer = client->layer();
-  std::vector<Window> wins;
+  Window wins[2];  // only ever restack 2 windows.
+  Client::List::iterator it = _stacking.begin();
+  Client::List::const_iterator end = _stacking.end();
+
+  for (; (it != end) && ((*it)->layer() >= client->layer()); ++it);
+
+  if (it == end) --it;                // want the last valid entry
+
+  if (*it == client)                  // already the bottom, return
+    return;
+
+  wins[0] = (*it)->frame->window();
+  wins[1] = client->frame->window();
 
   _stacking.remove(client);
+  _stacking.insert(++it, client);
 
+  XRestackWindows(**otk::display, wins, 2);
+  changeStackingList();
+}
+
+void Screen::raiseWindow(Client *client)
+{
+  Window wins[2];  // only ever restack 2 windows.
+
+  Client::List::iterator it = _stacking.begin();
+  Client::List::const_iterator end = _stacking.end();
+
   // the stacking list is from highest to lowest
-  
-  Client::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))
-      break;
-    wins.push_back((*it)->frame->window());
+  for (; it != end && (*it)->layer() != client->layer(); ++it);
+
+  if (*it == client)               // already topmost in layer
+    return;
+
+  /* if our new position is the top, we want to stack under the focuswindow
+     otherwise, we want to stack under the previous window in the stack.
+  */
+  if (it == _stacking.begin()) {
+    wins[0] = _focuswindow;
+  } else {
+    --it;
+    wins[0] = (*it)->frame->window();
+    ++it;
   }
-  // insert our client
-  wins.push_back(client->frame->window());
+
+  wins[1] = client->frame->window();
+
+  _stacking.remove(client);
   _stacking.insert(it, client);
-  // insert the remaining below this window
-  for (; it != end; ++it)
-    wins.push_back((*it)->frame->window());
 
-  XRestackWindows(**otk::display, &wins[0], wins.size());
+  XRestackWindows(**otk::display, wins, 2);
   changeStackingList();
 }
 
Index: src/screen.hh
===================================================================
RCS file: /cvs/cvsroot/openbox/src/screen.hh,v
retrieving revision 1.36
diff -p -u -r1.36 screen.hh
--- src/screen.hh	2003/01/13 05:54:40	1.36
+++ src/screen.hh	2003/01/16 18:34:20
@@ -182,9 +182,11 @@ public:
   */
   void unmanageWindow(Client *client);
 
-  //! Raises/Lowers a client window above/below all others in its stacking
-  //! layer
-  void restack(bool raise, Client *client);
+  //! Raises a client window above all others in its stacking layer
+  void raiseWindow(Client *client);
+
+  //! Lowers a client window below all others in its stacking layer
+  void lowerWindow(Client *client);
 
   //! Sets the name of a desktop by changing the root window property
   /*!


More information about the openbox mailing list