From dea3281e6917601a81df7833457a942b875b8e49 Mon Sep 17 00:00:00 2001 From: rathnor Date: Sun, 21 Mar 2004 09:00:25 +0000 Subject: primarily focus fix/tweak/rejigging --- ChangeLog | 7 +++++++ src/FbWinFrame.cc | 7 ++++--- src/Screen.cc | 32 ++++++++++++++++++---------- src/Screen.hh | 3 ++- src/Window.cc | 30 +++++++++++++-------------- src/Window.hh | 4 +++- src/Workspace.cc | 32 +++++++--------------------- src/Workspace.hh | 2 +- src/fluxbox.cc | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++---- src/fluxbox.hh | 4 +++- 10 files changed, 121 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index 75df366..2ccdd33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index 9b8b7e7..8d93184 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc @@ -19,7 +19,7 @@ // 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 @@ void FbWinFrame::removeLabelButton(FbTk::TextButton &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; } diff --git a/src/Screen.cc b/src/Screen.cc index 4fb6576..8c01402 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.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 @@ void BScreen::removeClient(WinClient &client) { 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 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id, // 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 @@ WinClient *BScreen::getLastFocusedWindow(int workspace) { 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"<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(), diff --git a/src/Workspace.hh b/src/Workspace.hh index 55479b3..c2b02f3 100644 --- a/src/Workspace.hh +++ b/src/Workspace.hh @@ -62,7 +62,7 @@ public: 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; } diff --git a/src/fluxbox.cc b/src/fluxbox.cc index dd70d6c..d32840a 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.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 @@ void Fluxbox::update(FbTk::Subject *changedsub) { 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 @@ void Fluxbox::update(FbTk::Subject *changedsub) { // 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 @@ void Fluxbox::revertFocus(BScreen &screen) { } } +/* + * 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) { diff --git a/src/fluxbox.hh b/src/fluxbox.hh index 184ffd2..f063a1b 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.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 @@ public: 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); -- cgit v0.11.2