diff -U 1 -r fluxbox-0.1.11/src/Screen.cc fluxbox-0.1.11-bugfix1/src/Screen.cc --- fluxbox-0.1.11/src/Screen.cc Fri Aug 30 16:03:31 2002 +++ fluxbox-0.1.11-bugfix1/src/Screen.cc Tue Sep 10 02:17:24 2002 @@ -393,3 +393,3 @@ - raiseWindows(0, 0); + raiseWindows(Workspace::Stack()); @@ -624,3 +624,3 @@ initMenu(); - raiseWindows(0, 0); + raiseWindows(Workspace::Stack()); rootmenu->reconfigure(); @@ -657,3 +657,3 @@ initMenu(); - raiseWindows(0, 0); + raiseWindows(Workspace::Stack()); @@ -1017,5 +1017,5 @@ -void BScreen::raiseWindows(Window *workspace_stack, int num) { +void BScreen::raiseWindows(const Workspace::Stack &workspace_stack) { - Window session_stack[(num + workspacesList.size() + rootmenuList.size() + 30)]; + Window session_stack[(workspace_stack.size() + workspacesList.size() + rootmenuList.size() + 30)]; int i = 0; @@ -1071,6 +1071,9 @@ #endif // SLIT - - int k=num; - while (k--) - session_stack[i++] = *(workspace_stack + k); + + if (!workspace_stack.empty()) { + Workspace::Stack::const_reverse_iterator it = workspace_stack.rbegin(); + Workspace::Stack::const_reverse_iterator it_end = workspace_stack.rend(); + for (; it != it_end; ++it) + session_stack[i++] = (*it); + } @@ -1137,6 +1140,6 @@ int focused_window_number = -1; - FluxboxWindow *focused; + FluxboxWindow *focused = fluxbox->getFocusedWindow(); const int num_windows = getCurrentWorkspace()->getCount(); - if ((focused = fluxbox->getFocusedWindow())) { + if (focused != 0) { if (focused->getScreen()->getScreenNumber() == @@ -1150,3 +1153,3 @@ Workspace *wksp = getCurrentWorkspace(); - Workspace::Windows wins = wksp->getWindowList(); + Workspace::Windows &wins = wksp->getWindowList(); Workspace::Windows::iterator it = wins.begin(); @@ -1163,3 +1166,3 @@ - if (*it != focused) + if (*it != focused && it != wins.end()) wksp->raiseWindow(*it); diff -U 1 -r fluxbox-0.1.11/src/Screen.hh fluxbox-0.1.11-bugfix1/src/Screen.hh --- fluxbox-0.1.11/src/Screen.hh Fri Aug 30 16:03:31 2002 +++ fluxbox-0.1.11-bugfix1/src/Screen.hh Tue Sep 10 02:14:36 2002 @@ -223,3 +223,3 @@ void sendToWorkspace(unsigned int workspace, FluxboxWindow *win=0, bool changeworkspace=true); - void raiseWindows(Window *workspace_stack, int num); + void raiseWindows(const Workspace::Stack &workspace_stack); void reassociateGroup(FluxboxWindow *window, unsigned int workspace_id, bool ignore_sticky); diff -U 1 -r fluxbox-0.1.11/src/Slit.cc fluxbox-0.1.11-bugfix1/src/Slit.cc --- fluxbox-0.1.11/src/Slit.cc Wed Aug 14 23:51:07 2002 +++ fluxbox-0.1.11-bugfix1/src/Slit.cc Tue Sep 10 02:16:22 2002 @@ -681,3 +681,5 @@ Window w[1] = { frame.window }; - screen->raiseWindows(w, 1); + Workspace::Stack st; + st.push_back(frame.window); + screen->raiseWindows(st); } else if (e->button == Button2 && (! on_top)) { @@ -890,3 +892,3 @@ if (slit.isOnTop()) - screen()->raiseWindows(0, 0); + screen()->raiseWindows(Workspace::Stack()); diff -U 1 -r fluxbox-0.1.11/src/Tab.cc fluxbox-0.1.11-bugfix1/src/Tab.cc --- fluxbox-0.1.11/src/Tab.cc Thu Aug 15 01:42:25 2002 +++ fluxbox-0.1.11-bugfix1/src/Tab.cc Tue Sep 10 02:18:07 2002 @@ -157,4 +157,7 @@ //raise tabs - for (tab = getFirst(this); tab!=0; tab = tab->m_next) - m_win->getScreen()->raiseWindows(&tab->m_tabwin, 1); + Workspace::Stack st; + for (tab = getFirst(this); tab!=0; tab = tab->m_next) { + st.push_back(tab->m_tabwin); + } + m_win->getScreen()->raiseWindows(st); } diff -U 1 -r fluxbox-0.1.11/src/Toolbar.cc fluxbox-0.1.11-bugfix1/src/Toolbar.cc --- fluxbox-0.1.11/src/Toolbar.cc Sat Aug 24 21:31:24 2002 +++ fluxbox-0.1.11-bugfix1/src/Toolbar.cc Tue Sep 10 02:18:32 2002 @@ -1024,4 +1024,5 @@ else if (! on_top) { - Window w[1] = { frame.window }; - screen->raiseWindows(w, 1); + Workspace::Stack st; + st.push_back(frame.window); + screen->raiseWindows(st); } @@ -1317,3 +1318,3 @@ if (toolbar->isOnTop()) - toolbar->screen->raiseWindows((Window *) 0, 0); + toolbar->screen->raiseWindows(Workspace::Stack()); diff -U 1 -r fluxbox-0.1.11/src/Window.cc fluxbox-0.1.11-bugfix1/src/Window.cc --- fluxbox-0.1.11/src/Window.cc Sun Sep 1 13:44:56 2002 +++ fluxbox-0.1.11-bugfix1/src/Window.cc Tue Sep 10 02:25:04 2002 @@ -142,3 +142,3 @@ client.wm_hint_flags = client.normal_hint_flags = 0; - client.transient_for = client.transient = 0; + client.transient_for = 0; client.mwm_hint = (MwmHints *) 0; @@ -376,18 +376,11 @@ - - if (isTransient()) { - //guard from having transient_for = this - if (client.transient_for == this) { -#ifdef DEBUG - cerr<<__FILE__<<"("<<__LINE__<<"): WARNING! client.transient_for == this WARNING!"<setFocusedWindow(client.transient_for); + client.transient_for->client.transients.remove(this); + client.transient_for = 0; + } + + while (!client.transients.empty()) { + client.transients.back()->client.transient_for = 0; + client.transients.pop_back(); } @@ -399,7 +392,2 @@ - if (transient && client.transient_for) - client.transient_for->client.transient = client.transient; - if (client.transient) - client.transient->client.transient_for = client.transient_for; - destroyTitlebar(); @@ -1793,5 +1781,10 @@ - if (client.transient && modal) { + if (client.transients.size() && modal) { fluxbox->ungrab(); - return client.transient->setInputFocus(); + std::list::iterator it = client.transients.begin(); + std::list::iterator it_end = client.transients.end(); + for (; it != it_end; ++it) { + if ((*it)->modal) + return (*it)->setInputFocus(); + } } else { @@ -1886,7 +1879,10 @@ - if (client.transient) { - if (! client.transient->iconic) - client.transient->iconify(); + if (client.transients.size()) { + std::list::iterator it = client.transients.begin(); + std::list::iterator it_end = client.transients.end(); + for (; it != it_end; ++it) { + if (! (*it)->iconic) + (*it)->iconify(); + } } - #ifdef GNOME @@ -1919,4 +1915,11 @@ - if (reassoc && client.transient) client.transient->deiconify(true, false); - + if (reassoc && client.transients.size()) { + // deiconify all transients + std::list::iterator it = client.transients.begin(); + std::list::iterator it_end = client.transients.end(); + for (; it != it_end; ++it) { + (*it)->deiconify(true, false); + } + } + if (tab) @@ -3758,7 +3761,8 @@ void FluxboxWindow::checkTransient() { - // default values + // remove us from parent + if (client.transient_for != 0) { + client.transient_for->client.transients.remove(this); + } client.transient_for = 0; - client.transient = 0; - Fluxbox *fluxbox = Fluxbox::instance(); // determine if this is a transient window @@ -3769,62 +3773,33 @@ } - + + if (win == client.window) return; - - if (win && (win != client.window)) { - FluxboxWindow *tr = fluxbox->searchWindow(win); - if (tr != 0) { - - while (tr->client.transient != 0) { - tr = tr->client.transient; - if (tr == tr->client.transient) { //ops! something is wrong with transient - tr->client.transient = 0; - if (tr->client.transient_for == tr) - tr->client.transient_for = 0; - break; - } - } - - if (tr != this) { - client.transient_for = tr; - tr->client.transient = this; - transient = true; - } else { - client.transient_for = 0; - client.transient = 0; - } - if (client.transient_for != 0) { - stuck = client.transient_for->stuck; - } - - } else if (win == client.window_group) { - if ((tr = fluxbox->searchGroup(win, this))) { - - while (tr->client.transient != 0) { - tr = tr->client.transient; - if (tr && tr == tr->client.transient) { //ops! somehtin is wrong with transient - tr->client.transient = 0; - } - } - - if (tr != this) { - client.transient_for = tr; - tr->client.transient = this; - transient = true; - } else { - client.transient_for = 0; - client.transient = 0; - } - - if (client.transient_for != 0) { - stuck = client.transient_for->stuck; - } - - } - } - } - + if (win == screen->getRootWindow()) modal = true; - + + client.transient_for = Fluxbox::instance()->searchWindow(win); + if (client.transient_for != 0 && + client.window_group != None && win == client.window_group) { + + FluxboxWindow *leader = Fluxbox::instance()->searchGroup(win, this); + if (leader != 0) + client.transient_for = leader; + return; + } + + // make sure we don't have deadlock loop in transient chain + for (FluxboxWindow *w = this; w != 0; w = w->client.transient_for) { + if (w == w->client.transient_for) { + w->client.transient_for = 0; + } + } + + if (client.transient_for != 0) { + client.transient_for->client.transients.push_back(this); + // make sure we only have on instance of this + client.transient_for->client.transients.unique(); + stuck = client.transient_for->stuck; + } } diff -U 1 -r fluxbox-0.1.11/src/Window.hh fluxbox-0.1.11-bugfix1/src/Window.hh --- fluxbox-0.1.11/src/Window.hh Fri Aug 30 16:06:40 2002 +++ fluxbox-0.1.11-bugfix1/src/Window.hh Tue Sep 10 02:16:02 2002 @@ -130,4 +130,4 @@ //@{ - inline bool isTransient() const { return ((transient) ? true : false); } - inline bool hasTransient() const { return ((client.transient) ? true : false); } + inline bool isTransient() const { return ((client.transient_for) ? true : false); } + inline bool hasTransient() const { return ((client.transients.size()) ? true : false); } inline bool isManaged() const { return managed; } @@ -151,4 +151,4 @@ inline Tab *getTab() { return tab; } - inline const FluxboxWindow *getTransient() const { return client.transient; } - inline FluxboxWindow *getTransient() { return client.transient; } + inline const std::list &getTransients() const { return client.transients; } + inline std::list &getTransients() { return client.transients; } inline const FluxboxWindow *getTransientFor() const { return client.transient_for; } @@ -271,4 +271,4 @@ struct _client { - FluxboxWindow *transient_for, // which window are we a transient for? - *transient; // which window is our transient? + FluxboxWindow *transient_for; // which window are we a transient for? + std::list transients; // which window is our transient? Window window, window_group; diff -U 1 -r fluxbox-0.1.11/src/Workspace.cc fluxbox-0.1.11-bugfix1/src/Workspace.cc --- fluxbox-0.1.11/src/Workspace.cc Sat Aug 31 12:40:50 2002 +++ fluxbox-0.1.11-bugfix1/src/Workspace.cc Tue Sep 10 02:12:44 2002 @@ -57,2 +57,19 @@ +namespace { // anonymous + +int countTransients(const FluxboxWindow &win) { + if (win.getTransients().size() == 0) + return 0; + // now go throu the entire tree and count transients + size_t ret = win.getTransients().size(); + std::list::const_iterator it = win.getTransients().begin(); + std::list::const_iterator it_end = win.getTransients().end(); + for (; it != it_end; ++it) + ret += countTransients(*(*it)); + + return ret; +} + +}; + Workspace::GroupList Workspace::m_groups; @@ -220,48 +237,23 @@ void Workspace::raiseWindow(FluxboxWindow *w) { - FluxboxWindow *win = (FluxboxWindow *) 0, *bottom = w; - - while (bottom->isTransient() && bottom->getTransientFor() && - bottom->getTransientFor() != bottom) { //prevent infinite loop -#ifdef DEBUG - assert(bottom != bottom->getTransientFor()); -#endif // DEBUG - bottom = bottom->getTransientFor(); - - } - - int i = 1; - win = bottom; - while (win->hasTransient() && win->getTransient() && - win->getTransient() != win) {//prevent infinite loop -#ifdef DEBUG - assert(win != win->getTransient()); -#endif // DEBUG - win = win->getTransient(); - i++; - } - - Window *nstack = new Window[i], *curr = nstack; - Workspace *wkspc; + FluxboxWindow *win = w; - win = bottom; - while (1) { - *(curr++) = win->getFrameWindow(); - screen->updateNetizenWindowRaise(win->getClientWindow()); - - if (! win->isIconic()) { - wkspc = screen->getWorkspace(win->getWorkspaceNumber()); - wkspc->stackingList.remove(win); - wkspc->stackingList.push_front(win); - } - - if (! win->hasTransient() || ! win->getTransient() || - win->getTransient() == win) //prevent infinite loop - break; - - win = win->getTransient(); - } + while (win->isTransient() && win->getTransientFor()) + win = win->getTransientFor(); + + int i = 1 + countTransients(*win); - screen->raiseWindows(nstack, i); + Stack nstack(i); + Stack::iterator stackit = nstack.begin(); + + *(stackit++) = win->getFrameWindow(); + screen->updateNetizenWindowRaise(win->getClientWindow()); + if (! win->isIconic()) { + Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber()); + wkspc->stackingList.remove(win); + wkspc->stackingList.push_front(win); + } + + raiseAndFillStack(stackit, *win); - delete [] nstack; + screen->raiseWindows(nstack); } @@ -275,39 +267,20 @@ - int i = 1; win = bottom; - while (win->hasTransient() && win->getTransient() && - win->getTransient() != win) { //prevent infinite loop - win = win->getTransient(); - - i++; - } - - Window *nstack = new Window[i], *curr = nstack; - Workspace *wkspc; - - while (True) { - *(curr++) = win->getFrameWindow(); - screen->updateNetizenWindowLower(win->getClientWindow()); - - if (! win->isIconic()) { - wkspc = screen->getWorkspace(win->getWorkspaceNumber()); - wkspc->stackingList.remove(win); - wkspc->stackingList.push_back(win); - } - - if (! win->getTransientFor() || - win->getTransientFor() == win)//prevent infinite loop - break; + int i = 1 + countTransients(*w); - win = win->getTransientFor(); + Stack st(i); + Stack::iterator stackit = st.begin(); + lowerAndFillStack(stackit, *win); + (*stackit) = win->getFrameWindow(); + + screen->updateNetizenWindowLower(win->getClientWindow()); + if (! win->isIconic()) { + Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber()); + wkspc->stackingList.remove(win); + wkspc->stackingList.push_back(win); } - Fluxbox::instance()->grab(); + XLowerWindow(BaseDisplay::getXDisplay(), st.front()); + XRestackWindows(BaseDisplay::getXDisplay(), &st[0], st.size()); - XLowerWindow(screen->getBaseDisplay()->getXDisplay(), *nstack); - XRestackWindows(screen->getBaseDisplay()->getXDisplay(), nstack, i); - - Fluxbox::instance()->ungrab(); - - delete [] nstack; } @@ -810,2 +783,54 @@ win->configure(place_x, place_y, win->getWidth(), win->getHeight()); +} + + +void Workspace::raiseAndFillStack(Stack::iterator &stackit, const FluxboxWindow &w) { + if (w.getTransients().empty()) + return; + + std::list::const_iterator it = w.getTransients().begin(); + std::list::const_iterator it_end = w.getTransients().end(); + for (; it != it_end; ++it) { + *stackit++ = (*it)->getFrameWindow(); + + screen->updateNetizenWindowRaise((*it)->getClientWindow()); + + if (! (*it)->isIconic()) { + Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber()); + wkspc->stackingList.remove((*it)); + wkspc->stackingList.push_front((*it)); + } + + + } + + it = w.getTransients().begin(); + for (; it != it_end; ++it) + raiseAndFillStack(stackit, *(*it)); + + +} + +void Workspace::lowerAndFillStack(Stack::iterator &stackit, const FluxboxWindow &win) { + if (win.getTransients().empty()) // nothing to lower and stack + return; + + std::list::const_reverse_iterator it = win.getTransients().rbegin(); + std::list::const_reverse_iterator it_end = win.getTransients().rend(); + for (; it != it_end; ++it) + lowerAndFillStack(stackit, *(*it)); + + it = win.getTransients().rbegin(); + + for (; it != it_end; ++it) { + (*stackit) = (*it)->getFrameWindow(); + ++stackit; + screen->updateNetizenWindowLower((*it)->getClientWindow()); + if (! (*it)->isIconic()) { + Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber()); + wkspc->stackingList.remove((*it)); + wkspc->stackingList.push_back((*it)); + } + } + } diff -U 1 -r fluxbox-0.1.11/src/Workspace.hh fluxbox-0.1.11-bugfix1/src/Workspace.hh --- fluxbox-0.1.11/src/Workspace.hh Wed Aug 7 23:40:16 2002 +++ fluxbox-0.1.11-bugfix1/src/Workspace.hh Tue Sep 10 02:13:28 2002 @@ -44,3 +44,4 @@ typedef std::vector Windows; - + typedef std::vector Stack; + Workspace(BScreen *screen, unsigned int workspaceid = 0); @@ -101,2 +102,4 @@ + void raiseAndFillStack(Stack::iterator &it, const FluxboxWindow &win); + void lowerAndFillStack(Stack::iterator &it, const FluxboxWindow &win); diff -U 1 -r fluxbox-0.1.11/src/fluxbox.cc fluxbox-0.1.11-bugfix1/src/fluxbox.cc --- fluxbox-0.1.11/src/fluxbox.cc Fri Aug 30 16:07:38 2002 +++ fluxbox-0.1.11-bugfix1/src/fluxbox.cc Tue Sep 10 02:26:06 2002 @@ -1244,3 +1244,3 @@ screen->nextFocus(key->getParam()); - if (focused_window) + if (focused_window && focused_window->getTab()) focused_window->getTab()->raise(); @@ -1249,3 +1249,3 @@ screen->prevFocus(key->getParam()); - if (focused_window) + if (focused_window && focused_window->getTab()) focused_window->getTab()->raise();