]> Dogcows Code - chaz/openbox/commitdiff
sync with blackbox-cvs
authorDana Jansens <danakj@orodu.net>
Fri, 21 Jun 2002 01:06:29 +0000 (01:06 +0000)
committerDana Jansens <danakj@orodu.net>
Fri, 21 Jun 2002 01:06:29 +0000 (01:06 +0000)
src/BaseDisplay.cc
src/Basemenu.cc
src/Basemenu.hh
src/Screen.cc
src/Slit.cc
src/Toolbar.cc
src/Window.cc
src/Workspace.cc

index 5c34a727133aa07733a26530ebabc8e770b2dcd7..8be0a7f781e91e58d183dfe26b70a612b49ee55d 100644 (file)
@@ -411,43 +411,55 @@ ScreenInfo::ScreenInfo(BaseDisplay *d, unsigned int num) {
   screen_number = num;
 
   root_window = RootWindow(basedisplay->getXDisplay(), screen_number);
-  depth = DefaultDepth(basedisplay->getXDisplay(), screen_number);
 
   rect.setSize(WidthOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
                                              screen_number)),
                HeightOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
                                               screen_number)));
+  /*
+    If the default depth is at least 15 we will use that,
+    otherwise we try to find the largest TrueColor visual.
+    Preference is given to 24 bit over larger depths if 24 bit is an option.
+  */
 
