X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FWorkspace.cc;h=366e8192e616e3f96dbfa093a8f489fb6e54e5a6;hb=733b4f4a3366eca53dc68fd40069b673b0261c96;hp=586adbadcf3f3fa99a2dd790757aa00e58a5cc86;hpb=5cf86b186c89ffb87f02ab732aa113ce8025dc2a;p=chaz%2Fopenbox diff --git a/src/Workspace.cc b/src/Workspace.cc index 586adbad..366e8192 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -48,6 +48,7 @@ using std::string; #include "i18n.hh" #include "blackbox.hh" #include "Clientmenu.hh" +#include "Font.hh" #include "Netizen.hh" #include "Screen.hh" #include "Toolbar.hh" @@ -62,7 +63,10 @@ Workspace::Workspace(BScreen *scrn, unsigned int i) { screen = scrn; xatom = screen->getBlackbox()->getXAtom(); - cascade_x = cascade_y = 32; + cascade_x = cascade_y = 0; +#ifdef XINERAMA + cascade_region = 0; +#endif // XINERAMA id = i; @@ -79,22 +83,38 @@ void Workspace::addWindow(BlackboxWindow *w, bool place) { if (place) placeWindow(w); - w->setWorkspace(id); - w->setWindowNumber(windowList.size()); - stackingList.push_front(w); - windowList.push_back(w); + + if (w->isNormal()) { + w->setWorkspace(id); + w->setWindowNumber(windowList.size()); - clientmenu->insert(w->getTitle()); - clientmenu->update(); + windowList.push_back(w); - screen->updateNetizenWindowAdd(w->getClientWindow(), id); + clientmenu->insert(w->getTitle()); + clientmenu->update(); + + screen->updateNetizenWindowAdd(w->getClientWindow(), id); + + if (id != screen->getCurrentWorkspaceID() && + screen->doFocusNew()) { + /* + not on the focused workspace, so the window is not going to get focus + but if the user wants new windows focused, then it should get focus + when this workspace does become focused. + */ + lastfocus = w; + } + } - raiseWindow(w); + if (! w->isDesktop()) + raiseWindow(w); + else + lowerWindow(w); } -unsigned int Workspace::removeWindow(BlackboxWindow *w) { +void Workspace::removeWindow(BlackboxWindow *w) { assert(w != 0); stackingList.remove(w); @@ -113,6 +133,8 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { } } + if (! w->isNormal()) return; + windowList.remove(w); clientmenu->remove(w->getWindowNumber()); clientmenu->update(); @@ -125,10 +147,12 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { for (; it != end; ++it, ++i) (*it)->setWindowNumber(i); - if (i == 0) - cascade_x = cascade_y = 32; - - return i; + if (i == 0) { + cascade_x = cascade_y = 0; +#ifdef XINERAMA + cascade_region = 0; +#endif // XINERAMA + } } @@ -154,7 +178,7 @@ void Workspace::focusFallback(const BlackboxWindow *old_window) { end = stackingList.end(); for (; it != end; ++it) { BlackboxWindow *tmp = *it; - if (tmp && tmp->setInputFocus()) { + if (tmp && tmp->isNormal() && tmp->setInputFocus()) { // we found our new focus target newfocus = tmp; break; @@ -178,20 +202,24 @@ void Workspace::focusFallback(const BlackboxWindow *old_window) { void Workspace::showAll(void) { - std::for_each(stackingList.begin(), stackingList.end(), - std::mem_fun(&BlackboxWindow::show)); + BlackboxWindowList::iterator it = stackingList.begin(); + const BlackboxWindowList::iterator end = stackingList.end(); + for (; it != end; ++it) { + BlackboxWindow *bw = *it; + if (! bw->isStuck()) + bw->show(); + } } void Workspace::hideAll(void) { // withdraw in reverse order to minimize the number of Expose events - - BlackboxWindowList lst(stackingList.rbegin(), stackingList.rend()); - - BlackboxWindowList::iterator it = lst.begin(); - const BlackboxWindowList::iterator end = lst.end(); - for (; it != end; ++it) { + BlackboxWindowList::reverse_iterator it = stackingList.rbegin(); + const BlackboxWindowList::reverse_iterator end = stackingList.rend(); + while (it != end) { BlackboxWindow *bw = *it; + ++it; // withdraw removes the current item from the list so we need the next + // iterator before that happens if (! bw->isStuck()) bw->withdraw(); } @@ -278,8 +306,10 @@ void Workspace::lowerTransients(const BlackboxWindow * const win, void Workspace::raiseWindow(BlackboxWindow *w) { BlackboxWindow *win = w; + if (win->isDesktop()) return; + // walk up the transient_for's to the window that is not a transient - while (win->isTransient()) { + while (win->isTransient() && ! win->isDesktop()) { if (! win->getTransientFor()) break; win = win->getTransientFor(); } @@ -293,7 +323,7 @@ void Workspace::raiseWindow(BlackboxWindow *w) { *(stack++) = win->getFrameWindow(); screen->updateNetizenWindowRaise(win->getClientWindow()); - if (! win->isIconic()) { + if (! (win->isIconic() || win->isDesktop())) { Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber()); wkspc->stackingList.remove(win); wkspc->stackingList.push_front(win); @@ -309,7 +339,7 @@ void Workspace::lowerWindow(BlackboxWindow *w) { BlackboxWindow *win = w; // walk up the transient_for's to the window that is not a transient - while (win->isTransient()) { + while (win->isTransient() && ! win->isDesktop()) { if (! win->getTransientFor()) break; win = win->getTransientFor(); } @@ -325,7 +355,7 @@ void Workspace::lowerWindow(BlackboxWindow *w) { *(stack++) = win->getFrameWindow(); screen->updateNetizenWindowLower(win->getClientWindow()); - if (! win->isIconic()) { + if (! (win->isIconic() || win->isDesktop())) { Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber()); wkspc->stackingList.remove(win); wkspc->stackingList.push_back(win); @@ -400,7 +430,8 @@ void Workspace::appendStackOrder(BlackboxWindowList &stack_order) const { BlackboxWindowList::const_reverse_iterator it = stackingList.rbegin(); const BlackboxWindowList::const_reverse_iterator end = stackingList.rend(); for (; it != end; ++it) - stack_order.push_back(*it); + if ((*it)->isNormal()) + stack_order.push_back(*it); } @@ -561,9 +592,21 @@ static bool colRLBT(const Rect &first, const Rect &second) { } -bool Workspace::smartPlacement(Rect& win, const Rect& availableArea) { +bool Workspace::smartPlacement(Rect& win) { rectList spaces; - spaces.push_back(availableArea); //initially the entire screen is free + + //initially the entire screen is free +#ifdef XINERAMA + if (screen->isXineramaActive() && + screen->getBlackbox()->doXineramaPlacement()) { + RectList availableAreas = screen->allAvailableAreas(); + RectList::iterator it, end = availableAreas.end(); + + for (it = availableAreas.begin(); it != end; ++it) + spaces.push_back(*it); + } else +#endif // XINERAMA + spaces.push_back(screen->availableArea()); //Find Free Spaces BlackboxWindowList::const_iterator wit = windowList.begin(), @@ -638,23 +681,39 @@ bool Workspace::smartPlacement(Rect& win, const Rect& availableArea) { } -bool Workspace::underMousePlacement(Rect &win, const Rect &availableArea) { +bool Workspace::underMousePlacement(Rect &win) { int x, y, rx, ry; Window c, r; unsigned int m; XQueryPointer(screen->getBlackbox()->getXDisplay(), screen->getRootWindow(), &r, &c, &rx, &ry, &x, &y, &m); + + Rect area; +#ifdef XINERAMA + if (screen->isXineramaActive() && + screen->getBlackbox()->doXineramaPlacement()) { + RectList availableAreas = screen->allAvailableAreas(); + RectList::iterator it, end = availableAreas.end(); + + for (it = availableAreas.begin(); it != end; ++it) + if (it->contains(rx, ry)) break; + assert(it != end); // the mouse isn't inside an area? + area = *it; + } else +#endif // XINERAMA + area = screen->availableArea(); + 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(); + if (x < area.x()) + x = area.x(); + if (y < area.y()) + y = area.y(); + if (x + win.width() > area.x() + area.width()) + x = area.x() + area.width() - win.width(); + if (y + win.height() > area.y() + area.height()) + y = area.y() + area.height() - win.height(); win.setX(x); win.setY(y); @@ -663,48 +722,69 @@ bool Workspace::underMousePlacement(Rect &win, const Rect &availableArea) { } -bool Workspace::cascadePlacement(Rect &win, const Rect &availableArea) { - if ((cascade_x > static_cast(availableArea.width() / 2)) || - (cascade_y > static_cast(availableArea.height() / 2))) - cascade_x = cascade_y = 32; +bool Workspace::cascadePlacement(Rect &win, const int offset) { + Rect area; + +#ifdef XINERAMA + if (screen->isXineramaActive() && + screen->getBlackbox()->doXineramaPlacement()) { + area = screen->allAvailableAreas()[cascade_region]; + } else +#endif // XINERAMA + area = screen->availableArea(); + + if ((static_cast(cascade_x + win.width()) > area.right() + 1) || + (static_cast(cascade_y + win.height()) > area.bottom() + 1)) { + cascade_x = cascade_y = 0; +#ifdef XINERAMA + if (screen->isXineramaActive() && + screen->getBlackbox()->doXineramaPlacement()) { + // go to the next xinerama region, and use its area + if (++cascade_region >= screen->allAvailableAreas().size()) + cascade_region = 0; + area = screen->allAvailableAreas()[cascade_region]; + } +#endif // XINERAMA + } - if (cascade_x == 32) { - cascade_x += availableArea.x(); - cascade_y += availableArea.y(); + if (cascade_x == 0) { + cascade_x = area.x() + offset; + cascade_y = area.y() + offset; } win.setPos(cascade_x, cascade_y); + cascade_x += offset; + cascade_y += offset; + return True; } void Workspace::placeWindow(BlackboxWindow *win) { - Rect availableArea(screen->availableArea()), - new_win(availableArea.x(), availableArea.y(), - win->frameRect().width(), win->frameRect().height()); + Rect new_win(0, 0, win->frameRect().width(), win->frameRect().height()); bool placed = False; switch (screen->getPlacementPolicy()) { case BScreen::RowSmartPlacement: case BScreen::ColSmartPlacement: - placed = smartPlacement(new_win, availableArea); + placed = smartPlacement(new_win); break; case BScreen::UnderMousePlacement: - placed = underMousePlacement(new_win, availableArea); + case BScreen::ClickMousePlacement: + placed = underMousePlacement(new_win); default: break; // handled below } // switch - if (placed == False) { - cascadePlacement(new_win, availableArea); - cascade_x += win->getTitleHeight() + (screen->getBorderWidth() * 2); - cascade_y += win->getTitleHeight() + (screen->getBorderWidth() * 2); - } + if (placed == False) + cascadePlacement(new_win, (win->getTitleHeight() + + screen->getBorderWidth() * 2)); + + if (new_win.right() > screen->availableArea().right()) + new_win.setX(screen->availableArea().left()); + if (new_win.bottom() > screen->availableArea().bottom()) + new_win.setY(screen->availableArea().top()); - if (new_win.right() > availableArea.right()) - new_win.setX(availableArea.left()); - if (new_win.bottom() > availableArea.bottom()) - new_win.setY(availableArea.top()); win->configure(new_win.x(), new_win.y(), new_win.width(), new_win.height()); }