]> Dogcows Code - chaz/openbox/blobdiff - src/Screen.cc
merged with 2_1-merged-to-HEAD-2002-09-30
[chaz/openbox] / src / Screen.cc
index 5441d0bba0d7eb2231f1d2f8ca5d37babc122986..7e7ce5a4f5d68342e337ab958319431336d93095 100644 (file)
@@ -339,6 +339,33 @@ BScreen::~BScreen(void) {
   if (resource.tstyle.font)
     delete resource.tstyle.font;
 
+#ifdef    BITMAPBUTTONS
+  if (resource.wstyle.close_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.wstyle.close_button.mask);
+  if (resource.wstyle.max_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.wstyle.max_button.mask);
+  if (resource.wstyle.icon_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.wstyle.icon_button.mask);
+  if (resource.wstyle.stick_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.wstyle.stick_button.mask);
+
+  if (resource.tstyle.left_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.tstyle.left_button.mask);
+  if (resource.tstyle.right_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.tstyle.right_button.mask);
+
+  if (resource.mstyle.bullet_image.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.mstyle.bullet_image.mask);
+  if (resource.mstyle.tick_image.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.mstyle.tick_image.mask);
+    
+  resource.wstyle.max_button.mask = resource.wstyle.close_button.mask =
+    resource.wstyle.icon_button.mask =
+    resource.wstyle.stick_button.mask = None;
+  resource.tstyle.left_button.mask = resource.tstyle.right_button.mask = None;
+  resource.mstyle.bullet_image.mask = resource.mstyle.tick_image.mask = None;
+#endif // BITMAPBUTTONS
+  
   XFreeGC(blackbox->getXDisplay(), opGC);
 }
 
