all repos — fluxbox @ d353b688dec41daddeec9696586a4519f58cce45

custom fork of the fluxbox windowmanager

update many things to use WinClient instead of FluxboxWindow
rathnor rathnor
commit

d353b688dec41daddeec9696586a4519f58cce45

parent

f9bb208da8e8926281c91f3e386ec1de48f700a2

M ChangeLogChangeLog

@@ -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
M src/AtomHandler.hhsrc/AtomHandler.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: 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 @@ virtual void updateHints(FluxboxWindow &win) = 0;

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; }
M src/CurrentWindowCmd.ccsrc/CurrentWindowCmd.cc

@@ -20,58 +20,68 @@ // 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: 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()); }
M src/CurrentWindowCmd.hhsrc/CurrentWindowCmd.hh

@@ -20,7 +20,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: 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::<the function> on execute() /// similar to FbTk::SimpleCommand<T> class CurrentWindowCmd: public FbTk::Command {

@@ -47,7 +49,8 @@ void execute();

protected: - FluxboxWindow &window(); + WinClient &winclient(); + FluxboxWindow &fbwindow(); virtual void real_execute() = 0; };
M src/Ewmh.ccsrc/Ewmh.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: 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::setupClient(WinClient &winclient) { + updateStrut(winclient); +} + void Ewmh::setupFrame(FluxboxWindow &win) { Atom ret_type;

@@ -122,8 +126,6 @@ win.screen().sendToWorkspace(desktop, &win, false);

XFree(data); } - - updateStrut(win); }

@@ -260,34 +262,36 @@

} // 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<unsigned int>(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 @@ return true;

} 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 @@ // ce.data.l[2] = y

// 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 @@ return false;

} -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 @@ win.shade();

} -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: "<<data[0]<<", "<<data[1]<<", "<< data[2]<<", "<<data[3]<<endl; #endif // DEBUG - win.setStrut(win.screen().requestStrut(data[0], data[1], data[2], data[3])); - win.screen().updateAvailableWorkspaceArea(); + winclient.setStrut( + winclient.screen().requestStrut(data[0], data[1], data[2], data[3])); + winclient.screen().updateAvailableWorkspaceArea(); } - }
M src/Ewmh.hhsrc/Ewmh.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: Ewmh.hh,v 1.9 2003/07/04 14:06:20 rathnor Exp $ +// $Id: Ewmh.hh,v 1.10 2003/07/28 15:06:33 rathnor Exp $ #include "AtomHandler.hh"

@@ -33,7 +33,7 @@ Ewmh();

~Ewmh(); void initForScreen(BScreen &screen); void setupFrame(FluxboxWindow &win); - void setupClient(WinClient &winclient) {} + void setupClient(WinClient &winclient); void updateClientList(BScreen &screen); void updateWorkspaceNames(BScreen &screen);

@@ -47,9 +47,9 @@ void updateWorkspace(FluxboxWindow &win);

bool checkClientMessage(const XClientMessageEvent &ce, - BScreen * screen, FluxboxWindow * const win); + BScreen * screen, WinClient * const winclient); - bool propertyNotify(FluxboxWindow &win, Atom the_property); + bool propertyNotify(WinClient &winclient, Atom the_property); //ignore these ones void updateFrameClose(FluxboxWindow &win) {} void updateClientClose(WinClient &winclient) {}

@@ -61,7 +61,7 @@

void setState(FluxboxWindow &win, Atom state, bool value) const; void toggleState(FluxboxWindow &win, Atom state) const; void createAtoms(); - void updateStrut(FluxboxWindow &win); + void updateStrut(WinClient &winclient); // root window properties Atom m_net_supported, m_net_client_list, m_net_client_list_stacking,
M src/Gnome.ccsrc/Gnome.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: Gnome.cc,v 1.30 2003/07/17 17:56:28 rathnor Exp $ +// $Id: Gnome.cc,v 1.31 2003/07/28 15:06:33 rathnor Exp $ #include "Gnome.hh"

