all repos — fluxbox @ d63bf127ad6391f3e8408ddfd0ba79c4841a1ecf

custom fork of the fluxbox windowmanager

transient fixes by making them WinClients
rathnor rathnor
commit

d63bf127ad6391f3e8408ddfd0ba79c4841a1ecf

parent

de68c88ed8ff8c7a887495a74de004f9da7f56df

7 files changed, 251 insertions(+), 315 deletions(-)

jump to
M ChangeLogChangeLog

@@ -1,6 +1,8 @@

(Format: Year/Month/Day) Changes for 0.9.2: *03/05/07: + * Fixed transient grouping issues (transients now WinClients) (Simon) + WinClient.hh/cc Window.hh/cc Workspace.cc Screen.cc * Fixed screen problem with redrawing menus (Henrik) The m_screen_num wasn't set in X Window assignment operator FbTk/FbWindow.cc
M src/Screen.ccsrc/Screen.cc

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.146 2003/05/07 13:50:41 rathnor Exp $ +// $Id: Screen.cc,v 1.147 2003/05/07 16:21:25 rathnor Exp $ #include "Screen.hh"

@@ -973,8 +973,14 @@ FluxboxWindow *focused = Fluxbox::instance()->getFocusedWindow();

focused_list.remove(&client); if (cyc == &client) { cycling_window = focused_list.end(); - } else if (focused && &focused->winClient() == &client) - Fluxbox::instance()->revertFocus(&focused->getScreen()); + } else if (focused && &focused->winClient() == &client) { + // if we are focused, then give our focus to our transient parent + // or revert normally + if (client.transientFor() && client.transientFor()->fbwindow()) + client.transientFor()->fbwindow()->setInputFocus(); + else + Fluxbox::instance()->revertFocus(&focused->getScreen()); + } } FluxboxWindow *BScreen::getIcon(unsigned int index) {
M src/WinClient.ccsrc/WinClient.cc

@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: WinClient.cc,v 1.6 2003/05/04 23:38:06 rathnor Exp $ +// $Id: WinClient.cc,v 1.7 2003/05/07 16:21:26 rathnor Exp $ #include "WinClient.hh"

@@ -54,6 +54,7 @@ wm_hint_flags(0),

mwm_hint(0), blackbox_hint(0), m_win(&fbwin), + modal(false), m_title(""), m_icon_title(""), m_diesig(*this) { }

@@ -62,42 +63,22 @@ #ifdef DEBUG

cerr<<__FILE__<<"(~"<<__FUNCTION__<<")[this="<<this<<"]"<<endl; #endif // DEBUG + // this takes care of any focus issues m_diesig.notify(); Fluxbox *fluxbox = Fluxbox::instance(); if (transient_for != 0) { - if (transientFor() == m_win) { - transient_for = 0; - } + assert(transient_for != this); + transient_for->transientList().remove(this); + transient_for = 0; + } - if (transient_for != 0) { - FluxboxWindow::ClientList::iterator client_it = - transientFor()->clientList().begin(); - FluxboxWindow::ClientList::iterator client_it_end = - transientFor()->clientList().end(); - for (; client_it != client_it_end; ++client_it) { - (*client_it)->transientList().remove(m_win); - } - - transient_for->setInputFocus(); - transient_for = 0; - } - } - while (!transients.empty()) { - FluxboxWindow::ClientList::iterator it = - transients.back()->clientList().begin(); - FluxboxWindow::ClientList::iterator it_end = - transients.back()->clientList().end(); - for (; it != it_end; ++it) { - if ((*it)->transientFor() == m_win) - (*it)->transient_for = 0; - } - + transients.back()->transient_for = 0; transients.pop_back(); } - + if (window_group != 0) { fluxbox->removeGroupSearch(window_group); window_group = 0;

@@ -199,17 +180,7 @@ if (m_win == 0)

return; // remove us from parent if (transientFor() != 0) { - //!! TODO - // since we don't know which client in transientFor() - // that we're transient for then we just remove us - // from every client in transientFor() clientlist - FluxboxWindow::ClientList::iterator client_it = - transientFor()->clientList().begin(); - FluxboxWindow::ClientList::iterator client_it_end = - transientFor()->clientList().end(); - for (; client_it != client_it_end; ++client_it) { - (*client_it)->transientList().remove(m_win); - } + transientFor()->transientList().remove(this); } transient_for = 0;

@@ -223,21 +194,19 @@ // we can't be transient to ourself

if (win == window()) return; - if (win != 0 && m_win->getScreen().getRootWindow() == win) { - m_win->modal = true; - return; + if (win != None && m_win->getScreen().getRootWindow() == win) { + modal = true; + return; // transient for root window... } - transient_for = Fluxbox::instance()->searchWindow(win); - if (transient_for != 0 && - window_group != None && win == window_group) { - transient_for = Fluxbox::instance()->searchGroup(win, m_win); - } - + FluxboxWindow *transient_win = Fluxbox::instance()->searchWindow(win); + if (transient_win) + transient_for = transient_win->findClient(win); + // make sure we don't have deadlock loop in transient chain - for (FluxboxWindow *w = m_win; w != 0; w = w->m_client->transient_for) { - if (w == w->m_client->transient_for) { - w->m_client->transient_for = 0; + for (WinClient *w = this; w != 0; w = w->transient_for) { + if (w == w->transient_for) { + w->transient_for = 0; break; } }

@@ -245,13 +214,10 @@

if (transientFor() != 0) { // we need to add ourself to the right client in // the transientFor() window so we search client - WinClient *client = transientFor()->findClient(win); - assert(client != 0); - client->transientList().push_back(m_win); - // make sure we only have on instance of this - client->transientList().unique(); - if (transientFor()->isStuck()) - m_win->stick(); + transient_for->transientList().push_back(this); + + if (transientFor()->fbwindow() && transientFor()->fbwindow()->isStuck()) + m_win->stick(); } }
M src/WinClient.hhsrc/WinClient.hh

@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: WinClient.hh,v 1.2 2003/04/14 12:08:21 fluxgen Exp $ +// $Id: WinClient.hh,v 1.3 2003/05/07 16:21:26 rathnor Exp $ #ifndef WINCLIENT_HH #define WINCLIENT_HH

@@ -36,7 +36,7 @@

/// Holds client window info class WinClient:public FbTk::FbWindow { public: - typedef std::list<FluxboxWindow *> TransientList; + typedef std::list<WinClient *> TransientList; WinClient(Window win, FluxboxWindow &fbwin);

@@ -56,10 +56,13 @@ FbTk::Subject &dieSig() { return m_diesig; }

/// updates transient window information void updateTransientInfo(); - FluxboxWindow *transientFor() { return transient_for; } - const FluxboxWindow *transientFor() const { return transient_for; } + WinClient *transientFor() { return transient_for; } + const WinClient *transientFor() const { return transient_for; } TransientList &transientList() { return transients; } const TransientList &transientList() const { return transients; } + bool isTransient() const { return transient_for != 0; } + bool isModal() const { return modal; } + bool operator == (const FluxboxWindow &win) const { return (m_win == &win); }

@@ -73,8 +76,8 @@ !! TODO !!

remove or move these to private */ - FluxboxWindow *transient_for; // which window are we a transient for? - std::list<FluxboxWindow *> transients; // which windows are our transients? + WinClient *transient_for; // which window are we a transient for? + std::list<WinClient *> transients; // which windows are our transients? Window window_group;

@@ -105,6 +108,7 @@ WinClient &m_winclient;

}; private: + bool modal; std::string m_title, m_icon_title; WinClientSubj m_diesig; };
M src/Window.ccsrc/Window.cc

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.159 2003/05/07 11:33:56 fluxgen Exp $ +// $Id: Window.cc,v 1.160 2003/05/07 16:21:26 rathnor Exp $ #include "Window.hh"

@@ -121,8 +121,20 @@

return false; } -/// raise window and do the same for each transient it holds +/// returns the deepest transientFor, asserting against a close loop +WinClient *getRootTransientFor(WinClient *client) { + while (client->transientFor()) { + assert(client != client->transientFor()); + client = client->transientFor(); + } + return client; +} + + +/// raise window and do the same for each transient of the current window void raiseFluxboxWindow(FluxboxWindow &win) { + if (win.oplock) return; + win.oplock = true; if (!win.isIconic()) { win.getScreen().updateNetizenWindowRaise(win.getClientWindow());

@@ -130,33 +142,40 @@ win.getLayerItem().raise();

} // for each transient do raise - std::list<FluxboxWindow *>::const_iterator it = win.getTransients().begin(); - std::list<FluxboxWindow *>::const_iterator it_end = win.getTransients().end(); + WinClient::TransientList::const_iterator it = win.winClient().transientList().begin(); + WinClient::TransientList::const_iterator it_end = win.winClient().transientList().end(); for (; it != it_end; ++it) { - if (!(*it)->isIconic()) - raiseFluxboxWindow(*(*it)); + if ((*it)->fbwindow() && !(*it)->fbwindow()->isIconic()) + // TODO: should we also check if it is the active client? + raiseFluxboxWindow(*(*it)->fbwindow()); } + win.oplock = false; } /// lower window and do the same for each transient it holds void lowerFluxboxWindow(FluxboxWindow &win) { + if (win.oplock) return; + win.oplock = true; if (!win.isIconic()) { win.getScreen().updateNetizenWindowLower(win.getClientWindow()); win.getLayerItem().lower(); } - // for each transient do lower - std::list<FluxboxWindow *>::const_iterator it = win.getTransients().begin(); - std::list<FluxboxWindow *>::const_iterator it_end = win.getTransients().end(); + WinClient::TransientList::const_iterator it = win.winClient().transientList().begin(); + WinClient::TransientList::const_iterator it_end = win.winClient().transientList().end(); for (; it != it_end; ++it) { - if (!(*it)->isIconic()) - lowerFluxboxWindow(*(*it)); + if ((*it)->fbwindow() && !(*it)->fbwindow()->isIconic()) + // TODO: should we also check if it is the active client? + lowerFluxboxWindow(*(*it)->fbwindow()); } + win.oplock = false; } /// raise window and do the same for each transient it holds void tempRaiseFluxboxWindow(FluxboxWindow &win) { + if (win.oplock) return; + win.oplock = true; if (!win.isIconic()) { // don't update netizen, as it is only temporary

