all repos — fluxbox @ 2ac0d82e451abd3cdc92df2a02c0da4eb8638ba1

custom fork of the fluxbox windowmanager

fix up focus problems
rathnor rathnor
commit

2ac0d82e451abd3cdc92df2a02c0da4eb8638ba1

parent

65bbfbe51b9d8531490708e83ba422c7dc53dc1a

M ChangeLogChangeLog

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

@@ -104,7 +104,7 @@ * Transparency (Henrik)

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 @@ + Shaped menu/slit/toolbar (Henrik)

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
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.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 @@ if (win == 0)

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)
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.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 @@ current_workspace->hideAll();

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 @@ getToolbar()->redrawWorkspaceLabel(true);

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

@@ -2429,6 +2420,26 @@ focused_list.erase(cycling_window);

focused_list.push_front(client); client->fbwindow()->raise(); } +} + +/** + * 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; } /**
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.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 @@ inline const Icons &getIconList() const { return iconList; }

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; } /**
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.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"

@@ -70,8 +70,6 @@ if (transient_for != 0) {

if (transientFor() == m_win) { transient_for = 0; } - - fluxbox->setFocusedWindow(transient_for); if (transient_for != 0) { FluxboxWindow::ClientList::iterator client_it =
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.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 @@ }

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

} */ if (top == 0|| !top->setInputFocus()) { - Fluxbox::instance()->setFocusedWindow(0); // set focused window to none + Fluxbox::instance()->revertFocus(&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.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 @@ win->unmapNotifyEvent(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 @@ }

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

@@ -2275,6 +2277,60 @@ if (old_screen && old_screen != screen)

old_screen->updateNetizenWindowFocus(); } + +/** + * This function is called whenever we aren't quite sure what + * focus is meant to be, it'll make things right ;-) + * last_focused is set to something if we want to make use of the + * previously focused window (it must NOT be set focused now, it + * is probably dying). + */ +void Fluxbox::revertFocus(BScreen *screen) { + // Relevant resources: + // resource.focus_last = whether we focus last focused when changing workspace + // Fluxbox::FocusModel = sloppy, click, whatever + + // if no given screen, get it from the mouse + if (screen == 0) { + Window root = 0, ignorew; + int ignored; + BScreen *tempscr = m_screen_list.front(); + XQueryPointer(FbTk::App::instance()->display(), + 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!"<<endl; +#endif // DEBUG + // flounder + XSetInputFocus(FbTk::App::instance()->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) {
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.52 2003/05/04 16:55:40 rathnor Exp $ +// $Id: fluxbox.hh,v 1.53 2003/05/04 23:38:06 rathnor Exp $ #ifndef FLUXBOX_HH #define FLUXBOX_HH

@@ -143,6 +143,7 @@

void watchKeyRelease(BScreen *screen, unsigned int mods); void setFocusedWindow(FluxboxWindow *w); + void revertFocus(BScreen *screen); void shutdown(); void load_rc(BScreen &scr); void loadRootCommand(BScreen &scr);