@@ -278,22 +278,22 @@ //TODO

} -bool Gnome::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, FluxboxWindow * const win) { +bool Gnome::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, WinClient * const winclient) { if (ce.message_type == m_gnome_wm_win_workspace) { #ifdef DEBUG cerr<<__FILE__<<"("<<__LINE__<<"): Got workspace atom="<<ce.data.l[0]<<endl; #endif//!DEBUG - if ( win !=0 && // the message sent to client window? + if ( winclient !=0 && // the message sent to client window? ce.data.l[0] >= 0 && - ce.data.l[0] < (signed)win->screen().getCount()) { - win->screen().changeWorkspaceID(ce.data.l[0]); + ce.data.l[0] < (signed)winclient->screen().getCount()) { + winclient->screen().changeWorkspaceID(ce.data.l[0]); } else if (screen!=0 && //the message sent to root window? ce.data.l[0] >= 0 && ce.data.l[0] < (signed)screen->getCount()) screen->changeWorkspaceID(ce.data.l[0]); return true; - } else if (win == 0) + } else if (winclient == 0) return false;

@@ -308,15 +308,16 @@ hex<<ce.data.l[0]<<dec<<endl; // mask_of_members_to_change

cerr<<"New members:"<<ce.data.l[1]<<endl; #endif // DEBUG - //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(win, flag); - // enable update of atom states - enableUpdate(); - + if (winclient && winclient->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"<<endl;

@@ -327,7 +328,8 @@ #ifdef DEBUG

cerr<<__FILE__<<"("<<__LINE__<<"): _WIN_LAYER"<<endl; #endif // DEBUG - setLayer(win, ce.data.l[0]); + if (winclient && winclient->fbwindow()) + setLayer(winclient->fbwindow(), ce.data.l[0]); } else return false; //the gnome atom wasn't found or not supported
M src/Gnome.hhsrc/Gnome.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: 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 @@ void updateLayer(FluxboxWindow &win);

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);
M src/Remember.hhsrc/Remember.hh

@@ -21,7 +21,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: 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 @@ void updateHints(FluxboxWindow &win) {}

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
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.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::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 @@ id == m_current_workspace->workspaceID())

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 = "<<focused<<endl; #endif // DEBUG

@@ -882,8 +886,11 @@ void BScreen::sendToWorkspace(unsigned int id, FluxboxWindow *win, bool changeWS) {

if (! m_current_workspace || id >= 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 @@ }

} Window f = ((Fluxbox::instance()->getFocusedWindow()) ? - Fluxbox::instance()->getFocusedWindow()->clientWindow() : None); + Fluxbox::instance()->getFocusedWindow()->window() : None); net->sendWindowFocus(f); }

@@ -970,7 +977,7 @@

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 @@ if (new_win) {

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 @@ }

// 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::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 @@ }

} 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 @@ it = wins.begin();

// 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::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 @@ 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 { if (it == wins.begin()) it = wins.end();

@@ -1380,9 +1394,9 @@ --it;

// 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 @@ const FluxboxWindow *win = winclient.fbwindow();

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 @@ return *it;

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 @@ Window w = winclient.getGroupLeftWindow();

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) {
M src/Screen.hhsrc/Screen.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: 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 @@

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?)

@@ -390,8 +388,6 @@ std::auto_ptr<FbTk::Menu> workspacemenu;

WorkspaceNames m_workspace_names; Workspaces m_workspaces_list; - - Window auto_group_window; std::auto_ptr<FbWinFrameTheme> m_windowtheme; std::auto_ptr<WinButtonTheme> m_winbutton_theme;
M src/Toolbar.ccsrc/Toolbar.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: 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 "I18n.hh"

#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::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 @@

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 @@ RevertToPointerRoot : RevertToParent), CurrentTime);

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 @@ m_editing = false;

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());
M src/ToolbarHandler.hhsrc/ToolbarHandler.hh

@@ -20,7 +20,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: 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 @@ void updateHints(FluxboxWindow &win) {}

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; }
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.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 @@ win_gravity(0),

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 @@ updateWMNormalHints();