@@ -164,12 +183,14 @@ win.getLayerItem().tempRaise();

} // for each transient do raise - std::list<FluxboxWindow *>::const_iterator it = win.getTransients().begin(); - std::list<FluxboxWindow *>::const_iterator it_end = win.getTransients().end(); + WinClient::TransientList::const_iterator it = win.winClient().transientList().begin(); + WinClient::TransientList::const_iterator it_end = win.winClient().transientList().end(); for (; it != it_end; ++it) { - if (!(*it)->isIconic()) - tempRaiseFluxboxWindow(*(*it)); + if ((*it)->fbwindow() && !(*it)->fbwindow()->isIconic()) + // TODO: should we also check if it is the active client? + tempRaiseFluxboxWindow(*(*it)->fbwindow()); } + win.oplock = false; } class SetClientCmd:public FbTk::Command {

@@ -195,14 +216,15 @@

FluxboxWindow::FluxboxWindow(WinClient &client, BScreen &scr, FbWinFrameTheme &tm, FbTk::MenuTheme &menutheme, FbTk::XLayer &layer): + oplock(false), m_hintsig(*this), m_statesig(*this), m_layersig(*this), m_workspacesig(*this), m_diesig(*this), moving(false), resizing(false), shaded(false), maximized(false), - iconic(false), transient(false), focused(false), - stuck(false), modal(false), send_focus_message(false), m_managed(false), + iconic(false), focused(false), + stuck(false), send_focus_message(false), m_managed(false), screen(scr), timer(this), display(0),

