all repos — fluxbox @ dea3281e6917601a81df7833457a942b875b8e49

custom fork of the fluxbox windowmanager

primarily focus fix/tweak/rejigging
rathnor rathnor
commit

dea3281e6917601a81df7833457a942b875b8e49

parent

2d82374b2f458c32895b093aff8c77e88daea2ba

M ChangeLogChangeLog

@@ -1,5 +1,12 @@

(Format: Year/Month/Day) Changes for 0.9.9: +*04/03/21: + * A number of small fixes (Simon) + - Fix up focus+highlights on tab close + - Centralise focus fallbacks (fluxbox::unfocusWindow) + - we now prefer the last focused window in the current tabgroup to + the actual last focused window on the whole screen. + fluxbox.hh/cc Screen.hh/cc Window.hh/cc Workspace.hh/cc FbWinFrame.cc *04/03/19: * fluxbox-generate_menu: (Han) removes the reload-menu code which is obsolete
M src/FbWinFrame.ccsrc/FbWinFrame.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: FbWinFrame.cc,v 1.76 2004/02/28 16:54:04 fluxgen Exp $ +// $Id: FbWinFrame.cc,v 1.77 2004/03/21 09:00:24 rathnor Exp $ #include "FbWinFrame.hh"

@@ -301,10 +301,11 @@ &btn);

if (erase_it == m_labelbuttons.end()) return; + if (&btn == m_current_label) + m_current_label = 0; + m_labelbuttons.erase(erase_it); - if (*erase_it == m_current_label) - m_current_label = 0; }
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.269 2004/03/18 14:45:56 fluxgen Exp $ +// $Id: Screen.cc,v 1.270 2004/03/21 09:00:24 rathnor Exp $ #include "Screen.hh"

@@ -937,7 +937,7 @@ void BScreen::removeWindow(FluxboxWindow *win) {

if (win->isIconic()) removeIcon(win); else - getWorkspace(win->workspaceNumber())->removeWindow(win); + getWorkspace(win->workspaceNumber())->removeWindow(win, false); }

@@ -951,13 +951,6 @@ WinClient *focused = Fluxbox::instance()->getFocusedWindow();

focused_list.remove(&client); if (cyc == &client) { cycling_window = focused_list.end(); - } 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()) - client.transientFor()->fbwindow()->setInputFocus(); - else - Fluxbox::instance()->revertFocus(focused->screen()); } if (cycling_last == &client)

@@ -1471,7 +1464,7 @@ // show whats on current/other workspace

// gets updated m_clientlist_sig.notify(); } else if (ignore_sticky || ! w->isStuck()) { - getWorkspace(w->workspaceNumber())->removeWindow(w); + getWorkspace(w->workspaceNumber())->removeWindow(w, true); getWorkspace(wkspc_id)->addWindow(*w); // see comment above m_clientlist_sig.notify();

@@ -2544,8 +2537,25 @@ }

return 0; } +/** + * Used to find out which window was last active in the given group + * If ignore_client is given, it excludes that client. + * Stuck, iconic etc don't matter within a group + */ +WinClient *BScreen::getLastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client) { + if (focused_list.empty()) return 0; + + FocusedWindows::iterator it = focused_list.begin(); + FocusedWindows::iterator it_end = focused_list.end(); + for (; it != it_end; ++it) { + if (((*it)->fbwindow() == &group) && + (*it) != ignore_client) + return *it; + } + return 0; +} + void BScreen::updateSize() { - cerr<<"update Size"<<endl; // force update geometry rootWindow().updateGeometry();
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.134 2004/01/19 18:28:58 fluxgen Exp $ +// $Id: Screen.hh,v 1.135 2004/03/21 09:00:25 rathnor Exp $ #ifndef SCREEN_HH #define SCREEN_HH

@@ -147,6 +147,7 @@ inline Icons &getIconList() { return m_icon_list; }

inline const FocusedWindows &getFocusedList() const { return focused_list; } inline FocusedWindows &getFocusedList() { return focused_list; } WinClient *getLastFocusedWindow(int workspace = -1); + WinClient *getLastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client = 0); const Workspaces &getWorkspacesList() const { return m_workspaces_list; } Workspaces &getWorkspacesList() { return m_workspaces_list; } const WorkspaceNames &getWorkspaceNames() const { return m_workspace_names; }
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.270 2004/03/08 12:20:31 rathnor Exp $ +// $Id: Window.cc,v 1.271 2004/03/21 09:00:25 rathnor Exp $ #include "Window.hh"

