X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FWorkspace.cc;h=11d5187ddf35512a8a9cfbc69fecff71d3f16c91;hb=c5d10bd1dda362a41460f91619ae5e85a7665f6f;hp=a7887945470223faa69d5b12ce458816fd2f4332;hpb=809f819e6f93a599e6312d5c4f226b339b9456f1;p=chaz%2Fopenbox diff --git a/src/Workspace.cc b/src/Workspace.cc index a7887945..11d5187d 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -78,32 +78,37 @@ Workspace::Workspace(BScreen *scrn, unsigned int i) { } -void Workspace::addWindow(BlackboxWindow *w, bool place) { +void Workspace::addWindow(BlackboxWindow *w, bool place, bool sticky) { assert(w != 0); if (place) placeWindow(w); stackingList.push_front(w); - + if (w->isNormal()) { - w->setWorkspace(id); - w->setWindowNumber(windowList.size()); + if (! sticky) { + w->setWorkspace(id); + w->setWindowNumber(windowList.size()); + } windowList.push_back(w); 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; + if (! sticky) + screen->updateNetizenWindowAdd(w->getClientWindow(), id); + + if (screen->doFocusNew() || (w->isTransient() && w->getTransientFor() && + w->getTransientFor()->isFocused())) { + 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 + when this workspace does become focused. + */ + lastfocus = w; + } } } @@ -114,7 +119,7 @@ void Workspace::addWindow(BlackboxWindow *w, bool place) { } -void Workspace::removeWindow(BlackboxWindow *w) { +void Workspace::removeWindow(BlackboxWindow *w, bool sticky) { assert(w != 0); stackingList.remove(w); @@ -123,29 +128,30 @@ void Workspace::removeWindow(BlackboxWindow *w) { if ((w->isFocused() || w == lastfocus) && ! screen->getBlackbox()->doShutdown()) { focusFallback(w); - - // if the window is sticky, then it needs to be removed on all other - // workspaces too! - if (w->isStuck()) { - for (unsigned int i = 0; i < screen->getWorkspaceCount(); ++i) - if (i != id) - screen->getWorkspace(i)->focusFallback(w); - } } - + if (! w->isNormal()) return; - windowList.remove(w); - clientmenu->remove(w->getWindowNumber()); + BlackboxWindowList::iterator it, end = windowList.end(); + int i; + for (i = 0, it = windowList.begin(); it != end; ++it, ++i) + if (*it == w) + break; + assert(it != end); + + windowList.erase(it); + clientmenu->remove(i); clientmenu->update(); - screen->updateNetizenWindowDel(w->getClientWindow()); + if (! sticky) { + screen->updateNetizenWindowDel(w->getClientWindow()); - BlackboxWindowList::iterator it = windowList.begin(); - const BlackboxWindowList::iterator end = windowList.end(); - unsigned int i = 0; - for (; it != end; ++it, ++i) - (*it)->setWindowNumber(i); + BlackboxWindowList::iterator it = windowList.begin(); + const BlackboxWindowList::iterator end = windowList.end(); + unsigned int i = 0; + for (; it != end; ++it, ++i) + (*it)->setWindowNumber(i); + } if (i == 0) { cascade_x = cascade_y = 0; @@ -201,28 +207,16 @@ void Workspace::focusFallback(const BlackboxWindow *old_window) { } -void Workspace::showAll(void) { - 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::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(); - } +void Workspace::setFocused(const BlackboxWindow *w, bool focused) { + BlackboxWindowList::iterator it, end = windowList.end(); + int i; + for (i = 0, it = windowList.begin(); it != end; ++it, ++i) + if (*it == w) + break; + // if its == end, then a window thats not in the windowList + // got focused, such as a !isNormal() window. + if (it != end) + clientmenu->setItemSelected(i, focused); } @@ -236,14 +230,16 @@ void Workspace::removeAll(void) { * 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; } @@ -256,48 +252,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); } } } @@ -309,10 +305,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); @@ -339,10 +333,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); @@ -375,9 +367,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; } @@ -409,6 +403,7 @@ BlackboxWindow* Workspace::getPrevWindowInList(BlackboxWindow *w) { BlackboxWindow* Workspace::getTopWindowOnStack(void) const { + assert(! stackingList.empty()); return stackingList.front(); } @@ -435,6 +430,57 @@ void Workspace::appendStackOrder(BlackboxWindowList &stack_order) const { } +void Workspace::hide(void) { + BlackboxWindow *focused = screen->getBlackbox()->getFocusedWindow(); + if (focused && focused->getScreen() == screen) { + assert(focused->isStuck() || focused->getWorkspaceNumber() == id); + + lastfocus = focused; + } else { + // if no window had focus, no need to store a last focus + lastfocus = (BlackboxWindow *) 0; + } + + // when we switch workspaces, unfocus whatever was focused + screen->getBlackbox()->setFocusedWindow((BlackboxWindow *) 0); + + // withdraw windows in reverse order to minimize the number of Expose events + + BlackboxWindowList::reverse_iterator it = stackingList.rbegin(); + const BlackboxWindowList::reverse_iterator end = stackingList.rend(); + for (; it != end; ++it) { + BlackboxWindow *bw = *it; + // not normal windows cant focus from mouse enters anyways, so we dont + // need to unmap/remap them on workspace changes + if (! bw->isStuck() || bw->isNormal()) + bw->withdraw(); + } +} + + +void Workspace::show(void) { + BlackboxWindowList::iterator it = stackingList.begin(); + const BlackboxWindowList::iterator end = stackingList.end(); + for (; it != end; ++it) { + BlackboxWindow *bw = *it; + // not normal windows cant focus from mouse enters anyways, so we dont + // need to unmap/remap them on workspace changes + if (! bw->isStuck() || bw->isNormal()) + bw->show(); + } + + XSync(screen->getBlackbox()->getXDisplay(), False); + + if (screen->doFocusLast()) { + if (! screen->isSloppyFocus() && ! lastfocus && ! stackingList.empty()) + lastfocus = stackingList.front(); + + if (lastfocus) + lastfocus->setInputFocus(); + } +} + + bool Workspace::isCurrent(void) const { return (id == screen->getCurrentWorkspaceID()); }