]> Dogcows Code - chaz/openbox/blobdiff - src/Slit.cc
use the snap offset as the margin for placing windows instead of a fixed value of 1
[chaz/openbox] / src / Slit.cc
index 087674005c27252e594391027dbd64aa0813abae..c15f66c4b361ce336e51bfafb3689ffa210e383e 100644 (file)
@@ -40,9 +40,10 @@ extern "C" {
 Slit::Slit(BScreen *scr) {
   screen = scr;
   blackbox = screen->getBlackbox();
+  slitstr = "session.screen" + itostring(screen->getScreenNumber()) + ".slit.";
+  config = blackbox->getConfig();
 
-  on_top = screen->isSlitOnTop();
-  hidden = do_auto_hide = screen->doSlitAutoHide();
+  load_rc();
 
   display = screen->getBaseDisplay()->getXDisplay();
   frame.window = frame.pixmap = None;
@@ -84,6 +85,9 @@ Slit::~Slit(void) {
 
   delete slitmenu;
 
+  screen->removeStrut(&strut);
+  screen->updateAvailableArea();
+
   screen->getImageControl()->removeImage(frame.pixmap);
 
   blackbox->removeSlitSearch(frame.window);
@@ -129,6 +133,17 @@ void Slit::addClient(Window w) {
     client->rect.setSize(64, 64);
   }
 
+  Atom *proto;
+  int num_return = 0;
+  if (XGetWMProtocols(display, client->window, &proto, &num_return)) {
+    for (int i = 0; i < num_return; ++i) {
+      if (proto[i] ==
+          blackbox->getXAtom()->getAtom(XAtom::blackbox_structure_messages)) {
+        screen->addNetizen(new Netizen(screen, client->window));
+      }
+    }
+  }
+
   XSetWindowBorderWidth(display, client->window, 0);
 
   XGrabServer(display);
@@ -197,6 +212,82 @@ void Slit::removeClient(Window w, bool remap) {
 }
 
 
+void Slit::saveOnTop(bool b) {
+  on_top = b;
+  config->setValue(slitstr + "onTop", on_top);
+}
+
+void Slit::saveAutoHide(bool b) {
+  do_auto_hide = b;
+  config->setValue(slitstr + "autoHide", do_auto_hide);
+}
+
+void Slit::savePlacement(int p) {
+  placement = p;
+  const char *pname;
+  switch (placement) {
+  case TopLeft: pname = "TopLeft"; break;
+  case CenterLeft: pname = "CenterLeft"; break;
+  case BottomLeft: pname = "BottomLeft"; break;
+  case TopCenter: pname = "TopCenter"; break;
+  case BottomCenter: pname = "BottomCenter"; break;
+  case TopRight: pname = "TopRight"; break;
+  case BottomRight: pname = "BottomRight"; break;
+  case CenterRight: default: pname = "CenterRight"; break;
+  }
+  config->setValue(slitstr + "placement", pname);
+}
+
+void Slit::saveDirection(int d) {
+  direction = d;
+  config->setValue(slitstr + "direction", (direction == Horizontal ?
+                                          "Horizontal" : "Vertical"));
+}
+
+void Slit::save_rc(void) {
+  saveOnTop(on_top);
+  saveAutoHide(do_auto_hide);
+  savePlacement(placement);
+  saveDirection(direction);
+}
+
+void Slit::load_rc(void) {
+  std::string s;
+
+  if (! config->getValue(slitstr + "onTop", on_top))
+    on_top = false;
+
+  if (! config->getValue(slitstr + "autoHide", do_auto_hide))
+    do_auto_hide = false;
+  hidden = do_auto_hide;
+
+  if (config->getValue(slitstr + "direction", s) && s == "Horizontal")
+    direction = Horizontal;
+  else
+    direction = Vertical;
+  
+  if (config->getValue(slitstr + "placement", s)) {
+    if (s == "TopLeft")
+      placement = TopLeft;
+    else if (s == "CenterLeft")
+      placement = CenterLeft;
+    else if (s == "BottomLeft")
+      placement = BottomLeft;
+    else if (s == "TopCenter")
+      placement = TopCenter;
+    else if (s == "BottomCenter")
+      placement = BottomCenter;
+    else if (s == "TopRight")
+      placement = TopRight;
+    else if (s == "BottomRight")
+      placement = BottomRight;
+    else //if (s == "CenterRight")
+      placement = CenterRight;
+  } else
+    placement = CenterRight;
+}
+
+
 void Slit::reconfigure(void) {
   SlitClientList::iterator it = clientList.begin();
   const SlitClientList::iterator end = clientList.end();
@@ -204,7 +295,7 @@ void Slit::reconfigure(void) {
 
   unsigned int width = 0, height = 0;
 
-  switch (screen->getSlitDirection()) {
+  switch (direction) {
   case Vertical:
     for (; it != end; ++it) {
       client = *it;
@@ -274,7 +365,7 @@ void Slit::reconfigure(void) {
 
   int x, y;
 
-  switch (screen->getSlitDirection()) {
+  switch (direction) {
   case Vertical:
     x = 0;
     y = screen->getBevelWidth();
@@ -355,46 +446,54 @@ void Slit::updateStrut(void) {
   strut.top = strut.bottom = strut.left = strut.right = 0;
 
   if (! clientList.empty()) {
-    switch (screen->getSlitDirection()) {
+    // 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 (screen->getSlitPlacement()) {
+      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;
     case Horizontal:
-      switch (screen->getSlitPlacement()) {
+      switch (placement) {
       case TopCenter:
       case TopLeft:
       case TopRight:
-        strut.top = getY() + getExposedHeight() +
-                    (screen->getBorderWidth() * 2);
+        strut.top = frame.rect.top() + getExposedHeight() + border_width;
         break;
       case BottomCenter:
       case BottomLeft:
       case BottomRight:
-        strut.bottom = screen->getHeight() - getY();
+        int pos;
+        if (do_auto_hide)
+          pos = frame.y_hidden;
+        else
+          pos = frame.rect.y();
+        strut.bottom = (screen->getRect().bottom() - pos);
         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;
@@ -407,106 +506,60 @@ void Slit::updateStrut(void) {
 
 
 void Slit::reposition(void) {
-  // place the slit in the appropriate place
-  switch (screen->getSlitPlacement()) {
-  case TopLeft:
-    frame.rect.setPos(0, 0);
-
-    if (screen->getSlitDirection() == Vertical) {
-      frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
-                       - frame.rect.width();
-      frame.y_hidden = 0;
-    } else {
-      frame.x_hidden = 0;
-      frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
-                       - frame.rect.height();
-    }
-    break;
+  int x = 0, y = 0;
 
+  switch (placement) {
+  case TopLeft:
   case CenterLeft:
-    frame.rect.setPos(0, (screen->getHeight() - frame.rect.height()) / 2);
-
+  case BottomLeft:
+    x = 0;
     frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
-                     - frame.rect.width();
-    frame.y_hidden = frame.rect.y();
-    break;
+      - frame.rect.width();
 
-  case BottomLeft:
-    frame.rect.setPos(0, (screen->getHeight() - frame.rect.height()
-                          - (screen->getBorderWidth() * 2)));
+    if (placement == TopLeft)
+      y = 0;
+    else if (placement == CenterLeft)
+      y = (screen->getHeight() - frame.rect.height()) / 2;
+    else
+      y = screen->getHeight() - frame.rect.height()
+        - (screen->getBorderWidth() * 2);
 
-    if (screen->getSlitDirection() == Vertical) {
-      frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
-                       - frame.rect.width();
-      frame.y_hidden = frame.rect.y();
-    } else {
-      frame.x_hidden = 0;
-      frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
-                       - screen->getBorderWidth();
-    }
     break;
 
   case TopCenter:
-    frame.rect.setPos((screen->getWidth() - frame.rect.width()) / 2, 0);
-
-    frame.x_hidden = frame.rect.x();
-    frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
-                     - frame.rect.height();
-    break;
-
   case BottomCenter:
-    frame.rect.setPos((screen->getWidth() - frame.rect.width()) / 2,
-                      (screen->getHeight() - frame.rect.height()
-                       - (screen->getBorderWidth() * 2)));
-    frame.x_hidden = frame.rect.x();
-    frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
-                     - screen->getBorderWidth();
-    break;
+    x = (screen->getWidth() - frame.rect.width()) / 2;
+    frame.x_hidden = x;
 
-  case TopRight:
-    frame.rect.setPos((screen->getWidth() - frame.rect.width()
-                       - (screen->getBorderWidth() * 2)), 0);
+    if (placement == TopCenter)
+      y = 0;
+    else
+      y = screen->getHeight() - frame.rect.height()
+        - (screen->getBorderWidth() * 2);
 
-    if (screen->getSlitDirection() == Vertical) {
-      frame.x_hidden = screen->getWidth() - screen->getBevelWidth()
-                       - screen->getBorderWidth();
-      frame.y_hidden = 0;
-    } else {
-      frame.x_hidden = frame.rect.x();
-      frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
-                       - frame.rect.height();
-    }
     break;
 
+  case TopRight:
   case CenterRight:
-  default:
-    frame.rect.setPos((screen->getWidth() - frame.rect.width()
-                       - (screen->getBorderWidth() * 2)),
-                      (screen->getHeight() - frame.rect.height()) / 2);
-
+  case BottomRight:
+    x = screen->getWidth() - frame.rect.width()
+      - (screen->getBorderWidth() * 2);
     frame.x_hidden = screen->getWidth() - screen->getBevelWidth()
-                     - screen->getBorderWidth();
-    frame.y_hidden = frame.rect.y();
-    break;
+      - screen->getBorderWidth();
 
-  case BottomRight:
-    frame.rect.setPos((screen->getWidth() - frame.rect.width()
-                       - (screen->getBorderWidth() * 2)),
-                      (screen->getHeight() - frame.rect.height()
-                       - (screen->getBorderWidth() * 2)));
-
-    if (screen->getSlitDirection() == Vertical) {
-      frame.x_hidden = screen->getWidth() - screen->getBevelWidth()
-                       - screen->getBorderWidth();
-      frame.y_hidden = frame.rect.y();
-    } else {
-      frame.x_hidden = frame.rect.x();
-      frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
-                       - screen->getBorderWidth();
-    }
+    if (placement == TopRight)
+      y = 0;
+    else if (placement == CenterRight)
+      y = (screen->getHeight() - frame.rect.height()) / 2;
+    else
+      y = screen->getHeight() - frame.rect.height()
+  - (screen->getBorderWidth() * 2);
     break;
   }
 
+  frame.rect.setPos(x, y);
+
+  // we have to add the border to the rect as it is not accounted for
   Rect tbar_rect = screen->getToolbar()->getRect();
   tbar_rect.setSize(tbar_rect.width() + (screen->getBorderWidth() * 2),
                     tbar_rect.height() + (screen->getBorderWidth() * 2));
@@ -514,26 +567,33 @@ void Slit::reposition(void) {
   slit_rect.setSize(slit_rect.width() + (screen->getBorderWidth() * 2),
                     slit_rect.height() + (screen->getBorderWidth() * 2));
 
-  if (slit_rect.intersects(tbar_rect)) {
-    Toolbar *tbar = screen->getToolbar();
-    frame.y_hidden = frame.rect.y();
-
-    int delta = tbar->getExposedHeight() + (screen->getBorderWidth() * 2);
-    if (frame.rect.bottom() <= tbar_rect.bottom()) {
+  if (! screen->doHideToolbar() && slit_rect.intersects(tbar_rect)) {
+    int delta = screen->getToolbar()->getExposedHeight() +
+      screen->getBorderWidth();
+    if (frame.rect.bottom() <= tbar_rect.bottom())
       delta = -delta;
-    }
+
     frame.rect.setY(frame.rect.y() + delta);
-    if (screen->getSlitDirection() == Vertical)
-      frame.y_hidden += delta;
   }
 
+  if (placement == TopCenter)
+    frame.y_hidden = 0 - frame.rect.height() + screen->getBorderWidth() 
+      + screen->getBevelWidth();
+  else if (placement == BottomCenter)
+    frame.y_hidden = screen->getHeight() - screen->getBorderWidth()
+      - screen->getBevelWidth();
+  else
+    frame.y_hidden = frame.rect.y();
+
   updateStrut();
 
   if (hidden)
-    XMoveResizeWindow(display, frame.window, frame.x_hidden,
-                      frame.y_hidden, frame.rect.width(), frame.rect.height());
+    XMoveResizeWindow(display, frame.window,
+                      frame.x_hidden, frame.y_hidden,
+                      frame.rect.width(), frame.rect.height());
   else
-    XMoveResizeWindow(display, frame.window, frame.rect.x(), frame.rect.y(),
+    XMoveResizeWindow(display, frame.window,
+                      frame.rect.x(), frame.rect.y(),
                       frame.rect.width(), frame.rect.height());
 }
 
@@ -544,7 +604,7 @@ void Slit::shutdown(void) {
 }
 
 
-void Slit::buttonPressEvent(XButtonEvent *e) {
+void Slit::buttonPressEvent(const XButtonEvent *e) {
   if (e->window != frame.window) return;
 
   if (e->button == Button1 && (! on_top)) {
@@ -578,7 +638,7 @@ void Slit::buttonPressEvent(XButtonEvent *e) {
 }
 
 
-void Slit::enterNotifyEvent(XCrossingEvent *) {
+void Slit::enterNotifyEvent(const XCrossingEvent *) {
   if (! do_auto_hide)
     return;
 
@@ -590,7 +650,7 @@ void Slit::enterNotifyEvent(XCrossingEvent *) {
 }
 
 
-void Slit::leaveNotifyEvent(XCrossingEvent *) {
+void Slit::leaveNotifyEvent(const XCrossingEvent *) {
   if (! do_auto_hide)
     return;
 
@@ -602,7 +662,7 @@ void Slit::leaveNotifyEvent(XCrossingEvent *) {
 }
 
 
-void Slit::configureRequestEvent(XConfigureRequestEvent *e) {
+void Slit::configureRequestEvent(const XConfigureRequestEvent *e) {
   if (! blackbox->validateWindow(e->window))
     return;
 
@@ -644,7 +704,7 @@ void Slit::timeout(void) {
 
 
 void Slit::toggleAutoHide(void) {
-  do_auto_hide = (do_auto_hide) ?  False : True;
+  saveAutoHide(do_auto_hide ?  False : True);
 
   updateStrut();
 
@@ -656,7 +716,7 @@ void Slit::toggleAutoHide(void) {
 }
 
 
-void Slit::unmapNotifyEvent(XUnmapEvent *e) {
+void Slit::unmapNotifyEvent(const XUnmapEvent *e) {
   removeClient(e->window);
 }
 
@@ -699,8 +759,8 @@ void Slitmenu::itemSelected(int button, unsigned int index) {
 
   switch (item->function()) {
   case 1: { // always on top
-    slit->on_top = ((slit->isOnTop()) ?  False : True);
-    setItemSelected(2, slit->on_top);
+    slit->saveOnTop(! slit->isOnTop());
+    setItemSelected(2, slit->isOnTop());
 
     if (slit->isOnTop()) slit->screen->raiseWindows((Window *) 0, 0);
     break;
@@ -708,7 +768,7 @@ void Slitmenu::itemSelected(int button, unsigned int index) {
 
   case 2: { // auto hide
     slit->toggleAutoHide();
-    setItemSelected(3, slit->do_auto_hide);
+    setItemSelected(3, slit->doAutoHide());
 
     break;
   }
@@ -732,7 +792,7 @@ void Slitmenu::reconfigure(void) {
 
 
 Slitmenu::Directionmenu::Directionmenu(Slitmenu *sm)
-  : Basemenu(sm->slit->screen) {
+  : Basemenu(sm->slit->screen), slit(sm->slit) {
 
   setLabel(i18n(SlitSet, SlitSlitDirection, "Slit Direction"));
   setInternalMenu();
@@ -743,11 +803,20 @@ Slitmenu::Directionmenu::Directionmenu(Slitmenu *sm)
          Slit::Vertical);
 
   update();
+  setValues();
+}
 
-  if (getScreen()->getSlitDirection() == Slit::Horizontal)
-    setItemSelected(0, True);
-  else
-    setItemSelected(1, True);
+
+void Slitmenu::Directionmenu::reconfigure(void) {
+  setValues();
+  Basemenu::reconfigure();
+}   
+
+
+void Slitmenu::Directionmenu::setValues(void) {
+  const bool horiz = slit->getDirection() == Slit::Horizontal;
+  setItemSelected(0, horiz);
+  setItemSelected(1, ! horiz);
 }
 
 
@@ -758,23 +827,14 @@ void Slitmenu::Directionmenu::itemSelected(int button, unsigned int index) {
   BasemenuItem *item = find(index);
   if (! item) return;
 
-  getScreen()->saveSlitDirection(item->function());
-
-  if (item->function() == Slit::Horizontal) {
-    setItemSelected(0, True);
-    setItemSelected(1, False);
-  } else {
-    setItemSelected(0, False);
-    setItemSelected(1, True);
-  }
-
+  slit->saveDirection(item->function());
   hide();
-  getScreen()->getSlit()->reconfigure();
+  slit->reconfigure();
 }
 
 
 Slitmenu::Placementmenu::Placementmenu(Slitmenu *sm)
-  : Basemenu(sm->slit->screen) {
+  : Basemenu(sm->slit->screen), slit(sm->slit) {
 
   setLabel(i18n(SlitSet, SlitSlitPlacement, "Slit Placement"));
   setMinimumSublevels(3);
@@ -799,6 +859,45 @@ Slitmenu::Placementmenu::Placementmenu(Slitmenu *sm)
          Slit::BottomRight);
 
   update();
+
+  setValues();
+}
+
+
+void Slitmenu::Placementmenu::reconfigure(void) {
+  setValues();
+  Basemenu::reconfigure();
+}   
+
+
+void Slitmenu::Placementmenu::setValues(void) {
+  int place = 0;
+  switch (slit->getPlacement()) {
+  case Slit::BottomRight:
+    place++;
+  case Slit::CenterRight:
+    place++;
+  case Slit::TopRight:
+    place++;
+  case Slit::BottomCenter:
+    place++;
+  case Slit::TopCenter:
+    place++;
+  case Slit::BottomLeft:
+    place++;
+  case Slit::CenterLeft:
+    place++;
+  case Slit::TopLeft:
+    break;
+  }
+  setItemSelected(0, 0 == place);
+  setItemSelected(1, 1 == place);
+  setItemSelected(2, 2 == place);
+  setItemSelected(3, 3 == place);
+  setItemSelected(5, 4 == place);
+  setItemSelected(6, 5 == place);
+  setItemSelected(7, 6 == place);
+  setItemSelected(8, 7 == place);
 }
 
 
@@ -809,8 +908,8 @@ void Slitmenu::Placementmenu::itemSelected(int button, unsigned int index) {
   BasemenuItem *item = find(index);
   if (! (item && item->function())) return;
 
-  getScreen()->saveSlitPlacement(item->function());
+  slit->savePlacement(item->function());
   hide();
-  getScreen()->getSlit()->reconfigure();
+  slit->reconfigure();
 }
 
This page took 0.03922 seconds and 4 git commands to generate.