-  // search for a TrueColor Visual... if we can't find one... we will use the
-  // default visual for the screen
-  XVisualInfo vinfo_template, *vinfo_return;
-  int vinfo_nitems;
-
-  vinfo_template.screen = screen_number;
-  vinfo_template.c_class = TrueColor;
-
-  visual = (Visual *) 0;
-
-  vinfo_return = XGetVisualInfo(basedisplay->getXDisplay(),
-                                VisualScreenMask | VisualClassMask,
-                                &vinfo_template, &vinfo_nitems);
-  if (vinfo_return && vinfo_nitems > 0) {
-    for (int i = 0; i < vinfo_nitems; i++) {
-      if (depth < (vinfo_return + i)->depth) {
-        depth = (vinfo_return + i)->depth;
-        visual = (vinfo_return + i)->visual;
+  depth = DefaultDepth(basedisplay->getXDisplay(), screen_number);
+  visual = DefaultVisual(basedisplay->getXDisplay(), screen_number);
+  colormap = DefaultColormap(basedisplay->getXDisplay(), screen_number);
+  
+  if (depth < 15) {
+    // search for a TrueColor Visual... if we can't find one...
+    // we will use the default visual for the screen
+    XVisualInfo vinfo_template, *vinfo_return;
+    int vinfo_nitems;
+    int best = -1;
+
+    vinfo_template.screen = screen_number;
+    vinfo_template.c_class = TrueColor;
+
+    vinfo_return = XGetVisualInfo(basedisplay->getXDisplay(),
+                                  VisualScreenMask | VisualClassMask,
+                                  &vinfo_template, &vinfo_nitems);
+    if (vinfo_return) {
+      int max_depth = 1;
+      for (int i = 0; i < vinfo_nitems; ++i) {
+        if (vinfo_return[i].depth > max_depth) {
+          if (max_depth == 24 && vinfo_return[i].depth > 24)
+            break;          // prefer 24 bit over 32
+          max_depth = vinfo_return[i].depth;
+          best = i;
+        }
       }
+      if (max_depth < depth) best = -1;
     }
 
-    XFree(vinfo_return);
-  }
+    if (best != -1) {
+      depth = vinfo_return[best].depth;
+      visual = vinfo_return[best].visual;
+      colormap = XCreateColormap(basedisplay->getXDisplay(), root_window,
+                                 visual, AllocNone);
+    }
 
-  if (visual) {
-    colormap = XCreateColormap(basedisplay->getXDisplay(), root_window,
-                               visual, AllocNone);
-  } else {
-    visual = DefaultVisual(basedisplay->getXDisplay(), screen_number);
-    colormap = DefaultColormap(basedisplay->getXDisplay(), screen_number);
+    XFree(vinfo_return);
   }
 
   // get the default display string and strip the screen number
index 575147e61c1e3538471e7a16d5ce4797a7928211..7358df3c3a6c814791ed62416a4b67cf89d788f4 100644 (file)
@@ -201,14 +201,11 @@ Basemenu::~Basemenu(void) {
 }
 
 
-BasemenuItem::~BasemenuItem(void) {}
-
-
 BasemenuItem *Basemenu::find(int index) {
-  if (index < 0 || index > static_cast<signed>(menuitems.size()))
+  if (index < 0 || index >= static_cast<signed>(menuitems.size()))
     return (BasemenuItem*) 0;
 
-  return *(menuitems.begin() + index);
+  return menuitems[index];
 }
 
 
@@ -593,8 +590,7 @@ bool Basemenu::hasSubmenu(int index) {
 
 
 void Basemenu::drawItem(int index, bool highlight, bool clear,
-                        int x, int y, unsigned int w, unsigned int h)
-{
+                        int x, int y, unsigned int w, unsigned int h) {
   BasemenuItem *item = find(index);
   if (! item) return;
 
index 46a8d52821f5bf9e598273ac930218695cd3b94b..23da10ee4ec7c3f696e20076735a945b4962a9a2 100644 (file)
@@ -163,8 +163,6 @@ public:
                                                      f(0), enabled(1),
                                                      selected(0) {}
 
-  ~BasemenuItem(void);
-
   inline const char *exec(void) const { return e.c_str(); }
   inline const char *label(void) const { return l.c_str(); }
   inline int function(void) const { return f; }
index 6d20451303bb0826322756f3704f48fe4e6a95a4..5f69d82af15025eaf2d54d5e8265c501a9c78c82 100644 (file)
@@ -245,6 +245,8 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) {
 
   workspacemenu->setItemSelected(2, True);
 
+  removeWorkspaceNames(); // do not need them any longer
+
   toolbar = new Toolbar(this);
 
   slit = new Slit(this);
@@ -593,7 +595,6 @@ void BScreen::load_rc(void) {
   else
     resource.col_direction = TopBottom;
 
-  removeWorkspaceNames();
   if (config->getValue(screenstr + "workspaceNames", s)) {
     string::const_iterator it = s.begin(), end = s.end();
     while(1) {
@@ -1060,10 +1061,6 @@ void BScreen::changeWorkspaceID(unsigned int id) {
   if (! current_workspace) return;
 
   if (id != current_workspace->getID()) {
-    current_workspace->hideAll();
-
-    workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
-
     BlackboxWindow *focused = blackbox->getFocusedWindow();
     if (focused && focused->getScreen() == this && ! focused->isStuck()) {
       if (focused->getWorkspaceNumber() != current_workspace->getID()) {
@@ -1072,8 +1069,15 @@ void BScreen::changeWorkspaceID(unsigned int id) {
         abort();
       }
       current_workspace->setLastFocusedWindow(focused);
-      blackbox->setFocusedWindow((BlackboxWindow *) 0);
+    } else {
+      // if no window had focus, no need to store a last focus
+      current_workspace->setLastFocusedWindow((BlackboxWindow *) 0);
     }
+    // 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);
 
@@ -1229,7 +1233,7 @@ void BScreen::updateNetizenConfigNotify(XEvent *e) {
 
 
 void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) {
-  // XXX: why 13??
+  // the 13 represents the number of blackbox windows such as menus
   Window *session_stack = new
     Window[(num + workspacesList.size() + rootmenuList.size() + 13)];
   unsigned int i = 0, k = num;
index 83923dfcb43d8278dbd4cc3387ee389b72d5461d..171432af9b2be2be84509313c6c40c807a8553cf 100644 (file)
@@ -433,25 +433,29 @@ void Slit::updateStrut(void) {
   strut.top = strut.bottom = strut.left = strut.right = 0;
 
   if (! clientList.empty()) {
+    // when not hidden both borders are in use, when hidden only one is
+    unsigned int border_width = screen->getBorderWidth();
+    if (! do_auto_hide)
+      border_width *= 2;
+
     switch (direction) {
     case Vertical:
       switch (placement) {
       case TopCenter:
-        strut.top = getY() + getExposedHeight() +
-                    (screen->getBorderWidth() * 2);
+        strut.top = getExposedHeight() + border_width;
         break;
       case BottomCenter:
-        strut.bottom = screen->getHeight() - getY();
+        strut.bottom = getExposedHeight() + border_width;
         break;
       case TopLeft:
       case CenterLeft:
       case BottomLeft:
-        strut.left = getExposedWidth() + (screen->getBorderWidth() * 2);
+        strut.left = getExposedWidth() + border_width;
         break;
       case TopRight:
       case CenterRight:
       case BottomRight:
-        strut.right = getExposedWidth() + (screen->getBorderWidth() * 2);
+        strut.right = getExposedWidth() + border_width;
         break;
       }
       break;
@@ -460,19 +464,18 @@ void Slit::updateStrut(void) {
       case TopCenter:
       case TopLeft:
       case TopRight:
-        strut.top = getY() + getExposedHeight() +
-                    (screen->getBorderWidth() * 2);
+        strut.top = getExposedHeight() + border_width;
         break;
       case BottomCenter:
       case BottomLeft:
       case BottomRight:
-        strut.bottom = screen->getHeight() - getY();
+        strut.bottom = getExposedHeight() + border_width;
         break;
       case CenterLeft:
-        strut.left = getExposedWidth() + (screen->getBorderWidth() * 2);
+        strut.left = getExposedWidth() + border_width;
         break;
       case CenterRight:
-        strut.right = getExposedWidth() + (screen->getBorderWidth() * 2);
+        strut.right = getExposedWidth() + border_width;
         break;
       }
       break;
index 447e0d033e9c621cff7a94d2bbed5f319ea40e52..55beb59de8898204a18aea5194ea5e90a227ff5d 100644 (file)
@@ -528,15 +528,20 @@ void Toolbar::updateStrut(void) {
   // left and right are always 0
   strut.top = strut.bottom = 0;
 
+  // when hidden only one border is visible
+  unsigned int border_width = screen->getBorderWidth();
+  if (! do_auto_hide)
+    border_width *= 2;
+
   if (! screen->doHideToolbar()) {
     switch(placement) {
     case TopLeft:
     case TopCenter:
     case TopRight:
-      strut.top = getExposedHeight() + (screen->getBorderWidth() * 2);
+      strut.top = getExposedHeight() + border_width;
       break;
     default:
-      strut.bottom = getExposedHeight() + (screen->getBorderWidth() * 2);
+      strut.bottom = getExposedHeight() + border_width;
     }
   }
 
index 417e15ac7f5d68615eb72e9f0bd2b5d4666ffe61..9e3d9f5eabd8a78dd4e183744c186e1794f16903 100644 (file)
@@ -68,9 +68,11 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
   fprintf(stderr, "BlackboxWindow::BlackboxWindow(): creating 0x%lx\n", w);
 #endif // DEBUG
 
-  // set timer to zero... it is initialized properly later, so we check
-  // if timer is zero in the destructor, and assume that the window is not
-  // fully constructed if timer is zero...
+  /*
+    set timer to zero... it is initialized properly later, so we check
+    if timer is zero in the destructor, and assume that the window is not
+    fully constructed if timer is zero...
+  */
   timer = 0;
   blackbox = b;
   client.window = w;
@@ -139,9 +141,11 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
   client.wm_hint_flags = client.normal_hint_flags = 0;
   client.transient_for = 0;
 
-  // get the initial size and location of client window (relative to the
-  // _root window_). This position is the reference point used with the
-  // window's gravity to find the window's initial position.
+  /*
+    get the initial size and location of client window (relative to the
+    _root window_). This position is the reference point used with the
+    window's gravity to find the window's initial position.
+  */
   client.rect.setRect(wattrib.x, wattrib.y, wattrib.width, wattrib.height);
   client.old_bw = wattrib.border_width;
 
@@ -254,15 +258,48 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
               frame.rect.width(), frame.rect.height());
   }
 
+  // preserve the window's initial state on first map, and its current state
+  // across a restart
+  if (! getState()) {
+    if (client.wm_hint_flags & StateHint)
+      current_state = client.initial_state;
+    else
+      current_state = NormalState;
+  }
+
   if (flags.shaded) {
     flags.shaded = False;
     shade();
+    
+    /*
+      Because the iconic'ness of shaded windows is lost, we need to set the
+      state to NormalState so that shaded windows on other workspaces will not
+      get shown on the first workspace.
+      At this point in the life of a window, current_state should only be set
+      to IconicState if the window was an *icon*, not if it was shaded.
+    */
+    current_state = NormalState;
+  }
+
+  if (flags.stuck) {
+    flags.stuck = False;
+    stick();
   }
 
   if (flags.maximized && (functions & Func_Maximize)) {
     remaximize();
   }
 
+  /*
+    When the window is mapped (and also when its attributes are restored), the
+    current_state that was set here will be used.
+    It is set to Normal if the window is to be mapped or it is set to Iconic
+    if the window is to be iconified.
+    *Note* that for sticky windows, the same rules apply here, they are in
+    fact never set to Iconic since there is no way for us to tell if a sticky
+    window was iconified previously.
+  */
+
   setFocusFlag(False);
 }
 
@@ -1309,6 +1346,16 @@ void BlackboxWindow::configureShape(void) {
 bool BlackboxWindow::setInputFocus(void) {
   if (flags.focused) return True;
 
+  assert(! flags.iconic);
+
+  // if the window is not visible, mark the window as wanting focus rather
+  // than give it focus.
+  if (! flags.visible) {
+    Workspace *wkspc = screen->getWorkspace(blackbox_attrib.workspace);
+    wkspc->setLastFocusedWindow(this);
+    return True;
+  }
+
   if (! client.rect.intersects(screen->getRect())) {
     // client is outside the screen, move it to the center
     configure((screen->getWidth() - frame.rect.width()) / 2,
@@ -1406,7 +1453,8 @@ void BlackboxWindow::iconify(void) {
 
 
 void BlackboxWindow::show(void) {
-  setState(NormalState);
+  current_state = (flags.shaded) ? IconicState : NormalState;
+  setState(current_state);
 
   XMapWindow(blackbox->getXDisplay(), client.window);
   XMapSubwindows(blackbox->getXDisplay(), frame.window);
@@ -1463,11 +1511,13 @@ void BlackboxWindow::withdraw(void) {
   XUnmapWindow(blackbox->getXDisplay(), frame.window);
 
   XGrabServer(blackbox->getXDisplay());
+
   XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
   XUnmapWindow(blackbox->getXDisplay(), client.window);
   XSelectInput(blackbox->getXDisplay(), client.window,
                PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
-    XUngrabServer(blackbox->getXDisplay());
+
+  XUngrabServer(blackbox->getXDisplay());
 
   if (windowmenu) windowmenu->hide();
 }
@@ -1631,6 +1681,10 @@ void BlackboxWindow::stick(void) {
 
 
 void BlackboxWindow::setFocusFlag(bool focus) {
+  // only focus a window if it is visible
+  if (focus && !flags.visible)
+    return;
+
   flags.focused = focus;
 
   if (decorations & Decor_Titlebar) {
@@ -1785,8 +1839,6 @@ bool BlackboxWindow::getState(void) {
 
 
 void BlackboxWindow::restoreAttributes(void) {
-  if (! getState()) current_state = NormalState;
-
   Atom atom_return;
   int foo;
   unsigned long ulfoo, nitems;
@@ -1801,36 +1853,42 @@ void BlackboxWindow::restoreAttributes(void) {
   if (ret != Success || ! net || nitems != PropBlackboxAttributesElements)
     return;
 
-  if (net->flags & AttribShaded &&
-      net->attrib & AttribShaded) {
-    int save_state =
-      ((current_state == IconicState) ? NormalState : current_state);
-
+  if (net->flags & AttribShaded && net->attrib & AttribShaded) {
     flags.shaded = False;
     shade();
 
-    current_state = save_state;
-  }
+    /*
+      Because the iconic'ness of shaded windows is lost, we need to set the
+      state to NormalState so that shaded windows on other workspaces will not
+      get shown on the first workspace.
+      At this point in the life of a window, current_state should only be set
+      to IconicState if the window was an *icon*, not if it was shaded.
+    */
+    current_state = NormalState;
+ }
 
   if ((net->workspace != screen->getCurrentWorkspaceID()) &&
       (net->workspace < screen->getWorkspaceCount())) {
     screen->reassociateWindow(this, net->workspace, True);
 
+    // set to WithdrawnState so it will be mapped on the new workspace
     if (current_state == NormalState) current_state = WithdrawnState;
   } else if (current_state == WithdrawnState) {
+    // the window is on this workspace and is Withdrawn, so it is waiting to
+    // be mapped
     current_state = NormalState;
   }
 
-  if (net->flags & AttribOmnipresent &&
-      net->attrib & AttribOmnipresent) {
+  if (net->flags & AttribOmnipresent && net->attrib & AttribOmnipresent) {
     flags.stuck = False;
     stick();
 
-    current_state = NormalState;
+    // if the window was on another workspace, it was going to be hidden. this
+    // specifies that the window should be mapped since it is sticky.
+    if (current_state == WithdrawnState) current_state = NormalState;
   }
 
-  if ((net->flags & AttribMaxHoriz) ||
-      (net->flags & AttribMaxVert)) {
+  if (net->flags & AttribMaxHoriz || net->flags & AttribMaxVert) {
     int x = net->premax_x, y = net->premax_y;
     unsigned int w = net->premax_w, h = net->premax_h;
     flags.maximized = 0;
@@ -1852,7 +1910,8 @@ void BlackboxWindow::restoreAttributes(void) {
     blackbox_attrib.premax_h = h;
   }
 
-  setState(current_state);
+  // with the state set it will then be the map events job to read the window's
+  // state and behave accordingly
 
   XFree((void *) net);
 }
@@ -2091,17 +2150,6 @@ void BlackboxWindow::mapRequestEvent(XMapRequestEvent *re) {
           client.window);
 #endif // DEBUG
 
-  bool get_state_ret = getState();
-  if (! (get_state_ret && blackbox->isStartup())) {
-    if ((client.wm_hint_flags & StateHint) &&
-        (! (current_state == NormalState || current_state == IconicState)))
-      current_state = client.initial_state;
-    else
-      current_state = NormalState;
-  } else if (flags.iconic) {
-    current_state = NormalState;
-  }
-
   switch (current_state) {
   case IconicState:
     iconify();
index 64710a59a999f86d14b089ef5600c22f2bbdf9da..1d07a5bea12daa5db632dc0b88df2d931f646ac3 100644 (file)
@@ -97,18 +97,39 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) {
 
   stackingList.remove(w);
 
-  if (w->isFocused() && ! screen->getBlackbox()->doShutdown()) {
+  // pass focus to the next appropriate window
+  if ((w->isFocused() || w == lastfocus) &&
+      ! screen->getBlackbox()->doShutdown()) {
     BlackboxWindow *newfocus = 0;
     if (w->isTransient())
       newfocus = w->getTransientFor();
     if (! newfocus && ! stackingList.empty())
       newfocus = stackingList.front();
-    if (! newfocus || ! newfocus->setInputFocus())
-      screen->getBlackbox()->setFocusedWindow(0);
-  }
 
-  if (lastfocus == w)
-    lastfocus = (BlackboxWindow *) 0;
+    assert(newfocus != w);  // this would be very wrong.
+
+    if (id == screen->getCurrentWorkspaceID()) {
+      /*
+        if the window is on the visible workspace, then try focus it, and fall
+        back to the default focus target if the window won't focus.
+      */
+      if (! newfocus || ! newfocus->setInputFocus())
+        screen->getBlackbox()->setFocusedWindow(0);
+    } else if (lastfocus == w) {
+      /*
+        If this workspace is not the current one do not assume that
+        w == lastfocus. If a sticky window is removed on a workspace other
+        than where it originated, it will fire the removeWindow on a
+        non-visible workspace.
+      */
+      
+      /*
+        If the window isn't on the visible workspace, don't focus the new one,
+        just mark it to be focused when the workspace comes into view.
+      */
+      setLastFocusedWindow(newfocus);
+    }
+  }
 
   windowList.remove(w);
   clientmenu->remove(w->getWindowNumber());
This page took 0.040069 seconds and 4 git commands to generate.