updateWMClassHint(); updateTitle(); updateIconTitle(); + Fluxbox::instance()->saveWindowSearch(win, this); + if (window_group != None) + Fluxbox::instance()->saveGroupSearch(window_group, this); + } WinClient::~WinClient() {

@@ -76,6 +81,8 @@ cerr<<__FILE__<<"(~"<<__FUNCTION__<<")[this="<<this<<"]"<<endl;

#endif // DEBUG FbTk::EventManager::instance()->remove(window()); + + clearStrut(); if (m_win != 0) m_win->removeClient(*this);

@@ -160,22 +167,27 @@ XSendEvent(disp, window(), false, NoEventMask, &ce);

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 @@ // I don't think we are group-aware yet

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 @@ --m_modal;

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. "<<endl; + } + +}
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.10 2003/07/21 15:26:56 rathnor Exp $ +// $Id: WinClient.hh,v 1.11 2003/07/28 15:06:34 rathnor Exp $ #ifndef WINCLIENT_HH #define WINCLIENT_HH

@@ -32,6 +32,7 @@ #include <X11/Xutil.h>

#include <string> class BScreen; +class Strut; /// Holds client window info class WinClient:public FbTk::FbWindow {

@@ -44,7 +45,8 @@ ~WinClient();

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 @@ /// @return class member of class structure

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 @@ bool operator == (const FluxboxWindow &win) const {

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 @@ Window getGroupLeftWindow() const;

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 @@ min_width, min_height, max_width, max_height, width_inc, height_inc,

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;

@@ -156,6 +167,8 @@ int m_focus_mode;

WinClientSubj m_diesig; BScreen &m_screen; + + Strut *m_strut; };
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.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 @@ m_windowmenu(*scr.menuTheme(), scr.screenNumber(), scr.imageControl()),

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 @@ cerr<<__FILE__<<"("<<__LINE__<<"): curr client = "<<m_client<<endl;

cerr<<__FILE__<<"("<<__LINE__<<"): m_labelbuttons.size = "<<m_labelbuttons.size()<<endl; #endif // DEBUG - clearStrut(); - if (moving || resizing || m_attaching_tab) { screen().hideGeometry(); XUngrabPointer(display, CurrentTime); } // no longer a valid window to do stuff with - Fluxbox::instance()->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 @@ decorations.sticky = decorations.shade = decorations.tab = true;

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 @@ // save old border width so we can restore it later

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 @@ return;

} m_managed = true; //this window is managed + + Fluxbox::instance()->saveWindowSearchGroup(frame().window().window(), this); // update transient infomation m_client->updateTransientInfo();

@@ -603,13 +595,11 @@

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 @@ evm.add(*this, btn->window()); // we take care of button events for this

client.m_win = this; - Fluxbox::instance()->saveWindowSearch(client.window(), this); client.saveBlackboxAttribs(m_blackbox_attrib); m_clientlist.push_back(&client); }

@@ -993,30 +982,6 @@ m_client->updateIconTitle();

} -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. "<<endl; - } - -} - - void FluxboxWindow::getMWMHints() { const WinClient::MwmHints *hint = m_client->getMwmHint();

