- switch (screen->getPlacementPolicy()) {
- case BScreen::RowSmartPlacement: {
- test_y = (screen->getColPlacementDirection() == BScreen::TopBottom) ?
- start_pos : screen->getHeight() - win_h - start_pos;
-
- while (!placed &&
- ((screen->getColPlacementDirection() == BScreen::BottomTop) ?
- test_y > 0 : test_y + win_h < (signed) screen->getHeight())) {
- test_x = (screen->getRowPlacementDirection() == BScreen::LeftRight) ?
- start_pos : screen->getWidth() - win_w - start_pos;
-
- while (!placed &&
- ((screen->getRowPlacementDirection() == BScreen::RightLeft) ?
- test_x > 0 : test_x + win_w < (signed) screen->getWidth())) {
- placed = True;
-
- it.reset();
- for (OpenboxWindow *curr = it.current(); placed && curr;
- it++, curr = it.current()) {
- if (curr->isMaximizedFull()) // fully maximized, ignore it
- continue;
- int curr_w = curr->getWidth() + (screen->getBorderWidth() * 4);
- int curr_h =
- ((curr->isShaded()) ? curr->getTitleHeight() : curr->getHeight()) +
- (screen->getBorderWidth() * 4);
-
- if (curr->getXFrame() < test_x + win_w &&
- curr->getXFrame() + curr_w > test_x &&
- curr->getYFrame() < test_y + win_h &&
- curr->getYFrame() + curr_h > test_y) {
- placed = False;
- }
- }
-
- if (placed &&
- (toolbar_x < test_x + win_w &&
- toolbar_x + toolbar_w > test_x &&
- toolbar_y < test_y + win_h &&
- toolbar_y + toolbar_h > test_y)
-#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)
-#endif // SLIT
- )
- placed = False;
-
- if (placed) {
- place_x = test_x;
- place_y = test_y;
-
- break;
- }
-
- test_x += (change_x * delta_x);
- }
-
- test_y += (change_y * delta_y);
+static bool rowRLBT(const Rect &first, const Rect &second) {
+ if (first.bottom() == second.bottom())
+ return first.right() > second.right();
+ return first.bottom() > second.bottom();
+}
+
+static bool rowRLTB(const Rect &first, const Rect &second) {
+ if (first.y() == second.y())
+ return first.right() > second.right();
+ return first.y() < second.y();
+}
+
+static bool rowLRBT(const Rect &first, const Rect &second) {
+ if (first.bottom() == second.bottom())
+ return first.x() < second.x();
+ return first.bottom() > second.bottom();
+}
+
+static bool rowLRTB(const Rect &first, const Rect &second) {
+ if (first.y() == second.y())
+ return first.x() < second.x();
+ return first.y() < second.y();
+}
+
+static bool colLRTB(const Rect &first, const Rect &second) {
+ if (first.x() == second.x())
+ return first.y() < second.y();
+ return first.x() < second.x();
+}
+
+static bool colLRBT(const Rect &first, const Rect &second) {
+ if (first.x() == second.x())
+ return first.bottom() > second.bottom();
+ return first.x() < second.x();
+}
+
+static bool colRLTB(const Rect &first, const Rect &second) {
+ if (first.right() == second.right())
+ return first.y() < second.y();
+ return first.right() > second.right();
+}
+
+static bool colRLBT(const Rect &first, const Rect &second) {
+ if (first.right() == second.right())
+ return first.bottom() > second.bottom();
+ return first.right() > second.right();
+}
+
+
+bool Workspace::smartPlacement(Rect& win, const Rect& availableArea) {
+ rectList spaces;
+ spaces.push_back(availableArea); //initially the entire screen is free
+
+ //Find Free Spaces
+ BlackboxWindowList::const_iterator wit = windowList.begin(),
+ end = windowList.end();
+ Rect tmp;
+ for (; wit != end; ++wit) {
+ const BlackboxWindow* const curr = *wit;
+
+ if (curr->isShaded()) continue;
+
+ tmp.setRect(curr->frameRect().x(), curr->frameRect().y(),
+ curr->frameRect().width() + screen->getBorderWidth(),
+ curr->frameRect().height() + screen->getBorderWidth());
+
+ spaces = calcSpace(tmp, spaces);
+ }
+
+ if (screen->getPlacementPolicy() == BScreen::RowSmartPlacement) {
+ if(screen->getRowPlacementDirection() == BScreen::LeftRight) {
+ if(screen->getColPlacementDirection() == BScreen::TopBottom)
+ std::sort(spaces.begin(), spaces.end(), rowLRTB);
+ else
+ std::sort(spaces.begin(), spaces.end(), rowLRBT);
+ } else {
+ if(screen->getColPlacementDirection() == BScreen::TopBottom)
+ std::sort(spaces.begin(), spaces.end(), rowRLTB);
+ else
+ std::sort(spaces.begin(), spaces.end(), rowRLBT);
+ }
+ } else {
+ if(screen->getColPlacementDirection() == BScreen::TopBottom) {
+ if(screen->getRowPlacementDirection() == BScreen::LeftRight)
+ std::sort(spaces.begin(), spaces.end(), colLRTB);
+ else
+ std::sort(spaces.begin(), spaces.end(), colRLTB);
+ } else {
+ if(screen->getRowPlacementDirection() == BScreen::LeftRight)
+ std::sort(spaces.begin(), spaces.end(), colLRBT);
+ else
+ std::sort(spaces.begin(), spaces.end(), colRLBT);