From 9932b880490d92d12bc07e60e1b7f0c59f29d0fc Mon Sep 17 00:00:00 2001 From: rathnor Date: Mon, 21 Jul 2003 15:26:57 +0000 Subject: fix focus properly --- ChangeLog | 4 ++++ src/WinClient.cc | 7 +++--- src/WinClient.hh | 5 +++-- src/Window.cc | 68 ++++++++++++++++++++++++++++++++++---------------------- src/fluxbox.cc | 7 +++--- 5 files changed, 56 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5622ba0..8039163 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ (Format: Year/Month/Day) Changes for 0.9.5: +*03/07/21: + * Really fix focus stuff. Should be properly standards compliant now (I + hope). This also fixes a crash introduced yesterday. (Simon) + WinClient.hh/cc Window.cc fluxbox.cc *03/07/20: * Fix aspects of focus and raising, including transients (Simon) - 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 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: WinClient.cc,v 1.18 2003/07/20 18:05:39 rathnor Exp $ +// $Id: WinClient.cc,v 1.19 2003/07/21 15:26:56 rathnor Exp $ #include "WinClient.hh" @@ -138,9 +138,9 @@ void WinClient::updateRect(int x, int y, } -void WinClient::sendFocus() { +bool WinClient::sendFocus() { if (!send_focus_message) - return; + return false; Display *disp = FbTk::App::instance()->display(); // setup focus msg @@ -157,6 +157,7 @@ void WinClient::sendFocus() { ce.xclient.data.l[4] = 0l; // send focus msg XSendEvent(disp, window(), false, NoEventMask, &ce); + return true; } 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 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: WinClient.hh,v 1.9 2003/07/20 18:05:39 rathnor Exp $ +// $Id: WinClient.hh,v 1.10 2003/07/21 15:26:56 rathnor Exp $ #ifndef WINCLIENT_HH #define WINCLIENT_HH @@ -42,7 +42,8 @@ public: ~WinClient(); void updateRect(int x, int y, unsigned int width, unsigned int height); - void sendFocus(); + bool sendFocus(); // returns whether we sent a message or not + // i.e. whether we assume the focus will get taken void sendClose(); void reparent(Window win, int x, int y); 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 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.207 2003/07/20 18:05:39 rathnor Exp $ +// $Id: Window.cc,v 1.208 2003/07/21 15:26:56 rathnor Exp $ #include "Window.hh" @@ -1097,9 +1097,13 @@ void FluxboxWindow::moveResize(int new_x, int new_y, shape(); } +// returns whether the focus was "set" to this window +// it doesn't guarantee that it has focus, but says that we have +// tried. A FocusqIn event should eventually arrive for that +// window if it actually got the focus, then setFocusedFlag is called, +// which updates all the graphics etc bool FluxboxWindow::setInputFocus() { - //TODO hint skip focus if (((signed) (frame().x() + frame().width())) < 0) { if (((signed) (frame().y() + frame().height())) < 0) { moveResize(frame().window().borderWidth(), frame().window().borderWidth(), @@ -1137,18 +1141,16 @@ bool FluxboxWindow::setInputFocus() { return (*it)->fbwindow()->setCurrentClient(**it, true); } } + if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE || m_client->getFocusMode() == WinClient::F_PASSIVE) { m_client->setInputFocus(RevertToPointerRoot, CurrentTime); + // this may or may not send, but we've setInputFocus already, so return true + m_client->sendFocus(); + return true; } else { - return false; + return m_client->sendFocus(); // checks if it should send or not } - - if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus()) - && screen().doAutoRaise()) - m_timer.start(); - - return true; } void FluxboxWindow::hide() { @@ -1581,28 +1583,36 @@ void FluxboxWindow::moveToLayer(int layernum) { } - +// window has actually RECEIVED focus (got a FocusIn event) +// so now we make it a focused frame etc void FluxboxWindow::setFocusFlag(bool focus) { focused = focus; // Record focus timestamp for window cycling enhancements - if (focused) + if (focused) { gettimeofday(&m_last_focus_time, 0); + screen().setFocusedWindow(*m_client); + } - screen().setFocusedWindow(*m_client); - m_client->sendFocus(); + installColormap(focus); frame().setFocus(focus); - if (!focused && (screen().isSloppyFocus() || screen().isSemiSloppyFocus()) && - screen().doAutoRaise()) - m_timer.stop(); + if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus()) + && screen().doAutoRaise()) + if (focused) + m_timer.start(); + else + m_timer.stop(); } void FluxboxWindow::installColormap(bool install) { + if (m_client == 0) return; + Fluxbox *fluxbox = Fluxbox::instance(); fluxbox->grab(); - if (! validateClient()) return; + if (! validateClient()) + return; int i = 0, ncmap = 0; Colormap *cmaps = XListInstalledColormaps(display, m_client->window(), &ncmap); @@ -2567,17 +2577,21 @@ void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) { XCheckIfEvent(display, &dummy, queueScanner, (char *) &sa); // if client is set, use setCurrent client, otherwise just setInputFocus - if ((!sa.leave || sa.inferior) && - ((client && setCurrentClient(*client, true)) || setInputFocus())) { - installColormap(True); + if ((!sa.leave || sa.inferior)) { + if (client) + setCurrentClient(*client, true); + else + setInputFocus(); } + } } } void FluxboxWindow::leaveNotifyEvent(XCrossingEvent &ev) { - if (ev.window == frame().window()) - installColormap(false); + // I hope commenting this out is right - simon 21jul2003 + //if (ev.window == frame().window()) + //installColormap(false); } // TODO: functions should not be affected by decoration @@ -2728,11 +2742,11 @@ bool FluxboxWindow::validateClient() { XSync(display, false); XEvent e; - if (XCheckTypedWindowEvent(display, m_client->window(), DestroyNotify, &e) || - XCheckTypedWindowEvent(display, m_client->window(), UnmapNotify, &e)) { - XPutBackEvent(display, &e); + if (!m_client || + ( XCheckTypedWindowEvent(display, m_client->window(), DestroyNotify, &e) || + XCheckTypedWindowEvent(display, m_client->window(), UnmapNotify, &e)) + && XPutBackEvent(display, &e)) { Fluxbox::instance()->ungrab(); - return false; } @@ -3041,6 +3055,8 @@ void FluxboxWindow::restore(WinClient *client, bool remap) { if (remap) client->show(); + installColormap(false); + delete client; #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 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.cc,v 1.172 2003/07/20 18:05:39 rathnor Exp $ +// $Id: fluxbox.cc,v 1.173 2003/07/21 15:26:57 rathnor Exp $ #include "fluxbox.hh" @@ -1085,9 +1085,8 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) { } else if (ce.message_type == m_fbatoms->getFluxboxChangeWindowFocusAtom()) { FluxboxWindow *win = searchWindow(ce.window); - if (win && win->isVisible() && win->setInputFocus()) { - win->installColormap(true); - } + if (win && win->isVisible()) + win->setInputFocus(); } else if (ce.message_type == m_fbatoms->getFluxboxCycleWindowFocusAtom()) { BScreen *screen = searchScreen(ce.window); -- cgit v0.11.2