From d63bf127ad6391f3e8408ddfd0ba79c4841a1ecf Mon Sep 17 00:00:00 2001 From: rathnor Date: Wed, 7 May 2003 16:21:26 +0000 Subject: transient fixes by making them WinClients --- ChangeLog | 2 + src/Screen.cc | 12 +- src/WinClient.cc | 82 ++++--------- src/WinClient.hh | 16 ++- src/Window.cc | 366 +++++++++++++++++++++++++++---------------------------- src/Window.hh | 18 +-- src/Workspace.cc | 70 +++-------- 7 files changed, 251 insertions(+), 315 deletions(-) diff --git a/ChangeLog b/ChangeLog index a1d1aeb..238d529 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/src/Screen.cc b/src/Screen.cc index 4c5f85e..93d1ddd 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -22,7 +22,7 @@ // 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 @@ void BScreen::removeClient(WinClient &client) { 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) { diff --git a/src/WinClient.cc b/src/WinClient.cc index ac84c91..1b468d1 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -19,7 +19,7 @@ // 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 @@ WinClient::WinClient(Window win, FluxboxWindow &fbwin):FbTk::FbWindow(win), mwm_hint(0), blackbox_hint(0), m_win(&fbwin), + modal(false), m_title(""), m_icon_title(""), m_diesig(*this) { } @@ -62,42 +63,22 @@ WinClient::~WinClient() { cerr<<__FILE__<<"(~"<<__FUNCTION__<<")[this="<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; - } + assert(transient_for != this); + transient_for->transientList().remove(this); + 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; - } + while (!transients.empty()) { + transients.back()->transient_for = 0; transients.pop_back(); } - + if (window_group != 0) { fluxbox->removeGroupSearch(window_group); window_group = 0; @@ -199,17 +180,7 @@ void WinClient::updateTransientInfo() { 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 @@ void WinClient::updateTransientInfo() { 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 @@ void WinClient::updateTransientInfo() { 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(); } } diff --git a/src/WinClient.hh b/src/WinClient.hh index 6cd14dd..466f456 100644 --- a/src/WinClient.hh +++ b/src/WinClient.hh @@ -19,7 +19,7 @@ // 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 @@ class FluxboxWindow; /// Holds client window info class WinClient:public FbTk::FbWindow { public: - typedef std::list TransientList; + typedef std::list TransientList; WinClient(Window win, FluxboxWindow &fbwin); @@ -56,10 +56,13 @@ public: /// 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 @@ public: remove or move these to private */ - FluxboxWindow *transient_for; // which window are we a transient for? - std::list transients; // which windows are our transients? + WinClient *transient_for; // which window are we a transient for? + std::list transients; // which windows are our transients? Window window_group; @@ -105,6 +108,7 @@ public: }; private: + bool modal; std::string m_title, m_icon_title; WinClientSubj m_diesig; }; diff --git a/src/Window.cc b/src/Window.cc index 1364254..dfcc7a9 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -22,7 +22,7 @@ // 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 @@ static Bool queueScanner(Display *, XEvent *e, char *args) { 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 @@ void raiseFluxboxWindow(FluxboxWindow &win) { } // for each transient do raise - std::list::const_iterator it = win.getTransients().begin(); - std::list::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::const_iterator it = win.getTransients().begin(); - std::list::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 @@ void tempRaiseFluxboxWindow(FluxboxWindow &win) { } // for each transient do raise - std::list::const_iterator it = win.getTransients().begin(); - std::list::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 @@ void LayerMenuItem::click(int button, int time) { 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(WinClient &client, BScreen &scr, FbWinFrameTheme &t 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 @@ void FluxboxWindow::init() { 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 @@ void FluxboxWindow::init() { 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 @@ void FluxboxWindow::init() { 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 @@ void FluxboxWindow::attachClient(WinClient &client) { 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 @@ void FluxboxWindow::attachClient(WinClient &client) { 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 @@ bool FluxboxWindow::removeClient(WinClient &client) { 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 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { } bool FluxboxWindow::isGroupable() const { - if (isResizable() && isMaximizable() && !isTransient()) + if (isResizable() && isMaximizable() && !winClient().isTransient()) return true; return false; } @@ -1136,12 +1145,12 @@ bool FluxboxWindow::setInputFocus() { bool ret = false; - if (m_client->transients.size() && modal) { - std::list::iterator it = m_client->transients.begin(); - std::list::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 @@ void FluxboxWindow::show() { 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 @@ void FluxboxWindow::iconify() { 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 @@ void FluxboxWindow::deiconify(bool reassoc, bool do_raise) { 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::iterator trans_it = + //TODO: Can this get stuck in a loop? + WinClient::TransientList::iterator trans_it = (*client_it)->transientList().begin(); - std::list::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 @@ void FluxboxWindow::raise() { 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 @@ void FluxboxWindow::tempRaise() { 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 @@ void FluxboxWindow::raiseLayer() { 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; - if (!win->isIconic()) { - screen.updateNetizenWindowRaise(win->getClientWindow()); - win->getLayerItem().raiseLayer(); - win->setLayerNum(win->getLayerItem().getLayerNum()); - } + FluxboxWindow *win = client->fbwindow(); + if (!win) return; + + if (!win->isIconic()) + screen.updateNetizenWindowRaise(client->window()); + + win->getLayerItem().raiseLayer(); + + // remember number just in case a transient happens to revisit this window + int layer_num = win->getLayerItem().getLayerNum(); + win->setLayerNum(layer_num); - std::list::const_iterator it = win->getTransients().begin(); - std::list::const_iterator it_end = win->getTransients().end(); + 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; - - while (bottom->getTransientFor()) { - bottom = bottom->getTransientFor(); - assert(bottom != bottom->getTransientFor()); - } - - win = bottom; + // 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.updateNetizenWindowLower(win->getClientWindow()); - win->getLayerItem().lowerLayer(); - win->setLayerNum(win->getLayerItem().getLayerNum()); + screen.updateNetizenWindowLower(client->window()); } - std::list::const_iterator it = win->getTransients().begin(); - std::list::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::const_iterator it = win->getTransients().begin(); - std::list::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 @@ void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) { setState(NormalState); - if (transient || screen.doFocusNew()) + if (client->isTransient() || screen.doFocusNew()) setInputFocus(); else setFocusFlag(false); @@ -2003,7 +2029,7 @@ void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) { iconic = false; // Auto-group from tab? - if (!transient) { + if (!client->isTransient()) { cerr<<__FILE__<<"("<<__FUNCTION__<<") TODO check grouping here"<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 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) { 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::updateIcon() { } } -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; @@ -2989,39 +3016,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::getTransients() const { - return m_client->transients; -} - -std::list &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 { if (m_client == 0) return 0; diff --git a/src/Window.hh b/src/Window.hh index 426196d..cc7eff9 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -22,7 +22,7 @@ // 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 @@ public: @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 @@ public: inline const FbTk::XLayerItem &getLayerItem() const { return m_layeritem; } inline FbTk::XLayerItem &getLayerItem() { return m_layeritem; } - const std::list &getTransients() const; - std::list &getTransients(); - const FluxboxWindow *getTransientFor() const; - FluxboxWindow *getTransientFor(); - Window getClientWindow() const; FbTk::FbWindow &getFbWindow() { return m_frame.window(); } @@ -335,6 +328,9 @@ public: FluxboxWindow &m_win; }; + bool oplock; // Used to help stop transient loops occurring by locking a window + // during certain operations + private: void init(); @@ -348,8 +344,6 @@ private: /// 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 void updateTitleFromClient(); @@ -387,8 +381,8 @@ private: 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 diff --git a/src/Workspace.cc b/src/Workspace.cc index ae986ad..f7bcb83 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -22,7 +22,7 @@ // 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::const_iterator it = win.getTransients().begin(); - std::list::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 @@ int Workspace::removeWindow(FluxboxWindow *w) { 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()) { - Fluxbox::instance()->revertFocus(&screen); + // 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); } } -- cgit v0.11.2