@@ -402,8 +429,15 @@ void BScreen::saveFocusLast(bool f) {
 
 void BScreen::saveAAFonts(bool f) {
   resource.aa_fonts = f;
-  reconfigure();
   config->setValue(screenstr + "antialiasFonts", resource.aa_fonts);
+  reconfigure();
+}
+
+
+void BScreen::saveShadowFonts(bool f) {
+  resource.shadow_fonts = f;
+  config->setValue(screenstr + "dropShadowFonts", resource.shadow_fonts);
+  reconfigure();
 }
 
 
@@ -589,10 +623,37 @@ void BScreen::saveRootScrollDirection(int d) {
 }
 
 
+void BScreen::saveRootMenuButton(unsigned int b) {
+  resource.root_menu_button = b;
+  const char *but;
+  switch (resource.root_menu_button) {
+  case 0: but = "None"; break;
+  case 1: but = "Left"; break;
+  case 2: but = "Middle"; break;
+  case 3: default: but = "Right"; break;
+  }
+  config->setValue(screenstr + "rootMenuButton", but);
+}
+
+
+void BScreen::saveWorkspaceMenuButton(unsigned int b) {
+  resource.workspace_menu_button = b;
+  const char *but;
+  switch (resource.workspace_menu_button) {
+  case 0: but = "None"; break;
+  case 1: but = "Left"; break;
+  case 2: default: but = "Middle"; break;
+  case 3: but = "Right"; break;
+  }
+  config->setValue(screenstr + "workspaceMenuButton", but);
+}
+
+
 void BScreen::save_rc(void) {
   saveSloppyFocus(resource.sloppy_focus);
   saveAutoRaise(resource.auto_raise);
   saveImageDither(doImageDither());
+  saveShadowFonts(resource.shadow_fonts);
   saveAAFonts(resource.aa_fonts);
   saveResizeZones(resource.resize_zones);
   saveOpaqueMove(resource.opaque_move);
@@ -621,6 +682,8 @@ void BScreen::save_rc(void) {
   saveAllowScrollLock(resource.allow_scroll_lock);
   saveWorkspaceWarping(resource.workspace_warping);
   saveRootScrollDirection(resource.root_scroll);
+  saveRootMenuButton(resource.root_menu_button);
+  saveWorkspaceMenuButton(resource.workspace_menu_button);
 
   toolbar->save_rc();
   slit->save_rc();
@@ -649,6 +712,10 @@ void BScreen::load_rc(void) {
   if (! config->getValue(screenstr + "antialiasFonts", resource.aa_fonts))
     resource.aa_fonts = true;
 
+  if (! resource.aa_fonts ||
+      ! config->getValue(screenstr + "dropShadowFonts", resource.shadow_fonts))
+    resource.shadow_fonts = false;
+
   if (! config->getValue(screenstr + "resizeZones", resource.resize_zones) ||
       (resource.resize_zones != 1 && resource.resize_zones != 2 &&
        resource.resize_zones != 4))
@@ -793,6 +860,29 @@ void BScreen::load_rc(void) {
     else if (s == "Reverse")
       resource.root_scroll = ReverseScroll;
   }
+
+  resource.root_menu_button = 3;
+  if (config->getValue(screenstr + "rootMenuButton", s)) {
+    if (s == "None")
+      resource.root_menu_button = 0;
+    else if (s == "Left")
+      resource.root_menu_button = 1;
+    else if (s == "Middle")
+      resource.root_menu_button = 2;
+  }
+
+  resource.workspace_menu_button = 2;
+  if (config->getValue(screenstr + "workspaceMenuButton", s)) {
+    if (s == "None")
+      resource.workspace_menu_button = 0;
+    else if (s == "Left")
+      resource.workspace_menu_button = 1;
+    else if (s == "Right")
+      resource.workspace_menu_button = 3;
+  }
+  // cant both be the same
+  if (resource.workspace_menu_button == resource.root_menu_button)
+    resource.workspace_menu_button = 0;
 }
 
 
@@ -975,6 +1065,30 @@ void BScreen::LoadStyle(void) {
   resource.wstyle.b_pressed =
     readDatabaseTexture("window.button.pressed", "black", style);
 
+#ifdef    BITMAPBUTTONS
+  if (resource.wstyle.close_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.wstyle.close_button.mask);
+  if (resource.wstyle.max_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.wstyle.max_button.mask);
+  if (resource.wstyle.icon_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.wstyle.icon_button.mask);
+  if (resource.wstyle.stick_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.wstyle.stick_button.mask);
+
+  resource.wstyle.close_button.mask = resource.wstyle.max_button.mask =
+    resource.wstyle.icon_button.mask =
+    resource.wstyle.icon_button.mask = None;
+  
+  readDatabaseMask("window.button.close.mask", resource.wstyle.close_button,
+                   style);
+  readDatabaseMask("window.button.max.mask", resource.wstyle.max_button,
+                   style);
+  readDatabaseMask("window.button.icon.mask", resource.wstyle.icon_button,
+                   style);
+  readDatabaseMask("window.button.stick.mask", resource.wstyle.stick_button,
+                   style);
+#endif // BITMAPBUTTONS
+
   // we create the window.frame texture by hand because it exists only to
   // make the code cleaner and is not actually used for display
   BColor color = readDatabaseColor("window.frame.focusColor", "white", style);
@@ -1014,7 +1128,14 @@ void BScreen::LoadStyle(void) {
   if (resource.wstyle.h_unfocus.texture() == BTexture::Parent_Relative)
     resource.wstyle.h_unfocus = resource.wstyle.f_unfocus;
 
-// load toolbar config
+  // load toolbar config
+#ifdef    BITMAPBUTTONS
+  if (resource.tstyle.left_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.tstyle.left_button.mask);
+  if (resource.tstyle.right_button.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.tstyle.right_button.mask);
+#endif // BITMAPBUTTONS
+  
   resource.tstyle.toolbar =
     readDatabaseTexture("toolbar", "black", style);
   resource.tstyle.label =
@@ -1036,6 +1157,13 @@ void BScreen::LoadStyle(void) {
   resource.tstyle.b_pic =
     readDatabaseColor("toolbar.button.picColor", "black", style);
 
+#ifdef    BITMAPBUTTONS
+  readDatabaseMask("toolbar.button.left.mask", resource.tstyle.left_button,
+                   style);
+  readDatabaseMask("toolbar.button.right.mask", resource.tstyle.right_button,
+                   style);
+#endif // BITMAPBUTTONS
+  
   resource.tstyle.justify = LeftJustify;
   if (style.getValue("toolbar.justify", s)) {
     if (s == "right" || s == "Right")
@@ -1053,6 +1181,13 @@ void BScreen::LoadStyle(void) {
   }
 
   // load menu config
+#ifdef   BITMAPBUTTONS
+  if (resource.mstyle.bullet_image.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.mstyle.bullet_image.mask);
+  if (resource.mstyle.tick_image.mask != None)
+    XFreePixmap(blackbox->getXDisplay(), resource.mstyle.tick_image.mask);
+#endif // BITMAPBUTTONS
+  
   resource.mstyle.title =
     readDatabaseTexture("menu.title", "white", style);
   resource.mstyle.frame =
@@ -1068,6 +1203,11 @@ void BScreen::LoadStyle(void) {
   resource.mstyle.h_text =
     readDatabaseColor("menu.hilite.textColor", "black", style);
 
+#ifdef    BITMAPBUTTONS
+  readDatabaseMask("menu.arrow.mask", resource.mstyle.bullet_image, style);
+  readDatabaseMask("menu.selected.mask", resource.mstyle.tick_image, style);
+#endif // BITMAPBUTTONS
+    
   resource.mstyle.t_justify = LeftJustify;
   if (style.getValue("menu.title.justify", s)) {
     if (s == "right" || s == "Right")
@@ -1232,8 +1372,10 @@ void BScreen::changeWorkspaceID(unsigned int id) {
     current_workspace->setLastFocusedWindow((BlackboxWindow *) 0);
   }
 
-  // when we switch workspaces, unfocus whatever was focused
-  blackbox->setFocusedWindow((BlackboxWindow *) 0);
+  // when we switch workspaces, unfocus whatever was focused if it is going
+  // to be unmapped
+  if (focused && ! focused->isStuck())
+    blackbox->setFocusedWindow((BlackboxWindow *) 0);
 
   current_workspace->hideAll();
   workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
@@ -1248,11 +1390,43 @@ void BScreen::changeWorkspaceID(unsigned int id) {
 
   current_workspace->showAll();
 
-  if (resource.focus_last && current_workspace->getLastFocusedWindow()) {
-    XSync(blackbox->getXDisplay(), False);
-    current_workspace->getLastFocusedWindow()->setInputFocus();
+  int x, y, rx, ry;
+  Window c, r;
+  unsigned int m;
+  BlackboxWindow *win = (BlackboxWindow *) 0;
+  bool f = False;
+
+  XSync(blackbox->getXDisplay(), False);
+
+  // If sloppy focus and we can find the client window under the pointer,
+  // try to focus it.  
+  if (resource.sloppy_focus &&
+      XQueryPointer(blackbox->getXDisplay(), getRootWindow(), &r, &c,
+                    &rx, &ry, &x, &y, &m) &&
+      c != None) {
+    if ( (win = blackbox->searchWindow(c)) )
+      f = win->setInputFocus();
   }
 
+  // If that fails, and we're doing focus_last, try to focus the last window.
+  if (! f && resource.focus_last &&
+      (win = current_workspace->getLastFocusedWindow()))
+    f = win->setInputFocus();
+
+  /*
+    if we found a focus target, then we set the focused window explicitly
+    because it is possible to switch off this workspace before the x server
+    generates the FocusIn event for the window. if that happens, openbox would
+    lose track of what window was the 'LastFocused' window on the workspace.
+
+    if we did not find a focus target, then set the current focused window to
+    nothing.
+  */
+  if (f)
+    blackbox->setFocusedWindow(win);
+  else
+    blackbox->setFocusedWindow((BlackboxWindow *) 0);
+
   updateNetizenCurrentWorkspace();
 }
 
@@ -1315,15 +1489,22 @@ void BScreen::updateStackingList(void) {
 
 
 void BScreen::addSystrayWindow(Window window) {
+  XGrabServer(blackbox->getXDisplay());
+  
+  XSelectInput(blackbox->getXDisplay(), window, StructureNotifyMask);
   systrayWindowList.push_back(window);
   xatom->setValue(getRootWindow(), XAtom::kde_net_system_tray_windows,
                   XAtom::window,
                   &systrayWindowList[0], systrayWindowList.size());
   blackbox->saveSystrayWindowSearch(window, this);
+
+  XUngrabServer(blackbox->getXDisplay());
 }
 
 
 void BScreen::removeSystrayWindow(Window window) {
+  XGrabServer(blackbox->getXDisplay());
+  
   WindowList::iterator it = systrayWindowList.begin();
   const WindowList::iterator end = systrayWindowList.end();
   for (; it != end; ++it)
@@ -1333,8 +1514,13 @@ void BScreen::removeSystrayWindow(Window window) {
                       XAtom::window,
                       &systrayWindowList[0], systrayWindowList.size());
       blackbox->removeSystrayWindowSearch(window);
+      XSelectInput(blackbox->getXDisplay(), window, NoEventMask);
       break;
     }
+
+  assert(it != end);    // not a systray window
+
+  XUngrabServer(blackbox->getXDisplay());
 }
 
 
@@ -1361,18 +1547,17 @@ void BScreen::manageWindow(Window w) {
   if (! win)
     return;
 
-
-  if (win->isNormal()) {
-    // don't list non-normal windows as managed windows
+  if (win->isDesktop()) {
+    desktopWindowList.push_back(win->getFrameWindow());
+  } else { // if (win->isNormal()) {
+    // don't list desktop windows as managed windows
     windowList.push_back(win);
     updateClientList();
   
     if (win->isTopmost())
       specialWindowList.push_back(win->getFrameWindow());
-  } else if (win->isDesktop()) {
-    desktopWindowList.push_back(win->getFrameWindow());
   }
-
+  
   XMapRequestEvent mre;
   mre.window = w;
   if (blackbox->isStartup() && win->isNormal()) win->restoreAttributes();
@@ -1406,8 +1591,17 @@ void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) {
   } else if (w->isIconic())
     removeIcon(w);
 
-  if (w->isNormal()) {
-    // we don't list non-normal windows as managed windows
+  if (w->isDesktop()) {
+    WindowList::iterator it = desktopWindowList.begin();
+    const WindowList::iterator end = desktopWindowList.end();
+    for (; it != end; ++it)
+      if (*it == w->getFrameWindow()) {
+        desktopWindowList.erase(it);
+        break;
+      }
+    assert(it != end);  // the window wasnt a desktop window?
+  } else { // if (w->isNormal()) {
+    // we don't list desktop windows as managed windows
     windowList.remove(w);
     updateClientList();
 
@@ -1421,15 +1615,6 @@ void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) {
         }
       assert(it != end);  // the window wasnt a special window?
     }
-  } else if (w->isDesktop()) {
-    WindowList::iterator it = desktopWindowList.begin();
-    const WindowList::iterator end = desktopWindowList.end();
-    for (; it != end; ++it)
-      if (*it == w->getFrameWindow()) {
-        desktopWindowList.erase(it);
-        break;
-      }
-    assert(it != end);  // the window wasnt a desktop window?
   }
 
   if (blackbox->getFocusedWindow() == w)
@@ -1569,6 +1754,9 @@ void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) {
 #ifdef    XINERAMA
   ++bbwins;
 #endif // XINERAMA
+#ifdef    XFT
+  ++bbwins;
+#endif // XFT
 
   Window *session_stack = new
     Window[(num + workspacesList.size() + rootmenuList.size() +
@@ -1592,6 +1780,9 @@ void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) {
 #ifdef    XINERAMA
   *(session_stack + i++) = configmenu->getXineramamenu()->getWindowID();
 #endif // XINERAMA
+#ifdef    XFT
+  *(session_stack + i++) = configmenu->getXftmenu()->getWindowID();
+#endif // XFT
   *(session_stack + i++) = configmenu->getWindowID();
 
   *(session_stack + i++) = slit->getMenu()->getDirectionmenu()->getWindowID();
@@ -1683,8 +1874,7 @@ void BScreen::propagateWindowName(const BlackboxWindow *bw) {
   if (bw->isIconic()) {
     iconmenu->changeItemLabel(bw->getWindowNumber(), bw->getIconTitle());
     iconmenu->update();
-  }
-  else {
+  } else {
     Clientmenu *clientmenu = getWorkspace(bw->getWorkspaceNumber())->getMenu();
     clientmenu->changeItemLabel(bw->getWindowNumber(), bw->getTitle());
     clientmenu->update();
@@ -1695,36 +1885,28 @@ void BScreen::propagateWindowName(const BlackboxWindow *bw) {
 }
 
 
-void BScreen::nextFocus(void) {
+void BScreen::nextFocus(void) const {
   BlackboxWindow *focused = blackbox->getFocusedWindow(),
     *next = focused;
 
-  if (focused) {
-    // if window is not on this screen, ignore it
-    if (focused->getScreen()->getScreenNumber() != getScreenNumber())
-      focused = (BlackboxWindow*) 0;
-  }
-
-  if (focused && current_workspace->getCount() > 1) {
-    // next is the next window to recieve focus, current is a place holder
-    BlackboxWindow *current;
+  if (focused &&
+      focused->getScreen()->getScreenNumber() == getScreenNumber() &&
+      current_workspace->getCount() > 1) {
     do {
-      current = next;
-      next = current_workspace->getNextWindowInList(current);
-    } while(! next->setInputFocus() && next != focused);
+      next = current_workspace->getNextWindowInList(next);
+    } while (next != focused && ! next->setInputFocus());
 
     if (next != focused)
       current_workspace->raiseWindow(next);
-  } else if (current_workspace->getCount() >= 1) {
+  } else if (current_workspace->getCount() > 0) {
     next = current_workspace->getTopWindowOnStack();
-
-    current_workspace->raiseWindow(next);
     next->setInputFocus();
+    current_workspace->raiseWindow(next);
   }
 }
 
 
-void BScreen::prevFocus(void) {
+void BScreen::prevFocus(void) const {
   BlackboxWindow *focused = blackbox->getFocusedWindow(),
     *next = focused;
 
@@ -1733,27 +1915,26 @@ void BScreen::prevFocus(void) {
     if (focused->getScreen()->getScreenNumber() != getScreenNumber())
       focused = (BlackboxWindow*) 0;
   }
-
-  if (focused && current_workspace->getCount() > 1) {
-    // next is the next window to recieve focus, current is a place holder
-    BlackboxWindow *current;
+  
+  if (focused &&
+      focused->getScreen()->getScreenNumber() == getScreenNumber() &&
+      current_workspace->getCount() > 1) {
+    // next is the next window to receive focus, current is a place holder
     do {
-      current = next;
-      next = current_workspace->getPrevWindowInList(current);
-    } while(! next->setInputFocus() && next != focused);
+      next = current_workspace->getPrevWindowInList(next);
+    } while (next != focused && ! next->setInputFocus());
 
     if (next != focused)
       current_workspace->raiseWindow(next);
-  } else if (current_workspace->getCount() >= 1) {
+  } else if (current_workspace->getCount() > 0) {
     next = current_workspace->getTopWindowOnStack();
-
-    current_workspace->raiseWindow(next);
     next->setInputFocus();
+    current_workspace->raiseWindow(next);
   }
 }
 
 
-void BScreen::raiseFocus(void) {
+void BScreen::raiseFocus(void) const {
   BlackboxWindow *focused = blackbox->getFocusedWindow();
   if (! focused)
     return;
@@ -2176,6 +2357,12 @@ void BScreen::shutdown(void) {
   while(! windowList.empty())
     unmanageWindow(windowList.front(), True);
 
+  while(! desktopWindowList.empty()) {
+    BlackboxWindow *win = blackbox->searchWindow(desktopWindowList.front());
+    assert(win);
+    unmanageWindow(win, True);
+  }
+
   slit->shutdown();
 }
 
@@ -2335,7 +2522,7 @@ void BScreen::updateAvailableArea(void) {
 }
 
 
-Workspace* BScreen::getWorkspace(unsigned int index) {
+Workspace* BScreen::getWorkspace(unsigned int index) const {
   assert(index < workspacesList.size());
   return workspacesList[index];
 }
@@ -2351,10 +2538,6 @@ void BScreen::buttonPressEvent(const XButtonEvent *xbutton) {
 
     if (rootmenu->isVisible())
       rootmenu->hide();
-  } else if (xbutton->button == 2) {
-    showWorkspaceMenu(xbutton->x_root, xbutton->y_root);
-  } else if (xbutton->button == 3) {
-    showRootMenu(xbutton->x_root, xbutton->y_root);
   // mouse wheel up
   } else if ((xbutton->button == 4 && resource.root_scroll == NormalScroll) ||
              (xbutton->button == 5 && resource.root_scroll == ReverseScroll)) {
@@ -2370,6 +2553,13 @@ void BScreen::buttonPressEvent(const XButtonEvent *xbutton) {
     else
       changeWorkspaceID(getCurrentWorkspaceID() - 1);
   }
+
+  if (resource.root_menu_button > 0 &&
+      xbutton->button == resource.root_menu_button)
+    showRootMenu(xbutton->x_root, xbutton->y_root);
+  else if (resource.workspace_menu_button > 0 &&
+           xbutton->button == resource.workspace_menu_button)
+    showWorkspaceMenu(xbutton->x_root, xbutton->y_root);
 }
 
 
@@ -2450,6 +2640,34 @@ void BScreen::toggleFocusModel(FocusModel model) {
                 std::mem_fun(&BlackboxWindow::grabButtons));
 }
 
+#ifdef    BITMAPBUTTONS
+void BScreen::readDatabaseMask(const string &rname, PixmapMask &pixmapMask,
+                               const Configuration &style) {
+  string s;
+  int hx, hy; //ignored
+  int ret = BitmapOpenFailed; //default to failure.
+  
+  if (style.getValue(rname, s))
+  {
+    if (s[0] != '/' && s[0] != '~')
+    {
+      std::string xbmFile = std::string("~/.openbox/buttons/") + s;
+      ret = XReadBitmapFile(blackbox->getXDisplay(), getRootWindow(),
+                            expandTilde(xbmFile).c_str(), &pixmapMask.w,
+                            &pixmapMask.h, &pixmapMask.mask, &hx, &hy);
+    } else
+      ret = XReadBitmapFile(blackbox->getXDisplay(), getRootWindow(),
+                            expandTilde(s).c_str(), &pixmapMask.w,
+                            &pixmapMask.h, &pixmapMask.mask, &hx, &hy);
+    
+    if (ret == BitmapSuccess)
+      return;
+  }
+
+  pixmapMask.mask = None;
+  pixmapMask.w = pixmapMask.h = 0;
+}
+#endif // BITMAPSUCCESS
 
 BTexture BScreen::readDatabaseTexture(const string &rname,
                                       const string &default_color,
@@ -2469,6 +2687,8 @@ BTexture BScreen::readDatabaseTexture(const string &rname,
   texture.setColor(readDatabaseColor(rname + ".color", default_color, style));
   texture.setColorTo(readDatabaseColor(rname + ".colorTo", default_color,
                                        style));
+  texture.setBorderColor(readDatabaseColor(rname + ".borderColor",
+                                           default_color, style));
   
   return texture;
 }
@@ -2508,7 +2728,7 @@ BFont *BScreen::readDatabaseFont(const string &rbasename,
     }
     
     BFont *b = new BFont(blackbox->getXDisplay(), this, family, i, bold,
-                         italic, resource.aa_fonts);
+                         italic, resource.shadow_fonts, resource.aa_fonts);
     if (b->valid())
       return b;
     else
This page took 0.03239 seconds and 4 git commands to generate.