@@ -227,14 +249,15 @@

FluxboxWindow::FluxboxWindow(Window w, BScreen &scr, FbWinFrameTheme &tm, FbTk::MenuTheme &menutheme, FbTk::XLayer &layer): + oplock(false), m_hintsig(*this), m_statesig(*this), m_layersig(*this), m_workspacesig(*this), m_diesig(*this), moving(false), resizing(false), shaded(false), maximized(false), - iconic(false), transient(false), focused(false), - stuck(false), modal(false), send_focus_message(false), m_managed(false), + iconic(false), focused(false), + stuck(false), send_focus_message(false), m_managed(false), screen(scr), timer(this), display(0),

@@ -399,10 +422,10 @@

m_managed = true; //this window is managed // update transient infomation - updateTransientInfo(); + m_client->updateTransientInfo(); // adjust the window decorations based on transience and window sizes - if (transient) { + if (m_client->isTransient()) { decorations.maximize = functions.maximize = false; decorations.handle = decorations.border = false; }

@@ -419,7 +442,7 @@

upsize(); bool place_window = true; - if (fluxbox->isStartup() || transient || + if (fluxbox->isStartup() || m_client->isTransient() || m_client->normal_hint_flags & (PPosition|USPosition)) { setGravityOffsets();

@@ -454,8 +477,10 @@ m_frame.move(wattrib.x, wattrib.y);

m_frame.resizeForClient(wattrib.width, wattrib.height); // if we're a transient then we should be on the same layer as our parent - if (isTransient()) - getLayerItem().setLayer(getTransientFor()->getLayerItem().getLayer()); + if (m_client->isTransient() && + m_client->transientFor()->fbwindow() && + m_client->transientFor()->fbwindow() != this) + getLayerItem().setLayer(m_client->transientFor()->fbwindow()->getLayerItem().getLayer()); else // if no parent then set default layer moveToLayer(m_layernum);

@@ -535,14 +560,6 @@ set_client_cmd(new SetClientCmd(*(*client_it)));

btn->setOnClick(set_client_cmd); evm.add(*this, btn->window()); // we take care of button events for this - // update transients in client to have this as transient_for - WinClient::TransientList::iterator trans_it = - (*client_it)->transientList().begin(); - WinClient::TransientList::iterator trans_it_end = - (*client_it)->transientList().end(); - for (; trans_it != trans_it_end; ++trans_it) { - (*trans_it)->m_client->transient_for = this; - } } // add client and move over all attached clients

@@ -571,14 +588,6 @@ btn->setOnClick(set_client_cmd);

evm.add(*this, btn->window()); // we take care of button events for this client.m_win = this; - // update transients in client to have this as transient_for - WinClient::TransientList::iterator trans_it = - client.transientList().begin(); - WinClient::TransientList::iterator trans_it_end = - client.transientList().end(); - for (; trans_it != trans_it_end; ++trans_it) { - (*trans_it)->m_client->transient_for = this; - } Fluxbox::instance()->saveWindowSearch(client.window(), this); }

@@ -632,7 +641,7 @@

client.m_win = 0; m_clientlist.remove(&client); - if (m_client == &client && m_clientlist.size() == 0) + if (m_client == &client && m_clientlist.empty()) m_client = 0; FbTk::EventManager &evm = *FbTk::EventManager::instance();

@@ -719,7 +728,7 @@ return setinput && setInputFocus();

} bool FluxboxWindow::isGroupable() const { - if (isResizable() && isMaximizable() && !isTransient()) + if (isResizable() && isMaximizable() && !winClient().isTransient()) return true; return false; }

@@ -1136,12 +1145,12 @@ return false;

bool ret = false; - if (m_client->transients.size() && modal) { - std::list<FluxboxWindow *>::iterator it = m_client->transients.begin(); - std::list<FluxboxWindow *>::iterator it_end = m_client->transients.end(); + if (!m_client->transients.empty() && m_client->isModal()) { + WinClient::TransientList::iterator it = m_client->transients.begin(); + WinClient::TransientList::iterator it_end = m_client->transients.end(); for (; it != it_end; ++it) { - if ((*it)->modal) - return (*it)->setInputFocus(); + if ((*it)->isModal()) + return (*it)->fbwindow()->setCurrentClient(**it,true); } } else { if (focus_mode == F_LOCALLYACTIVE || focus_mode == F_PASSIVE) {

@@ -1184,7 +1193,6 @@ /**

Unmaps the window and removes it from workspace list */ void FluxboxWindow::iconify() { - if (isIconic()) // no need to iconify if we're already return;

@@ -1202,22 +1210,28 @@ WinClient &client = *(*client_it);

client.setEventMask(NoEventMask); client.hide(); client.setEventMask(PropertyChangeMask | StructureNotifyMask | FocusChangeMask); - if (client.transientFor()) { - if (! client.transientFor()->isIconic()) { - client.transientFor()->iconify(); - } + if (client.transientFor() && + client.transientFor()->fbwindow()) { + if (!client.transientFor()->fbwindow()->isIconic()) { + client.transientFor()->fbwindow()->iconify(); + } } - if (client.transientList().size()) { - for_each(client.transientList().begin(), - client.transientList().end(), - mem_fun(&FluxboxWindow::iconify)); + if (!client.transientList().empty()) { + WinClient::TransientList::iterator it = client.transientList().begin(); + WinClient::TransientList::iterator it_end = client.transientList().end(); + for (; it != it_end; it++) + if ((*it)->fbwindow()) + (*it)->fbwindow()->iconify(); } } } void FluxboxWindow::deiconify(bool reassoc, bool do_raise) { + if (oplock) return; + oplock = true; + if (iconic || reassoc) { screen.reassociateWindow(this, screen.getCurrentWorkspace()->workspaceID(), false); } else if (moving || workspace_number != screen.getCurrentWorkspace()->workspaceID())

@@ -1245,22 +1259,22 @@ if (focused != m_frame.focused())

m_frame.setFocus(focused); - if (reassoc && m_client->transients.size()) { + if (reassoc && !m_client->transients.empty()) { // deiconify all transients client_it = clientList().begin(); for (; client_it != client_it_end; ++client_it) { - - std::list<FluxboxWindow *>::iterator trans_it = + //TODO: Can this get stuck in a loop? + WinClient::TransientList::iterator trans_it = (*client_it)->transientList().begin(); - std::list<FluxboxWindow *>::iterator trans_it_end = + WinClient::TransientList::iterator trans_it_end = (*client_it)->transientList().end(); for (; trans_it != trans_it_end; ++trans_it) { - (*trans_it)->deiconify(true, false); - } + if ((*trans_it)->fbwindow()) + (*trans_it)->fbwindow()->deiconify(true, false); + } } - } - + oplock = false; if (do_raise) raise(); }

@@ -1412,34 +1426,30 @@ if (isIconic())

deiconify(); // get root window - FluxboxWindow *win = this; - while (win->getTransientFor()) { - win = win->getTransientFor(); - assert(win != win->getTransientFor()); - } + WinClient *client = getRootTransientFor(m_client); + // if we don't have any root window use this as root - if (win == 0) - win = this; + if (client == 0) + client = m_client; // raise this window and every transient in it - raiseFluxboxWindow(*win); + if (client->fbwindow()) + raiseFluxboxWindow(*client->fbwindow()); } void FluxboxWindow::lower() { if (isIconic()) deiconify(); - // get root window (i.e the bottom window) - FluxboxWindow *bottom = this; - while (bottom->getTransientFor()) { - bottom = bottom->getTransientFor(); - assert(bottom != bottom->getTransientFor()); - } + // get root window + WinClient *client = getRootTransientFor(m_client); - if (bottom == 0) - bottom = this; + // if we don't have any root window use this as root + if (client == 0) + client = m_client; - lowerFluxboxWindow(*bottom); + if (client->fbwindow()) + lowerFluxboxWindow(*client->fbwindow()); } void FluxboxWindow::tempRaise() {

@@ -1447,17 +1457,14 @@ if (isIconic())

deiconify(); // get root window - FluxboxWindow *win = this; - while (win->getTransientFor()) { - win = win->getTransientFor(); - assert(win != win->getTransientFor()); - } + WinClient *client = getRootTransientFor(m_client); + // if we don't have any root window use this as root - if (win == 0) - win = this; + if (client == 0) + client = m_client; - // raise this window and every transient in it - tempRaiseFluxboxWindow(*win); + if (client->fbwindow()) + tempRaiseFluxboxWindow(*client->fbwindow()); }

@@ -1466,84 +1473,103 @@ // don't let it up to menu layer

if (getLayerNum() == (Fluxbox::instance()->getMenuLayer()+1)) return; - FluxboxWindow *win = this; - - while (win->getTransientFor()) { - win = win->getTransientFor(); - assert(win != win->getTransientFor()); - } + // get root window + WinClient *client = getRootTransientFor(m_client); + + // if we don't have any root window use this as root + if (client == 0) + client = m_client; + + FluxboxWindow *win = client->fbwindow(); + if (!win) return; + + if (!win->isIconic()) + screen.updateNetizenWindowRaise(client->window()); - if (!win->isIconic()) { - screen.updateNetizenWindowRaise(win->getClientWindow()); - win->getLayerItem().raiseLayer(); - win->setLayerNum(win->getLayerItem().getLayerNum()); - } + win->getLayerItem().raiseLayer(); - std::list<FluxboxWindow *>::const_iterator it = win->getTransients().begin(); - std::list<FluxboxWindow *>::const_iterator it_end = win->getTransients().end(); + // remember number just in case a transient happens to revisit this window + int layer_num = win->getLayerItem().getLayerNum(); + win->setLayerNum(layer_num); + + WinClient::TransientList::const_iterator it = client->transientList().begin(); + WinClient::TransientList::const_iterator it_end = client->transientList().end(); for (; it != it_end; ++it) { - if (!(*it)->isIconic()) { - screen.updateNetizenWindowRaise((*it)->getClientWindow()); - (*it)->getLayerItem().raiseLayer(); - (*it)->setLayerNum((*it)->getLayerItem().getLayerNum()); + win = (*it)->fbwindow(); + if (win && !win->isIconic()) { + screen.updateNetizenWindowRaise((*it)->window()); + win->getLayerItem().moveToLayer(layer_num); + win->setLayerNum(layer_num); } } } void FluxboxWindow::lowerLayer() { - FluxboxWindow *win = (FluxboxWindow *) 0, *bottom = this; + // get root window + WinClient *client = getRootTransientFor(m_client); - while (bottom->getTransientFor()) { - bottom = bottom->getTransientFor(); - assert(bottom != bottom->getTransientFor()); - } - - win = bottom; - + // if we don't have any root window use this as root + if (client == 0) + client = m_client; + + FluxboxWindow *win = client->fbwindow(); + if (!win) return; + if (!win->isIconic()) { - screen.updateNetizenWindowLower(win->getClientWindow()); - win->getLayerItem().lowerLayer(); - win->setLayerNum(win->getLayerItem().getLayerNum()); + screen.updateNetizenWindowLower(client->window()); } - std::list<FluxboxWindow *>::const_iterator it = win->getTransients().begin(); - std::list<FluxboxWindow *>::const_iterator it_end = win->getTransients().end(); + win->getLayerItem().lowerLayer(); + // remember number just in case a transient happens to revisit this window + int layer_num = win->getLayerItem().getLayerNum(); + win->setLayerNum(layer_num); + + WinClient::TransientList::const_iterator it = client->transientList().begin(); + WinClient::TransientList::const_iterator it_end = client->transientList().end(); for (; it != it_end; ++it) { - if (!(*it)->isIconic()) { - screen.updateNetizenWindowLower((*it)->getClientWindow()); - (*it)->getLayerItem().lowerLayer(); - (*it)->setLayerNum((*it)->getLayerItem().getLayerNum()); + win = (*it)->fbwindow(); + if (win && !win->isIconic()) { + screen.updateNetizenWindowLower((*it)->window()); + win->getLayerItem().moveToLayer(layer_num); + win->setLayerNum(layer_num); } } - } + void FluxboxWindow::moveToLayer(int layernum) { Fluxbox * fluxbox = Fluxbox::instance(); - FluxboxWindow *win = this; - // don't let it set its layer into menu area if (layernum <= fluxbox->getMenuLayer()) { layernum = fluxbox->getMenuLayer() + 1; } - while (win->getTransientFor()) { - win = win->getTransientFor(); - assert(win != win->getTransientFor()); - } + // get root window + WinClient *client = getRootTransientFor(m_client); + + // if we don't have any root window use this as root + if (client == 0) + client = m_client; + + FluxboxWindow *win = client->fbwindow(); + if (!win) return; if (!win->isIconic()) { - screen.updateNetizenWindowRaise(win->getClientWindow()); - win->getLayerItem().moveToLayer(layernum); - win->setLayerNum(win->getLayerItem().getLayerNum()); + screen.updateNetizenWindowRaise(client->window()); } - std::list<FluxboxWindow *>::const_iterator it = win->getTransients().begin(); - std::list<FluxboxWindow *>::const_iterator it_end = win->getTransients().end(); + win->getLayerItem().lowerLayer(); + // remember number just in case a transient happens to revisit this window + layernum = win->getLayerItem().getLayerNum(); + win->setLayerNum(layernum); + + WinClient::TransientList::const_iterator it = client->transientList().begin(); + WinClient::TransientList::const_iterator it_end = client->transientList().end(); for (; it != it_end; ++it) { - if (!(*it)->isIconic()) { - screen.updateNetizenWindowRaise((*it)->getClientWindow()); - (*it)->getLayerItem().moveToLayer(layernum); - (*it)->setLayerNum((*it)->getLayerItem().getLayerNum()); + win = (*it)->fbwindow(); + if (win && !win->isIconic()) { + screen.updateNetizenWindowRaise((*it)->window()); + win->getLayerItem().moveToLayer(layernum); + win->setLayerNum(layernum); } } }

@@ -1992,7 +2018,7 @@ return;

setState(NormalState); - if (transient || screen.doFocusNew()) + if (client->isTransient() || screen.doFocusNew()) setInputFocus(); else setFocusFlag(false);

@@ -2003,7 +2029,7 @@

iconic = false; // Auto-group from tab? - if (!transient) { + if (!client->isTransient()) { cerr<<__FILE__<<"("<<__FUNCTION__<<") TODO check grouping here"<<endl; }

@@ -2055,12 +2081,18 @@ case XA_WM_COMMAND:

break; case XA_WM_TRANSIENT_FOR: { - bool was_transient = isTransient(); - updateTransientInfo(); + // TODO: this property notify should be handled by winclient + // but for now we'll justhave to update all transient info + //bool was_transient = isTransient(); + ClientList::iterator it = clientList().begin(); + ClientList::iterator it_end = clientList().end(); + for (; it != it_end; it++) + (*it)->updateTransientInfo(); reconfigure(); + // TODO: this is broken whilst we don't know which client // update our layer to be the same layer as our transient for - if (isTransient() && isTransient() != was_transient) - getLayerItem().setLayer(getTransientFor()->getLayerItem().getLayer()); + //if (isTransient() && isTransient() != was_transient) + // getLayerItem().setLayer(getTransientFor()->getLayerItem().getLayer()); } break;

@@ -2097,7 +2129,8 @@ decorations.handle = false;

functions.resize=false; functions.maximize=false; } else { - if (! isTransient()) { + // TODO: is broken while handled by FbW, needs to be in WinClient + if (! winClient().isTransient()) { decorations.maximize = true; decorations.handle = true; functions.maximize = true;

@@ -2929,12 +2962,6 @@ }

} } -void FluxboxWindow::updateTransientInfo() { - for_each(clientList().begin(), - clientList().end(), - mem_fun(&WinClient::updateTransientInfo)); -} - void FluxboxWindow::restore(WinClient *client, bool remap) { if (client->m_win != this) return;

@@ -2987,39 +3014,6 @@ }

void FluxboxWindow::timeout() { raise(); -} - -bool FluxboxWindow::isTransient() const { - if (m_client == 0) - return false; - - return (m_client->transientFor() ? true : false); -} - -bool FluxboxWindow::hasTransient() const { - if (m_client == 0) - return false; - return (m_client->transients.size() ? true : false); -} - -const std::list<FluxboxWindow *> &FluxboxWindow::getTransients() const { - return m_client->transients; -} - -std::list<FluxboxWindow *> &FluxboxWindow::getTransients() { - return m_client->transients; -} - -const FluxboxWindow *FluxboxWindow::getTransientFor() const { - if (m_client == 0) - return 0; - return m_client->transient_for; -} - -FluxboxWindow *FluxboxWindow::getTransientFor() { - if (m_client == 0) - return 0; - return m_client->transient_for; } Window FluxboxWindow::getClientWindow() const {
M src/Window.hhsrc/Window.hh

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.hh,v 1.66 2003/05/01 13:19:36 rathnor Exp $ +// $Id: Window.hh,v 1.67 2003/05/07 16:21:26 rathnor Exp $ #ifndef WINDOW_HH #define WINDOW_HH

@@ -238,8 +238,6 @@ /**

@name accessors */ //@{ - bool isTransient() const; - bool hasTransient() const; inline bool isManaged() const { return m_managed; } inline bool isFocused() const { return focused; } inline bool isVisible() const { return m_frame.isVisible(); }

@@ -267,11 +265,6 @@

inline const FbTk::XLayerItem &getLayerItem() const { return m_layeritem; } inline FbTk::XLayerItem &getLayerItem() { return m_layeritem; } - const std::list<FluxboxWindow *> &getTransients() const; - std::list<FluxboxWindow *> &getTransients(); - const FluxboxWindow *getTransientFor() const; - FluxboxWindow *getTransientFor(); - Window getClientWindow() const; FbTk::FbWindow &getFbWindow() { return m_frame.window(); }

@@ -335,6 +328,9 @@ private:

FluxboxWindow &m_win; }; + bool oplock; // Used to help stop transient loops occurring by locking a window + // during certain operations + private: void init();

@@ -347,8 +343,6 @@ void stopResizing(Window win=0);

void updateIcon(); /// try to attach current attaching client to a window at pos x, y void attachTo(int x, int y); - - void updateTransientInfo(); bool getState(); /// gets title string from client window and updates frame's title

@@ -387,8 +381,8 @@ std::string m_instance_name; /// instance name from WM_CLASS

std::string m_class_name; /// class name from WM_CLASS //Window state - bool moving, resizing, shaded, maximized, iconic, transient, - focused, stuck, modal, send_focus_message, m_managed; + bool moving, resizing, shaded, maximized, iconic, + focused, stuck, send_focus_message, m_managed; WinClient *m_attaching_tab; BScreen &screen; /// screen on which this window exist
M src/Workspace.ccsrc/Workspace.cc

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Workspace.cc,v 1.58 2003/05/04 23:38:06 rathnor Exp $ +// $Id: Workspace.cc,v 1.59 2003/05/07 16:21:26 rathnor Exp $ #include "Workspace.hh"

@@ -57,13 +57,13 @@ using namespace std;

namespace { // anonymous -int countTransients(const FluxboxWindow &win) { - if (win.getTransients().size() == 0) +int countTransients(const WinClient &client) { + if (client.transientList().empty()) return 0; // now go throu the entire tree and count transients - size_t ret = win.getTransients().size(); - std::list<FluxboxWindow *>::const_iterator it = win.getTransients().begin(); - std::list<FluxboxWindow *>::const_iterator it_end = win.getTransients().end(); + size_t ret = client.transientList().size(); + WinClient::TransientList::const_iterator it = client.transientList().begin(); + WinClient::TransientList::const_iterator it_end = client.transientList().end(); for (; it != it_end; ++it) ret += countTransients(*(*it));

@@ -219,52 +219,22 @@

if (w->isFocused()) { if (screen.isSloppyFocus()) { Fluxbox::instance()->revertFocus(&screen); - } else if (w->isTransient() && w->getTransientFor() && - w->getTransientFor()->isVisible()) { - w->getTransientFor()->setInputFocus(); } else { - FluxboxWindow *top = 0; - - // this bit is pretty dodgy at present - // it gets the next item down, then scans through our windowlist to see if it is - // in this workspace. If not, goes down more - /* //!! TODO! FbTk::XLayerItem *item = 0, *lastitem = w->getLayerItem(); - do { - item = m_layermanager.getItemBelow(*lastitem); - Windows::iterator it = m_windowlist.begin(); - Windows::iterator it_end = m_windowlist.end(); - for (; it != it_end; ++it) { - if ((*it)->getLayerItem() == item) { - // found one! - top = *it; - } - } - - lastitem = item; - - } while (item && !top); - - if (!top) { - // look upwards - lastitem = w->getLayerItem(); - do { - item = m_layermanager.getItemAbove(*lastitem); - Windows::iterator it = m_windowlist.begin(); - Windows::iterator it_end = m_windowlist.end(); - for (; it != it_end; ++it) { - if ((*it)->getLayerItem() == item) { - // found one! - top = *it; - } - } - lastitem = item; - } while (item && !top); - - } - */ - if (top == 0|| !top->setInputFocus()) { + // go up the transient tree looking for a focusable window + WinClient *client = 0; + if (w->numClients() > 0) { + client = w->winClient().transientFor(); + while (client) { + if (client->fbwindow() && + client->fbwindow() != w && // can't be this window + client->fbwindow()->isVisible() && + client->fbwindow()->setCurrentClient(*client, true)) + break; + client = client->transientFor(); + } + } + if (client == 0) // we were unsuccessful Fluxbox::instance()->revertFocus(&screen); - } } }