all repos — fluxbox @ 7588fc10a61c141208ccccc423cc7920207b2e89

custom fork of the fluxbox windowmanager

fix some flickering on focus change
Mark Tiefenbruck mark@fluxbox.org
commit

7588fc10a61c141208ccccc423cc7920207b2e89

parent

72d2f0e48143115aae38b75d5b1bda4cee5d512a

5 files changed, 63 insertions(+), 80 deletions(-)

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

@@ -251,10 +251,9 @@

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() && + if ((*it)->fbwindow() && (*it)->acceptsFocus() && ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace || - (*it)->fbwindow()->isStuck()) && (*it)->acceptsFocus() && - !(*it)->fbwindow()->isIconic())) + (*it)->fbwindow()->isStuck()) && !(*it)->fbwindow()->isIconic())) return *it; } return 0;

@@ -531,7 +530,8 @@ cerr<<"------------------"<<endl;

#endif // DEBUG // Update the old focused client to non focus - if (s_focused_fbwindow) + if (s_focused_fbwindow && + (!client || client->fbwindow() != s_focused_fbwindow)) s_focused_fbwindow->setFocusFlag(false); if (client && client->fbwindow() && !client->fbwindow()->isIconic()) {
M src/WinClient.ccsrc/WinClient.cc

@@ -140,6 +140,7 @@ transients.back()->transient_for = 0;

transients.pop_back(); } + accepts_input = send_focus_message = false; if (fbwindow() != 0) fbwindow()->removeClient(*this);
M src/Window.ccsrc/Window.cc

@@ -1013,10 +1013,21 @@ return false;

WinClient *old = m_client; m_client = &client; + + bool ret = setinput && focus(); + if (setinput) { + m_client = old; + return ret; + } + m_client->raise(); - if (setinput != m_focused || setinput && m_client != old) + if (m_focused) { m_client->focusSig().notify(); - titleSig().notify(); + if (old) + old->focusSig().notify(); + } + if (old != &client) + titleSig().notify(); #ifdef DEBUG cerr<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<<

@@ -1025,16 +1036,6 @@ #endif // DEBUG

// frame focused doesn't necessarily mean input focused frame().setLabelButtonFocus(*button); frame().setShapingClient(&client, false); - - bool ret = setinput && focus(); - if (setinput) { - // restore old client until focus event comes - m_client = old; - if (!ret && old) { - old->raise(); - titleSig().notify(); - } - } return ret; }
M src/fluxbox.ccsrc/fluxbox.cc

@@ -218,7 +218,6 @@ m_last_time(0),

m_masked(0), m_rc_file(rcfilename ? rcfilename : ""), m_argv(argv), m_argc(argc), - m_revert_screen(0), m_showing_dialog(false), m_starting(true), m_restarting(false),

@@ -273,12 +272,6 @@ to.tv_usec = 1;

m_reconfig_timer.setTimeout(to); m_reconfig_timer.setCommand(reconfig_cmd); m_reconfig_timer.fireOnce(true); - - // set a timer to revert focus on FocusOut, in case no FocusIn arrives - FbTk::RefCount<FbTk::Command> revert_cmd(new FbTk::SimpleCommand<Fluxbox>(*this, &Fluxbox::revert_focus)); - m_revert_timer.setCommand(revert_cmd); - m_revert_timer.setTimeout(to); - m_revert_timer.fireOnce(true); // XSynchronize(disp, True);

@@ -546,7 +539,7 @@

if (last_bad_window != None && e.xany.window == last_bad_window && e.type != DestroyNotify) { // we must let the actual destroys through if (e.type == FocusOut) - m_revert_timer.start(); + revertFocus(); #ifdef DEBUG else cerr<<"Fluxbox::eventLoop(): removing bad window from event queue"<<endl;

@@ -711,30 +704,6 @@ screen->propertyNotify(e->xproperty.atom);

} } - // we need to check focus out for menus before - // we call FbTk eventhandler - // so we can get FbTk::Menu::focused() before it sets to 0 - if (e->type == FocusOut && - e->xfocus.mode != NotifyGrab && - e->xfocus.detail != NotifyPointer && - e->xfocus.detail != NotifyInferior && - FbTk::Menu::focused() != 0 && - FbTk::Menu::focused()->window() == e->xfocus.window) { - - // find screen num - ScreenList::iterator it = m_screen_list.begin(); - ScreenList::iterator it_end = m_screen_list.end(); - for (; it != it_end; ++it) { - if ( (*it)->screenNumber() == - FbTk::Menu::focused()->fbwindow().screenNumber()) { - FocusControl::setFocusedWindow(0); - m_revert_screen = *it; - m_revert_timer.start(); - break; // found the screen, no more search - } - } - } - // try FbTk::EventHandler first FbTk::EventManager::instance()->handleEvent(*e);

