diff options
author | Mark Tiefenbruck <mark@fluxbox.org> | 2008-01-01 18:29:36 (GMT) |
---|---|---|
committer | Mark Tiefenbruck <mark@fluxbox.org> | 2008-01-01 18:29:36 (GMT) |
commit | 7588fc10a61c141208ccccc423cc7920207b2e89 (patch) | |
tree | ca9acf5c5bb36df5a9a77a4b7ce0f79cb3e054ab | |
parent | 72d2f0e48143115aae38b75d5b1bda4cee5d512a (diff) | |
download | fluxbox_paul-7588fc10a61c141208ccccc423cc7920207b2e89.zip fluxbox_paul-7588fc10a61c141208ccccc423cc7920207b2e89.tar.bz2 |
fix some flickering on focus change
-rw-r--r-- | src/FocusControl.cc | 8 | ||||
-rw-r--r-- | src/WinClient.cc | 1 | ||||
-rw-r--r-- | src/Window.cc | 25 | ||||
-rw-r--r-- | src/fluxbox.cc | 104 | ||||
-rw-r--r-- | src/fluxbox.hh | 5 |
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 | ||
1643 | void Fluxbox::revert_focus() { | 1611 | void 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 | ||
1661 | bool Fluxbox::validateClient(const WinClient *client) const { | 1643 | bool 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; |