aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMark Tiefenbruck <mark@fluxbox.org>2008-01-13 00:47:40 (GMT)
committerMark Tiefenbruck <mark@fluxbox.org>2008-01-13 00:47:40 (GMT)
commitb302dab2f187e364df36237c44b8e48f1e892f04 (patch)
tree207955232ddf7aef1b4a13ccb5ae85a2404aa509 /src
parentf66d446a94450d509748afe28a95f48b8fdfcfc5 (diff)
downloadfluxbox-b302dab2f187e364df36237c44b8e48f1e892f04.zip
fluxbox-b302dab2f187e364df36237c44b8e48f1e892f04.tar.bz2
fix some issues with reverting focus
Diffstat (limited to 'src')
-rw-r--r--src/FocusControl.cc5
-rw-r--r--src/FocusControl.hh3
-rw-r--r--src/ToolFactory.cc1
-rw-r--r--src/WinClient.cc4
-rw-r--r--src/Window.cc10
-rw-r--r--src/fluxbox.cc32
6 files changed, 25 insertions, 30 deletions
diff --git a/src/FocusControl.cc b/src/FocusControl.cc
index a81d68f..c17b900 100644
--- a/src/FocusControl.cc
+++ b/src/FocusControl.cc
@@ -45,6 +45,7 @@ using std::string;
45 45
46WinClient *FocusControl::s_focused_window = 0; 46WinClient *FocusControl::s_focused_window = 0;
47FluxboxWindow *FocusControl::s_focused_fbwindow = 0; 47FluxboxWindow *FocusControl::s_focused_fbwindow = 0;
48WinClient *FocusControl::s_expecting_focus = 0;
48bool FocusControl::s_reverting = false; 49bool FocusControl::s_reverting = false;
49 50
50namespace { 51namespace {
@@ -242,7 +243,7 @@ void FocusControl::stopCyclingFocus() {
242 * is given. 243 * is given.
243 */ 244 */
244Focusable *FocusControl::lastFocusedWindow(int workspace) { 245Focusable *FocusControl::lastFocusedWindow(int workspace) {
245 if (m_focused_list.empty() || m_screen.isShuttingdown()) return 0; 246 if (m_screen.isShuttingdown()) return 0;
246 if (workspace < 0 || workspace >= (int) m_screen.numberOfWorkspaces()) 247 if (workspace < 0 || workspace >= (int) m_screen.numberOfWorkspaces())
247 return m_focused_list.clientList().front(); 248 return m_focused_list.clientList().front();
248 249
@@ -250,6 +251,7 @@ Focusable *FocusControl::lastFocusedWindow(int workspace) {
250 Focusables::iterator it_end = m_focused_list.clientList().end(); 251 Focusables::iterator it_end = m_focused_list.clientList().end();
251 for (; it != it_end; ++it) { 252 for (; it != it_end; ++it) {
252 if ((*it)->fbwindow() && (*it)->acceptsFocus() && 253 if ((*it)->fbwindow() && (*it)->acceptsFocus() &&
254 (*it)->fbwindow()->winClient().validateClient() &&
253 ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace || 255 ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace ||
254 (*it)->fbwindow()->isStuck()) && !(*it)->fbwindow()->isIconic())) 256 (*it)->fbwindow()->isStuck()) && !(*it)->fbwindow()->isIconic()))
255 return *it; 257 return *it;
@@ -536,6 +538,7 @@ void FocusControl::setFocusedWindow(WinClient *client) {
536 // screen should be ok 538 // screen should be ok
537 s_focused_fbwindow = client->fbwindow(); 539 s_focused_fbwindow = client->fbwindow();
538 s_focused_window = client; // update focused window 540 s_focused_window = client; // update focused window
541 s_expecting_focus = 0;
539 s_focused_fbwindow->setCurrentClient(*client, 542 s_focused_fbwindow->setCurrentClient(*client,
540 false); // don't set inputfocus 543 false); // don't set inputfocus
541 s_focused_fbwindow->setFocusFlag(true); // set focus flag 544 s_focused_fbwindow->setFocusFlag(true); // set focus flag
diff --git a/src/FocusControl.hh b/src/FocusControl.hh
index 0baa401..4de4310 100644
--- a/src/FocusControl.hh
+++ b/src/FocusControl.hh
@@ -134,8 +134,10 @@ public:
134 static void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false); 134 static void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false);
135 static void setFocusedWindow(WinClient *focus_to); 135 static void setFocusedWindow(WinClient *focus_to);
136 static void setFocusedFbWindow(FluxboxWindow *focus_to) { s_focused_fbwindow = focus_to; } 136 static void setFocusedFbWindow(FluxboxWindow *focus_to) { s_focused_fbwindow = focus_to; }
137 static void setExpectingFocus(WinClient *client) { s_expecting_focus = client; }
137 static WinClient *focusedWindow() { return s_focused_window; } 138 static WinClient *focusedWindow() { return s_focused_window; }
138 static FluxboxWindow *focusedFbWindow() { return s_focused_fbwindow; } 139 static FluxboxWindow *focusedFbWindow() { return s_focused_fbwindow; }
140 static WinClient *expectingFocus() { return s_expecting_focus; }
139private: 141private:
140 142
141 BScreen &m_screen; 143 BScreen &m_screen;
@@ -158,6 +160,7 @@ private:
158 160
159 static WinClient *s_focused_window; 161 static WinClient *s_focused_window;
160 static FluxboxWindow *s_focused_fbwindow; 162 static FluxboxWindow *s_focused_fbwindow;
163 static WinClient *s_expecting_focus;
161 static bool s_reverting; 164 static bool s_reverting;
162}; 165};
163 166
diff --git a/src/ToolFactory.cc b/src/ToolFactory.cc
index 074ae71..e6d633e 100644
--- a/src/ToolFactory.cc
+++ b/src/ToolFactory.cc
@@ -30,7 +30,6 @@
30#include "ArrowButton.hh" 30#include "ArrowButton.hh"
31 31
32// Themes 32// Themes
33#include "IconbarTheme.hh"
34#include "WorkspaceNameTheme.hh" 33#include "WorkspaceNameTheme.hh"
35#include "ButtonTheme.hh" 34#include "ButtonTheme.hh"
36 35
diff --git a/src/WinClient.cc b/src/WinClient.cc
index ed6fe25..450a041 100644
--- a/src/WinClient.cc
+++ b/src/WinClient.cc
@@ -174,7 +174,8 @@ bool WinClient::acceptsFocus() const {
174 174
175bool WinClient::sendFocus() { 175bool WinClient::sendFocus() {
176 if (accepts_input) { 176 if (accepts_input) {
177 setInputFocus(RevertToParent, CurrentTime); 177 setInputFocus(RevertToPointerRoot, CurrentTime);
178 FocusControl::setExpectingFocus(this);
178 return true; 179 return true;
179 } 180 }
180 if (!send_focus_message) 181 if (!send_focus_message)
@@ -198,6 +199,7 @@ bool WinClient::sendFocus() {
198 ce.xclient.data.l[4] = 0l; 199 ce.xclient.data.l[4] = 0l;
199 // send focus msg 200 // send focus msg
200 XSendEvent(display(), window(), false, NoEventMask, &ce); 201 XSendEvent(display(), window(), false, NoEventMask, &ce);
202 FocusControl::setExpectingFocus(this);
201 return true; 203 return true;
202} 204}
203 205
diff --git a/src/Window.cc b/src/Window.cc
index 3e1ad4e..86026c9 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -2353,8 +2353,9 @@ void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) {
2353#ifdef DEBUG 2353#ifdef DEBUG
2354 cerr<<__FILE__<<"("<<__LINE__<<"): DestroyNotifyEvent this="<<this<<" title = "<<title()<<endl; 2354 cerr<<__FILE__<<"("<<__LINE__<<"): DestroyNotifyEvent this="<<this<<" title = "<<title()<<endl;
2355#endif // DEBUG 2355#endif // DEBUG
2356 if (numClients() == 1) 2356 delete m_client;
2357 hide(); 2357 if (numClients() == 0)
2358 delete this;
2358 } 2359 }
2359 2360
2360} 2361}
@@ -3680,9 +3681,8 @@ void FluxboxWindow::restore(WinClient *client, bool remap) {
3680 cerr<<"FluxboxWindow::restore: remap = "<<remap<<endl; 3681 cerr<<"FluxboxWindow::restore: remap = "<<remap<<endl;
3681 cerr<<__FILE__<<"("<<__FUNCTION__<<"): numClients() = "<<numClients()<<endl; 3682 cerr<<__FILE__<<"("<<__FUNCTION__<<"): numClients() = "<<numClients()<<endl;
3682#endif // DEBUG 3683#endif // DEBUG
3683 if (numClients() == 0) { 3684 if (numClients() == 0)
3684 hide(true); 3685 delete this;
3685 }
3686 3686
3687} 3687}
3688 3688
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index e93f363..110123c 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -749,11 +749,6 @@ void Fluxbox::handleEvent(XEvent * const e) {
749 FluxboxWindow *win = winclient->fbwindow(); 749 FluxboxWindow *win = winclient->fbwindow();
750 if (win) 750 if (win)
751 win->destroyNotifyEvent(e->xdestroywindow); 751 win->destroyNotifyEvent(e->xdestroywindow);
752
753 delete winclient;
754
755 if (win && win->numClients() == 0)
756 delete win;
757 } 752 }
758 753
759 } 754 }
@@ -835,10 +830,11 @@ void Fluxbox::handleEvent(XEvent * const e) {
835 break; 830 break;
836 831
837 WinClient *winclient = searchWindow(e->xfocus.window); 832 WinClient *winclient = searchWindow(e->xfocus.window);
838 if (winclient && (winclient == FocusControl::focusedWindow() || 833 if ((winclient == FocusControl::focusedWindow() ||
839 FocusControl::focusedWindow() == 0) && 834 FocusControl::focusedWindow() == 0) &&
840 // we don't unfocus a moving window 835 // we don't unfocus a moving window
841 (winclient->fbwindow() == 0 || !winclient->fbwindow()->isMoving())) 836 (!winclient || !winclient->fbwindow() ||
837 !winclient->fbwindow()->isMoving()))
842 revertFocus(); 838 revertFocus();
843 } 839 }
844 break; 840 break;
@@ -884,13 +880,6 @@ void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) {
884 // this should delete client and adjust m_focused_window if necessary 880 // this should delete client and adjust m_focused_window if necessary
885 win->unmapNotifyEvent(ue); 881 win->unmapNotifyEvent(ue);
886 882
887 winclient = 0; // it's invalid now when win destroyed the client
888
889 // finally destroy window if empty
890 if (win->numClients() == 0) {
891 delete win;
892 win = 0;
893 }
894 } 883 }
895 884
896 // according to http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.4 885 // according to http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.4
@@ -1077,6 +1066,9 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
1077 FocusControl::unfocusWindow(*client); 1066 FocusControl::unfocusWindow(*client);
1078 // make sure nothing else uses this window before focus reverts 1067 // make sure nothing else uses this window before focus reverts
1079 FocusControl::setFocusedWindow(0); 1068 FocusControl::setFocusedWindow(0);
1069 } else if (FocusControl::expectingFocus() == client) {
1070 FocusControl::setExpectingFocus(0);
1071 revertFocus();
1080 } 1072 }
1081 1073
1082 screen.removeClient(*client); 1074 screen.removeClient(*client);
@@ -1555,22 +1547,18 @@ void Fluxbox::revertFocus() {
1555 if (revert) { 1547 if (revert) {
1556 // see if there are any more focus events in the queue 1548 // see if there are any more focus events in the queue
1557 XEvent ev; 1549 XEvent ev;
1558 while (XCheckMaskEvent(display(), FocusChangeMask, &ev)) { 1550 while (XCheckMaskEvent(display(), FocusChangeMask, &ev))
1559 handleEvent(&ev); 1551 handleEvent(&ev);
1560 revert = false; 1552 if (FocusControl::focusedWindow() || FocusControl::expectingFocus())
1561 }
1562 if (!revert)
1563 return; // already handled 1553 return; // already handled
1564 }
1565 1554
1566 if (revert) {
1567 Window win; 1555 Window win;
1568 int blah; 1556 int blah;
1569 XGetInputFocus(display(), &win, &blah); 1557 XGetInputFocus(display(), &win, &blah);
1570 1558
1571 // we only want to revert focus if it's left dangling, as some other 1559 // we only want to revert focus if it's left dangling, as some other
1572 // application may have set the focus to an unmanaged window 1560 // application may have set the focus to an unmanaged window
1573 if (win != None && win != PointerRoot && 1561 if (win != None && win != PointerRoot && !searchWindow(win) &&
1574 win != m_keyscreen->rootWindow().window()) 1562 win != m_keyscreen->rootWindow().window())
1575 revert = false; 1563 revert = false;
1576 } 1564 }