@@ -903,9 +872,18 @@ if (e->xfocus.mode == NotifyGrab ||

e->xfocus.detail == NotifyPointer || e->xfocus.detail == NotifyInferior) break; + + if (FbTk::Menu::focused() && + FbTk::Menu::focused()->window() == e->xfocus.window) { + m_keyscreen = findScreen(FbTk::Menu::focused()->screenNumber()); + break; + } + WinClient *winclient = searchWindow(e->xfocus.window); - if (winclient && FocusControl::focusedWindow() != winclient) - FocusControl::setFocusedWindow(winclient); + if (!winclient) + break; + m_keyscreen = &winclient->screen(); + FocusControl::setFocusedWindow(winclient); } break; case FocusOut:{

@@ -916,19 +894,11 @@ e->xfocus.detail == NotifyInferior)

break; WinClient *winclient = searchWindow(e->xfocus.window); - if (winclient == 0 && FbTk::Menu::focused() == 0) { -#ifdef DEBUG - cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<<endl; -#endif // DEBUG - } else if (winclient && (winclient == FocusControl::focusedWindow() || - FocusControl::focusedWindow() == 0) && - (winclient->fbwindow() == 0 - || !winclient->fbwindow()->isMoving())) { + if (winclient && (winclient == FocusControl::focusedWindow() || + FocusControl::focusedWindow() == 0) && // we don't unfocus a moving window - FocusControl::setFocusedWindow(0); - m_revert_screen = &winclient->screen(); - m_revert_timer.start(); - } + (winclient->fbwindow() == 0 || !winclient->fbwindow()->isMoving())) + revertFocus(); } break; case ClientMessage:

@@ -1166,8 +1136,6 @@ if (FocusControl::focusedWindow() == client) {

FocusControl::unfocusWindow(*client); // make sure nothing else uses this window before focus reverts FocusControl::setFocusedWindow(0); - m_revert_screen = &screen; - m_revert_timer.start(); } screen.removeClient(*client);

@@ -1640,22 +1608,36 @@

m_reconfigure_wait = m_reread_menu_wait = false; } -void Fluxbox::revert_focus() { - if (!m_revert_screen || FocusControl::focusedWindow() || - FbTk::Menu::focused() || m_showing_dialog) - return; +void Fluxbox::revertFocus() { + bool revert = m_keyscreen && !m_showing_dialog; - Window win; - int revert; - Display *disp = display(); + if (revert) { + // see if there are any more focus events in the queue + XEvent ev; + while (XCheckMaskEvent(display(), FocusChangeMask, &ev)) { + handleEvent(&ev); + revert = false; + } + if (!revert) + return; // already handled + } - XGetInputFocus(disp, &win, &revert); + 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 || - win == m_revert_screen->rootWindow().window()) - FocusControl::revertFocus(*m_revert_screen); + // 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 && + win != m_keyscreen->rootWindow().window()) + revert = false; + } + + if (revert) + FocusControl::revertFocus(*m_keyscreen); + else + FocusControl::setFocusedWindow(0); } bool Fluxbox::validateClient(const WinClient *client) const {
M src/fluxbox.hhsrc/fluxbox.hh

@@ -166,7 +166,7 @@ void attachSignals(FluxboxWindow &win);

void attachSignals(WinClient &winclient); void timed_reconfigure(); - void revert_focus(); + void revertFocus(); void setShowingDialog(bool value) { m_showing_dialog = value; } bool isStartup() const { return m_starting; }

@@ -267,8 +267,7 @@

XEvent m_last_event; ///< when we execute reconfig command we must wait until next event round - FbTk::Timer m_reconfig_timer, m_revert_timer; - BScreen *m_revert_screen; + FbTk::Timer m_reconfig_timer; bool m_showing_dialog; std::auto_ptr<Keys> m_key;