aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Tiefenbruck <mark@fluxbox.org>2008-01-01 18:29:36 (GMT)
committerMark Tiefenbruck <mark@fluxbox.org>2008-01-01 18:29:36 (GMT)
commit7588fc10a61c141208ccccc423cc7920207b2e89 (patch)
treeca9acf5c5bb36df5a9a77a4b7ce0f79cb3e054ab
parent72d2f0e48143115aae38b75d5b1bda4cee5d512a (diff)
downloadfluxbox-7588fc10a61c141208ccccc423cc7920207b2e89.zip
fluxbox-7588fc10a61c141208ccccc423cc7920207b2e89.tar.bz2
fix some flickering on focus change
-rw-r--r--src/FocusControl.cc8
-rw-r--r--src/WinClient.cc1
-rw-r--r--src/Window.cc25
-rw-r--r--src/fluxbox.cc104
-rw-r--r--src/fluxbox.hh5
5 files changed, 63 insertions, 80 deletions
diff --git a/src/FocusControl.cc b/src/FocusControl.cc
index 426c026..184b69b 100644
--- a/src/FocusControl.cc
+++ b/src/FocusControl.cc
@@ -251,10 +251,9 @@ Focusable *FocusControl::lastFocusedWindow(int workspace) {
251 Focusables::iterator it = m_focused_list.clientList().begin(); 251 Focusables::iterator it = m_focused_list.clientList().begin();
252 Focusables::iterator it_end = m_focused_list.clientList().end(); 252 Focusables::iterator it_end = m_focused_list.clientList().end();
253 for (; it != it_end; ++it) { 253 for (; it != it_end; ++it) {
254 if ((*it)->fbwindow() && 254 if ((*it)->fbwindow() && (*it)->acceptsFocus() &&
255 ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace || 255 ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace ||
256 (*it)->fbwindow()->isStuck()) && (*it)->acceptsFocus() && 256 (*it)->fbwindow()->isStuck()) && !(*it)->fbwindow()->isIconic()))
257 !(*it)->fbwindow()->isIconic()))
258 return *it; 257 return *it;
259 } 258 }
260 return 0; 259 return 0;
@@ -531,7 +530,8 @@ void FocusControl::setFocusedWindow(WinClient *client) {
531#endif // DEBUG 530#endif // DEBUG
532 531
533 // Update the old focused client to non focus 532 // Update the old focused client to non focus
534 if (s_focused_fbwindow) 533 if (s_focused_fbwindow &&
534 (!client || client->fbwindow() != s_focused_fbwindow))
535 s_focused_fbwindow->setFocusFlag(false); 535 s_focused_fbwindow->setFocusFlag(false);
536 536
537 if (client && client->fbwindow() && !client->fbwindow()->isIconic()) { 537 if (client && client->fbwindow() && !client->fbwindow()->isIconic()) {
diff --git a/src/WinClient.cc b/src/WinClient.cc
index 4ae5cad..55d6efc 100644
--- a/src/WinClient.cc
+++ b/src/WinClient.cc
@@ -140,6 +140,7 @@ WinClient::~WinClient() {
140 transients.pop_back(); 140 transients.pop_back();
141 } 141 }
142 142
143 accepts_input = send_focus_message = false;
143 if (fbwindow() != 0) 144 if (fbwindow() != 0)
144 fbwindow()->removeClient(*this); 145 fbwindow()->removeClient(*this);
145 146
diff --git a/src/Window.cc b/src/Window.cc
index cdfcfea..8222c06 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -1013,10 +1013,21 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
1013 1013
1014 WinClient *old = m_client; 1014 WinClient *old = m_client;
1015 m_client = &client; 1015 m_client = &client;
1016
1017 bool ret = setinput && focus();
1018 if (setinput) {
1019 m_client = old;
1020 return ret;
1021 }
1022
1016 m_client->raise(); 1023 m_client->raise();
1017 if (setinput != m_focused || setinput && m_client != old) 1024 if (m_focused) {
1018 m_client->focusSig().notify(); 1025 m_client->focusSig().notify();
1019 titleSig().notify(); 1026 if (old)
1027 old->focusSig().notify();
1028 }
1029 if (old != &client)
1030 titleSig().notify();
1020 1031
1021#ifdef DEBUG 1032#ifdef DEBUG
1022 cerr<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<< 1033 cerr<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<<
@@ -1025,16 +1036,6 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
1025 // frame focused doesn't necessarily mean input focused 1036 // frame focused doesn't necessarily mean input focused
1026 frame().setLabelButtonFocus(*button); 1037 frame().setLabelButtonFocus(*button);
1027 frame().setShapingClient(&client, false); 1038 frame().setShapingClient(&client, false);
1028
1029 bool ret = setinput && focus();
1030 if (setinput) {
1031 // restore old client until focus event comes
1032 m_client = old;
1033 if (!ret && old) {
1034 old->raise();
1035 titleSig().notify();
1036 }
1037 }
1038 return ret; 1039 return ret;
1039} 1040}
1040 1041
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 341fda8..b96b0a2 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -218,7 +218,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
218 m_masked(0), 218 m_masked(0),
219 m_rc_file(rcfilename ? rcfilename : ""), 219 m_rc_file(rcfilename ? rcfilename : ""),
220 m_argv(argv), m_argc(argc), 220 m_argv(argv), m_argc(argc),
221 m_revert_screen(0),
222 m_showing_dialog(false), 221 m_showing_dialog(false),
223 m_starting(true), 222 m_starting(true),
224 m_restarting(false), 223 m_restarting(false),
@@ -274,12 +273,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
274 m_reconfig_timer.setCommand(reconfig_cmd); 273 m_reconfig_timer.setCommand(reconfig_cmd);
275 m_reconfig_timer.fireOnce(true); 274 m_reconfig_timer.fireOnce(true);
276 275
277 // set a timer to revert focus on FocusOut, in case no FocusIn arrives
278 FbTk::RefCount<FbTk::Command> revert_cmd(new FbTk::SimpleCommand<Fluxbox>(*this, &Fluxbox::revert_focus));
279 m_revert_timer.setCommand(revert_cmd);
280 m_revert_timer.setTimeout(to);
281 m_revert_timer.fireOnce(true);
282
283 // XSynchronize(disp, True); 276 // XSynchronize(disp, True);
284 277
285 s_singleton = this; 278 s_singleton = this;
@@ -546,7 +539,7 @@ void Fluxbox::eventLoop() {
546 if (last_bad_window != None && e.xany.window == last_bad_window && 539 if (last_bad_window != None && e.xany.window == last_bad_window &&
547 e.type != DestroyNotify) { // we must let the actual destroys through 540 e.type != DestroyNotify) { // we must let the actual destroys through
548 if (e.type == FocusOut) 541 if (e.type == FocusOut)
549 m_revert_timer.start(); 542 revertFocus();
550#ifdef DEBUG 543#ifdef DEBUG
551 else 544 else
552 cerr<<"Fluxbox::eventLoop(): removing bad window from event queue"<<endl; 545 cerr<<"Fluxbox::eventLoop(): removing bad window from event queue"<<endl;
@@ -711,30 +704,6 @@ void Fluxbox::handleEvent(XEvent * const e) {
711 } 704 }
712 } 705 }
713 706
714 // we need to check focus out for menus before
715 // we call FbTk eventhandler
716 // so we can get FbTk::Menu::focused() before it sets to 0
717 if (e->type == FocusOut &&
718 e->xfocus.mode != NotifyGrab &&
719 e->xfocus.detail != NotifyPointer &&
720 e->xfocus.detail != NotifyInferior &&
721 FbTk::Menu::focused() != 0 &&
722 FbTk::Menu::focused()->window() == e->xfocus.window) {
723
724 // find screen num
725 ScreenList::iterator it = m_screen_list.begin();
726 ScreenList::iterator it_end = m_screen_list.end();
727 for (; it != it_end; ++it) {
728 if ( (*it)->screenNumber() ==
729 FbTk::Menu::focused()->fbwindow().screenNumber()) {
730 FocusControl::setFocusedWindow(0);
731 m_revert_screen = *it;
732 m_revert_timer.start();
733 break; // found the screen, no more search
734 }
735 }
736 }
737
738 // try FbTk::EventHandler first 707 // try FbTk::EventHandler first
739 FbTk::EventManager::instance()->handleEvent(*e); 708 FbTk::EventManager::instance()->handleEvent(*e);
740 709
@@ -903,9 +872,18 @@ void Fluxbox::handleEvent(XEvent * const e) {
903 e->xfocus.detail == NotifyPointer || 872 e->xfocus.detail == NotifyPointer ||
904 e->xfocus.detail == NotifyInferior) 873 e->xfocus.detail == NotifyInferior)
905 break; 874 break;
875
876 if (FbTk::Menu::focused() &&
877 FbTk::Menu::focused()->window() == e->xfocus.window) {
878 m_keyscreen = findScreen(FbTk::Menu::focused()->screenNumber());
879 break;
880 }
881
906 WinClient *winclient = searchWindow(e->xfocus.window); 882 WinClient *winclient = searchWindow(e->xfocus.window);
907 if (winclient && FocusControl::focusedWindow() != winclient) 883 if (!winclient)
908 FocusControl::setFocusedWindow(winclient); 884 break;
885 m_keyscreen = &winclient->screen();
886 FocusControl::setFocusedWindow(winclient);
909 887
910 } break; 888 } break;
911 case FocusOut:{ 889 case FocusOut:{
@@ -916,19 +894,11 @@ void Fluxbox::handleEvent(XEvent * const e) {
916 break; 894 break;
917 895
918 WinClient *winclient = searchWindow(e->xfocus.window); 896 WinClient *winclient = searchWindow(e->xfocus.window);
919 if (winclient == 0 && FbTk::Menu::focused() == 0) { 897 if (winclient && (winclient == FocusControl::focusedWindow() ||
920#ifdef DEBUG 898 FocusControl::focusedWindow() == 0) &&
921 cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<<endl;
922#endif // DEBUG
923 } else if (winclient && (winclient == FocusControl::focusedWindow() ||
924 FocusControl::focusedWindow() == 0) &&
925 (winclient->fbwindow() == 0
926 || !winclient->fbwindow()->isMoving())) {
927 // we don't unfocus a moving window 899 // we don't unfocus a moving window
928 FocusControl::setFocusedWindow(0); 900 (winclient->fbwindow() == 0 || !winclient->fbwindow()->isMoving()))
929 m_revert_screen = &winclient->screen(); 901 revertFocus();
930 m_revert_timer.start();
931 }
932 } 902 }
933 break; 903 break;
934 case ClientMessage: 904 case ClientMessage:
@@ -1166,8 +1136,6 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
1166 FocusControl::unfocusWindow(*client); 1136 FocusControl::unfocusWindow(*client);
1167 // make sure nothing else uses this window before focus reverts 1137 // make sure nothing else uses this window before focus reverts
1168 FocusControl::setFocusedWindow(0); 1138 FocusControl::setFocusedWindow(0);
1169 m_revert_screen = &screen;
1170 m_revert_timer.start();
1171 } 1139 }
1172 1140
1173 screen.removeClient(*client); 1141 screen.removeClient(*client);
@@ -1640,22 +1608,36 @@ void Fluxbox::timed_reconfigure() {
1640 m_reconfigure_wait = m_reread_menu_wait = false; 1608 m_reconfigure_wait = m_reread_menu_wait = false;
1641} 1609}
1642 1610
1643void Fluxbox::revert_focus() { 1611void Fluxbox::revertFocus() {
1644 if (!m_revert_screen || FocusControl::focusedWindow() || 1612 bool revert = m_keyscreen && !m_showing_dialog;
1645 FbTk::Menu::focused() || m_showing_dialog)
1646 return;
1647 1613
1648 Window win; 1614 if (revert) {
1649 int revert; 1615 // see if there are any more focus events in the queue
1650 Display *disp = display(); 1616 XEvent ev;
1617 while (XCheckMaskEvent(display(), FocusChangeMask, &ev)) {
1618 handleEvent(&ev);
1619 revert = false;
1620 }
1621 if (!revert)
1622 return; // already handled
1623 }
1651 1624
1652 XGetInputFocus(disp, &win, &revert); 1625 if (revert) {
1626 Window win;
1627 int blah;
1628 XGetInputFocus(display(), &win, &blah);
1629
1630 // we only want to revert focus if it's left dangling, as some other
1631 // application may have set the focus to an unmanaged window
1632 if (win != None && win != PointerRoot &&
1633 win != m_keyscreen->rootWindow().window())
1634 revert = false;
1635 }
1653 1636
1654 // we only want to revert focus if it's left dangling, as some other 1637 if (revert)
1655 // application may have set the focus to an unmanaged window 1638 FocusControl::revertFocus(*m_keyscreen);
1656 if (win == None || win == PointerRoot || 1639 else
1657 win == m_revert_screen->rootWindow().window()) 1640 FocusControl::setFocusedWindow(0);
1658 FocusControl::revertFocus(*m_revert_screen);
1659} 1641}
1660 1642
1661bool Fluxbox::validateClient(const WinClient *client) const { 1643bool Fluxbox::validateClient(const WinClient *client) const {
diff --git a/src/fluxbox.hh b/src/fluxbox.hh
index 8dac8ed..ea529e9 100644
--- a/src/fluxbox.hh
+++ b/src/fluxbox.hh
@@ -166,7 +166,7 @@ public:
166 void attachSignals(WinClient &winclient); 166 void attachSignals(WinClient &winclient);
167 167
168 void timed_reconfigure(); 168 void timed_reconfigure();
169 void revert_focus(); 169 void revertFocus();
170 void setShowingDialog(bool value) { m_showing_dialog = value; } 170 void setShowingDialog(bool value) { m_showing_dialog = value; }
171 171
172 bool isStartup() const { return m_starting; } 172 bool isStartup() const { return m_starting; }
@@ -267,8 +267,7 @@ private:
267 XEvent m_last_event; 267 XEvent m_last_event;
268 268
269 ///< when we execute reconfig command we must wait until next event round 269 ///< when we execute reconfig command we must wait until next event round
270 FbTk::Timer m_reconfig_timer, m_revert_timer; 270 FbTk::Timer m_reconfig_timer;
271 BScreen *m_revert_screen;
272 bool m_showing_dialog; 271 bool m_showing_dialog;
273 272
274 std::auto_ptr<Keys> m_key; 273 std::auto_ptr<Keys> m_key;