all repos — fluxbox @ b302dab2f187e364df36237c44b8e48f1e892f04

custom fork of the fluxbox windowmanager

fix some issues with reverting focus
Mark Tiefenbruck mark@fluxbox.org
commit

b302dab2f187e364df36237c44b8e48f1e892f04

parent

f66d446a94450d509748afe28a95f48b8fdfcfc5

6 files changed, 25 insertions(+), 30 deletions(-)

jump to
M src/FocusControl.ccsrc/FocusControl.cc

@@ -45,6 +45,7 @@ using std::string;

WinClient *FocusControl::s_focused_window = 0; FluxboxWindow *FocusControl::s_focused_fbwindow = 0; +WinClient *FocusControl::s_expecting_focus = 0; bool FocusControl::s_reverting = false; namespace {

@@ -242,7 +243,7 @@ * If workspace is outside the ID range, then the absolute last focused window

* is given. */ Focusable *FocusControl::lastFocusedWindow(int workspace) { - if (m_focused_list.empty() || m_screen.isShuttingdown()) return 0; + if (m_screen.isShuttingdown()) return 0; if (workspace < 0 || workspace >= (int) m_screen.numberOfWorkspaces()) return m_focused_list.clientList().front();

@@ -250,6 +251,7 @@ Focusables::iterator it = m_focused_list.clientList().begin();

Focusables::iterator it_end = m_focused_list.clientList().end(); for (; it != it_end; ++it) { if ((*it)->fbwindow() && (*it)->acceptsFocus() && + (*it)->fbwindow()->winClient().validateClient() && ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace || (*it)->fbwindow()->isStuck()) && !(*it)->fbwindow()->isIconic())) return *it;

@@ -536,6 +538,7 @@ if (client && client->fbwindow() && !client->fbwindow()->isIconic()) {

// screen should be ok s_focused_fbwindow = client->fbwindow(); s_focused_window = client; // update focused window + s_expecting_focus = 0; s_focused_fbwindow->setCurrentClient(*client, false); // don't set inputfocus s_focused_fbwindow->setFocusFlag(true); // set focus flag
M src/FocusControl.hhsrc/FocusControl.hh

@@ -134,8 +134,10 @@ // like revertFocus, but specifically related to this window (transients etc)

static void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false); static void setFocusedWindow(WinClient *focus_to); static void setFocusedFbWindow(FluxboxWindow *focus_to) { s_focused_fbwindow = focus_to; } + static void setExpectingFocus(WinClient *client) { s_expecting_focus = client; } static WinClient *focusedWindow() { return s_focused_window; } static FluxboxWindow *focusedFbWindow() { return s_focused_fbwindow; } + static WinClient *expectingFocus() { return s_expecting_focus; } private: BScreen &m_screen;

@@ -158,6 +160,7 @@ WinClient *m_cycling_last;

static WinClient *s_focused_window; static FluxboxWindow *s_focused_fbwindow; + static WinClient *s_expecting_focus; static bool s_reverting; };
M src/ToolFactory.ccsrc/ToolFactory.cc

@@ -30,7 +30,6 @@ #include "WorkspaceNameTool.hh"

#include "ArrowButton.hh" // Themes -#include "IconbarTheme.hh" #include "WorkspaceNameTheme.hh" #include "ButtonTheme.hh"
M src/WinClient.ccsrc/WinClient.cc

@@ -174,7 +174,8 @@ }

bool WinClient::sendFocus() { if (accepts_input) { - setInputFocus(RevertToParent, CurrentTime); + setInputFocus(RevertToPointerRoot, CurrentTime); + FocusControl::setExpectingFocus(this); return true; } if (!send_focus_message)

@@ -198,6 +199,7 @@ ce.xclient.data.l[3] = 0l;

ce.xclient.data.l[4] = 0l; // send focus msg XSendEvent(display(), window(), false, NoEventMask, &ce); + FocusControl::setExpectingFocus(this); return true; }
M src/Window.ccsrc/Window.cc

@@ -2353,8 +2353,9 @@ if (de.window == m_client->window()) {

#ifdef DEBUG cerr<<__FILE__<<"("<<__LINE__<<"): DestroyNotifyEvent this="<<this<<" title = "<<title()<<endl; #endif // DEBUG - if (numClients() == 1) - hide(); + delete m_client; + if (numClients() == 0) + delete this; } }

@@ -3680,9 +3681,8 @@ #ifdef DEBUG

cerr<<"FluxboxWindow::restore: remap = "<<remap<<endl; cerr<<__FILE__<<"("<<__FUNCTION__<<"): numClients() = "<<numClients()<<endl; #endif // DEBUG - if (numClients() == 0) { - hide(true); - } + if (numClients() == 0) + delete this; }
M src/fluxbox.ccsrc/fluxbox.cc

@@ -749,11 +749,6 @@ if (winclient != 0) {

FluxboxWindow *win = winclient->fbwindow(); if (win) win->destroyNotifyEvent(e->xdestroywindow); - - delete winclient; - - if (win && win->numClients() == 0) - delete win; } }

@@ -835,10 +830,11 @@ e->xfocus.detail == NotifyInferior)

break; WinClient *winclient = searchWindow(e->xfocus.window); - if (winclient && (winclient == FocusControl::focusedWindow() || - FocusControl::focusedWindow() == 0) && + if ((winclient == FocusControl::focusedWindow() || + FocusControl::focusedWindow() == 0) && // we don't unfocus a moving window - (winclient->fbwindow() == 0 || !winclient->fbwindow()->isMoving())) + (!winclient || !winclient->fbwindow() || + !winclient->fbwindow()->isMoving())) revertFocus(); } break;

@@ -884,13 +880,6 @@

// this should delete client and adjust m_focused_window if necessary win->unmapNotifyEvent(ue); - winclient = 0; // it's invalid now when win destroyed the client - - // finally destroy window if empty - if (win->numClients() == 0) { - delete win; - win = 0; - } } // according to http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.4

@@ -1077,6 +1066,9 @@ if (FocusControl::focusedWindow() == client) {

FocusControl::unfocusWindow(*client); // make sure nothing else uses this window before focus reverts FocusControl::setFocusedWindow(0); + } else if (FocusControl::expectingFocus() == client) { + FocusControl::setExpectingFocus(0); + revertFocus(); } screen.removeClient(*client);

@@ -1555,22 +1547,18 @@

if (revert) { // see if there are any more focus events in the queue XEvent ev; - while (XCheckMaskEvent(display(), FocusChangeMask, &ev)) { + while (XCheckMaskEvent(display(), FocusChangeMask, &ev)) handleEvent(&ev); - revert = false; - } - if (!revert) + if (FocusControl::focusedWindow() || FocusControl::expectingFocus()) return; // already handled - } - if (revert) { Window win; int blah; XGetInputFocus(display(), &win, &blah); // we only want to revert focus if it's left dangling, as some other // application may have set the focus to an unmanaged window - if (win != None && win != PointerRoot && + if (win != None && win != PointerRoot && !searchWindow(win) && win != m_keyscreen->rootWindow().window()) revert = false; }