]> Dogcows Code - chaz/openbox/commitdiff
sync with blackbox
authorDana Jansens <danakj@orodu.net>
Wed, 7 Aug 2002 00:24:58 +0000 (00:24 +0000)
committerDana Jansens <danakj@orodu.net>
Wed, 7 Aug 2002 00:24:58 +0000 (00:24 +0000)
src/Screen.cc
src/Toolbar.cc
src/Window.cc
src/Window.hh
src/Workspace.cc
src/Workspace.hh
src/blackbox.cc

index b24c514a4815609072dd8474da7cc369f0d82020..3d51a2d20164d9775021448beedc7e0bdb55ef6f 100644 (file)
@@ -1129,7 +1129,8 @@ void BScreen::removeIcon(BlackboxWindow *w) {
 BlackboxWindow *BScreen::getIcon(unsigned int index) {
   if (index < iconList.size()) {
     BlackboxWindowList::iterator it = iconList.begin();
-    for (; index > 0; --index, ++it) ; /* increment to index */
+    while (index-- > 0) // increment to index
+      ++it;
     return *it;
   }
 
@@ -1185,38 +1186,20 @@ unsigned int BScreen::removeLastWorkspace(void) {
 void BScreen::changeWorkspaceID(unsigned int id) {
   if (! current_workspace || id == current_workspace->getID()) return;
 
-  BlackboxWindow *focused = blackbox->getFocusedWindow();
-  if (focused && focused->getScreen() == this) {
-    assert(focused->isStuck() ||
-           focused->getWorkspaceNumber() == current_workspace->getID());
-
-    current_workspace->setLastFocusedWindow(focused);
-  } else {
-    // if no window had focus, no need to store a last focus
-    current_workspace->setLastFocusedWindow((BlackboxWindow *) 0);
-  }
+  current_workspace->hide();
 
-  // when we switch workspaces, unfocus whatever was focused
-  blackbox->setFocusedWindow((BlackboxWindow *) 0);
-    
-  current_workspace->hideAll();
   workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
 
   current_workspace = getWorkspace(id);
 
+  current_workspace->show();
+
   xatom->setValue(getRootWindow(), XAtom::net_current_desktop,
                   XAtom::cardinal, id);
 
   workspacemenu->setItemSelected(current_workspace->getID() + 2, True);
   toolbar->redrawWorkspaceLabel(True);
 
-  current_workspace->showAll();
-
-  if (resource.focus_last && current_workspace->getLastFocusedWindow()) {
-    XSync(blackbox->getXDisplay(), False);
-    current_workspace->getLastFocusedWindow()->setInputFocus();
-  }
-
   updateNetizenCurrentWorkspace();
 }
 
@@ -1790,12 +1773,13 @@ void BScreen::InitMenu(void) {
 
 
 static
-void string_within(char begin, char end, const char *input, size_t length,
-                   char *output) {
+size_t string_within(char begin, char end,
+                     const char *input, size_t start_at, size_t length,
+                     char *output) {
   bool parse = False;
   size_t index = 0;
-
-  for (size_t i = 0; i < length; ++i) {
+  size_t i = start_at;
+  for (; i < length; ++i) {
     if (input[i] == begin) {
       parse = True;
     } else if (input[i] == end) {
@@ -1810,6 +1794,8 @@ void string_within(char begin, char end, const char *input, size_t length,
     output[index] = '\0';
   else
     output[0] = '\0';
+
+  return i;
 }
 
 
@@ -1832,7 +1818,7 @@ bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
     unsigned int key = 0;
 
     // get the keyword enclosed in []'s
-    string_within('[', ']', line, line_length, keyword);
+    size_t pos = string_within('[', ']', line, 0, line_length, keyword);
 
     if (keyword[0] == '\0') {  // no keyword, no menu entry
       continue;
@@ -1845,10 +1831,10 @@ bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
     }
 
     // get the label enclosed in ()'s
-    string_within('(', ')', line, line_length, label);
+    pos = string_within('(', ')', line, pos, line_length, label);
 
     // get the command enclosed in {}'s
-    string_within('{', '}', line, line_length, command);
+    pos = string_within('{', '}', line, pos, line_length, command);
 
     switch (key) {
     case 311: // end
index a1a6e118269ad96182dd8b5885c913bffdcfab53..955eb5a05223ed47384a204c2e7a2a2f187fa2de 100644 (file)
@@ -53,16 +53,14 @@ using std::string;
 
 #include "i18n.hh"
 #include "blackbox.hh"
-#include "Clientmenu.hh"
 #include "Font.hh"
 #include "GCCache.hh"
-#include "Iconmenu.hh"
 #include "Image.hh"
-#include "Rootmenu.hh"
 #include "Screen.hh"
 #include "Toolbar.hh"
 #include "Window.hh"
 #include "Workspace.hh"
+#include "Clientmenu.hh"
 #include "Workspacemenu.hh"
 #include "Slit.hh"
 
@@ -910,11 +908,10 @@ void Toolbar::keyPressEvent(const XKeyEvent *ke) {
       editing = False;
 
       blackbox->setNoFocus(False);
-      if (blackbox->getFocusedWindow()) {
+      if (blackbox->getFocusedWindow())
         blackbox->getFocusedWindow()->setInputFocus();
-      } else {
+      else
         blackbox->setFocusedWindow(0);
-      }
 
       // the toolbar will be reconfigured when the change to the workspace name
       // gets caught in the PropertyNotify event handler
index fa49ec216f296f0a06c9278eea252371d80f94f3..46bd644ddf64145652730399ee95828b58ba4404 100644 (file)
@@ -155,6 +155,8 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
 
   current_state = NormalState;
 
+  windowmenu = 0;
+
   /*
     get the initial size and location of client window (relative to the
     _root window_). This position is the reference point used with the
@@ -168,8 +170,6 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
   timer = new BTimer(blackbox, this);
   timer->setTimeout(blackbox->getAutoRaiseDelay());
 
-  windowmenu = new Windowmenu(this);
-
   // get size, aspect, minimum/maximum size and other hints set by the
   // client
 
@@ -257,21 +257,6 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
   screen->addStrut(&client.strut);
   updateStrut();
   
-#ifdef    SHAPE
-  if (blackbox->hasShapeExtensions() && flags.shaped)
-    configureShape();
-#endif // SHAPE
-  
-  // get the window's title before adding it to the workspace
-  getWMName();
-  getWMIconName();
-
-  if (blackbox_attrib.workspace >= screen->getWorkspaceCount())
-    screen->getCurrentWorkspace()->addWindow(this, place_window);
-  else
-    screen->getWorkspace(blackbox_attrib.workspace)->
-      addWindow(this, place_window);
-
   /*
     the server needs to be grabbed here to prevent client's from sending
     events while we are in the process of configuring their window.
@@ -284,6 +269,12 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
 
   blackbox->saveWindowSearch(client.window, this);
 
+  if (blackbox_attrib.workspace >= screen->getWorkspaceCount())
+    screen->getCurrentWorkspace()->addWindow(this, place_window);
+  else
+    screen->getWorkspace(blackbox_attrib.workspace)->
+      addWindow(this, place_window);
+
   if (! place_window) {
     // don't need to call configure if we are letting the workspace
     // place the window
@@ -296,6 +287,11 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
 
   XUngrabServer(blackbox->getXDisplay());
 
+#ifdef    SHAPE
+  if (blackbox->hasShapeExtensions() && flags.shaped)
+    configureShape();
+#endif // SHAPE
+
   // now that we know where to put the window and what it should look like
   // we apply the decorations
   decorate();
@@ -338,6 +334,9 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
 
   if (flags.maximized && (functions & Func_Maximize))
     remaximize();
+
+  // create this last so it only needs to be configured once
+  windowmenu = new Windowmenu(this);
 }
 
 
@@ -369,18 +368,16 @@ BlackboxWindow::~BlackboxWindow(void) {
 
   // remove ourselves from our transient_for
   if (isTransient()) {
-    if (client.transient_for != (BlackboxWindow *) ~0ul) {
+    if (client.transient_for != (BlackboxWindow *) ~0ul)
       client.transient_for->client.transientList.remove(this);
-    }
     client.transient_for = (BlackboxWindow*) 0;
   }
 
   if (client.transientList.size() > 0) {
     // reset transient_for for all transients
     BlackboxWindowList::iterator it, end = client.transientList.end();
-    for (it = client.transientList.begin(); it != end; ++it) {
+    for (it = client.transientList.begin(); it != end; ++it)
       (*it)->client.transient_for = (BlackboxWindow*) 0;
-    }
   }
 
   if (frame.title)
@@ -417,7 +414,8 @@ Window BlackboxWindow::createToplevelWindow(void) {
   attrib_create.colormap = screen->getColormap();
   attrib_create.override_redirect = True;
   attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
-                             ButtonMotionMask | EnterWindowMask;
+                             ButtonMotionMask |
+                             EnterWindowMask | LeaveWindowMask;
 
   return XCreateWindow(blackbox->getXDisplay(), screen->getRootWindow(),
                        0, 0, 1, 1, frame.border_w, screen->getDepth(),
@@ -452,6 +450,8 @@ Window BlackboxWindow::createChildWindow(Window parent, Cursor cursor) {
 
 void BlackboxWindow::associateClientWindow(void) {
   XSetWindowBorderWidth(blackbox->getXDisplay(), client.window, 0);
+  getWMName();
+  getWMIconName();
 
   XChangeSaveSet(blackbox->getXDisplay(), client.window, SetModeInsert);
 
@@ -1417,9 +1417,22 @@ void BlackboxWindow::getTransientInfo(void) {
     return;
   }
 
-  // register ourselves with our new transient_for
-  client.transient_for->client.transientList.push_back(this);
-  flags.stuck = client.transient_for->flags.stuck;
+  // Check for a circular transient state: this can lock up Blackbox
+  // when it tries to find the non-transient window for a transient.
+  BlackboxWindow *w = this;
+  while(w->client.transient_for) {
+    if(w->client.transient_for == this) {
+      client.transient_for = (BlackboxWindow*) 0;
+      break;
+    }
+    w = w->client.transient_for;
+  }
+
+  if (client.transient_for) {
+    // register ourselves with our new transient_for
+    client.transient_for->client.transientList.push_back(this);
+    flags.stuck = client.transient_for->flags.stuck;
+  }
 }
 
 
@@ -1559,9 +1572,8 @@ bool BlackboxWindow::setInputFocus(void) {
   if (client.transientList.size() > 0) {
     // transfer focus to any modal transients
     BlackboxWindowList::iterator it, end = client.transientList.end();
-    for (it = client.transientList.begin(); it != end; ++it) {
+    for (it = client.transientList.begin(); it != end; ++it)
       if ((*it)->flags.modal) return (*it)->setInputFocus();
-    }
   }
 
   bool ret = True;
@@ -1692,9 +1704,8 @@ void BlackboxWindow::deiconify(bool reassoc, bool raise) {
   // reassociate and deiconify all transients
   if (reassoc && client.transientList.size() > 0) {
     BlackboxWindowList::iterator it, end = client.transientList.end();
-    for (it = client.transientList.begin(); it != end; ++it) {
+    for (it = client.transientList.begin(); it != end; ++it)
       (*it)->deiconify(True, False);
-    }
   }
 
   if (raise)
@@ -2064,18 +2075,13 @@ void BlackboxWindow::redrawWindowFrame(void) const {
 
 void BlackboxWindow::setFocusFlag(bool focus) {
   // only focus a window if it is visible
-  if (focus && !flags.visible)
+  if (focus && ! flags.visible)
     return;
 
   flags.focused = focus;
 
   redrawWindowFrame();
 
-  if (screen->isSloppyFocus() && screen->doAutoRaise()) {
-    if (isFocused()) timer->start();
-    else timer->stop();
-  }
-
   if (flags.focused)
     blackbox->setFocusedWindow(this);
  
@@ -3487,7 +3493,7 @@ void BlackboxWindow::beginResize(int x_root, int y_root, Corner dir) {
   flags.resizing = True;
   blackbox->setChangingWindow(this);
 
-  int gw, gh;
+  unsigned int gw, gh;
   frame.changing = frame.rect;
 
   constrain(anchor,  &gw, &gh);
@@ -3511,7 +3517,7 @@ void BlackboxWindow::doResize(int x_root, int y_root) {
                  screen->getOpGC(), frame.changing.x(), frame.changing.y(),
                  frame.changing.width() - 1, frame.changing.height() - 1);
 
-  int gw, gh;
+  unsigned int gw, gh;
   Corner anchor;
 
   switch (resize_dir) {
@@ -3627,6 +3633,43 @@ void BlackboxWindow::motionNotifyEvent(const XMotionEvent *me) {
 }
 
 
+void BlackboxWindow::enterNotifyEvent(const XCrossingEvent* ce) {
+  if (! (screen->isSloppyFocus() && isVisible() && isNormal()))
+    return;
+
+  XEvent e;
+  bool leave = False, inferior = False;
+
+  while (XCheckTypedWindowEvent(blackbox->getXDisplay(), ce->window,
+                                LeaveNotify, &e)) {
+    if (e.type == LeaveNotify && e.xcrossing.mode == NotifyNormal) {
+      leave = True;
+      inferior = (e.xcrossing.detail == NotifyInferior);
+    }
+  }
+
+  if ((! leave || inferior) && ! isFocused()) {
+    bool success = setInputFocus();
+    if (success)    // if focus succeeded install the colormap
+      installColormap(True); // XXX: shouldnt we honour no install?
+  }
+
+  if (screen->doAutoRaise())
+    timer->start();
+}
+
+
+void BlackboxWindow::leaveNotifyEvent(const XCrossingEvent*) {
+  if (! (screen->isSloppyFocus() && screen->doAutoRaise() && isNormal()))
+    return;
+
+  installColormap(False);
+
+  if (timer->isTiming())
+    timer->stop();
+}
+
+
 #ifdef    SHAPE
 void BlackboxWindow::shapeEvent(XShapeEvent *) {
   if (blackbox->hasShapeExtensions() && flags.shaped) {
@@ -3878,11 +3921,14 @@ void BlackboxWindow::upsize(void) {
  * The logical width and height are placed into pw and ph, if they
  * are non-zero.  Logical size refers to the users perception of
  * the window size (for example an xterm resizes in cells, not in pixels).
+ * pw and ph are then used to display the geometry during window moves, resize,
+ * etc.
  *
  * The physical geometry is placed into frame.changing_{x,y,width,height}.
  * Physical geometry refers to the geometry of the window in pixels.
  */
-void BlackboxWindow::constrain(Corner anchor, int *pw, int *ph) {
+void BlackboxWindow::constrain(Corner anchor,
+                               unsigned int *pw, unsigned int *ph) {
   // frame.changing represents the requested frame size, we need to
   // strip the frame margin off and constrain the client size
   frame.changing.setCoords(frame.changing.left() + frame.margin.left,
@@ -3890,39 +3936,42 @@ void BlackboxWindow::constrain(Corner anchor, int *pw, int *ph) {
                            frame.changing.right() - frame.margin.right,
                            frame.changing.bottom() - frame.margin.bottom);
 
-  int dw = frame.changing.width(), dh = frame.changing.height(),
+  unsigned int dw = frame.changing.width(), dh = frame.changing.height(),
     base_width = (client.base_width) ? client.base_width : client.min_width,
     base_height = (client.base_height) ? client.base_height :
                                          client.min_height;
 
   // constrain
-  if (dw < static_cast<signed>(client.min_width)) dw = client.min_width;
-  if (dh < static_cast<signed>(client.min_height)) dh = client.min_height;
-  if (dw > static_cast<signed>(client.max_width)) dw = client.max_width;
-  if (dh > static_cast<signed>(client.max_height)) dh = client.max_height;
-
-  dw -= base_width;
-  dw /= client.width_inc;
-  dh -= base_height;
-  dh /= client.height_inc;
-
-  if (pw) {
-    if (client.width_inc == 1)
-      *pw = dw + base_width;
-    else
-      *pw = dw;
+  if (dw < client.min_width) dw = client.min_width;
+  if (dh < client.min_height) dh = client.min_height;
+  if (dw > client.max_width) dw = client.max_width;
+  if (dh > client.max_height) dh = client.max_height;
+
+  assert(dw >= base_width && dh >= base_height);
+
+  if (client.width_inc > 1) {
+    dw -= base_width;
+    dw /= client.width_inc;
   }
-  if (ph) {
-    if (client.height_inc == 1)
-      *ph = dh + base_height;
-    else
-      *ph = dh;
+  if (client.height_inc > 1) {
+    dh -= base_height;
+    dh /= client.height_inc;
   }
 
-  dw *= client.width_inc;
-  dw += base_width;
-  dh *= client.height_inc;
-  dh += base_height;
+  if (pw)
+    *pw = dw;
+
+  if (ph)
+    *ph = dh;
+
+  if (client.width_inc > 1) {
+    dw *= client.width_inc;
+    dw += base_width;
+  }
+  if (client.height_inc > 1) {
+    dh *= client.height_inc;
+    dh += base_height;
+  }
 
   frame.changing.setSize(dw, dh);
 
@@ -4011,13 +4060,10 @@ BWindowGroup::find(BScreen *screen, bool allow_transients) const {
   BlackboxWindow *ret = blackbox->getFocusedWindow();
 
   // does the focus window match (or any transient_fors)?
-  while (ret) {
-    if (ret->getScreen() == screen && ret->getGroupWindow() == group) {
-      if (ret->isTransient() && allow_transients) break;
-      else if (! ret->isTransient()) break;
-    }
-
-    ret = ret->getTransientFor();
+  for (; ret; ret = ret->getTransientFor()) {
+    if (ret->getScreen() == screen && ret->getGroupWindow() == group &&
+        (! ret->isTransient() || allow_transients))
+      break;
   }
 
   if (ret) return ret;
@@ -4026,10 +4072,9 @@ BWindowGroup::find(BScreen *screen, bool allow_transients) const {
   BlackboxWindowList::const_iterator it, end = windowList.end();
   for (it = windowList.begin(); it != end; ++it) {
     ret = *it;
-    if (ret->getScreen() == screen && ret->getGroupWindow() == group) {
-      if (ret->isTransient() && allow_transients) break;
-      else if (! ret->isTransient()) break;
-    }
+    if (ret->getScreen() == screen && ret->getGroupWindow() == group &&
+        (! ret->isTransient() || allow_transients))
+      break;
   }
 
   return ret;
index 46bc2662d08f10ba751bac7071e4df11ec571ad7..105aef166d6cbcad09cba823b381066414b9a1e6 100644 (file)
@@ -301,7 +301,7 @@ private:
   void doResize(int x_root, int y_root);
   void endResize(void);
 
-  void constrain(Corner anchor, int *pw = 0, int *ph = 0);
+  void constrain(Corner anchor, unsigned int *pw = 0, unsigned int *ph = 0);
 
 public:
   BlackboxWindow(Blackbox *b, Window w, BScreen *s);
@@ -398,13 +398,15 @@ public:
   void buttonPressEvent(const XButtonEvent *be);
   void buttonReleaseEvent(const XButtonEvent *re);
   void motionNotifyEvent(const XMotionEvent *me);
-  void destroyNotifyEvent(const XDestroyWindowEvent */*unused*/);
+  void destroyNotifyEvent(const XDestroyWindowEvent/*unused*/);
   void mapRequestEvent(const XMapRequestEvent *mre);
-  void unmapNotifyEvent(const XUnmapEvent */*unused*/);
-  void reparentNotifyEvent(const XReparentEvent */*unused*/);
+  void unmapNotifyEvent(const XUnmapEvent/*unused*/);
+  void reparentNotifyEvent(const XReparentEvent/*unused*/);
   void propertyNotifyEvent(const XPropertyEvent *pe);
   void exposeEvent(const XExposeEvent *ee);
   void configureRequestEvent(const XConfigureRequestEvent *cr);
+  void enterNotifyEvent(const XCrossingEvent *ce);
+  void leaveNotifyEvent(const XCrossingEvent* /*unused*/);
 
 #ifdef    SHAPE
   void configureShape(void);
index 85f9cdcad6ba169adbf1071926b5fa6a398e7f94..7cd21f1c281f0187916bc88c58ac60b90407e134 100644 (file)
@@ -222,36 +222,6 @@ void Workspace::setFocused(const BlackboxWindow *w, bool focused) {
 }
 
 
-void Workspace::showAll(void) {
-  BlackboxWindowList::iterator it = stackingList.begin();
-  const BlackboxWindowList::iterator end = stackingList.end();
-  for (; it != end; ++it) {
-    BlackboxWindow *bw = *it;
-    // not normal windows cant focus from mouse enters anyways, so we dont
-    // need to unmap/remap them on workspace changes
-    if (! bw->isStuck() || bw->isNormal())
-      bw->show();
-  }
-}
-
-
-void Workspace::hideAll(void) {
-  // withdraw in reverse order to minimize the number of Expose events
-
-  BlackboxWindowList lst(stackingList.rbegin(), stackingList.rend());
-
-  BlackboxWindowList::iterator it = lst.begin();
-  const BlackboxWindowList::iterator end = lst.end();
-  for (; it != end; ++it) {
-    BlackboxWindow *bw = *it;
-    // not normal windows cant focus from mouse enters anyways, so we dont
-    // need to unmap/remap them on workspace changes
-    if (! bw->isStuck() || bw->isNormal())
-      bw->withdraw();
-  }
-}
-
-
 void Workspace::removeAll(void) {
   while (! windowList.empty())
     windowList.front()->iconify();
@@ -262,14 +232,16 @@ void Workspace::removeAll(void) {
  * returns the number of transients for win, plus the number of transients
  * associated with each transient of win
  */
-static int countTransients(const BlackboxWindow * const win) {
-  int ret = win->getTransients().size();
-  if (ret > 0) {
-    BlackboxWindowList::const_iterator it, end = win->getTransients().end();
-    for (it = win->getTransients().begin(); it != end; ++it) {
-      ret += countTransients(*it);
-    }
-  }
+static unsigned int countTransients(const BlackboxWindow * const win) {
+  BlackboxWindowList transients = win->getTransients();
+  if (transients.empty()) return 0;
+
+  unsigned int ret = transients.size();
+  BlackboxWindowList::const_iterator it = transients.begin(),
+    end = transients.end();
+  for (; it != end; ++it)
+    ret += countTransients(*it);
+
   return ret;
 }
 
@@ -282,48 +254,48 @@ static int countTransients(const BlackboxWindow * const win) {
  */
 void Workspace::raiseTransients(const BlackboxWindow * const win,
                                 StackVector::iterator &stack) {
-  if (win->getTransients().size() == 0) return; // nothing to do
+  if (win->getTransients().empty()) return; // nothing to do
 
   // put win's transients in the stack
   BlackboxWindowList::const_iterator it, end = win->getTransients().end();
   for (it = win->getTransients().begin(); it != end; ++it) {
-    *stack++ = (*it)->getFrameWindow();
-    screen->updateNetizenWindowRaise((*it)->getClientWindow());
-
-    if (! (*it)->isIconic()) {
-      Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber());
-      wkspc->stackingList.remove((*it));
-      wkspc->stackingList.push_front((*it));
+    BlackboxWindow *w = *it;
+    *stack++ = w->getFrameWindow();
+    screen->updateNetizenWindowRaise(w->getClientWindow());
+
+    if (! w->isIconic()) {
+      Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber());
+      wkspc->stackingList.remove(w);
+      wkspc->stackingList.push_front(w);
     }
   }
 
   // put transients of win's transients in the stack
-  for (it = win->getTransients().begin(); it != end; ++it) {
+  for (it = win->getTransients().begin(); it != end; ++it)
     raiseTransients(*it, stack);
-  }
 }
 
 
 void Workspace::lowerTransients(const BlackboxWindow * const win,
                                 StackVector::iterator &stack) {
-  if (win->getTransients().size() == 0) return; // nothing to do
+  if (win->getTransients().empty()) return; // nothing to do
 
   // put transients of win's transients in the stack
   BlackboxWindowList::const_reverse_iterator it,
     end = win->getTransients().rend();
-  for (it = win->getTransients().rbegin(); it != end; ++it) {
+  for (it = win->getTransients().rbegin(); it != end; ++it)
     lowerTransients(*it, stack);
-  }
 
   // put win's transients in the stack
   for (it = win->getTransients().rbegin(); it != end; ++it) {
-    *stack++ = (*it)->getFrameWindow();
-    screen->updateNetizenWindowLower((*it)->getClientWindow());
-
-    if (! (*it)->isIconic()) {
-      Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber());
-      wkspc->stackingList.remove((*it));
-      wkspc->stackingList.push_back((*it));
+    BlackboxWindow *w = *it;
+    *stack++ = w->getFrameWindow();
+    screen->updateNetizenWindowLower(w->getClientWindow());
+
+    if (! w->isIconic()) {
+      Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber());
+      wkspc->stackingList.remove(w);
+      wkspc->stackingList.push_back(w);
     }
   }
 }
@@ -335,10 +307,8 @@ void Workspace::raiseWindow(BlackboxWindow *w) {
   if (win->isDesktop()) return;
 
   // walk up the transient_for's to the window that is not a transient
-  while (win->isTransient() && ! win->isDesktop()) {
-    if (! win->getTransientFor()) break;
+  while (win->isTransient() && win->getTransientFor())
     win = win->getTransientFor();
-  }
 
   // get the total window count (win and all transients)
   unsigned int i = 1 + countTransients(win);
@@ -365,10 +335,8 @@ void Workspace::lowerWindow(BlackboxWindow *w) {
   BlackboxWindow *win = w;
 
   // walk up the transient_for's to the window that is not a transient
-  while (win->isTransient() && ! win->isDesktop()) {
-    if (! win->getTransientFor()) break;
+  while (win->isTransient() && win->getTransientFor())
     win = win->getTransientFor();
-  }
 
   // get the total window count (win and all transients)
   unsigned int i = 1 + countTransients(win);
@@ -401,9 +369,11 @@ void Workspace::reconfigure(void) {
 BlackboxWindow *Workspace::getWindow(unsigned int index) {
   if (index < windowList.size()) {
     BlackboxWindowList::iterator it = windowList.begin();
-    for(; index > 0; --index, ++it); /* increment to index */
+    while (index-- > 0) // increment to index
+      ++it;
     return *it;
   }
+
   return 0;
 }
 
@@ -435,6 +405,7 @@ BlackboxWindow* Workspace::getPrevWindowInList(BlackboxWindow *w) {
 
 
 BlackboxWindow* Workspace::getTopWindowOnStack(void) const {
+  assert(! stackingList.empty());
   return stackingList.front();
 }
 
@@ -461,6 +432,50 @@ void Workspace::appendStackOrder(BlackboxWindowList &stack_order) const {
 }
   
 
+void Workspace::hide(void) {
+  BlackboxWindow *focused = screen->getBlackbox()->getFocusedWindow();
+  if (focused && focused->getScreen() == screen) {
+    assert(focused->isStuck() || focused->getWorkspaceNumber() == id);
+
+    lastfocus = focused;
+  } else {
+    // if no window had focus, no need to store a last focus
+    lastfocus = (BlackboxWindow *) 0;
+  }
+
+  // when we switch workspaces, unfocus whatever was focused
+  screen->getBlackbox()->setFocusedWindow((BlackboxWindow *) 0);
+
+  // withdraw windows in reverse order to minimize the number of Expose events
+
+  BlackboxWindowList::reverse_iterator it = stackingList.rbegin();
+  const BlackboxWindowList::reverse_iterator end = stackingList.rend();
+  for (; it != end; ++it) {
+    BlackboxWindow *bw = *it;
+    // not normal windows cant focus from mouse enters anyways, so we dont
+    // need to unmap/remap them on workspace changes
+    if (! bw->isStuck() || bw->isNormal())
+      bw->withdraw();
+  }
+}
+
+
+void Workspace::show(void) {
+  std::for_each(stackingList.begin(), stackingList.end(),
+                std::mem_fun(&BlackboxWindow::show));
+
+  XSync(screen->getBlackbox()->getXDisplay(), False);
+
+  if (screen->doFocusLast()) {
+    if (! screen->isSloppyFocus() && ! lastfocus && ! stackingList.empty())
+      lastfocus = stackingList.front();
+
+    if (lastfocus)
+      lastfocus->setInputFocus();
+  }
+}
+
+
 bool Workspace::isCurrent(void) const {
   return (id == screen->getCurrentWorkspaceID());
 }
index 72203f2dbbd37329bd979a8c33828a54e6bbed24..e0295e29b0a5f2797f7b7ed98d0b1eb8376f75d1 100644 (file)
@@ -104,8 +104,8 @@ public:
   unsigned int getCount(void) const;
   void appendStackOrder(BlackboxWindowList &stack_order) const;
 
-  void showAll(void);
-  void hideAll(void);
+  void show(void);
+  void hide(void);
   void removeAll(void);
   void raiseWindow(BlackboxWindow *w);
   void lowerWindow(BlackboxWindow *w);
index 04e68bb17155720d3bf56e6dc6c539f35f7838b6..6995c0b534218c8c450ab31b9b7f194820faf8df 100644 (file)
@@ -112,26 +112,6 @@ using std::string;
 #include "Workspacemenu.hh"
 #include "XAtom.hh"
 
-// X event scanner for enter/leave notifies - adapted from twm
-struct scanargs {
-  Window w;
-  bool leave, inferior, enter;
-};
-
-static Bool queueScanner(Display *, XEvent *e, char *args) {
-  scanargs *scan = (scanargs *) args;
-  if ((e->type == LeaveNotify) &&
-      (e->xcrossing.window == scan->w) &&
-      (e->xcrossing.mode == NotifyNormal)) {
-    scan->leave = True;
-    scan->inferior = (e->xcrossing.detail == NotifyInferior);
-  } else if ((e->type == EnterNotify) && (e->xcrossing.mode == NotifyUngrab)) {
-    scan->enter = True;
-  }
-
-  return False;
-}
-
 Blackbox *blackbox;
 
 
@@ -474,24 +454,12 @@ void Blackbox::process_event(XEvent *e) {
 
     if (e->xcrossing.mode == NotifyGrab) break;
 
-    XEvent dummy;
-    scanargs sa;
-    sa.w = e->xcrossing.window;
-    sa.enter = sa.leave = False;
-    XCheckIfEvent(getXDisplay(), &dummy, queueScanner, (char *) &sa);
-
     if ((e->xcrossing.window == e->xcrossing.root) &&
         (screen = searchScreen(e->xcrossing.window))) {
       screen->getImageControl()->installRootColormap();
     } else if ((win = searchWindow(e->xcrossing.window))) {
-      if (win->getScreen()->isSloppyFocus() &&
-          (! win->isFocused()) && (! no_focus) &&
-          win->isNormal()) {  // don't focus non-normal windows with mouseover
-        if ((! sa.leave || sa.inferior) && win->isVisible()) {
-          if (win->setInputFocus())
-            win->installColormap(True); // XXX: shouldnt we honour no install?
-        }
-      }
+      if (! no_focus)
+        win->enterNotifyEvent(&e->xcrossing);
     } else if ((menu = searchMenu(e->xcrossing.window))) {
       menu->enterNotifyEvent(&e->xcrossing);
     } else if ((tbar = searchToolbar(e->xcrossing.window))) {
@@ -513,7 +481,7 @@ void Blackbox::process_event(XEvent *e) {
     if ((menu = searchMenu(e->xcrossing.window)))
       menu->leaveNotifyEvent(&e->xcrossing);
     else if ((win = searchWindow(e->xcrossing.window)))
-      win->installColormap(False);
+      win->leaveNotifyEvent(&e->xcrossing);
     else if ((tbar = searchToolbar(e->xcrossing.window)))
       tbar->leaveNotifyEvent(&e->xcrossing);
     else if ((slit = searchSlit(e->xcrossing.window)))
This page took 0.044476 seconds and 4 git commands to generate.