@@ -1185,7 +1150,7 @@ frame().width(), frame().height());

} } - if (! validateClient()) + if (! m_client->validateClient()) return false; if (!m_client->transients.empty() && m_client->isModal()) {

@@ -1256,7 +1221,9 @@ if ((*it)->fbwindow())

(*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 @@ raise();

} /** - Send close request to client window -*/ -void FluxboxWindow::close() { -#ifdef DEBUG - cerr<<__FILE__<<"("<<__FUNCTION__<<")"<<endl; -#endif // DEBUG - m_client->sendClose(); -} - -/** Set window in withdrawn state */ void FluxboxWindow::withdraw() {

@@ -1703,7 +1660,7 @@ if (m_client == 0) return;

Fluxbox *fluxbox = Fluxbox::instance(); fluxbox->grab(); - if (! validateClient()) + if (! m_client->validateClient()) return; int i = 0, ncmap = 0;

@@ -2151,13 +2108,13 @@

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 @@ }

/** 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 @@ }

default: if (atom == FbAtoms::instance()->getWMProtocolsAtom()) { - getWMProtocols(); + m_client->getWMProtocols(); //!!TODO check this area // reset window actions setupWindow();

@@ -2771,18 +2730,6 @@ }

} } -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)

@@ -2823,21 +2770,6 @@ decorations.shade = mask & DECORM_SHADE;

decorations.tab = mask & DECORM_TAB; decorations.enabled = mask & DECORM_ENABLED; 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) {

@@ -3096,7 +3028,12 @@ if (XTranslateCoordinates(display, parent().window(),

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 = "<<client<<", child = "<<hex<<child<<dec<<", fbwin = "<<attach_to_win<<endl; if (attach_to_win != this && attach_to_win != 0) {

@@ -3468,6 +3405,10 @@ }

setupWindow(); } +void FluxboxWindow::close() { + if (m_client) + m_client->sendClose(false); +} void FluxboxWindow::setupWindow() { // sets up our window
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.88 2003/07/28 12:42:32 fluxgen Exp $ +// $Id: Window.hh,v 1.89 2003/07/28 15:06:35 rathnor Exp $ #ifndef WINDOW_HH #define WINDOW_HH

@@ -44,7 +44,6 @@

class WinClient; class FbWinFrameTheme; class BScreen; -class Strut; class TextButton; class FbWinFrame;

@@ -168,7 +167,6 @@ void prevClient();

void moveClientLeft(); void moveClientRight(); - bool validateClient(); bool setInputFocus(); void raiseAndFocus() { raise(); setInputFocus(); } void setFocusFlag(bool flag);

@@ -178,7 +176,7 @@ // unmap this window

void hide(); void iconify(); void deiconify(bool = true, bool = true); - /// destroy this window + /// close current client void close(); /// set the window in withdrawn state void withdraw();

@@ -247,9 +245,6 @@ void applyDecorations(bool initial = false);

void toggleDecoration(); - void setStrut(Strut *strut); - void clearStrut(); - unsigned int decorationMask() const; void setDecorationMask(unsigned int mask);

@@ -382,7 +377,6 @@ /// gets title string from client window and updates frame's title

void updateTitleFromClient(); /// gets icon name from client window void updateIconNameFromClient(); - void getWMProtocols(); void getMWMHints(); void getBlackboxHints(); void saveBlackboxAttribs();

@@ -456,8 +450,6 @@ unsigned int m_old_width, m_old_height; ///< old size so we can restore from maximized state

int m_last_button_x, ///< last known x position of the mouse button m_last_button_y; ///< last known y position of the mouse button std::auto_ptr<FbWinFrame> m_frame; - - Strut *m_strut; FbTk::XLayerItem m_layeritem; int m_layernum;
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.77 2003/07/25 10:03:55 rathnor Exp $ +// $Id: Workspace.cc,v 1.78 2003/07/28 15:06:35 rathnor Exp $ #include "Workspace.hh"

@@ -276,7 +276,7 @@

Windows::iterator it = m_windowlist.begin(); Windows::iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { - if ((*it)->validateClient()) + if ((*it)->winClient().validateClient()) (*it)->reconfigure(); } }
M src/fluxbox.ccsrc/fluxbox.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: 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 @@ case ButtonPress:

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 @@ #ifdef DEBUG

cerr<<"MapRequest for 0x"<<hex<<e->xmaprequest.window<<dec<<endl; #endif // DEBUG - FluxboxWindow *win = searchWindow(e->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 @@ win = scr->createWindow(e->xmaprequest.window);

else cerr<<"Fluxbox Warning! Could not find screen to map window on!"<<endl; + } else { + win = winclient->fbwindow(); } + // we don't handle MapRequest in FluxboxWindow::handleEvent if (win) win->mapRequestEvent(e->xmaprequest);

@@ -854,9 +858,6 @@ }

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 @@ break;

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 @@ case MotionNotify:

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; i<m_atomhandler.size(); ++i) { - if (m_atomhandler[i]->propertyNotify(*win, e->xproperty.atom)) + if (m_atomhandler[i]->propertyNotify(*winclient, e->xproperty.atom)) break; } } break;

@@ -942,10 +939,9 @@ if (e->xfocus.mode == NotifyUngrab ||

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 @@

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 !!"<<endl; #endif // DEBUG

@@ -1079,25 +1075,29 @@

void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) { - FluxboxWindow *win = 0; + WinClient *winclient = 0; BScreen *screen = searchScreen(ue.event); if ( ue.event != ue.window && (screen != 0 || !ue.send_event)) return; - if ((win = searchWindow(ue.window)) != 0) { - WinClient *client = win->findClient(ue.window); + if ((winclient = searchWindow(ue.window)) != 0) { + + if (winclient != 0) { + FluxboxWindow *win = winclient->fbwindow(); - if (client != 0) { + if (!win) { + delete winclient; + return; + } - win->unmapNotifyEvent(ue); - client = 0; // it's invalid now when win destroyed the client + // 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 @@ if (ce.format != 32)

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 @@ ce.data.l[0] < (signed)screen->getCount())

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 @@ if (! ce.data.l[0])

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 @@ net.decoration = static_cast<int>(ce.data.l[4]);

win->changeBlackboxHints(net); } } else { - FluxboxWindow *win = searchWindow(ce.window); + WinClient *winclient = searchWindow(ce.window); BScreen *screen = searchScreen(ce.window); - - for (size_t i=0; i<m_atomhandler.size(); ++i) { - m_atomhandler[i]->checkClientMessage(ce, screen, win); + + if (winclient && screen) { + for (size_t i=0; i<m_atomhandler.size(); ++i) { + m_atomhandler[i]->checkClientMessage(ce, screen, winclient); + } } } }

@@ -1325,8 +1329,6 @@ }

// 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; i<m_atomhandler.size(); ++i) {

@@ -1372,9 +1374,13 @@ for (size_t i=0; i<m_atomhandler.size(); ++i) {

if (m_atomhandler[i]->update()) 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,30 +1440,45 @@ }

} } -FluxboxWindow *Fluxbox::searchWindow(Window window) { - std::map<Window, FluxboxWindow *>::iterator it = m_window_search.find(window); - return it == m_window_search.end() ? 0 : it->second; +WinClient *Fluxbox::searchWindow(Window window) { + std::map<Window, WinClient *>::iterator it = m_window_search.find(window); + if (it != m_window_search.end()) + return it->second; + + std::map<Window, FluxboxWindow *>::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<Window, FluxboxWindow *>::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, WinClient *>(window, data)); } 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) {

@@ -1996,9 +2017,9 @@ m_reconfigure_wait = m_reread_menu_wait = false;

} // 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"<<endl; #endif // DEBUG

@@ -2006,19 +2027,19 @@ return;

} #ifdef DEBUG cerr<<"-----------------"<<endl; - cerr<<"Setting Focused window = "<<win<<endl; + cerr<<"Setting Focused window = "<<client<<endl; cerr<<"Current Focused window = "<<m_focused_window<<endl; cerr<<"------------------"<<endl; #endif // DEBUG BScreen *old_screen = 0, *screen = 0; - FluxboxWindow *old_win = 0; + WinClient *old_client = 0; Workspace *old_wkspc = 0, *wkspc = 0; if (m_focused_window != 0) { // check if m_focused_window is valid bool found = false; - std::map<Window, FluxboxWindow *>::iterator it = m_window_search.begin(); - std::map<Window, FluxboxWindow *>::iterator it_end = m_window_search.end(); + std::map<Window, WinClient *>::iterator it = m_window_search.begin(); + std::map<Window, WinClient *>::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 @@

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
M src/fluxbox.hhsrc/fluxbox.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: 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 @@ void ungrab();

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 @@ { m_masked = w; m_masked_window = bw; }

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 @@ void saveMenuFilename(const char *);

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 @@ FbTk::Resource<TitlebarList> m_rc_titlebar_left, m_rc_titlebar_right;

FbTk::Resource<unsigned int> m_rc_cache_life, m_rc_cache_max; - std::map<Window, FluxboxWindow *> m_window_search; - std::map<Window, FluxboxWindow *> m_group_search; + std::map<Window, WinClient *> m_window_search; + std::map<Window, FluxboxWindow *> 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<Window, WinClient *> m_group_search; std::list<MenuTimestamp *> m_menu_timestamps; typedef std::list<BScreen *> 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;