@@ -784,15 +784,11 @@ #endif // DEBUG

// if it is our active client, deal with it... if (m_client == &client) { - // set next client to be focused - // if the client we're about to remove is the last client then set prev client - if (&client == m_clientlist.back()) - prevClient(); - else - nextClient(); + WinClient *next_client = screen().getLastFocusedWindow(*this, m_client); + if (next_client != 0) + setCurrentClient(*next_client, false); } - client.m_win = 0; m_clientlist.remove(&client); if (m_client == &client) {

@@ -815,12 +811,12 @@ label_btn = 0;

} m_labelbuttons.erase(&client); - frame().reconfigure(); + updateClientLeftWindow(); #ifdef DEBUG cerr<<__FILE__<<"("<<__FUNCTION__<<")["<<this<<"] numClients = "<<numClients()<<endl; -#endif // DEBUG +#endif // DEBUG return true; }

@@ -905,6 +901,9 @@ }

/// Update LEFT window atom on all clients. void FluxboxWindow::updateClientLeftWindow() { + if (clientList().empty()) + return; + // It should just update the affected clients but that // would require more complex code and we're assuming // the user dont have alot of windows grouped so this

@@ -929,8 +928,11 @@ return false;

m_client = &client; m_client->raise(); + + // frame focused doesn't necessarily mean input focused + frame().setLabelButtonFocus(*m_labelbuttons[m_client]); + if (setinput && setInputFocus()) { - frame().setLabelButtonFocus(*m_labelbuttons[m_client]); return true; }

@@ -1242,7 +1244,6 @@ ret = true;

} else { ret = m_client->sendFocus(); } - return ret; }

@@ -1296,10 +1297,7 @@ (*it)->fbwindow()->iconify();

} } - WinClient *focused_client = Fluxbox::instance()->getFocusedWindow(); - if (focused_client && focused_client->fbwindow() == this) - Fluxbox::instance()->revertFocus(screen()); - + // focus revert is done elsewhere (based on signal) } void FluxboxWindow::deiconify(bool reassoc, bool do_raise) {
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.109 2004/02/20 09:07:27 fluxgen Exp $ +// $Id: Window.hh,v 1.110 2004/03/21 09:00:25 rathnor Exp $ #ifndef WINDOW_HH #define WINDOW_HH

@@ -281,6 +281,7 @@ inline bool isMoving() const { return moving; }

inline bool isResizing() const { return resizing; } bool isGroupable() const; inline int numClients() const { return m_clientlist.size(); } + inline bool empty() const { return m_clientlist.empty(); } inline ClientList &clientList() { return m_clientlist; } inline const ClientList &clientList() const { return m_clientlist; } inline WinClient &winClient() { return *m_client; }

@@ -370,6 +371,7 @@ FluxboxWindow &m_win;

}; bool oplock; ///< Used to help stop transient loops occurring by locking a window during certain operations + private: static const int PropBlackboxAttributesElements = 8;
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.94 2004/03/15 23:36:13 rathnor Exp $ +// $Id: Workspace.cc,v 1.95 2004/03/21 09:00:25 rathnor Exp $ #include "Workspace.hh"

