X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2FWorkspace.cc;h=0a95c24f04e644a76d2f98cc2f59e69e41fc8995;hb=df7120d5ff0942dcae5a20bed79052e7be9bc1d1;hp=d2a43f440e209d44720ea7852bf378b0335b85b7;hpb=8ff1b7097381bcd20567ea2dd615b4fec84d5a8b;p=chaz%2Fopenbox diff --git a/src/Workspace.cc b/src/Workspace.cc index d2a43f44..0a95c24f 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -70,8 +70,7 @@ Workspace::Workspace(BScreen *scrn, unsigned int i) { lastfocus = (BlackboxWindow *) 0; - setName(""); - fprintf(stderr, "WORKSPACE NAME: %s\n", name.c_str()); + readName(); } @@ -80,22 +79,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); - - clientmenu->insert(w->getTitle()); - clientmenu->update(); - - screen->updateNetizenWindowAdd(w->getClientWindow(), id); + + if (w->isNormal()) { + 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; + } + } - 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); @@ -103,22 +118,19 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { // pass focus to the next appropriate window if ((w->isFocused() || w == lastfocus) && ! screen->getBlackbox()->doShutdown()) { - if (id == screen->getCurrentWorkspaceID()) { - // The window is on the visible workspace - focusFallback(w); - } else { - // The window is not on the visible workspace. - if (lastfocus == w) { - // The window was the last-focus target, so we need to replace it. - setLastFocusedWindow(stackingList.front()); - } - // if the window focused on the current workspace, then reapply that - // workspace's focus too - if (w->isFocused()) - screen->getCurrentWorkspace()->focusFallback(w); + 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()); clientmenu->update(); @@ -133,57 +145,73 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { if (i == 0) cascade_x = cascade_y = 32; - - return i; } void Workspace::focusFallback(const BlackboxWindow *old_window) { BlackboxWindow *newfocus = 0; - // if it's a transient, then try to focus its parent - if (old_window && old_window->isTransient()) { - newfocus = old_window->getTransientFor(); + if (id == screen->getCurrentWorkspaceID()) { + // The window is on the visible workspace. - if (! newfocus || - newfocus->isIconic() || // do not focus icons - newfocus->getWorkspaceNumber() != id || // or other workspaces - ! newfocus->setInputFocus()) - newfocus = 0; - } + // if it's a transient, then try to focus its parent + if (old_window && old_window->isTransient()) { + newfocus = old_window->getTransientFor(); - if (! newfocus) { - BlackboxWindowList::iterator it = stackingList.begin(), - end = stackingList.end(); - for (; it != end; ++it) { - BlackboxWindow *tmp = *it; - if (tmp && tmp->setInputFocus()) { - // we found our new focus target - newfocus = tmp; - break; + if (! newfocus || + newfocus->isIconic() || // do not focus icons + newfocus->getWorkspaceNumber() != id || // or other workspaces + ! newfocus->setInputFocus()) + newfocus = 0; + } + + if (! newfocus) { + BlackboxWindowList::iterator it = stackingList.begin(), + end = stackingList.end(); + for (; it != end; ++it) { + BlackboxWindow *tmp = *it; + if (tmp && tmp->isNormal() && tmp->setInputFocus()) { + // we found our new focus target + newfocus = tmp; + break; + } } } - } - screen->getBlackbox()->setFocusedWindow(newfocus); + screen->getBlackbox()->setFocusedWindow(newfocus); + } else { + // The window is not on the visible workspace. + + if (old_window && lastfocus == old_window) { + // The window was the last-focus target, so we need to replace it. + BlackboxWindow *win = (BlackboxWindow*) 0; + if (! stackingList.empty()) + win = stackingList.front(); + setLastFocusedWindow(win); + } + } } 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(); } @@ -270,8 +298,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(); } @@ -285,7 +315,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); @@ -301,7 +331,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(); } @@ -317,7 +347,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); @@ -392,7 +422,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); } @@ -411,43 +442,48 @@ void Workspace::setCurrent(void) { } -void Workspace::setName(const string& new_name) { - if (! new_name.empty()) { - name = new_name; +void Workspace::readName(void) { + XAtom::StringVect namesList; + unsigned long numnames = id + 1; + + // attempt to get from the _NET_WM_DESKTOP_NAMES property + if (xatom->getValue(screen->getRootWindow(), XAtom::net_desktop_names, + XAtom::utf8, numnames, namesList) && + namesList.size() > id) { + name = namesList[id]; + + clientmenu->setLabel(name); + clientmenu->update(); } else { - // attempt to get from the _NET_WM_DESKTOP_NAMES property - XAtom::StringVect namesList; - unsigned long numnames = id + 1; - if (xatom->getValue(screen->getRootWindow(), XAtom::net_desktop_names, - XAtom::utf8, numnames, namesList) && - namesList.size() > id) { - name = namesList[id]; - } else { - string tmp =i18n(WorkspaceSet, WorkspaceDefaultNameFormat, - "Workspace %d"); - assert(tmp.length() < 32); - char default_name[32]; - sprintf(default_name, tmp.c_str(), id + 1); - name = default_name; - } + /* + Use a default name. This doesn't actually change the class. That will + happen after the setName changes the root property, and that change + makes its way back to this function. + */ + string tmp =i18n(WorkspaceSet, WorkspaceDefaultNameFormat, + "Workspace %d"); + assert(tmp.length() < 32); + char default_name[32]; + sprintf(default_name, tmp.c_str(), id + 1); + + setName(default_name); // save this into the _NET_WM_DESKTOP_NAMES property } - - // reset the property with the new name +} + + +void Workspace::setName(const string& new_name) { + // set the _NET_WM_DESKTOP_NAMES property with the new name XAtom::StringVect namesList; unsigned long numnames = (unsigned) -1; if (xatom->getValue(screen->getRootWindow(), XAtom::net_desktop_names, XAtom::utf8, numnames, namesList) && namesList.size() > id) - namesList[id] = name; + namesList[id] = new_name; else - namesList.push_back(name); + namesList.push_back(new_name); xatom->setValue(screen->getRootWindow(), XAtom::net_desktop_names, XAtom::utf8, namesList); - - clientmenu->setLabel(name); - clientmenu->update(); - screen->saveWorkspaceNames(); } @@ -559,7 +595,8 @@ bool Workspace::smartPlacement(Rect& win, const Rect& availableArea) { for (; wit != end; ++wit) { const BlackboxWindow* const curr = *wit; - if (curr->isShaded()) continue; + if (curr->isShaded() && screen->getPlaceIgnoreShaded()) continue; + if (curr->isMaximizedFull() && screen->getPlaceIgnoreMaximized()) continue; tmp.setRect(curr->frameRect().x(), curr->frameRect().y(), curr->frameRect().width() + screen->getBorderWidth(), @@ -677,6 +714,7 @@ void Workspace::placeWindow(BlackboxWindow *win) { placed = smartPlacement(new_win, availableArea); break; case BScreen::UnderMousePlacement: + case BScreen::ClickMousePlacement: placed = underMousePlacement(new_win, availableArea); default: break; // handled below