diff options
author | rathnor <rathnor> | 2003-07-21 15:26:57 (GMT) |
---|---|---|
committer | rathnor <rathnor> | 2003-07-21 15:26:57 (GMT) |
commit | 9932b880490d92d12bc07e60e1b7f0c59f29d0fc (patch) | |
tree | 0e1b1ccf13625e4197d563545636f34efb7db0be | |
parent | 370a9d474475d708f03795665d915f314f1665fa (diff) | |
download | fluxbox-9932b880490d92d12bc07e60e1b7f0c59f29d0fc.zip fluxbox-9932b880490d92d12bc07e60e1b7f0c59f29d0fc.tar.bz2 |
fix focus properly
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/WinClient.cc | 7 | ||||
-rw-r--r-- | src/WinClient.hh | 5 | ||||
-rw-r--r-- | src/Window.cc | 68 | ||||
-rw-r--r-- | src/fluxbox.cc | 7 |
5 files changed, 56 insertions, 35 deletions
@@ -1,5 +1,9 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 0.9.5: | 2 | Changes for 0.9.5: |
3 | *03/07/21: | ||
4 | * Really fix focus stuff. Should be properly standards compliant now (I | ||
5 | hope). This also fixes a crash introduced yesterday. (Simon) | ||
6 | WinClient.hh/cc Window.cc fluxbox.cc | ||
3 | *03/07/20: | 7 | *03/07/20: |
4 | * Fix aspects of focus and raising, including transients (Simon) | 8 | * Fix aspects of focus and raising, including transients (Simon) |
5 | - fixes focus toggling with transients and sloppy focus | 9 | - fixes focus toggling with transients and sloppy focus |
diff --git a/src/WinClient.cc b/src/WinClient.cc index 416dd63..092c10d 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc | |||
@@ -19,7 +19,7 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: WinClient.cc,v 1.18 2003/07/20 18:05:39 rathnor Exp $ | 22 | // $Id: WinClient.cc,v 1.19 2003/07/21 15:26:56 rathnor Exp $ |
23 | 23 | ||
24 | #include "WinClient.hh" | 24 | #include "WinClient.hh" |
25 | 25 | ||
@@ -138,9 +138,9 @@ void WinClient::updateRect(int x, int y, | |||
138 | 138 | ||
139 | } | 139 | } |
140 | 140 | ||
141 | void WinClient::sendFocus() { | 141 | bool WinClient::sendFocus() { |
142 | if (!send_focus_message) | 142 | if (!send_focus_message) |
143 | return; | 143 | return false; |
144 | 144 | ||
145 | Display *disp = FbTk::App::instance()->display(); | 145 | Display *disp = FbTk::App::instance()->display(); |
146 | // setup focus msg | 146 | // setup focus msg |
@@ -157,6 +157,7 @@ void WinClient::sendFocus() { | |||
157 | ce.xclient.data.l[4] = 0l; | 157 | ce.xclient.data.l[4] = 0l; |
158 | // send focus msg | 158 | // send focus msg |
159 | XSendEvent(disp, window(), false, NoEventMask, &ce); | 159 | XSendEvent(disp, window(), false, NoEventMask, &ce); |
160 | return true; | ||
160 | } | 161 | } |
161 | 162 | ||
162 | void WinClient::sendClose() { | 163 | void WinClient::sendClose() { |
diff --git a/src/WinClient.hh b/src/WinClient.hh index cedbdd7..7626514 100644 --- a/src/WinClient.hh +++ b/src/WinClient.hh | |||
@@ -19,7 +19,7 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: WinClient.hh,v 1.9 2003/07/20 18:05:39 rathnor Exp $ | 22 | // $Id: WinClient.hh,v 1.10 2003/07/21 15:26:56 rathnor Exp $ |
23 | 23 | ||
24 | #ifndef WINCLIENT_HH | 24 | #ifndef WINCLIENT_HH |
25 | #define WINCLIENT_HH | 25 | #define WINCLIENT_HH |
@@ -42,7 +42,8 @@ public: | |||
42 | 42 | ||
43 | ~WinClient(); | 43 | ~WinClient(); |
44 | void updateRect(int x, int y, unsigned int width, unsigned int height); | 44 | void updateRect(int x, int y, unsigned int width, unsigned int height); |
45 | void sendFocus(); | 45 | bool sendFocus(); // returns whether we sent a message or not |
46 | // i.e. whether we assume the focus will get taken | ||
46 | void sendClose(); | 47 | void sendClose(); |
47 | void reparent(Window win, int x, int y); | 48 | void reparent(Window win, int x, int y); |
48 | bool getAttrib(XWindowAttributes &attr) const; | 49 | bool getAttrib(XWindowAttributes &attr) const; |
diff --git a/src/Window.cc b/src/Window.cc index 4e45370..10892df 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Window.cc,v 1.207 2003/07/20 18:05:39 rathnor Exp $ | 25 | // $Id: Window.cc,v 1.208 2003/07/21 15:26:56 rathnor Exp $ |
26 | 26 | ||
27 | #include "Window.hh" | 27 | #include "Window.hh" |
28 | 28 | ||
@@ -1097,9 +1097,13 @@ void FluxboxWindow::moveResize(int new_x, int new_y, | |||
1097 | shape(); | 1097 | shape(); |
1098 | } | 1098 | } |
1099 | 1099 | ||
1100 | // returns whether the focus was "set" to this window | ||
1101 | // it doesn't guarantee that it has focus, but says that we have | ||
1102 | // tried. A FocusqIn event should eventually arrive for that | ||
1103 | // window if it actually got the focus, then setFocusedFlag is called, | ||
1104 | // which updates all the graphics etc | ||
1100 | bool FluxboxWindow::setInputFocus() { | 1105 | bool FluxboxWindow::setInputFocus() { |
1101 | 1106 | ||
1102 | //TODO hint skip focus | ||
1103 | if (((signed) (frame().x() + frame().width())) < 0) { | 1107 | if (((signed) (frame().x() + frame().width())) < 0) { |
1104 | if (((signed) (frame().y() + frame().height())) < 0) { | 1108 | if (((signed) (frame().y() + frame().height())) < 0) { |
1105 | moveResize(frame().window().borderWidth(), frame().window().borderWidth(), | 1109 | moveResize(frame().window().borderWidth(), frame().window().borderWidth(), |
@@ -1137,18 +1141,16 @@ bool FluxboxWindow::setInputFocus() { | |||
1137 | return (*it)->fbwindow()->setCurrentClient(**it, true); | 1141 | return (*it)->fbwindow()->setCurrentClient(**it, true); |
1138 | } | 1142 | } |
1139 | } | 1143 | } |
1144 | |||
1140 | if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE || | 1145 | if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE || |
1141 | m_client->getFocusMode() == WinClient::F_PASSIVE) { | 1146 | m_client->getFocusMode() == WinClient::F_PASSIVE) { |
1142 | m_client->setInputFocus(RevertToPointerRoot, CurrentTime); | 1147 | m_client->setInputFocus(RevertToPointerRoot, CurrentTime); |
1148 | // this may or may not send, but we've setInputFocus already, so return true | ||
1149 | m_client->sendFocus(); | ||
1150 | return true; | ||
1143 | } else { | 1151 | } else { |
1144 | return false; | 1152 | return m_client->sendFocus(); // checks if it should send or not |
1145 | } | 1153 | } |
1146 | |||
1147 | if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus()) | ||
1148 | && screen().doAutoRaise()) | ||
1149 | m_timer.start(); | ||
1150 | |||
1151 | return true; | ||
1152 | } | 1154 | } |
1153 | 1155 | ||
1154 | void FluxboxWindow::hide() { | 1156 | void FluxboxWindow::hide() { |
@@ -1581,28 +1583,36 @@ void FluxboxWindow::moveToLayer(int layernum) { | |||
1581 | } | 1583 | } |
1582 | 1584 | ||
1583 | 1585 | ||
1584 | 1586 | // window has actually RECEIVED focus (got a FocusIn event) | |
1587 | // so now we make it a focused frame etc | ||
1585 | void FluxboxWindow::setFocusFlag(bool focus) { | 1588 | void FluxboxWindow::setFocusFlag(bool focus) { |
1586 | focused = focus; | 1589 | focused = focus; |
1587 | 1590 | ||
1588 | // Record focus timestamp for window cycling enhancements | 1591 | // Record focus timestamp for window cycling enhancements |
1589 | if (focused) | 1592 | if (focused) { |
1590 | gettimeofday(&m_last_focus_time, 0); | 1593 | gettimeofday(&m_last_focus_time, 0); |
1594 | screen().setFocusedWindow(*m_client); | ||
1595 | } | ||
1591 | 1596 | ||
1592 | screen().setFocusedWindow(*m_client); | 1597 | installColormap(focus); |
1593 | m_client->sendFocus(); | ||
1594 | frame().setFocus(focus); | 1598 | frame().setFocus(focus); |
1595 | 1599 | ||
1596 | if (!focused && (screen().isSloppyFocus() || screen().isSemiSloppyFocus()) && | 1600 | if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus()) |
1597 | screen().doAutoRaise()) | 1601 | && screen().doAutoRaise()) |
1598 | m_timer.stop(); | 1602 | if (focused) |
1603 | m_timer.start(); | ||
1604 | else | ||
1605 | m_timer.stop(); | ||
1599 | } | 1606 | } |
1600 | 1607 | ||
1601 | 1608 | ||
1602 | void FluxboxWindow::installColormap(bool install) { | 1609 | void FluxboxWindow::installColormap(bool install) { |
1610 | if (m_client == 0) return; | ||
1611 | |||
1603 | Fluxbox *fluxbox = Fluxbox::instance(); | 1612 | Fluxbox *fluxbox = Fluxbox::instance(); |
1604 | fluxbox->grab(); | 1613 | fluxbox->grab(); |
1605 | if (! validateClient()) return; | 1614 | if (! validateClient()) |
1615 | return; | ||
1606 | 1616 | ||
1607 | int i = 0, ncmap = 0; | 1617 | int i = 0, ncmap = 0; |
1608 | Colormap *cmaps = XListInstalledColormaps(display, m_client->window(), &ncmap); | 1618 | Colormap *cmaps = XListInstalledColormaps(display, m_client->window(), &ncmap); |
@@ -2567,17 +2577,21 @@ void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) { | |||
2567 | XCheckIfEvent(display, &dummy, queueScanner, (char *) &sa); | 2577 | XCheckIfEvent(display, &dummy, queueScanner, (char *) &sa); |
2568 | 2578 | ||
2569 | // if client is set, use setCurrent client, otherwise just setInputFocus | 2579 | // if client is set, use setCurrent client, otherwise just setInputFocus |
2570 | if ((!sa.leave || sa.inferior) && | 2580 | if ((!sa.leave || sa.inferior)) { |
2571 | ((client && setCurrentClient(*client, true)) || setInputFocus())) { | 2581 | if (client) |
2572 | installColormap(True); | 2582 | setCurrentClient(*client, true); |
2583 | else | ||
2584 | setInputFocus(); | ||
2573 | } | 2585 | } |
2586 | |||
2574 | } | 2587 | } |
2575 | } | 2588 | } |
2576 | } | 2589 | } |
2577 | 2590 | ||
2578 | void FluxboxWindow::leaveNotifyEvent(XCrossingEvent &ev) { | 2591 | void FluxboxWindow::leaveNotifyEvent(XCrossingEvent &ev) { |
2579 | if (ev.window == frame().window()) | 2592 | // I hope commenting this out is right - simon 21jul2003 |
2580 | installColormap(false); | 2593 | //if (ev.window == frame().window()) |
2594 | //installColormap(false); | ||
2581 | } | 2595 | } |
2582 | 2596 | ||
2583 | // TODO: functions should not be affected by decoration | 2597 | // TODO: functions should not be affected by decoration |
@@ -2728,11 +2742,11 @@ bool FluxboxWindow::validateClient() { | |||
2728 | XSync(display, false); | 2742 | XSync(display, false); |
2729 | 2743 | ||
2730 | XEvent e; | 2744 | XEvent e; |
2731 | if (XCheckTypedWindowEvent(display, m_client->window(), DestroyNotify, &e) || | 2745 | if (!m_client || |
2732 | XCheckTypedWindowEvent(display, m_client->window(), UnmapNotify, &e)) { | 2746 | ( XCheckTypedWindowEvent(display, m_client->window(), DestroyNotify, &e) || |
2733 | XPutBackEvent(display, &e); | 2747 | XCheckTypedWindowEvent(display, m_client->window(), UnmapNotify, &e)) |
2748 | && XPutBackEvent(display, &e)) { | ||
2734 | Fluxbox::instance()->ungrab(); | 2749 | Fluxbox::instance()->ungrab(); |
2735 | |||
2736 | return false; | 2750 | return false; |
2737 | } | 2751 | } |
2738 | 2752 | ||
@@ -3041,6 +3055,8 @@ void FluxboxWindow::restore(WinClient *client, bool remap) { | |||
3041 | if (remap) | 3055 | if (remap) |
3042 | client->show(); | 3056 | client->show(); |
3043 | 3057 | ||
3058 | installColormap(false); | ||
3059 | |||
3044 | delete client; | 3060 | delete client; |
3045 | 3061 | ||
3046 | #ifdef DEBUG | 3062 | #ifdef DEBUG |
diff --git a/src/fluxbox.cc b/src/fluxbox.cc index b7a4d5b..5bf54bc 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: fluxbox.cc,v 1.172 2003/07/20 18:05:39 rathnor Exp $ | 25 | // $Id: fluxbox.cc,v 1.173 2003/07/21 15:26:57 rathnor Exp $ |
26 | 26 | ||
27 | #include "fluxbox.hh" | 27 | #include "fluxbox.hh" |
28 | 28 | ||
@@ -1085,9 +1085,8 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) { | |||
1085 | 1085 | ||
1086 | } else if (ce.message_type == m_fbatoms->getFluxboxChangeWindowFocusAtom()) { | 1086 | } else if (ce.message_type == m_fbatoms->getFluxboxChangeWindowFocusAtom()) { |
1087 | FluxboxWindow *win = searchWindow(ce.window); | 1087 | FluxboxWindow *win = searchWindow(ce.window); |
1088 | if (win && win->isVisible() && win->setInputFocus()) { | 1088 | if (win && win->isVisible()) |
1089 | win->installColormap(true); | 1089 | win->setInputFocus(); |
1090 | } | ||
1091 | } else if (ce.message_type == m_fbatoms->getFluxboxCycleWindowFocusAtom()) { | 1090 | } else if (ce.message_type == m_fbatoms->getFluxboxCycleWindowFocusAtom()) { |
1092 | BScreen *screen = searchScreen(ce.window); | 1091 | BScreen *screen = searchScreen(ce.window); |
1093 | 1092 | ||