From d353b688dec41daddeec9696586a4519f58cce45 Mon Sep 17 00:00:00 2001 From: rathnor Date: Mon, 28 Jul 2003 15:06:36 +0000 Subject: update many things to use WinClient instead of FluxboxWindow --- ChangeLog | 14 ++++ src/AtomHandler.hh | 6 +- src/CurrentWindowCmd.cc | 36 ++++++---- src/CurrentWindowCmd.hh | 7 +- src/Ewmh.cc | 56 ++++++++------- src/Ewmh.hh | 10 +-- src/Gnome.cc | 34 ++++----- src/Gnome.hh | 6 +- src/Remember.hh | 6 +- src/Screen.cc | 110 +++++++++++++++------------- src/Screen.hh | 6 +- src/Toolbar.cc | 31 ++++---- src/ToolbarHandler.hh | 6 +- src/WinClient.cc | 110 ++++++++++++++++++++++------ src/WinClient.hh | 21 ++++-- src/Window.cc | 113 +++++++---------------------- src/Window.hh | 12 +--- src/Workspace.cc | 4 +- src/fluxbox.cc | 185 +++++++++++++++++++++++++++--------------------- src/fluxbox.hh | 32 ++++++--- 20 files changed, 449 insertions(+), 356 deletions(-) diff --git a/ChangeLog b/ChangeLog index b4f4698..78db46b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ (Format: Year/Month/Day) Changes for 0.9.5: +*03/07/29: + * Change: (Simon) + - Fluxbox::window search + - Fluxbox::m_focused_window + - strut saving + - Some event handling + - and more + to use WinClient, not FluxboxWindow. + This should fix some bugs where things weren't consistent and + hopefully sets the stage to fix various other things that get out of + whack. + fluxbox.hh/cc Screen.hh/cc Window.hh/cc Workspace.cc WinClient.hh/cc + CurrentWindowCmd.hh/cc AtomHandler.hh Ewmh.hh/cc Gnome.hh/cc + Remember.hh ToolbarHandler.hh Toolbar.cc CurrentWindowCmd.hh/cc *03/07/28: * Added MoveTabLeft and MoveTabRight commands (Henrik) Window.hh/cc, FbWinFrame.hh/cc, FbCommandFactory.cc diff --git a/src/AtomHandler.hh b/src/AtomHandler.hh index 3117b1a..45b7914 100644 --- a/src/AtomHandler.hh +++ b/src/AtomHandler.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: AtomHandler.hh,v 1.11 2003/07/10 11:23:35 fluxgen Exp $ +// $Id: AtomHandler.hh,v 1.12 2003/07/28 15:06:33 rathnor Exp $ #ifndef ATOMHANDLER_HH #define ATOMHANDLER_HH @@ -51,9 +51,9 @@ public: virtual void updateLayer(FluxboxWindow &win) = 0; virtual bool checkClientMessage(const XClientMessageEvent &ce, - BScreen * screen, FluxboxWindow * const win) = 0; + BScreen * screen, WinClient * const winclient) = 0; - virtual bool propertyNotify(FluxboxWindow &win, Atom the_property) = 0; + virtual bool propertyNotify(WinClient &winclient, Atom the_property) = 0; /// should this object be updated or not? bool update() const { return m_update; } diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc index f4d4af7..b8913bb 100644 --- a/src/CurrentWindowCmd.cc +++ b/src/CurrentWindowCmd.cc @@ -20,58 +20,68 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: CurrentWindowCmd.cc,v 1.2 2003/07/26 13:44:00 rathnor Exp $ +// $Id: CurrentWindowCmd.cc,v 1.3 2003/07/28 15:06:33 rathnor Exp $ #include "CurrentWindowCmd.hh" #include "fluxbox.hh" #include "Window.hh" #include "Screen.hh" +#include "WinClient.hh" CurrentWindowCmd::CurrentWindowCmd(Action act):m_action(act) { } void CurrentWindowCmd::execute() { - Fluxbox *fb = Fluxbox::instance(); - if (fb->getFocusedWindow() != 0) - (*fb->getFocusedWindow().*m_action)(); + WinClient *client = Fluxbox::instance()->getFocusedWindow(); + if (client && client->fbwindow()) + (client->fbwindow()->*m_action)(); } void KillWindowCmd::real_execute() { - XKillClient(FbTk::App::instance()->display(), window().clientWindow()); + winclient().sendClose(true); } void SendToWorkspaceCmd::real_execute() { - if (m_workspace_num >= 0 && m_workspace_num < window().screen().getNumberOfWorkspaces()) - window().screen().sendToWorkspace(m_workspace_num, &window()); + if (m_workspace_num >= 0 && m_workspace_num < fbwindow().screen().getNumberOfWorkspaces()) + fbwindow().screen().sendToWorkspace(m_workspace_num, &fbwindow()); } void WindowHelperCmd::execute() { - if (Fluxbox::instance()->getFocusedWindow()) + WinClient *client = Fluxbox::instance()->getFocusedWindow(); + if (client && client->fbwindow()) // guarantee that fbwindow() exists too real_execute(); } -FluxboxWindow &WindowHelperCmd::window() { +WinClient &WindowHelperCmd::winclient() { + // will exist from execute above return *Fluxbox::instance()->getFocusedWindow(); } +FluxboxWindow &WindowHelperCmd::fbwindow() { + // will exist from execute above + return *Fluxbox::instance()->getFocusedWindow()->fbwindow(); +} + MoveLeftCmd::MoveLeftCmd(int step_size):MoveHelper(step_size) { } void MoveLeftCmd::real_execute() { - window().move(window().x() - stepSize(), window().y()); + fbwindow().move(fbwindow().x() - stepSize(), + fbwindow().y()); } MoveRightCmd::MoveRightCmd(int step_size):MoveHelper(step_size) { } void MoveRightCmd::real_execute() { - window().move(window().x() + stepSize(), window().y()); + fbwindow().move(fbwindow().x() + stepSize(), + fbwindow().y()); } MoveDownCmd::MoveDownCmd(int step_size):MoveHelper(step_size) { } void MoveDownCmd::real_execute() { - window().move(window().x(), window().y() + stepSize()); + fbwindow().move(fbwindow().x(), fbwindow().y() + stepSize()); } MoveUpCmd::MoveUpCmd(int step_size):MoveHelper(step_size) { } void MoveUpCmd::real_execute() { - window().move(window().x(), window().y() - stepSize()); + fbwindow().move(fbwindow().x(), fbwindow().y() - stepSize()); } diff --git a/src/CurrentWindowCmd.hh b/src/CurrentWindowCmd.hh index fd6ac40..3e56625 100644 --- a/src/CurrentWindowCmd.hh +++ b/src/CurrentWindowCmd.hh @@ -20,7 +20,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: CurrentWindowCmd.hh,v 1.1 2003/06/30 14:35:11 fluxgen Exp $ +// $Id: CurrentWindowCmd.hh,v 1.2 2003/07/28 15:06:33 rathnor Exp $ #ifndef CURRENTWINDOWCMD_HH #define CURRENTWINDOWCMD_HH @@ -28,6 +28,8 @@ #include "Command.hh" class FluxboxWindow; +class WinClient; + /// command that calls FluxboxWindow:: on execute() /// similar to FbTk::SimpleCommand class CurrentWindowCmd: public FbTk::Command { @@ -47,7 +49,8 @@ public: protected: - FluxboxWindow &window(); + WinClient &winclient(); + FluxboxWindow &fbwindow(); virtual void real_execute() = 0; }; diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 10fa722..e6a0994 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Ewmh.cc,v 1.29 2003/07/04 01:03:40 rathnor Exp $ +// $Id: Ewmh.cc,v 1.30 2003/07/28 15:06:33 rathnor Exp $ #include "Ewmh.hh" @@ -95,6 +95,10 @@ void Ewmh::initForScreen(BScreen &screen) { } +void Ewmh::setupClient(WinClient &winclient) { + updateStrut(winclient); +} + void Ewmh::setupFrame(FluxboxWindow &win) { Atom ret_type; @@ -123,8 +127,6 @@ void Ewmh::setupFrame(FluxboxWindow &win) { XFree(data); } - updateStrut(win); - } void Ewmh::updateClientList(BScreen &screen) { @@ -260,34 +262,36 @@ void Ewmh::updateWorkspace(FluxboxWindow &win) { } // return true if we did handle the atom here -bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, FluxboxWindow * const win) { +bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, WinClient * const winclient) { if (ce.message_type == m_net_wm_desktop) { if (screen == 0) return true; // ce.data.l[0] = workspace number // valid window and workspace number? - if (win == 0 || + if (winclient == 0 || winclient->fbwindow() == 0 || static_cast(ce.data.l[0]) >= screen->getCount()) return true; - screen->sendToWorkspace(ce.data.l[0], win, false); + screen->sendToWorkspace(ce.data.l[0], winclient->fbwindow(), false); return true; } else if (ce.message_type == m_net_wm_state) { - if (win == 0) + if (winclient == 0 || winclient->fbwindow() == 0) return true; + + FluxboxWindow &win = *winclient->fbwindow(); // ce.data.l[0] = the action (remove, add or toggle) // ce.data.l[1] = the first property to alter // ce.data.l[2] = second property to alter (can be zero) if (ce.data.l[0] == STATE_REMOVE) { - setState(*win, ce.data.l[1], false); - setState(*win, ce.data.l[2], false); + setState(win, ce.data.l[1], false); + setState(win, ce.data.l[2], false); } else if (ce.data.l[0] == STATE_ADD) { - setState(*win, ce.data.l[1], true); - setState(*win, ce.data.l[2], true); + setState(win, ce.data.l[1], true); + setState(win, ce.data.l[2], true); } else if (ce.data.l[0] == STATE_TOGGLE) { - toggleState(*win, ce.data.l[1]); - toggleState(*win, ce.data.l[2]); + toggleState(win, ce.data.l[1]); + toggleState(win, ce.data.l[2]); } return true; @@ -330,20 +334,20 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, F } else if (ce.message_type == m_net_active_window) { // make sure we have a valid window - if (win == 0) + if (winclient == 0) return true; // ce.window = window to focus - win->setInputFocus(); + winclient->focus(); return true; } else if (ce.message_type == m_net_close_window) { - if (win == 0) + if (winclient == 0) return true; // ce.window = window to close (which in this case is the win argument) - win->close(); + winclient->sendClose(); return true; } else if (ce.message_type == m_net_moveresize_window) { - if (win == 0) + if (winclient == 0 && winclient->fbwindow()) return true; // ce.data.l[0] = gravity and flags // ce.data.l[1] = x @@ -351,7 +355,7 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, F // ce.data.l[3] = width // ce.data.l[4] = height // TODO: gravity and flags - win->moveResize(ce.data.l[1], ce.data.l[2], + winclient->fbwindow()->moveResize(ce.data.l[1], ce.data.l[2], ce.data.l[3], ce.data.l[4]); return true; } @@ -361,9 +365,9 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, F } -bool Ewmh::propertyNotify(FluxboxWindow &win, Atom the_property) { +bool Ewmh::propertyNotify(WinClient &winclient, Atom the_property) { if (the_property == m_net_wm_strut) { - updateStrut(win); + updateStrut(winclient); return true; } @@ -434,20 +438,20 @@ void Ewmh::toggleState(FluxboxWindow &win, Atom state) const { } -void Ewmh::updateStrut(FluxboxWindow &win) { +void Ewmh::updateStrut(WinClient &winclient) { Atom ret_type = 0; int fmt = 0; unsigned long nitems = 0, bytes_after = 0; long *data = 0; - if (win.winClient().property(m_net_wm_strut, 0, 4, False, XA_CARDINAL, + if (winclient.property(m_net_wm_strut, 0, 4, False, XA_CARDINAL, &ret_type, &fmt, &nitems, &bytes_after, (unsigned char **) &data) && data) { #ifdef DEBUG cerr<<__FILE__<<"("<<__FUNCTION__<<"): Strut: "<fbwindow()) { + //get new states + int flag = ce.data.l[0] & ce.data.l[1]; + //don't update this when when we set new state + disableUpdate(); + // convert to Fluxbox state + setState(winclient->fbwindow(), flag); + // enable update of atom states + enableUpdate(); + } } else if (ce.message_type == m_gnome_wm_win_hints) { #ifdef DEBUG cerr<<__FILE__<<"("<<__LINE__<<"): _WIN_HINTS"<fbwindow()) + setLayer(winclient->fbwindow(), ce.data.l[0]); } else return false; //the gnome atom wasn't found or not supported diff --git a/src/Gnome.hh b/src/Gnome.hh index a9a63f5..1275b90 100644 --- a/src/Gnome.hh +++ b/src/Gnome.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Gnome.hh,v 1.9 2003/07/04 14:06:20 rathnor Exp $ +// $Id: Gnome.hh,v 1.10 2003/07/28 15:06:33 rathnor Exp $ #ifndef GNOME_HH #define GNOME_HH @@ -78,12 +78,12 @@ public: void updateHints(FluxboxWindow &win); void updateWorkspace(FluxboxWindow &win); - bool checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, FluxboxWindow * const win); + bool checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, WinClient * const winclient); // ignore these ones void updateFrameClose(FluxboxWindow &win) {} void updateClientClose(WinClient &winclient) {} - bool propertyNotify(FluxboxWindow &win, Atom the_property) { return false; } + bool propertyNotify(WinClient &winclient, Atom the_property) { return false; } private: void setLayer(FluxboxWindow *win, int layer); diff --git a/src/Remember.hh b/src/Remember.hh index 4520c23..1671a41 100644 --- a/src/Remember.hh +++ b/src/Remember.hh @@ -21,7 +21,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Remember.hh,v 1.11 2003/07/10 13:23:09 rathnor Exp $ +// $Id: Remember.hh,v 1.12 2003/07/28 15:06:33 rathnor Exp $ /* Based on the original "Remember patch" by Xavier Brouckaert */ @@ -188,9 +188,9 @@ public: void updateLayer(FluxboxWindow &win) {} bool checkClientMessage(const XClientMessageEvent &ce, - BScreen * screen, FluxboxWindow * const win) { return false; } + BScreen * screen, WinClient * const winclient) { return false; } // ignore this - bool propertyNotify(FluxboxWindow &win, Atom the_property) { return false; } + bool propertyNotify(WinClient &winclient, Atom the_property) { return false; } private: // returns number of lines read diff --git a/src/Screen.cc b/src/Screen.cc index 880d769..3838528 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.207 2003/07/25 10:03:55 rathnor Exp $ +// $Id: Screen.cc,v 1.208 2003/07/28 15:06:33 rathnor Exp $ #include "Screen.hh" @@ -738,11 +738,11 @@ void BScreen::removeWindow(FluxboxWindow *win) { void BScreen::removeClient(WinClient &client) { WinClient *cyc = *cycling_window; - FluxboxWindow *focused = Fluxbox::instance()->getFocusedWindow(); + WinClient *focused = Fluxbox::instance()->getFocusedWindow(); focused_list.remove(&client); if (cyc == &client) { cycling_window = focused_list.end(); - } else if (focused && &focused->winClient() == &client) { + } else if (focused == &client) { // if we are focused, then give our focus to our transient parent // or revert normally if (client.transientFor() && client.transientFor()->fbwindow()) @@ -832,7 +832,11 @@ void BScreen::changeWorkspaceID(unsigned int id) { return; XSync(FbTk::App::instance()->display(), true); - FluxboxWindow *focused = Fluxbox::instance()->getFocusedWindow(); + WinClient *focused_client = Fluxbox::instance()->getFocusedWindow(); + FluxboxWindow *focused = 0; + if (focused_client) + focused = focused_client->fbwindow(); + #ifdef DEBUG cerr<<__FILE__<<"("<<__FUNCTION__<<"): focused = "<= m_workspaces_list.size()) return; - if (!win) - win = Fluxbox::instance()->getFocusedWindow(); + if (!win) { + WinClient *client = Fluxbox::instance()->getFocusedWindow(); + if (client) + win = client->fbwindow(); + } if (id != currentWorkspace()->workspaceID()) { XSync(FbTk::App::instance()->display(), True); @@ -930,7 +937,7 @@ void BScreen::addNetizen(Window win) { } Window f = ((Fluxbox::instance()->getFocusedWindow()) ? - Fluxbox::instance()->getFocusedWindow()->clientWindow() : None); + Fluxbox::instance()->getFocusedWindow()->window() : None); net->sendWindowFocus(f); } @@ -970,7 +977,7 @@ void BScreen::updateNetizenWindowFocus() { Netizens::iterator it = m_netizen_list.begin(); Netizens::iterator it_end = m_netizen_list.end(); Window f = ((Fluxbox::instance()->getFocusedWindow()) ? - Fluxbox::instance()->getFocusedWindow()->clientWindow() : None); + Fluxbox::instance()->getFocusedWindow()->window() : None); for (; it != it_end; ++it) { (*it)->sendWindowFocus(f); } @@ -1075,8 +1082,6 @@ FluxboxWindow *BScreen::createWindow(Window client) { Fluxbox::instance()->attachSignals(*win); } - Fluxbox::instance()->saveWindowSearch(client, win); - // we also need to check if another window expects this window to the left // and if so, then join it. FluxboxWindow *otherwin = 0; @@ -1108,7 +1113,6 @@ FluxboxWindow *BScreen::createWindow(WinClient &client) { // don't add to focused_list, as it should already be in there (since the // WinClient already exists). - Fluxbox::instance()->saveWindowSearch(client.window(), win); Fluxbox::instance()->attachSignals(*win); // winclient actions should have been setup when the WinClient was created if (win->workspaceNumber() == currentWorkspaceID() || win->isStuck()) { @@ -1213,16 +1217,8 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id, void BScreen::nextFocus(int opts) { - bool have_focused = false; - FluxboxWindow *focused = Fluxbox::instance()->getFocusedWindow(); const int num_windows = currentWorkspace()->numberOfWindows(); - if (focused != 0) { - if (focused->screen().screenNumber() == screenNumber()) { - have_focused = true; - } - } - if (num_windows >= 1) { if (!(opts & CYCLELINEAR)) { if (!cycling_focus) { @@ -1272,16 +1268,30 @@ void BScreen::nextFocus(int opts) { } cycling_window = it; } else { // not stacked cycling + // I really don't like this, but evidently some people use it(!) Workspace *wksp = currentWorkspace(); Workspace::Windows &wins = wksp->windowList(); Workspace::Windows::iterator it = wins.begin(); - + + FluxboxWindow *focused_group = 0; + // start from the focused window + bool have_focused = false; + WinClient *focused = Fluxbox::instance()->getFocusedWindow(); + if (focused != 0) { + if (focused->screen().screenNumber() == screenNumber()) { + have_focused = true; + focused_group = focused->fbwindow(); + } + } + if (!have_focused) { - focused = (*it); + focused_group = (*it); } else { - for (; (*it) != focused; ++it) //get focused window iterator + //get focused window iterator + for (; it != wins.end() && (*it) != focused_group; ++it) continue; } + do { ++it; if (it == wins.end()) @@ -1289,8 +1299,8 @@ void BScreen::nextFocus(int opts) { // see if the window should be skipped if (! (doSkipWindow((*it)->winClient(), opts) || !(*it)->setInputFocus()) ) break; - } while ((*it) != focused); - if ((*it) != focused && it != wins.end()) + } while ((*it) != focused_group); + if ((*it) != focused_group && it != wins.end()) (*it)->raise(); } @@ -1300,16 +1310,8 @@ void BScreen::nextFocus(int opts) { void BScreen::prevFocus(int opts) { - bool have_focused = false; - FluxboxWindow *focused; int num_windows = currentWorkspace()->numberOfWindows(); - if ((focused = Fluxbox::instance()->getFocusedWindow())) { - if (focused->screen().screenNumber() == screenNumber()) { - have_focused = true; - } - } - if (num_windows >= 1) { if (!(opts & CYCLELINEAR)) { if (!cycling_focus) { @@ -1366,13 +1368,25 @@ void BScreen::prevFocus(int opts) { Workspace::Windows &wins = wksp->windowList(); Workspace::Windows::iterator it = wins.begin(); + FluxboxWindow *focused_group = 0; + // start from the focused window + bool have_focused = false; + WinClient *focused = Fluxbox::instance()->getFocusedWindow(); + if (focused != 0) { + if (focused->screen().screenNumber() == screenNumber()) { + have_focused = true; + focused_group = focused->fbwindow(); + } + } + if (!have_focused) { - focused = (*it); + focused_group = (*it); } else { - for (; (*it) != focused; ++it) //get focused window iterator + //get focused window iterator + for (; it != wins.end() && (*it) != focused_group; ++it) continue; } - + do { if (it == wins.begin()) it = wins.end(); @@ -1380,9 +1394,9 @@ void BScreen::prevFocus(int opts) { // see if the window should be skipped if (! (doSkipWindow((*it)->winClient(), opts) || !(*it)->setInputFocus()) ) break; - } while ((*it) != focused); + } while ((*it) != focused_group); - if ((*it) != focused && it != wins.end()) + if ((*it) != focused_group && it != wins.end()) (*it)->raise(); } } @@ -2150,7 +2164,7 @@ bool BScreen::doSkipWindow(const WinClient &winclient, int opts) { return (!win || (opts & CYCLESKIPSTUCK) != 0 && win->isStuck() || // skip if stuck // skip if not active client (i.e. only visit each fbwin once) - (opts & CYCLEGROUPS) != 0 && win->winClient() != winclient.window() || + (opts & CYCLEGROUPS) != 0 && win->winClient().window() != winclient.window() || (opts & CYCLESKIPSHADED) != 0 && win->isShaded() // skip if shaded ); } @@ -2229,15 +2243,6 @@ WinClient *BScreen::getLastFocusedWindow(int workspace) { return 0; } -/** - Access and clear the auto-group window -*/ -FluxboxWindow* BScreen::useAutoGroupWindow() { - Window w = auto_group_window; - auto_group_window = 0; - return w ? Fluxbox::instance()->searchWindow(w) : 0; -} - void BScreen::updateSize() { rootWindow().updateGeometry(); @@ -2263,16 +2268,19 @@ FluxboxWindow *BScreen::findGroupLeft(WinClient &winclient) { if (w == None) return 0; - FluxboxWindow *fbwin = Fluxbox::instance()->searchWindow(w); + WinClient *have_client = Fluxbox::instance()->searchWindow(w); - if (!fbwin) { + if (!have_client) { // not found, add it to expecting m_expecting_groups[w] = &winclient; - } else if (&fbwin->screen() != &winclient.screen()) + } else if (&have_client->screen() != &winclient.screen()) // something is not consistent return 0; - return fbwin; + if (have_client) + return have_client->fbwindow(); + else + return 0; } FluxboxWindow *BScreen::findGroupRight(WinClient &winclient) { diff --git a/src/Screen.hh b/src/Screen.hh index 4181698..ebd5a60 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.hh,v 1.116 2003/07/20 08:12:36 rathnor Exp $ +// $Id: Screen.hh,v 1.117 2003/07/28 15:06:34 rathnor Exp $ #ifndef SCREEN_HH #define SCREEN_HH @@ -258,8 +258,6 @@ public: void setLayer(FbTk::XLayerItem &item, int layernum); // remove? no, items are never removed from their layer until they die - FluxboxWindow* useAutoGroupWindow(); - /// updates root window size and resizes/reconfigures screen clients /// that depends on screen size (slit) /// (and maximized windows?) @@ -391,8 +389,6 @@ private: WorkspaceNames m_workspace_names; Workspaces m_workspaces_list; - Window auto_group_window; - std::auto_ptr m_windowtheme; std::auto_ptr m_winbutton_theme; std::auto_ptr m_menutheme; diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 409181b..dc8c2b3 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Toolbar.cc,v 1.103 2003/07/25 10:03:55 rathnor Exp $ +// $Id: Toolbar.cc,v 1.104 2003/07/28 15:06:34 rathnor Exp $ #include "Toolbar.hh" @@ -31,6 +31,7 @@ #include "fluxbox.hh" #include "Screen.hh" #include "Window.hh" +#include "WinClient.hh" #include "Workspace.hh" #include "ImageControl.hh" #include "ToolbarTheme.hh" @@ -880,21 +881,23 @@ void Toolbar::checkClock(bool redraw, bool date) { void Toolbar::redrawWindowLabel(bool redraw) { - if (Fluxbox::instance()->getFocusedWindow()) { + WinClient *winclient = Fluxbox::instance()->getFocusedWindow(); + if (winclient) { if (redraw) frame.window_label.clear(); - FluxboxWindow *foc = Fluxbox::instance()->getFocusedWindow(); + const std::string &title = winclient->getTitle(); + // don't draw focused window if it's not on the same screen - if (&foc->screen() != &screen() || foc->title().size() == 0) + if (&winclient->screen() != &screen() || title.size() == 0) return; - - unsigned int newlen = foc->title().size(); + + unsigned int newlen = title.size(); int dx = FbTk::doAlignment(frame.window_label_w, frame.bevel_w*2, m_theme.justify(), m_theme.font(), - foc->title().c_str(), - foc->title().size(), newlen); + title.c_str(), + title.size(), newlen); int dy = 1 + m_theme.font().ascent(); if (m_theme.font().isRotated()) { @@ -907,7 +910,7 @@ void Toolbar::redrawWindowLabel(bool redraw) { m_theme.font().drawText(frame.window_label.window(), screen().screenNumber(), m_theme.windowTextGC(), - foc->title().c_str(), newlen, + title.c_str(), newlen, dx, dy); } else frame.window_label.clear(); @@ -961,8 +964,9 @@ void Toolbar::edit() { frame.workspace_label.clear(); Fluxbox * const fluxbox = Fluxbox::instance(); - if (fluxbox->getFocusedWindow()) //disable focus on current focused window - fluxbox->getFocusedWindow()->setFocusFlag(false); + WinClient *winclient = fluxbox->getFocusedWindow(); + if (winclient && winclient->fbwindow()) //disable focus on current focused window + winclient->fbwindow()->setFocusFlag(false); frame.workspace_label.drawRectangle(screen().winFrameTheme().labelTextFocusGC(), frame.workspace_label_w / 2, 0, 1, @@ -1116,10 +1120,9 @@ void Toolbar::keyPressEvent(XKeyEvent &ke) { Fluxbox * const fluxbox = Fluxbox::instance(); if (fluxbox->getFocusedWindow()) { - fluxbox->getFocusedWindow()->setInputFocus(); - fluxbox->getFocusedWindow()->setFocusFlag(true); + fluxbox->getFocusedWindow()->focus(); } else - XSetInputFocus(FbTk::App::instance()->display(), PointerRoot, None, CurrentTime); + fluxbox->revertFocus(screen()); if (ks == XK_Return) //change workspace name if keypress = Return screen().currentWorkspace()->setName(m_new_workspace_name.c_str()); diff --git a/src/ToolbarHandler.hh b/src/ToolbarHandler.hh index a8b31cf..599fd67 100644 --- a/src/ToolbarHandler.hh +++ b/src/ToolbarHandler.hh @@ -20,7 +20,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: ToolbarHandler.hh,v 1.6 2003/07/04 14:06:20 rathnor Exp $ +// $Id: ToolbarHandler.hh,v 1.7 2003/07/28 15:06:34 rathnor Exp $ #ifndef TOOLBARHANDLER_HH #define TOOLBARHANDLER_HH @@ -74,9 +74,9 @@ public: void updateLayer(FluxboxWindow &win) {} bool checkClientMessage(const XClientMessageEvent &ce, - BScreen * screen, FluxboxWindow * const win) { return false; } + BScreen * screen, WinClient * const winclient) { return false; } - bool propertyNotify(FluxboxWindow &win, Atom the_atom) { return false; } + bool propertyNotify(WinClient &winclient, Atom the_atom) { return false; } inline FbTk::Menu &getModeMenu() { return m_modemenu; } inline const FbTk::Menu &getModeMenu() const { return m_modemenu; } diff --git a/src/WinClient.cc b/src/WinClient.cc index 092c10d..60cf647 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.19 2003/07/21 15:26:56 rathnor Exp $ +// $Id: WinClient.cc,v 1.20 2003/07/28 15:06:34 rathnor Exp $ #include "WinClient.hh" @@ -52,9 +52,10 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb initial_state(0), normal_hint_flags(0), wm_hint_flags(0), - send_focus_message(false), m_win(fbwin), m_modal(0), + send_focus_message(false), + closable(false), m_title(""), m_icon_title(""), m_class_name(""), m_instance_name(""), m_blackbox_hint(0), @@ -68,6 +69,10 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb updateWMClassHint(); updateTitle(); updateIconTitle(); + Fluxbox::instance()->saveWindowSearch(win, this); + if (window_group != None) + Fluxbox::instance()->saveGroupSearch(window_group, this); + } WinClient::~WinClient() { @@ -77,6 +82,8 @@ WinClient::~WinClient() { FbTk::EventManager::instance()->remove(window()); + clearStrut(); + if (m_win != 0) m_win->removeClient(*this); @@ -160,22 +167,27 @@ bool WinClient::sendFocus() { return true; } -void WinClient::sendClose() { - Display *disp = FbTk::App::instance()->display(); - // fill in XClientMessage structure for delete message - XEvent ce; - ce.xclient.type = ClientMessage; - ce.xclient.message_type = FbAtoms::instance()->getWMProtocolsAtom(); - ce.xclient.display = disp; - ce.xclient.window = window(); - ce.xclient.format = 32; - ce.xclient.data.l[0] = FbAtoms::instance()->getWMDeleteAtom(); - ce.xclient.data.l[1] = CurrentTime; - ce.xclient.data.l[2] = 0l; - ce.xclient.data.l[3] = 0l; - ce.xclient.data.l[4] = 0l; - // send event delete message to client window - XSendEvent(disp, window(), false, NoEventMask, &ce); +void WinClient::sendClose(bool forceful) { + if (forceful || !isClosable()) + XKillClient(FbTk::App::instance()->display(), window()); + else { + // send WM_DELETE message + Display *disp = FbTk::App::instance()->display(); + // fill in XClientMessage structure for delete message + XEvent ce; + ce.xclient.type = ClientMessage; + ce.xclient.message_type = FbAtoms::instance()->getWMProtocolsAtom(); + ce.xclient.display = disp; + ce.xclient.window = window(); + ce.xclient.format = 32; + ce.xclient.data.l[0] = FbAtoms::instance()->getWMDeleteAtom(); + ce.xclient.data.l[1] = CurrentTime; + ce.xclient.data.l[2] = 0l; + ce.xclient.data.l[3] = 0l; + ce.xclient.data.l[4] = 0l; + // send event delete message to client window + XSendEvent(disp, window(), false, NoEventMask, &ce); + } } void WinClient::reparent(Window win, int x, int y) { @@ -251,9 +263,8 @@ void WinClient::updateTransientInfo() { return; } - FluxboxWindow *transient_win = Fluxbox::instance()->searchWindow(win); - if (transient_win) - transient_for = transient_win->findClient(win); + + transient_for = Fluxbox::instance()->searchWindow(win); // make sure we don't have deadlock loop in transient chain for (WinClient *w = this; w != 0; w = w->transient_for) { @@ -528,3 +539,60 @@ void WinClient::removeModal() { if (transient_for) transient_for->removeModal(); } + +bool WinClient::validateClient() const { + Display *display = FbTk::App::instance()->display(); + XSync(display, false); + + XEvent e; + if (( XCheckTypedWindowEvent(display, window(), DestroyNotify, &e) || + XCheckTypedWindowEvent(display, window(), UnmapNotify, &e)) + && XPutBackEvent(display, &e)) { + Fluxbox::instance()->ungrab(); + return false; + } + + return true; +} + +void WinClient::setStrut(Strut *strut) { + clearStrut(); + m_strut = strut; +} + +void WinClient::clearStrut() { + if (m_strut != 0) { + screen().clearStrut(m_strut); + m_strut = 0; + } +} + +bool WinClient::focus() { + if (m_win == 0) + return false; + else + return m_win->setCurrentClient(*this, true); +} + +void WinClient::getWMProtocols() { + Atom *proto = 0; + int num_return = 0; + FbAtoms *fbatoms = FbAtoms::instance(); + + if (XGetWMProtocols(FbTk::App::instance()->display(), window(), &proto, &num_return)) { + + for (int i = 0; i < num_return; ++i) { + if (proto[i] == fbatoms->getWMDeleteAtom()) + closable = true; + else if (proto[i] == fbatoms->getWMTakeFocusAtom()) + send_focus_message = true; + else if (proto[i] == fbatoms->getFluxboxStructureMessagesAtom()) + screen().addNetizen(window()); + } + + XFree(proto); + } else { + cerr<<"Warning: Failed to read WM Protocols. "< class BScreen; +class Strut; /// Holds client window info class WinClient:public FbTk::FbWindow { @@ -44,7 +45,8 @@ public: void updateRect(int x, int y, unsigned int width, unsigned int height); bool sendFocus(); // returns whether we sent a message or not // i.e. whether we assume the focus will get taken - void sendClose(); + void sendClose(bool forceful = false); + inline bool isClosable() const { return closable; } void reparent(Window win, int x, int y); bool getAttrib(XWindowAttributes &attr) const; bool getWMName(XTextProperty &textprop) const; @@ -55,8 +57,9 @@ public: const std::string &getWMClassClass() const; /// updates from wm class hints void updateWMClassHint(); + void getWMProtocols(); - inline const std::string getTitle() const { return m_title; } + inline const std::string &getTitle() const { return m_title; } void updateTitle(); void updateIconTitle(); BScreen &screen() { return m_screen; } @@ -80,6 +83,11 @@ public: return (m_win == &win); } + void setStrut(Strut *strut); + void clearStrut(); + + bool focus(); // calls Window->setCurrentClient to give focus to this client + const std::string &title() const { return m_title; } const std::string &iconTitle() const { return m_icon_title; } const FluxboxWindow *fbwindow() const { return m_win; } @@ -98,6 +106,9 @@ public: void setGroupLeftWindow(Window win); bool hasGroupLeftWindow() const; + // does this client have a pending unmap or destroy event? + bool validateClient() const; + /** !! TODO !! remove or move these to private @@ -114,7 +125,6 @@ public: min_aspect_x, min_aspect_y, max_aspect_x, max_aspect_y, base_width, base_height, win_gravity; unsigned long initial_state, normal_hint_flags, wm_hint_flags; - bool send_focus_message; // this structure only contains 3 elements... the Motif 2.0 structure contains // 5... we only need the first 3... so that is all we will define @@ -145,6 +155,7 @@ private: // number of transients which we are modal for // or indicates that we are modal if don't have any transients int m_modal; + bool send_focus_message, closable; std::string m_title, m_icon_title; std::string m_class_name, m_instance_name; @@ -157,6 +168,8 @@ private: WinClientSubj m_diesig; BScreen &m_screen; + Strut *m_strut; + }; #endif // WINCLIENT_HH diff --git a/src/Window.cc b/src/Window.cc index ac2333b..70d1ee1 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.212 2003/07/28 12:49:18 fluxgen Exp $ +// $Id: Window.cc,v 1.213 2003/07/28 15:06:34 rathnor Exp $ #include "Window.hh" @@ -262,7 +262,6 @@ FluxboxWindow::FluxboxWindow(WinClient &client, BScreen &scr, FbWinFrameTheme &t m_old_decoration(DECOR_NORMAL), m_client(&client), m_frame(new FbWinFrame(tm, scr.imageControl(), scr.screenNumber(), 0, 0, 100, 100)), - m_strut(0), m_layeritem(m_frame->window(), layer), m_layernum(layer.getLayerNum()), m_parent(scr.rootWindow()) { @@ -279,15 +278,13 @@ FluxboxWindow::~FluxboxWindow() { cerr<<__FILE__<<"("<<__LINE__<<"): m_labelbuttons.size = "<removeWindowSearch(frame().window().window()); + Fluxbox::instance()->removeWindowSearchGroup(frame().window().window()); Client2ButtonMap::iterator it = m_labelbuttons.begin(); Client2ButtonMap::iterator it_end = m_labelbuttons.end(); @@ -421,20 +418,15 @@ void FluxboxWindow::init() { functions.resize = functions.move = functions.iconify = functions.maximize = true; - functions.close = decorations.close = false; + decorations.close = false; + + functions.close = m_client->isClosable(); if (m_client->getBlackboxHint() != 0) getBlackboxHints(); else getMWMHints(); - // get size, aspect, minimum/maximum size and other hints set - // by the client - - getWMProtocols(); - if (m_client->window_group != None) - Fluxbox::instance()->saveGroupSearch(m_client->window_group, this); - //!! // fetch client size and placement XWindowAttributes wattrib; @@ -448,8 +440,6 @@ void FluxboxWindow::init() { m_client->old_bw = wattrib.border_width; m_client->x = wattrib.x; m_client->y = wattrib.y; - fluxbox.saveWindowSearch(frame().window().window(), this); - m_timer.setTimeout(fluxbox.getAutoRaiseDelay()); m_timer.fireOnce(true); @@ -458,6 +448,8 @@ void FluxboxWindow::init() { } m_managed = true; //this window is managed + + Fluxbox::instance()->saveWindowSearchGroup(frame().window().window(), this); // update transient infomation m_client->updateTransientInfo(); @@ -603,13 +595,11 @@ void FluxboxWindow::attachClient(WinClient &client) { if (client.fbwindow() != 0) { FluxboxWindow *old_win = client.fbwindow(); // store old window - Fluxbox *fb = Fluxbox::instance(); // make sure we set new window search for each client ClientList::iterator client_it = old_win->clientList().begin(); ClientList::iterator client_it_end = old_win->clientList().end(); for (; client_it != client_it_end; ++client_it) { // setup eventhandlers for client - fb->saveWindowSearch((*client_it)->window(), this); evm.add(*this, (*client_it)->window()); // reparent window to this @@ -671,7 +661,6 @@ void FluxboxWindow::attachClient(WinClient &client) { client.m_win = this; - Fluxbox::instance()->saveWindowSearch(client.window(), this); client.saveBlackboxAttribs(m_blackbox_attrib); m_clientlist.push_back(&client); } @@ -993,30 +982,6 @@ void FluxboxWindow::updateIconNameFromClient() { } -void FluxboxWindow::getWMProtocols() { - Atom *proto = 0; - int num_return = 0; - FbAtoms *fbatoms = FbAtoms::instance(); - - if (XGetWMProtocols(display, m_client->window(), &proto, &num_return)) { - - for (int i = 0; i < num_return; ++i) { - if (proto[i] == fbatoms->getWMDeleteAtom()) - functions.close = true; - else if (proto[i] == fbatoms->getWMTakeFocusAtom()) - m_client->send_focus_message = true; - else if (proto[i] == fbatoms->getFluxboxStructureMessagesAtom()) - screen().addNetizen(m_client->window()); - } - - XFree(proto); - } else { - cerr<<"Warning: Failed to read WM Protocols. "<getMwmHint(); @@ -1185,7 +1150,7 @@ bool FluxboxWindow::setInputFocus() { } } - if (! validateClient()) + if (! m_client->validateClient()) return false; if (!m_client->transients.empty() && m_client->isModal()) { @@ -1256,7 +1221,9 @@ void FluxboxWindow::iconify() { (*it)->fbwindow()->iconify(); } } - if (Fluxbox::instance()->getFocusedWindow() == this) + + WinClient *focused_client = Fluxbox::instance()->getFocusedWindow(); + if (focused_client && focused_client->fbwindow() == this) Fluxbox::instance()->revertFocus(screen()); } @@ -1319,16 +1286,6 @@ void FluxboxWindow::deiconify(bool reassoc, bool do_raise) { } /** - Send close request to client window -*/ -void FluxboxWindow::close() { -#ifdef DEBUG - cerr<<__FILE__<<"("<<__FUNCTION__<<")"<sendClose(); -} - -/** Set window in withdrawn state */ void FluxboxWindow::withdraw() { @@ -1703,7 +1660,7 @@ void FluxboxWindow::installColormap(bool install) { Fluxbox *fluxbox = Fluxbox::instance(); fluxbox->grab(); - if (! validateClient()) + if (! m_client->validateClient()) return; int i = 0, ncmap = 0; @@ -2151,13 +2108,13 @@ void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) { if (!ne.override_redirect && isVisible()) { Fluxbox *fluxbox = Fluxbox::instance(); fluxbox->grab(); - if (! validateClient()) + if (! client->validateClient()) return; setState(NormalState); if (client->isTransient() || screen().doFocusNew()) { - setInputFocus(); + setCurrentClient(*client, true); } else setFocusFlag(false); @@ -2197,6 +2154,8 @@ void FluxboxWindow::unmapNotifyEvent(XUnmapEvent &ue) { /** Checks if event is for m_client->window. + If it isn't, we leave it until the window is unmapped, if it is, + we just hide it for now. */ void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) { if (de.window == m_client->window()) { @@ -2295,7 +2254,7 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) { default: if (atom == FbAtoms::instance()->getWMProtocolsAtom()) { - getWMProtocols(); + m_client->getWMProtocols(); //!!TODO check this area // reset window actions setupWindow(); @@ -2771,18 +2730,6 @@ void FluxboxWindow::toggleDecoration() { } } -void FluxboxWindow::setStrut(Strut *strut) { - clearStrut(); - m_strut = strut; -} - -void FluxboxWindow::clearStrut() { - if (m_strut != 0) { - screen().clearStrut(m_strut); - m_strut = 0; - } -} - unsigned int FluxboxWindow::decorationMask() const { unsigned int ret = 0; if (decorations.titlebar) @@ -2825,21 +2772,6 @@ void FluxboxWindow::setDecorationMask(unsigned int mask) { applyDecorations(); } -bool FluxboxWindow::validateClient() { - XSync(display, false); - - XEvent e; - if (!m_client || - ( XCheckTypedWindowEvent(display, m_client->window(), DestroyNotify, &e) || - XCheckTypedWindowEvent(display, m_client->window(), UnmapNotify, &e)) - && XPutBackEvent(display, &e)) { - Fluxbox::instance()->ungrab(); - return false; - } - - return true; -} - void FluxboxWindow::startMoving(Window win) { moving = true; Fluxbox *fluxbox = Fluxbox::instance(); @@ -3096,7 +3028,12 @@ void FluxboxWindow::attachTo(int x, int y) { parent().window(), x, y, &dest_x, &dest_y, &child)) { // search for a fluxboxwindow - FluxboxWindow *attach_to_win = Fluxbox::instance()->searchWindow(child); + WinClient *client = Fluxbox::instance()->searchWindow(child); + FluxboxWindow *attach_to_win = 0; + if (client) + attach_to_win = client->fbwindow(); + + cerr<<"client = "<validateClient()) + if ((*it)->winClient().validateClient()) (*it)->reconfigure(); } } diff --git a/src/fluxbox.cc b/src/fluxbox.cc index ee93883..2e37a46 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.cc,v 1.175 2003/07/27 13:53:34 fluxgen Exp $ +// $Id: fluxbox.cc,v 1.176 2003/07/28 15:06:35 rathnor Exp $ #include "fluxbox.hh" @@ -757,9 +757,9 @@ void Fluxbox::handleEvent(XEvent * const e) { handleButtonEvent(e->xbutton); break; case ConfigureRequest: { - FluxboxWindow *win = (FluxboxWindow *) 0; + WinClient *winclient = (WinClient *) 0; - if ((win = searchWindow(e->xconfigurerequest.window))) { + if ((winclient = searchWindow(e->xconfigurerequest.window))) { // already handled in FluxboxWindow::handleEvent } else { grab(); @@ -836,9 +836,10 @@ void Fluxbox::handleEvent(XEvent * const e) { cerr<<"MapRequest for 0x"<xmaprequest.window<xmaprequest.window); + WinClient *winclient = searchWindow(e->xmaprequest.window); + FluxboxWindow *win = 0; - if (! win) { + if (! winclient) { //!!! TODO BScreen *scr = searchScreen(e->xmaprequest.parent); if (scr != 0) @@ -846,7 +847,10 @@ void Fluxbox::handleEvent(XEvent * const e) { else cerr<<"Fluxbox Warning! Could not find screen to map window on!"<fbwindow(); } + // we don't handle MapRequest in FluxboxWindow::handleEvent if (win) win->mapRequestEvent(e->xmaprequest); @@ -854,9 +858,6 @@ void Fluxbox::handleEvent(XEvent * const e) { break; case MapNotify: { // handled directly in FluxboxWindow::handleEvent - FluxboxWindow *win = searchWindow(e->xmap.window); - if (win) - win->mapNotifyEvent(e->xmap); } break; case UnmapNotify: handleUnmapNotify(e->xunmap); @@ -873,20 +874,16 @@ void Fluxbox::handleEvent(XEvent * const e) { case CreateNotify: break; case DestroyNotify: { - FluxboxWindow *win = searchWindow(e->xdestroywindow.window); - if (win != 0) { - WinClient *client = win->findClient(e->xdestroywindow.window); - if (client != 0) { + WinClient *winclient = searchWindow(e->xdestroywindow.window); + if (winclient != 0) { + FluxboxWindow *win = winclient->fbwindow(); + if (win) win->destroyNotifyEvent(e->xdestroywindow); - delete client; + delete winclient; - if (win->numClients() == 0 || - &win->winClient() == client && win->numClients() == 1) { - delete win; - } - - } + if (win && win->numClients() == 0) + delete win; } } @@ -895,13 +892,13 @@ void Fluxbox::handleEvent(XEvent * const e) { break; case PropertyNotify: { m_last_time = e->xproperty.time; - FluxboxWindow *win = searchWindow(e->xproperty.window); - if (win == 0) + WinClient *winclient = searchWindow(e->xproperty.window); + if (winclient == 0) break; // most of them are handled in FluxboxWindow::handleEvent // but some special cases like ewmh propertys needs to be checked for (size_t i=0; ipropertyNotify(*win, e->xproperty.atom)) + if (m_atomhandler[i]->propertyNotify(*winclient, e->xproperty.atom)) break; } } break; @@ -942,10 +939,9 @@ void Fluxbox::handleEvent(XEvent * const e) { e->xfocus.detail == NotifyPointer) break; - FluxboxWindow *win = searchWindow(e->xfocus.window); - if (win && ! win->isFocused()) { - setFocusedWindow(win); - } + WinClient *winclient = searchWindow(e->xfocus.window); + if (winclient && !(m_focused_window == winclient)) + setFocusedWindow(winclient); } break; case FocusOut:{ @@ -953,8 +949,8 @@ void Fluxbox::handleEvent(XEvent * const e) { if (e->xfocus.mode == NotifyUngrab || e->xfocus.detail == NotifyPointer) break; - FluxboxWindow *win = searchWindow(e->xfocus.window); - if (win == 0 && FbTk::Menu::focused() == 0) { + WinClient *winclient = searchWindow(e->xfocus.window); + if (winclient == 0 && FbTk::Menu::focused() == 0) { #ifdef DEBUG cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<findClient(ue.window); + if ((winclient = searchWindow(ue.window)) != 0) { - if (client != 0) { + if (winclient != 0) { + FluxboxWindow *win = winclient->fbwindow(); - win->unmapNotifyEvent(ue); - client = 0; // it's invalid now when win destroyed the client + if (!win) { + delete winclient; + return; + } + + // this should delete client and adjust m_focused_window if necessary + win->unmapNotifyEvent(ue); - if (win == m_focused_window) - revertFocus(win->screen()); + winclient = 0; // it's invalid now when win destroyed the client - // finaly destroy window if empty + // finally destroy window if empty if (win->numClients() == 0) { delete win; win = 0; @@ -1120,14 +1120,14 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) { return; if (ce.message_type == m_fbatoms->getWMChangeStateAtom()) { - FluxboxWindow *win = searchWindow(ce.window); - if (! win || ! win->validateClient()) + WinClient *winclient = searchWindow(ce.window); + if (! winclient || !winclient->fbwindow() || ! winclient->validateClient()) return; if (ce.data.l[0] == IconicState) - win->iconify(); + winclient->fbwindow()->iconify(); if (ce.data.l[0] == NormalState) - win->deiconify(); + winclient->fbwindow()->deiconify(); } else if (ce.message_type == m_fbatoms->getFluxboxChangeWorkspaceAtom()) { BScreen *screen = searchScreen(ce.window); @@ -1136,9 +1136,12 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) { screen->changeWorkspaceID(ce.data.l[0]); } else if (ce.message_type == m_fbatoms->getFluxboxChangeWindowFocusAtom()) { - FluxboxWindow *win = searchWindow(ce.window); - if (win && win->isVisible()) - win->setInputFocus(); + WinClient *winclient = searchWindow(ce.window); + if (winclient) { + FluxboxWindow *win = winclient->fbwindow(); + if (win && win->isVisible()) + win->setCurrentClient(*winclient, true); + } } else if (ce.message_type == m_fbatoms->getFluxboxCycleWindowFocusAtom()) { BScreen *screen = searchScreen(ce.window); @@ -1147,12 +1150,11 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) { screen->prevFocus(); else screen->nextFocus(); - } + } } else if (ce.message_type == m_fbatoms->getFluxboxChangeAttributesAtom()) { - - FluxboxWindow *win = searchWindow(ce.window); - - if (win && win->validateClient()) { + WinClient *winclient = searchWindow(ce.window); + FluxboxWindow *win = 0; + if (winclient && (win = winclient->fbwindow()) && winclient->validateClient()) { FluxboxWindow::BlackboxHints net; net.flags = ce.data.l[0]; net.attrib = ce.data.l[1]; @@ -1162,11 +1164,13 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) { win->changeBlackboxHints(net); } } else { - FluxboxWindow *win = searchWindow(ce.window); + WinClient *winclient = searchWindow(ce.window); BScreen *screen = searchScreen(ce.window); - - for (size_t i=0; icheckClientMessage(ce, screen, win); + + if (winclient && screen) { + for (size_t i=0; icheckClientMessage(ce, screen, winclient); + } } } } @@ -1325,8 +1329,6 @@ void Fluxbox::update(FbTk::Subject *changedsub) { // make sure each workspace get this BScreen &scr = win.screen(); scr.removeWindow(&win); - if (m_focused_window == &win) - revertFocus(scr); } else if ((&(win.workspaceSig())) == changedsub) { // workspace signal for (size_t i=0; iupdate()) m_atomhandler[i]->updateClientClose(client); } + BScreen &screen = client.screen(); screen.updateNetizenWindowDel(client.window()); screen.removeClient(client); + if (m_focused_window == &client) + revertFocus(screen); + removeWindowSearch(client.window()); } } @@ -1434,25 +1440,36 @@ void Fluxbox::removeAtomHandler(AtomHandler *atomh) { } } -FluxboxWindow *Fluxbox::searchWindow(Window window) { - std::map::iterator it = m_window_search.find(window); - return it == m_window_search.end() ? 0 : it->second; +WinClient *Fluxbox::searchWindow(Window window) { + std::map::iterator it = m_window_search.find(window); + if (it != m_window_search.end()) + return it->second; + + std::map::iterator git = m_window_search_group.find(window); + return git == m_window_search_group.end() ? 0 : &git->second->winClient(); } -FluxboxWindow *Fluxbox::searchGroup(Window window, FluxboxWindow *win) { - std::map::iterator it = m_group_search.find(window); - return it == m_group_search.end() ? 0 : it->second; +/* Not implemented until we know how it'll be used + * Recall that this refers to ICCCM groups, not fluxbox tabgroups + * See ICCCM 4.1.11 for details + */ +/* +WinClient *Fluxbox::searchGroup(Window window) { } +*/ - -void Fluxbox::saveWindowSearch(Window window, FluxboxWindow *data) { +void Fluxbox::saveWindowSearch(Window window, WinClient *data) { m_window_search[window] = data; } +/* some windows relate to the whole group */ +void Fluxbox::saveWindowSearchGroup(Window window, FluxboxWindow *data) { + m_window_search_group[window] = data; +} -void Fluxbox::saveGroupSearch(Window window, FluxboxWindow *data) { - m_group_search[window] = data; +void Fluxbox::saveGroupSearch(Window window, WinClient *data) { + m_group_search.insert(pair(window, data)); } @@ -1460,6 +1477,10 @@ void Fluxbox::removeWindowSearch(Window window) { m_window_search.erase(window); } +void Fluxbox::removeWindowSearchGroup(Window window) { + m_window_search_group.erase(window); +} + void Fluxbox::removeGroupSearch(Window window) { m_group_search.erase(window); } @@ -1996,9 +2017,9 @@ void Fluxbox::timeout() { } // set focused window -void Fluxbox::setFocusedWindow(FluxboxWindow *win) { +void Fluxbox::setFocusedWindow(WinClient *client) { // already focused - if (m_focused_window == win) { + if (m_focused_window == client) { #ifdef DEBUG cerr<<"Focused window already win"<::iterator it = m_window_search.begin(); - std::map::iterator it_end = m_window_search.end(); + std::map::iterator it = m_window_search.begin(); + std::map::iterator it_end = m_window_search.end(); for (; it != it_end; ++it) { if (it->second == m_focused_window) { // we found it, end loop @@ -2030,26 +2051,32 @@ void Fluxbox::setFocusedWindow(FluxboxWindow *win) { if (!found) { m_focused_window = 0; } else { - old_win = m_focused_window; - old_screen = &old_win->screen(); + old_client = m_focused_window; + old_screen = &old_client->screen(); - old_wkspc = old_screen->getWorkspace(old_win->workspaceNumber()); + if (old_client->fbwindow()) { + FluxboxWindow *old_win = old_client->fbwindow(); + old_wkspc = old_screen->getWorkspace(old_win->workspaceNumber()); - old_win->setFocusFlag(false); + if (!client || client->fbwindow() != old_win) + old_win->setFocusFlag(false); + } } } - if (win && ! win->isIconic()) { + if (client && client->fbwindow() && !client->fbwindow()->isIconic()) { + FluxboxWindow *win = client->fbwindow(); // make sure we have a valid win pointer with a valid screen ScreenList::iterator winscreen = std::find(m_screen_list.begin(), m_screen_list.end(), - &win->screen()); + &client->screen()); if (winscreen == m_screen_list.end()) { m_focused_window = 0; // the window pointer wasn't valid, mark no window focused } else { screen = *winscreen; - wkspc = screen->getWorkspace(win->workspaceNumber()); - m_focused_window = win; // update focused window + wkspc = screen->getWorkspace(win->workspaceNumber()); + m_focused_window = client; // update focused window + win->setCurrentClient(*client, false); // don't setinputfocus win->setFocusFlag(true); // set focus flag } } else diff --git a/src/fluxbox.hh b/src/fluxbox.hh index 19f3d32..4f32ea3 100644 --- a/src/fluxbox.hh +++ b/src/fluxbox.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.hh,v 1.68 2003/07/23 10:43:30 fluxgen Exp $ +// $Id: fluxbox.hh,v 1.69 2003/07/28 15:06:36 rathnor Exp $ #ifndef FLUXBOX_HH #define FLUXBOX_HH @@ -88,9 +88,10 @@ public: inline Atom getFluxboxPidAtom() const { return m_fluxbox_pid; } - FluxboxWindow *searchGroup(Window, FluxboxWindow *); - FluxboxWindow *searchWindow(Window); - inline FluxboxWindow *getFocusedWindow() { return m_focused_window; } + // Not currently implemented until we decide how it'll be used + //WinClient *searchGroup(Window); + WinClient *searchWindow(Window); + inline WinClient *getFocusedWindow() { return m_focused_window; } BScreen *searchScreen(Window w); @@ -151,7 +152,7 @@ public: void watchKeyRelease(BScreen &screen, unsigned int mods); - void setFocusedWindow(FluxboxWindow *w); + void setFocusedWindow(WinClient *w); void revertFocus(BScreen &screen); void shutdown(); void load_rc(BScreen &scr); @@ -162,10 +163,14 @@ public: void clearMenuFilenames(); void saveTitlebarFilename(const char *); void saveSlitlistFilename(const char *val) { m_rc_slitlistfile = (val == 0 ? "" : val); } - void saveWindowSearch(Window win, FluxboxWindow *fbwin); - void saveGroupSearch(Window win, FluxboxWindow *fbwin); + void saveWindowSearch(Window win, WinClient *winclient); + // some windows relate to the group, not the client, so we record separately + // searchWindow on these windows will give the active client in the group + void saveWindowSearchGroup(Window win, FluxboxWindow *fbwin); + void saveGroupSearch(Window win, WinClient *winclient); void save_rc(); void removeWindowSearch(Window win); + void removeWindowSearchGroup(Window win); void removeGroupSearch(Window win); void restart(const char *command = 0); void reconfigure(); @@ -243,14 +248,21 @@ private: FbTk::Resource m_rc_cache_life, m_rc_cache_max; - std::map m_window_search; - std::map m_group_search; + std::map m_window_search; + std::map m_window_search_group; + // A window is the group leader, which can map to several + // WinClients in the group, it is *not* fluxbox's concept of groups + // See ICCCM section 4.1.11 + // The group leader (which may not be mapped, so may not have a WinClient) + // will have it's window being the group index + std::multimap m_group_search; std::list m_menu_timestamps; typedef std::list ScreenList; ScreenList m_screen_list; - FluxboxWindow *m_focused_window, *m_masked_window; + WinClient *m_focused_window; + FluxboxWindow *m_masked_window; FbTk::Timer m_timer; BScreen *m_mousescreen, *m_keyscreen; -- cgit v0.11.2