X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FWorkspace.cc;h=67e191107ccb851cf01987cf28fcd77bcb5de1e6;hb=72a2e98738d87b89620bafd15141690aa4be8fab;hp=70d1923c83788fe89bd6ec9f1a86ea65ad2fa1f5;hpb=86af1224bd80ed987f9c2389efa9bf9744ebada8;p=chaz%2Fopenbox diff --git a/src/Workspace.cc b/src/Workspace.cc index 70d1923c..67e19110 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -84,20 +84,19 @@ void Workspace::addWindow(BlackboxWindow *w, bool place, bool sticky) { if (place) placeWindow(w); stackingList.push_front(w); - - // if the window is sticky, then it needs to be added on all other - // workspaces too! - if (! sticky && w->isStuck()) { - for (unsigned int i = 0; i < screen->getWorkspaceCount(); ++i) - if (i != id) - screen->getWorkspace(i)->addWindow(w, place, True); - } - if (w->isNormal()) { + if (! sticky) + w->setWorkspace(id); + + if (! w->isNormal()) { if (! sticky) { - w->setWorkspace(id); - w->setWindowNumber(windowList.size()); + // just give it some number, else bad things happen as it is assumed to + // not be on a workspace + w->setWindowNumber(0); } + } else { + if (! sticky) + w->setWindowNumber(windowList.size()); windowList.push_back(w); @@ -109,9 +108,7 @@ void Workspace::addWindow(BlackboxWindow *w, bool place, bool sticky) { if (screen->doFocusNew() || (w->isTransient() && w->getTransientFor() && w->getTransientFor()->isFocused())) { - if (id == screen->getCurrentWorkspaceID()) - w->setInputFocus(); - else { + if (id != screen->getCurrentWorkspaceID()) { /* 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 @@ -140,14 +137,6 @@ void Workspace::removeWindow(BlackboxWindow *w, bool sticky) { focusFallback(w); } - // if the window is sticky, then it needs to be removed on all other - // workspaces too! - if (! sticky && w->isStuck()) { - for (unsigned int i = 0; i < screen->getWorkspaceCount(); ++i) - if (i != id) - screen->getWorkspace(i)->removeWindow(w, True); - } - if (! w->isNormal()) return; BlackboxWindowList::iterator it, end = windowList.end(); @@ -238,47 +227,57 @@ void Workspace::setFocused(const BlackboxWindow *w, bool focused) { } +void Workspace::removeAll(void) { + while (! windowList.empty()) + windowList.front()->iconify(); +} + void Workspace::showAll(void) { BlackboxWindowList::iterator it = stackingList.begin(); const BlackboxWindowList::iterator end = stackingList.end(); for (; it != end; ++it) { BlackboxWindow *bw = *it; - bw->show(); + // sticky windows arent unmapped on a workspace change so we don't have ot + // map them, but sometimes on a restart, another app can unmap our sticky + // windows, so we map on startup always + if (! bw->isStuck() || screen->getBlackbox()->isStartup()) + bw->show(); } } void Workspace::hideAll(void) { // withdraw in reverse order to minimize the number of Expose events - BlackboxWindowList::reverse_iterator it = stackingList.rbegin(); - const BlackboxWindowList::reverse_iterator end = stackingList.rend(); - while (it != end) { + + BlackboxWindowList lst(stackingList.rbegin(), stackingList.rend()); + + BlackboxWindowList::iterator it = lst.begin(); + const BlackboxWindowList::iterator end = lst.end(); + for (; it != end; ++it) { BlackboxWindow *bw = *it; - ++it; // withdraw removes the current item from the list so we need the next - // iterator before that happens - bw->withdraw(); + // don't hide sticky windows, or they'll end up flickering on a workspace + // change + if (! bw->isStuck()) + bw->withdraw(); } } -void Workspace::removeAll(void) { - while (! windowList.empty()) - windowList.front()->iconify(); -} - /* * returns the number of transients for win, plus the number of transients * associated with each transient of win */ -static int countTransients(const BlackboxWindow * const win) { - int ret = win->getTransients().size(); - if (ret > 0) { - BlackboxWindowList::const_iterator it, end = win->getTransients().end(); - for (it = win->getTransients().begin(); it != end; ++it) { - ret += countTransients(*it); - } - } +static unsigned int countTransients(const BlackboxWindow * const win) { + BlackboxWindowList transients = win->getTransients(); + if (transients.empty()) return 0; + + unsigned int ret = transients.size(); + BlackboxWindowList::const_iterator it = transients.begin(), + end = transients.end(); + for (; it != end; ++it) + ret += countTransients(*it); + return ret; } @@ -291,48 +290,48 @@ static int countTransients(const BlackboxWindow * const win) { */ void Workspace::raiseTransients(const BlackboxWindow * const win, StackVector::iterator &stack) { - if (win->getTransients().size() == 0) return; // nothing to do + if (win->getTransients().empty()) return; // nothing to do // put win's transients in the stack BlackboxWindowList::const_iterator it, end = win->getTransients().end(); for (it = win->getTransients().begin(); it != end; ++it) { - *stack++ = (*it)->getFrameWindow(); - screen->updateNetizenWindowRaise((*it)->getClientWindow()); - - if (! (*it)->isIconic()) { - Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber()); - wkspc->stackingList.remove((*it)); - wkspc->stackingList.push_front((*it)); + BlackboxWindow *w = *it; + *stack++ = w->getFrameWindow(); + screen->updateNetizenWindowRaise(w->getClientWindow()); + + if (! w->isIconic()) { + Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber()); + wkspc->stackingList.remove(w); + wkspc->stackingList.push_front(w); } } // put transients of win's transients in the stack - for (it = win->getTransients().begin(); it != end; ++it) { + for (it = win->getTransients().begin(); it != end; ++it) raiseTransients(*it, stack); - } } void Workspace::lowerTransients(const BlackboxWindow * const win, StackVector::iterator &stack) { - if (win->getTransients().size() == 0) return; // nothing to do + if (win->getTransients().empty()) return; // nothing to do // put transients of win's transients in the stack BlackboxWindowList::const_reverse_iterator it, end = win->getTransients().rend(); - for (it = win->getTransients().rbegin(); it != end; ++it) { + for (it = win->getTransients().rbegin(); it != end; ++it) lowerTransients(*it, stack); - } // put win's transients in the stack for (it = win->getTransients().rbegin(); it != end; ++it) { - *stack++ = (*it)->getFrameWindow(); - screen->updateNetizenWindowLower((*it)->getClientWindow()); - - if (! (*it)->isIconic()) { - Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber()); - wkspc->stackingList.remove((*it)); - wkspc->stackingList.push_back((*it)); + BlackboxWindow *w = *it; + *stack++ = w->getFrameWindow(); + screen->updateNetizenWindowLower(w->getClientWindow()); + + if (! w->isIconic()) { + Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber()); + wkspc->stackingList.remove(w); + wkspc->stackingList.push_back(w); } } } @@ -344,10 +343,8 @@ void Workspace::raiseWindow(BlackboxWindow *w) { if (win->isDesktop()) return; // walk up the transient_for's to the window that is not a transient - while (win->isTransient() && ! win->isDesktop()) { - if (! win->getTransientFor()) break; + while (win->isTransient() && win->getTransientFor()) win = win->getTransientFor(); - } // get the total window count (win and all transients) unsigned int i = 1 + countTransients(win); @@ -374,10 +371,8 @@ 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() && ! win->isDesktop()) { - if (! win->getTransientFor()) break; + while (win->isTransient() && win->getTransientFor()) win = win->getTransientFor(); - } // get the total window count (win and all transients) unsigned int i = 1 + countTransients(win); @@ -410,9 +405,11 @@ void Workspace::reconfigure(void) { BlackboxWindow *Workspace::getWindow(unsigned int index) { if (index < windowList.size()) { BlackboxWindowList::iterator it = windowList.begin(); - for(; index > 0; --index, ++it); /* increment to index */ + while (index-- > 0) // increment to index + ++it; return *it; } + return 0; } @@ -444,6 +441,7 @@ BlackboxWindow* Workspace::getPrevWindowInList(BlackboxWindow *w) { BlackboxWindow* Workspace::getTopWindowOnStack(void) const { + assert(! stackingList.empty()); return stackingList.front(); } @@ -465,10 +463,12 @@ 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) - if ((*it)->isNormal()) + // don't add desktop wnidows, or sticky windows more than once + if (! ( (*it)->isDesktop() || + ((*it)->isStuck() && id != screen->getCurrentWorkspaceID()))) stack_order.push_back(*it); } - + bool Workspace::isCurrent(void) const { return (id == screen->getCurrentWorkspaceID()); @@ -533,9 +533,8 @@ void Workspace::setName(const string& new_name) { /* * Calculate free space available for window placement. */ -typedef std::vector rectList; - -static rectList calcSpace(const Rect &win, const rectList &spaces) { +Workspace::rectList Workspace::calcSpace(const Rect &win, + const rectList &spaces) const { Rect isect, extra; rectList result; rectList::const_iterator siter, end = spaces.end(); @@ -556,21 +555,21 @@ static rectList calcSpace(const Rect &win, const rectList &spaces) { // left extra.setCoords(curr.left(), curr.top(), - isect.left() - 1, curr.bottom()); + isect.left() - screen->getSnapOffset(), curr.bottom()); if (extra.valid()) result.push_back(extra); // top extra.setCoords(curr.left(), curr.top(), - curr.right(), isect.top() - 1); + curr.right(), isect.top() - screen->getSnapOffset()); if (extra.valid()) result.push_back(extra); // right - extra.setCoords(isect.right() + 1, curr.top(), + extra.setCoords(isect.right() + screen->getSnapOffset(), curr.top(), curr.right(), curr.bottom()); if (extra.valid()) result.push_back(extra); // bottom - extra.setCoords(curr.left(), isect.bottom() + 1, + extra.setCoords(curr.left(), isect.bottom() + screen->getSnapOffset(), curr.right(), curr.bottom()); if (extra.valid()) result.push_back(extra); } @@ -637,11 +636,24 @@ bool Workspace::smartPlacement(Rect& win) { RectList availableAreas = screen->allAvailableAreas(); RectList::iterator it, end = availableAreas.end(); - for (it = availableAreas.begin(); it != end; ++it) + for (it = availableAreas.begin(); it != end; ++it) { + Rect r = *it; + r.setRect(r.x() + screen->getSnapOffset(), + r.y() + screen->getSnapOffset(), + r.width() - screen->getSnapOffset(), + r.height() - screen->getSnapOffset()); spaces.push_back(*it); + } } else #endif // XINERAMA - spaces.push_back(screen->availableArea()); + { + Rect r = screen->availableArea(); + r.setRect(r.x() + screen->getSnapOffset(), + r.y() + screen->getSnapOffset(), + r.width() - screen->getSnapOffset(), + r.height() - screen->getSnapOffset()); + spaces.push_back(r); + } //Find Free Spaces BlackboxWindowList::const_iterator wit = windowList.begin(),