#endif // HAVE_STRING_H
}
+#include <assert.h>
+
#include <functional>
#include <string>
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());
wkspc->stackingList.push_back((*it));
}
}
-
}
XLowerWindow(screen->getBaseDisplay()->getXDisplay(), stack_vector.front());
XRestackWindows(screen->getBaseDisplay()->getXDisplay(),
&stack_vector[0], stack_vector.size());
+ screen->lowerDesktops();
}
}
+void Workspace::appendStackOrder(BlackboxWindowList &stack_order) const {
+ BlackboxWindowList::const_iterator it = stackingList.begin();
+ const BlackboxWindowList::const_iterator end = stackingList.end();
+ for (; it != end; ++it)
+ stack_order.push_back(*it);
+}
+
+
bool Workspace::isCurrent(void) const {
return (id == screen->getCurrentWorkspaceID());
}
spaces.push_back(availableArea); //initially the entire screen is free
//Find Free Spaces
- BlackboxWindowList::iterator wit = windowList.begin(),
- end = windowList.end();
+ 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());
if (screen->getPlacementPolicy() == BScreen::RowSmartPlacement) {
if(screen->getRowPlacementDirection() == BScreen::LeftRight) {
if(screen->getColPlacementDirection() == BScreen::TopBottom)
- sort(spaces.begin(), spaces.end(), rowLRTB);
+ std::sort(spaces.begin(), spaces.end(), rowLRTB);
else
- sort(spaces.begin(), spaces.end(), rowLRBT);
+ std::sort(spaces.begin(), spaces.end(), rowLRBT);
} else {
if(screen->getColPlacementDirection() == BScreen::TopBottom)
- sort(spaces.begin(), spaces.end(), rowRLTB);
+ std::sort(spaces.begin(), spaces.end(), rowRLTB);
else
- sort(spaces.begin(), spaces.end(), rowRLBT);
+ std::sort(spaces.begin(), spaces.end(), rowRLBT);
}
} else {
if(screen->getColPlacementDirection() == BScreen::TopBottom) {
if(screen->getRowPlacementDirection() == BScreen::LeftRight)
- sort(spaces.begin(), spaces.end(), colLRTB);
+ std::sort(spaces.begin(), spaces.end(), colLRTB);
else
- sort(spaces.begin(), spaces.end(), colRLTB);
+ std::sort(spaces.begin(), spaces.end(), colRLTB);
} else {
if(screen->getRowPlacementDirection() == BScreen::LeftRight)
- sort(spaces.begin(), spaces.end(), colLRBT);
+ std::sort(spaces.begin(), spaces.end(), colLRBT);
else
- sort(spaces.begin(), spaces.end(), colRLBT);
+ std::sort(spaces.begin(), spaces.end(), colRLBT);
}
}
}
+bool Workspace::underMousePlacement(Rect &win, const Rect &availableArea) {
+ int x, y, rx, ry;
+ Window c, r;
+ unsigned int m;
+ XQueryPointer(screen->getBlackbox()->getXDisplay(), screen->getRootWindow(),
+ &r, &c, &rx, &ry, &x, &y, &m);
+ x = rx - win.width() / 2;
+ y = ry - win.height() / 2;
+
+ if (x < availableArea.x())
+ x = availableArea.x();
+ if (y < availableArea.y())
+ y = availableArea.y();
+ if (x + win.width() > availableArea.x() + availableArea.width())
+ x = availableArea.x() + availableArea.width() - win.width();
+ if (y + win.height() > availableArea.y() + availableArea.height())
+ y = availableArea.y() + availableArea.height() - win.height();
+
+ win.setX(x);
+ win.setY(y);
+
+ return True;
+}
+
+
bool Workspace::cascadePlacement(Rect &win, const Rect &availableArea) {
if ((cascade_x > static_cast<signed>(availableArea.width() / 2)) ||
(cascade_y > static_cast<signed>(availableArea.height() / 2)))
case BScreen::ColSmartPlacement:
placed = smartPlacement(new_win, availableArea);
break;
+ case BScreen::UnderMousePlacement:
+ placed = underMousePlacement(new_win, availableArea);
default:
break; // handled below
} // switch