From 2ac0d82e451abd3cdc92df2a02c0da4eb8638ba1 Mon Sep 17 00:00:00 2001 From: rathnor Date: Sun, 4 May 2003 23:38:06 +0000 Subject: fix up focus problems --- ChangeLog | 5 +++++ RoadMap | 4 ++-- src/Ewmh.cc | 6 ++---- src/Screen.cc | 37 ++++++++++++++++++++++------------ src/Screen.hh | 3 ++- src/WinClient.cc | 4 +--- src/Workspace.cc | 6 +++--- src/fluxbox.cc | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/fluxbox.hh | 3 ++- 9 files changed, 99 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index cf2449e..2ad292c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ (Format: Year/Month/Day) Changes for 0.9.2: +*03/05/05: + * Rework focus somewhat - now use Fluxbox::revertFocus when a window + dies/gets forced out of focus (Simon) + - should fix click focus sometimes acting sloppy + fluxbox.hh/cc Screen.hh/cc WinClient.cc Workspace.cc Ewmh.cc *03/05/04: * add session.ignoreBorder - ignores window border with movement (Simon) fluxbox.hh/cc Window.cc diff --git a/RoadMap b/RoadMap index ce3643c..e50b5d7 100644 --- a/RoadMap +++ b/RoadMap @@ -104,7 +104,7 @@ Major Features: Minor Features: - more keybinding actions (Both) * directional focus movement (Simon) - = fix up focus issues (Simon) + * fix up focus issues (Simon) * snap to windows (Simon) - improved command-line help option (Henrik) = pixmap buttons (Henrik) @@ -112,7 +112,7 @@ Minor Features: Bugfixes/lower priority: - Bugs from 0.9.1 (Both) * stop window moving from borders (Simon) - = Focus acts sloppy on window close/warp (Simon) + * Focus acts sloppy on window close/warp (Simon) ---------------------------------------------------------- Release: 0.9.3 diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 4fdede2..47a74c3 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.18 2003/04/25 11:14:11 fluxgen Exp $ +// $Id: Ewmh.cc,v 1.19 2003/05/04 23:38:06 rathnor Exp $ #include "Ewmh.hh" @@ -337,9 +337,7 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, F return true; // ce.window = window to focus - // should move set focus somewhere else - // so we don't need fluxbox depedencies here - Fluxbox::instance()->setFocusedWindow(win); + win->setInputFocus(); return true; } else if (ce.message_type == m_net_close_window) { if (win == 0) diff --git a/src/Screen.cc b/src/Screen.cc index 7677ec9..28d1506 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.143 2003/05/04 13:04:31 rathnor Exp $ +// $Id: Screen.cc,v 1.144 2003/05/04 23:38:06 rathnor Exp $ #include "Screen.hh" @@ -1069,12 +1069,6 @@ void BScreen::changeWorkspaceID(unsigned int id) { workspacemenu->setItemSelected(current_workspace->workspaceID() + 2, false); - if (focused && &focused->getScreen() == this && - (! focused->isStuck()) && (!focused->isMoving())) { - current_workspace->setLastFocusedWindow(focused); - Fluxbox::instance()->setFocusedWindow(0); // set focused window to none - } - // set new workspace current_workspace = getWorkspace(id); @@ -1084,13 +1078,10 @@ void BScreen::changeWorkspaceID(unsigned int id) { current_workspace->showAll(); - if (*resource.focus_last && current_workspace->getLastFocusedWindow() && - !(focused && focused->isMoving())) { - current_workspace->getLastFocusedWindow()->setInputFocus(); - - } else if (focused && (focused->isStuck() || focused->isMoving())) { + if (focused && (focused->isStuck() || focused->isMoving())) { focused->setInputFocus(); - } + } else + Fluxbox::instance()->revertFocus(this); if (focused && focused->isMoving()) { focused->resumeMoving(); @@ -2432,6 +2423,26 @@ void BScreen::notifyReleasedKeys(XKeyEvent &ke) { } /** + * Used to find out which window was last focused on the given workspace + * If workspace is outside the ID range, then the absolute last focused window + * is given. + */ +WinClient *BScreen::getLastFocusedWindow(int workspace) { + if (focused_list.empty()) return 0; + if (workspace < 0 || workspace >= (int) getCount()) + return focused_list.front(); + + FocusedWindows::iterator it = focused_list.begin(); + FocusedWindows::iterator it_end = focused_list.end(); + for (; it != it_end; ++it) + if ((*it)->fbwindow() && + (((int)(*it)->fbwindow()->getWorkspaceNumber()) == workspace + || (*it)->fbwindow()->isStuck())) + return *it; + return 0; +} + +/** Access and clear the auto-group window */ FluxboxWindow* BScreen::useAutoGroupWindow() { diff --git a/src/Screen.hh b/src/Screen.hh index 59e2df4..16644fb 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.89 2003/04/28 22:42:29 fluxgen Exp $ +// $Id: Screen.hh,v 1.90 2003/05/04 23:38:06 rathnor Exp $ #ifndef SCREEN_HH #define SCREEN_HH @@ -150,6 +150,7 @@ public: inline Icons &getIconList() { return iconList; } inline const FocusedWindows &getFocusedList() const { return focused_list; } inline FocusedWindows &getFocusedList() { return focused_list; } + WinClient *getLastFocusedWindow(int workspace = -1); const Workspaces &getWorkspacesList() const { return workspacesList; } const WorkspaceNames &getWorkspaceNames() const { return workspaceNames; } /** diff --git a/src/WinClient.cc b/src/WinClient.cc index 6a41434..ac84c91 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.5 2003/04/27 02:26:21 rathnor Exp $ +// $Id: WinClient.cc,v 1.6 2003/05/04 23:38:06 rathnor Exp $ #include "WinClient.hh" @@ -71,8 +71,6 @@ WinClient::~WinClient() { transient_for = 0; } - fluxbox->setFocusedWindow(transient_for); - if (transient_for != 0) { FluxboxWindow::ClientList::iterator client_it = transientFor()->clientList().begin(); diff --git a/src/Workspace.cc b/src/Workspace.cc index d8b77a4..ae986ad 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Workspace.cc,v 1.57 2003/05/04 13:07:17 rathnor Exp $ +// $Id: Workspace.cc,v 1.58 2003/05/04 23:38:06 rathnor Exp $ #include "Workspace.hh" @@ -218,7 +218,7 @@ int Workspace::removeWindow(FluxboxWindow *w) { if (w->isFocused()) { if (screen.isSloppyFocus()) { - Fluxbox::instance()->setFocusedWindow(0); // set focused window to none + Fluxbox::instance()->revertFocus(&screen); } else if (w->isTransient() && w->getTransientFor() && w->getTransientFor()->isVisible()) { w->getTransientFor()->setInputFocus(); @@ -263,7 +263,7 @@ int Workspace::removeWindow(FluxboxWindow *w) { } */ if (top == 0|| !top->setInputFocus()) { - Fluxbox::instance()->setFocusedWindow(0); // set focused window to none + Fluxbox::instance()->revertFocus(&screen); } } } diff --git a/src/fluxbox.cc b/src/fluxbox.cc index d26d8b3..19580d9 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.127 2003/05/04 16:55:40 rathnor Exp $ +// $Id: fluxbox.cc,v 1.128 2003/05/04 23:38:06 rathnor Exp $ #include "fluxbox.hh" @@ -902,7 +902,7 @@ void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) { client = 0; // it's invalid now when win destroyed the client if (win == m_focused_window) - m_focused_window = 0; + revertFocus(&win->getScreen()); // finaly destroy window if empty if (win->numClients() == 0) { @@ -1492,6 +1492,8 @@ void Fluxbox::update(FbTk::Subject *changedsub) { // make sure each workspace get this BScreen &scr = win.getScreen(); scr.removeWindow(&win); + if (m_focused_window == &win) + revertFocus(&scr); } else if ((&(win.workspaceSig())) == changedsub) { // workspace signal for (size_t i=0; idisplay(), + tempscr->getRootWindow(), &root, &ignorew, &ignored, + &ignored, &ignored, &ignored, &((unsigned int) ignored)); + screen = searchScreen(root); + if (screen == 0) { +#ifdef DEBUG + cerr<<"No screen to base focus revert on!"<display(), + PointerRoot, None, CurrentTime); + return; + } + } + + WinClient *next_focus = screen->getLastFocusedWindow(screen->getCurrentWorkspaceID()); + + if (next_focus && next_focus->fbwindow()) { + next_focus->fbwindow()->setInputFocus(); + } else { + switch (screen->getFocusModel()) { + case SLOPPYFOCUS: + case SEMISLOPPYFOCUS: + XSetInputFocus(FbTk::App::instance()->display(), + PointerRoot, None, CurrentTime); + break; + case CLICKTOFOCUS: + XSetInputFocus(FbTk::App::instance()->display(), + screen->getRootWindow(), + RevertToPointerRoot, CurrentTime); + break; + } + } +} + + + void Fluxbox::watchKeyRelease(BScreen *screen, unsigned int mods) { if (mods == 0) { cerr<<"WARNING: attempt to grab without modifiers!"<