fix focus properly
@@ -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
@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// 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 @@ XSendEvent(disp, window(), False, StructureNotifyMask, &event);
} -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 @@ ce.xclient.data.l[3] = 0l;
ce.xclient.data.l[4] = 0l; // send focus msg XSendEvent(disp, window(), false, NoEventMask, &ce); + return true; } void WinClient::sendClose() {
@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// 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 @@ WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin = 0);
~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;
@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// 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 @@
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 @@ if ((*it)->isModal())
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 @@ }
} - +// 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 @@ sa.enter = sa.leave = False;
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; }@@ -3040,6 +3054,8 @@ }
if (remap) client->show(); + + installColormap(false); delete client;
@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// 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 @@ screen->changeWorkspaceID(ce.data.l[0]);
} 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);