On Thu, Apr 12, 2001 at 04:47:50PM +0200, Wilbert Berendsen wrote:
> Hi,
> 
> On my Pentium 75, I love to run blackbox. (Now I've a LFS system, with bb
> as the only available wm.)
> 
> But I notice, that when I use Smart Placement (Rows), Left to Right, Top
> to Bottom, Blackbox places new windows very quick when there is room at
> the top, but when tere is only room at the bottom, Blackbox calculates
> almost 2 seconds on my machine before the window pops up!
> 
> Perhaps the Smart Placement code needs to be smarter? (did'nt look in the
> source right now)

Oh, yes, it could do to be a _whole_ lot smarter... the catch is finding
a balance between smarter and faster. Attached is a patch which rewrites
the smart-placement code so that it uses some non-optimal, but hopefully
good enough, shortcuts.

Now, I don't use smart placement myself, so God only knows if it still
works like it was supposed to (or at all)... if folks used to the usual
smart placement could test it out it would be much appreciated (and for
people on low-end boxes, I'm also curious if it's actually any faster).

Jeff Raven
diff -ur blackbox-0.61.1/src/Workspace.cc blackbox-0.61.1-smarter/src/Workspace.cc
--- blackbox-0.61.1/src/Workspace.cc    Thu Oct  5 12:29:50 2000
+++ blackbox-0.61.1-smarter/src/Workspace.cc    Tue May  1 23:12:14 2001
@@ -334,160 +334,147 @@
 
 
 void Workspace::placeWindow(BlackboxWindow *win) {
-  Bool placed = False;
+  bool placed = false,
+       x_reversed = (screen->getRowPlacementDirection() == BScreen::RightLeft),
+       y_reversed = (screen->getColPlacementDirection() == BScreen::BottomTop);
   LinkedListIterator<BlackboxWindow> it(windowList);
-  int win_w = win->getWidth() + (screen->getBorderWidth2x() * 2),
-    win_h = win->getHeight() + (screen->getBorderWidth2x() * 2),
+
+  int win_w = win->getWidth() + screen->getBorderWidth2x(),
+      win_h = win->getHeight() + screen->getBorderWidth2x(),
+      min_x = screen->getBorderWidth(), max_x = screen->getWidth() - win_w,
+      min_y = screen->getBorderWidth(), max_y = screen->getHeight() - win_h,
 #ifdef    SLIT
-    slit_x = screen->getSlit()->getX() - screen->getBorderWidth(),
-    slit_y = screen->getSlit()->getY() - screen->getBorderWidth(),
-    slit_w = screen->getSlit()->getWidth() +
-      (screen->getBorderWidth2x() * 2),
-    slit_h = screen->getSlit()->getHeight() +
-      (screen->getBorderWidth2x() * 2),
+      slit_x = screen->getSlit()->getX() - screen->getBorderWidth(),
+      slit_y = screen->getSlit()->getY() - screen->getBorderWidth(),
+      slit_w = screen->getSlit()->getWidth() + screen->getBorderWidth2x(),
+      slit_h = screen->getSlit()->getHeight() + screen->getBorderWidth2x(),
 #endif // SLIT
-    toolbar_x = screen->getToolbar()->getX() - screen->getBorderWidth(),
-    toolbar_y = screen->getToolbar()->getY() - screen->getBorderWidth(),
-    toolbar_w = screen->getToolbar()->getWidth() +
-      (screen->getBorderWidth2x() * 2),
-    toolbar_h = screen->getToolbar()->getHeight() +
-      (screen->getBorderWidth2x() * 2),
-    place_x = 0, place_y = 0, change_x = 1, change_y = 1;
-
-  if (screen->getColPlacementDirection() == BScreen::BottomTop)
-    change_y = -1;
-  if (screen->getRowPlacementDirection() == BScreen::RightLeft)
-    change_x = -1;
-
-  register int test_x, test_y, curr_w, curr_h;
-
-  switch (screen->getPlacementPolicy()) {
-  case BScreen::RowSmartPlacement: {
-    test_y = screen->getBorderWidth() + screen->getEdgeSnapThreshold();
-    if (screen->getColPlacementDirection() == BScreen::BottomTop)
-      test_y = screen->getHeight() - win_h - test_y;
-
-    while (((screen->getColPlacementDirection() == BScreen::BottomTop) ?
-           test_y > 0 :    test_y + win_h < (signed) screen->getHeight()) &&
-          ! placed) {
-      test_x = screen->getBorderWidth() + screen->getEdgeSnapThreshold();
-      if (screen->getRowPlacementDirection() == BScreen::RightLeft)
-       test_x = screen->getWidth() - win_w - test_x;
-
-      while (((screen->getRowPlacementDirection() == BScreen::RightLeft) ?
-             test_x > 0 : test_x + win_w < (signed) screen->getWidth()) &&
-            ! placed) {
-        placed = True;
-
-        it.reset();
-        for (; it.current() && placed; it++) {
-          curr_w = it.current()->getWidth() + screen->getBorderWidth2x() +
-            screen->getBorderWidth2x();
-          curr_h =
-            ((it.current()->isShaded()) ? it.current()->getTitleHeight() :
-                                          it.current()->getHeight()) +
-            screen->getBorderWidth2x() + screen->getBorderWidth2x();
-
-          if (it.current()->getXFrame() < test_x + win_w &&
-              it.current()->getXFrame() + curr_w > test_x &&
-              it.current()->getYFrame() < test_y + win_h &&
-              it.current()->getYFrame() + curr_h > test_y)
-            placed = False;
-        }
-
-        if ((toolbar_x < test_x + win_w &&
-             toolbar_x + toolbar_w > test_x &&
-             toolbar_y < test_y + win_h &&
-             toolbar_y + toolbar_h > test_y)
+      toolbar_x = screen->getToolbar()->getX() - screen->getBorderWidth(),
+      toolbar_y = screen->getToolbar()->getY() - screen->getBorderWidth(),
+      toolbar_w = screen->getToolbar()->getWidth() + screen->getBorderWidth2x(),
+      toolbar_h = screen->getToolbar()->getHeight() + screen->getBorderWidth2x(),
+      place_x = 0, place_y = 0, test_x = 0, test_y = 0;
+
+  if (screen->getPlacementPolicy() == BScreen::RowSmartPlacement) {
+    int next_y = (y_reversed ? min_y - 1 : max_y + 1);
+
+    test_x = (x_reversed ? max_x : min_x);
+    test_y = (y_reversed ? max_y : min_y);
+
+    while (! placed) {
+      if ((test_x < min_x) || (test_x > max_x)) {
+       test_y = next_y;
+       test_x = (x_reversed ? max_x : min_x);
+       next_y = (y_reversed ? min_y - 1 : max_y + 1);
+      }
+      if ((test_y < min_y) || (test_y > max_y)) break;
+
+      if (toolbar_x < test_x + win_w     &&
+          toolbar_x + toolbar_w > test_x &&
+          toolbar_y < test_y + win_h     &&
+          toolbar_y + toolbar_h > test_y) {
+       test_x = (x_reversed ? toolbar_x - win_w : toolbar_x + toolbar_w);
+       if (y_reversed)
+         next_y = max(next_y, toolbar_y - win_h);
+       else
+         next_y = min(next_y, toolbar_y + toolbar_h);
 #ifdef    SLIT
-             ||
-            (slit_x < test_x + win_w &&
-             slit_x + slit_w > test_x &&
-             slit_y < test_y + win_h &&
-             slit_y + slit_h > test_y)
+      } else if (slit_x < test_x + win_w  &&
+                 slit_x + slit_w > test_x &&
+                 slit_y < test_y + win_h  &&
+                 slit_y + slit_h > test_y) {
+       test_x = (x_reversed ? slit_x - win_w : slit_x + slit_w);
+       if (y_reversed)
+         next_y = max(next_y, slit_y - win_h);
+       else
+         next_y = min(next_y, slit_y + slit_h);
 #endif // SLIT
-          )
-          placed = False;
-
-        if (placed) {
-          place_x = test_x;
-          place_y = test_y;
-
-          break;
-        }
-
-        test_x += change_x;
+      } else {
+       it.reset();
+       placed = True;
+       for (; it.current() && placed; it++) {
+         int curr_x = it.current()->getXFrame(),
+             curr_y = it.current()->getYFrame(),
+             curr_w = it.current()->getWidth() + screen->getBorderWidth2x(),
+             curr_h = it.current()->getHeight() + screen->getBorderWidth2x();
+
+          if (curr_x < test_x + win_w  &&
+              curr_x + curr_w > test_x &&
+              curr_y < test_y + win_h  &&
+              curr_y + curr_h > test_y) {
+           test_x = (x_reversed ? curr_x - win_w : curr_x + curr_w);
+           if (y_reversed)
+             next_y = max(next_y, curr_y - win_h);
+           else
+             next_y = min(next_y, curr_y + curr_h);
+           placed = false;
+         }
+       }
       }
-
-      test_y += change_y;
     }
+  } else if (screen->getPlacementPolicy() == BScreen::ColSmartPlacement) {
+    int next_x = (x_reversed ? min_x - 1 : max_x + 1);
+
+    test_x = (x_reversed ? max_x : min_x);
+    test_y = (y_reversed ? max_y : min_y);
 
-    break; }
+    while (! placed) {
+      if ((test_y < min_y) || (test_y > max_y)) {
+       test_x = next_x;
+       test_y = (y_reversed ? max_y : min_y);
+       next_x = (x_reversed ? min_x - 1 : max_x + 1);
+      }
+      if ((test_x < min_x) || (test_x > max_x)) break;
 
-  case BScreen::ColSmartPlacement: {
-    test_x = screen->getBorderWidth() + screen->getEdgeSnapThreshold();
-    if (screen->getRowPlacementDirection() == BScreen::RightLeft)
-      test_x = screen->getWidth() - win_w - test_x;
-
-    while (((screen->getRowPlacementDirection() == BScreen::RightLeft) ?
-           test_x > 0 : test_x + win_w < (signed) screen->getWidth()) &&
-          ! placed) {
-      test_y = screen->getBorderWidth() + screen->getEdgeSnapThreshold();
-      if (screen->getColPlacementDirection() == BScreen::BottomTop)
-       test_y = screen->getHeight() - win_h - test_y;
-
-      while (((screen->getColPlacementDirection() == BScreen::BottomTop) ?
-             test_y > 0 : test_y + win_h < (signed) screen->getHeight()) &&
-            ! placed) {
-        placed = True;
-
-        it.reset();
-        for (; it.current() && placed; it++) {
-          curr_w = it.current()->getWidth() + screen->getBorderWidth2x() +
-            screen->getBorderWidth2x();
-          curr_h =
-            ((it.current()->isShaded()) ? it.current()->getTitleHeight() :
-                                          it.current()->getHeight()) +
-            screen->getBorderWidth2x() + screen->getBorderWidth2x();
-
-          if (it.current()->getXFrame() < test_x + win_w &&
-              it.current()->getXFrame() + curr_w > test_x &&
-              it.current()->getYFrame() < test_y + win_h &&
-              it.current()->getYFrame() + curr_h > test_y)
-            placed = False;
-        }
-
-        if ((toolbar_x < test_x + win_w &&
-             toolbar_x + toolbar_w > test_x &&
-             toolbar_y < test_y + win_h &&
-             toolbar_y + toolbar_h > test_y)
+      if (toolbar_x < test_x + win_w     &&
+          toolbar_x + toolbar_w > test_x &&
+          toolbar_y < test_y + win_h     &&
+          toolbar_y + toolbar_h > test_y) {
+       test_y = (y_reversed ? toolbar_y - win_h : toolbar_y + toolbar_h);
+       if (x_reversed)
+         next_x = max(next_x, toolbar_x - win_w);
+       else
+         next_x = min(next_x, toolbar_x + toolbar_w);
 #ifdef    SLIT
-             ||
-            (slit_x < test_x + win_w &&
-             slit_x + slit_w > test_x &&
-             slit_y < test_y + win_h &&
-             slit_y + slit_h > test_y)
+      } else if (slit_x < test_x + win_w  &&
+                 slit_x + slit_w > test_x &&
+                 slit_y < test_y + win_h  &&
+                 slit_y + slit_h > test_y) {
+       test_y = (y_reversed ? slit_y - win_h : slit_y + slit_h);
+       if (x_reversed)
+         next_x = max(next_x, slit_x - win_w);
+       else
+         next_x = min(next_x, slit_x + slit_w);
 #endif // SLIT
-         )
-         placed = False;
-
-       if (placed) {
-         place_x = test_x;
-         place_y = test_y;
-
-         break;
-       }
-
-       test_y += change_y;
-     }
-
-     test_x += change_x;
-   }
-
-   break; }
+      } else {
+       it.reset();
+       placed = True;
+       for (; it.current() && placed; it++) {
+         int curr_x = it.current()->getXFrame(),
+             curr_y = it.current()->getYFrame(),
+             curr_w = it.current()->getWidth() + screen->getBorderWidth2x(),
+             curr_h = it.current()->getHeight() + screen->getBorderWidth2x();
+
+          if (curr_x < test_x + win_w  &&
+              curr_x + curr_w > test_x &&
+              curr_y < test_y + win_h  &&
+              curr_y + curr_h > test_y) {
+           test_y = (y_reversed ? curr_y - win_h : curr_y + curr_h);
+           if (x_reversed)
+             next_x = max(next_x, curr_x - win_w);
+           else
+             next_x = min(next_x, curr_x + curr_w);
+           placed = false;
+         }
+       }
+      }
+    }
   }
 
-  if (! placed) {
+  if (placed) {
+    place_x = test_x;
+    place_y = test_y;
+  } else {
     if (((unsigned) cascade_x > (screen->getWidth() / 2)) ||
        ((unsigned) cascade_y > (screen->getHeight() / 2)))
       cascade_x = cascade_y = 32;

Reply via email to