@@ -167,8 +167,11 @@ }

} - -int Workspace::removeWindow(FluxboxWindow *w) { +// still_alive is true if the window will continue to exist after +// this event. Particularly, this isn't the removeWindow for +// the destruction of the window. Because if so, the focus revert +// is done in another place +int Workspace::removeWindow(FluxboxWindow *w, bool still_alive) { if (w == 0) return -1;

@@ -180,27 +183,8 @@ if (m_lastfocus == w) {

m_lastfocus = 0; } - if (w->isFocused()) { - if (screen().isSloppyFocus()) { - Fluxbox::instance()->revertFocus(screen()); - } else { - // go up the transient tree looking for a focusable window - WinClient *client = 0; - if (w->numClients() > 0) { - client = w->winClient().transientFor(); - while (client) { - if (client->fbwindow() && - client->fbwindow() != w && // can't be this window - client->fbwindow()->isVisible() && - client->fbwindow()->setCurrentClient(*client, true)) - break; - client = client->transientFor(); - } - } - if (client == 0) // we were unsuccessful - Fluxbox::instance()->revertFocus(screen()); - } - } + if (w->isFocused() && still_alive) + Fluxbox::instance()->unfocusWindow(w->winClient(), true, true); // we don't remove it from the layermanager, as it may be being moved Windows::iterator erase_it = remove(m_windowlist.begin(),
M src/Workspace.hhsrc/Workspace.hh

@@ -62,7 +62,7 @@ void removeAll();

void reconfigure(); void shutdown(); void addWindow(FluxboxWindow &win, bool place = false); - int removeWindow(FluxboxWindow *win); + int removeWindow(FluxboxWindow *win, bool still_alive); void updateClientmenu(); BScreen &screen() { return m_screen; }
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.234 2004/03/03 12:53:06 rathnor Exp $ +// $Id: fluxbox.cc,v 1.235 2004/03/21 09:00:25 rathnor Exp $ #include "fluxbox.hh"

@@ -1321,7 +1321,7 @@ // add to icon list

if (win.isIconic()) { Workspace *space = win.screen().getWorkspace(win.workspaceNumber()); if (space != 0) - space->removeWindow(&win); + space->removeWindow(&win, true); win.screen().addIcon(&win); }

@@ -1409,8 +1409,14 @@ screen.removeClient(client);

// finaly send notify signal screen.updateNetizenWindowDel(client.window()); - if (m_focused_window == &client) - revertFocus(screen); + // At this point, we trust that this client is no longer in the + // client list of its frame (but it still has reference to the frame) + // We also assume that any remaining active one is the last focused one + + // This is where we revert focus on window close + // NOWHERE ELSE!!! + if (m_focused_window == &client) + unfocusWindow(client); // failed to revert focus? if (m_focused_window == &client)

@@ -1992,6 +1998,54 @@ }

} } +/* + * Like revertFocus, but specifically related to this window (transients etc) + * if full_revert, we fallback to a full revertFocus if we can't find anything + * local to the client. + * If unfocus_frame is true, we won't focus anything in the same frame + * as the client. + * + * So, we first prefer to choose a transient parent, then the last + * client in this window, and if no luck (or unfocus_frame), then + * we just use the normal revertFocus on the screen. + * + * assumption: client has focus + */ +void Fluxbox::unfocusWindow(WinClient &client, bool full_revert, bool unfocus_frame) { + // go up the transient tree looking for a focusable window + + FluxboxWindow *fbwin = client.fbwindow(); + if (fbwin == 0) + unfocus_frame = false; + + WinClient *trans_parent = client.transientFor(); + while (trans_parent) { + if (trans_parent->fbwindow() && // can't focus if no fbwin + (!unfocus_frame || trans_parent->fbwindow() != fbwin) && // can't be this window + trans_parent->fbwindow()->isVisible() && + trans_parent->fbwindow()->setCurrentClient(*trans_parent, m_focused_window == &client)) { + return; + } + trans_parent = trans_parent->transientFor(); + } + + if (fbwin == 0) + return; // nothing more we can do + + BScreen &screen = fbwin->screen(); + + if (!unfocus_frame) { + WinClient *last_focus = screen.getLastFocusedWindow(*fbwin, &client); + if (last_focus != 0 && + fbwin->setCurrentClient(*last_focus, m_focused_window == &client)) { + return; + } + } + + if (full_revert && m_focused_window == &client) + revertFocus(screen); + +} void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) {
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.83 2004/02/10 18:45:57 fluxgen Exp $ +// $Id: fluxbox.hh,v 1.84 2004/03/21 09:00:25 rathnor Exp $ #ifndef FLUXBOX_HH #define FLUXBOX_HH

@@ -157,6 +157,8 @@ void watchKeyRelease(BScreen &screen, unsigned int mods);

void setFocusedWindow(WinClient *w); void revertFocus(BScreen &screen); + // like revertFocus, but specifically related to this window (transients etc) + void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false); void shutdown(); void load_rc(BScreen &scr); void loadRootCommand(BScreen &scr);