fix some flickering on focus change
This commit is contained in:
parent
72d2f0e481
commit
7588fc10a6
5 changed files with 63 additions and 80 deletions
|
@ -251,10 +251,9 @@ Focusable *FocusControl::lastFocusedWindow(int workspace) {
|
|||
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 @@ void FocusControl::setFocusedWindow(WinClient *client) {
|
|||
#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()) {
|
||||
|
|
|
@ -140,6 +140,7 @@ WinClient::~WinClient() {
|
|||
transients.pop_back();
|
||||
}
|
||||
|
||||
accepts_input = send_focus_message = false;
|
||||
if (fbwindow() != 0)
|
||||
fbwindow()->removeClient(*this);
|
||||
|
||||
|
|
|
@ -1013,9 +1013,20 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
|
|||
|
||||
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();
|
||||
if (old)
|
||||
old->focusSig().notify();
|
||||
}
|
||||
if (old != &client)
|
||||
titleSig().notify();
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -1025,16 +1036,6 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
|
|||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -218,7 +218,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
|
|||
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),
|
||||
|
@ -274,12 +273,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
|
|||
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);
|
||||
|
||||
s_singleton = this;
|
||||
|
@ -546,7 +539,7 @@ void Fluxbox::eventLoop() {
|
|||
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 @@ void Fluxbox::handleEvent(XEvent * const e) {
|
|||
}
|
||||
}
|
||||
|
||||
// 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,8 +872,17 @@ void Fluxbox::handleEvent(XEvent * const e) {
|
|||
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)
|
||||
if (!winclient)
|
||||
break;
|
||||
m_keyscreen = &winclient->screen();
|
||||
FocusControl::setFocusedWindow(winclient);
|
||||
|
||||
} break;
|
||||
|
@ -916,19 +894,11 @@ void Fluxbox::handleEvent(XEvent * const e) {
|
|||
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() ||
|
||||
if (winclient && (winclient == FocusControl::focusedWindow() ||
|
||||
FocusControl::focusedWindow() == 0) &&
|
||||
(winclient->fbwindow() == 0
|
||||
|| !winclient->fbwindow()->isMoving())) {
|
||||
// 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 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
|
|||
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 @@ void Fluxbox::timed_reconfigure() {
|
|||
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;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if (revert) {
|
||||
Window win;
|
||||
int revert;
|
||||
Display *disp = display();
|
||||
|
||||
XGetInputFocus(disp, &win, &revert);
|
||||
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);
|
||||
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 {
|
||||
|
|
|
@ -166,7 +166,7 @@ public:
|
|||
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 @@ private:
|
|||
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;
|
||||
|
|
Loading…
Reference in a new issue