From 10a957473803e87f119c363dc19efe92ea938a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Sun, 14 Aug 2016 13:42:27 +0200 Subject: Fix autohiding/raising timer logics Trying to control a timer bound to an unconditional toggle, caused by opposing events does not work. <- That's a period. The toolbar implementation would act too seldom, the slit to often. Instead, fire the timer whenever the state does not match the event and bind it to a function that queries the pointer position and acts accordingly. --- src/Slit.cc | 74 ++++++++++++++++++++++++++-------------------------------- src/Slit.hh | 1 + src/Toolbar.cc | 68 ++++++++++++++++++++++++----------------------------- src/Toolbar.hh | 2 ++ 4 files changed, 67 insertions(+), 78 deletions(-) diff --git a/src/Slit.cc b/src/Slit.cc index b628d18..7eb7dea 100644 --- a/src/Slit.cc +++ b/src/Slit.cc @@ -272,8 +272,8 @@ Slit::Slit(BScreen &scr, FbTk::Layer &layer, const char *filename) // setup timer m_timer.setTimeout(200L * FbTk::FbTime::IN_MILLISECONDS); // default timeout m_timer.fireOnce(true); - FbTk::RefCount > toggle_hidden(new FbTk::SimpleCommand(*this, &Slit::toggleHidden)); - m_timer.setCommand(toggle_hidden); + FbTk::RefCount > ucs(new FbTk::SimpleCommand(*this, &Slit::updateCrossingState)); + m_timer.setCommand(ucs); FbTk::EventManager::instance()->add(*this, frame.window); @@ -958,45 +958,47 @@ void Slit::buttonPressEvent(XButtonEvent &be) { } -void Slit::enterNotifyEvent(XCrossingEvent &) { - if (m_rc_auto_raise) - m_layeritem->moveToLayer(ResourceLayer::ABOVE_DOCK); - - if (! doAutoHide()) - return; - - if (isHidden()) { - if (! m_timer.isTiming()) - m_timer.start(); +void Slit::updateCrossingState() { + Window wr, wc; + int rx, ry, x, y; + unsigned int mask; + const int bw = -theme()->borderWidth(); + bool hovered = false; + if (XQueryPointer(Fluxbox::instance()->display(), window().window(), &wr, &wc, &rx, &ry, &x, &y, &mask)) + hovered = x >= bw && y >= bw && x < int(width()) && y < int(height()); + + if (hovered) { + if (m_rc_auto_raise) + m_layeritem->moveToLayer(ResourceLayer::ABOVE_DOCK); + if (m_rc_auto_hide && isHidden()) + toggleHidden(); } else { - if (m_timer.isTiming()) - m_timer.stop(); + if (m_rc_auto_hide && !isHidden()) + toggleHidden(); + if (m_rc_auto_raise) + m_layeritem->moveToLayer(m_rc_layernum->getNum()); } } +void Slit::enterNotifyEvent(XCrossingEvent &ce) { + if (!m_rc_auto_hide && isHidden()) { + toggleHidden(); + } -void Slit::leaveNotifyEvent(XCrossingEvent &ev) { - if (m_rc_auto_raise) - m_layeritem->moveToLayer(m_rc_layernum->getNum()); + if (!m_timer.isTiming() && (m_rc_auto_hide && isHidden()) || + (m_rc_auto_raise && m_layeritem->getLayerNum() != ResourceLayer::ABOVE_DOCK)) + m_timer.start(); +} - if (! doAutoHide()) +void Slit::leaveNotifyEvent(XCrossingEvent &event) { + if (m_slitmenu.isVisible()) return; - if (isHidden()) { - if (m_timer.isTiming()) - m_timer.stop(); - } else { - if (! m_timer.isTiming()) { - // the menu is open, keep it firing until it closes - if (m_slitmenu.isVisible()) - m_timer.fireOnce(false); - m_timer.start(); - } - } - + if (!m_timer.isTiming() && (m_rc_auto_hide && !isHidden()) || + (m_rc_auto_raise && m_layeritem->getLayerNum() != m_rc_layernum->getNum())) + m_timer.start(); } - void Slit::configureRequestEvent(XConfigureRequestEvent &event) { bool reconf = false; XWindowChanges xwc; @@ -1050,16 +1052,6 @@ void Slit::clearWindow() { } void Slit::toggleHidden() { - if (doAutoHide()) { - if (!m_slitmenu.isVisible()) { - m_timer.fireOnce(true); - } else { - return; - } - //} else if (!isHidden()) { - // return; - } - m_hidden = ! m_hidden; // toggle hidden state if (isHidden()) frame.window.move(frame.x_hidden, frame.y_hidden); diff --git a/src/Slit.hh b/src/Slit.hh index 0b476b5..d882309 100644 --- a/src/Slit.hh +++ b/src/Slit.hh @@ -134,6 +134,7 @@ private: void screenSizeChanged(BScreen &screen); void updateAlpha(); + void updateCrossingState(); void clearWindow(); void setupMenu(); diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 23a8244..2920925 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -250,8 +250,8 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::Layer &layer, size_t width): // setup hide timer m_hide_timer.setTimeout(Fluxbox::instance()->getAutoRaiseDelay() * FbTk::FbTime::IN_MILLISECONDS); - FbTk::RefCount > toggle_hidden(new FbTk::SimpleCommand(*this, &Toolbar::toggleHidden)); - m_hide_timer.setCommand(toggle_hidden); + FbTk::RefCount > ucs(new FbTk::SimpleCommand(*this, &Toolbar::updateCrossingState)); + m_hide_timer.setCommand(ucs); m_hide_timer.fireOnce(true); @@ -523,55 +523,49 @@ void Toolbar::buttonPressEvent(XButtonEvent &be) { .placeAndShowMenu(menu(), be.x_root, be.y_root, false); } -void Toolbar::enterNotifyEvent(XCrossingEvent &ce) { - if (m_rc_auto_raise) - m_layeritem.moveToLayer(ResourceLayer::ABOVE_DOCK); - - Fluxbox::instance()->keys()->doAction(ce.type, ce.state, 0, - Keys::ON_TOOLBAR); - - if (! doAutoHide()) { - if (isHidden()) +void Toolbar::updateCrossingState() { + Window wr, wc; + int rx, ry, x, y; + unsigned int mask; + const int bw = -theme()->border().width(); + bool hovered = false; + if (XQueryPointer(Fluxbox::instance()->display(), window().window(), &wr, &wc, &rx, &ry, &x, &y, &mask)) + hovered = x >= bw && y >= bw && x < int(width()) && y < int(height()); + if (hovered) { + if (m_rc_auto_raise) + m_layeritem.moveToLayer(ResourceLayer::ABOVE_DOCK); + if (m_rc_auto_hide && isHidden()) toggleHidden(); - return; - } - - if (isHidden()) { - if (! m_hide_timer.isTiming()) - m_hide_timer.start(); } else { - if (m_hide_timer.isTiming()) - m_hide_timer.stop(); + if (m_rc_auto_hide && !isHidden()) + toggleHidden(); + if (m_rc_auto_raise) + m_layeritem.moveToLayer(m_rc_layernum->getNum()); } } -void Toolbar::leaveNotifyEvent(XCrossingEvent &event) { +void Toolbar::enterNotifyEvent(XCrossingEvent &ce) { + Fluxbox::instance()->keys()->doAction(ce.type, ce.state, 0, Keys::ON_TOOLBAR); - // in autoHide mode we'll receive a leaveNotifyEvent when activating - // the toolbar. so check if we are still inside the toolbar area. - // event.subwindow gets != None if we really left the window (eg the Slit - // was entered ontop of the toolbar) - if (event.x_root > x() && event.x_root <= (int)(x() + width()) && - event.y_root > y() && event.y_root <= (int)(y() + height()) && - event.subwindow == None ) { - return; + if (!m_rc_auto_hide && isHidden()) { + toggleHidden(); } - if (m_rc_auto_raise) - m_layeritem.moveToLayer(m_rc_layernum->getNum()); + if ((m_rc_auto_hide || m_rc_auto_raise) && !m_hide_timer.isTiming()) + m_hide_timer.start(); +} - Fluxbox::instance()->keys()->doAction(event.type, event.state, 0, - Keys::ON_TOOLBAR); +void Toolbar::leaveNotifyEvent(XCrossingEvent &event) { - if (! doAutoHide()) + if (menu().isVisible()) return; - if (isHidden()) { - if (m_hide_timer.isTiming()) - m_hide_timer.stop(); - } else if (! menu().isVisible() && ! m_hide_timer.isTiming()) + if (!m_hide_timer.isTiming() && (m_rc_auto_hide && !isHidden()) || + (m_rc_auto_raise && m_layeritem.getLayerNum() != m_rc_layernum->getNum())) m_hide_timer.start(); + if (!isHidden()) + Fluxbox::instance()->keys()->doAction(event.type, event.state, 0, Keys::ON_TOOLBAR); } diff --git a/src/Toolbar.hh b/src/Toolbar.hh index 47569f6..c31a85f 100644 --- a/src/Toolbar.hh +++ b/src/Toolbar.hh @@ -143,6 +143,8 @@ private: void updateStrut(); void updateAlpha(); + void updateCrossingState(); + /// Called when the screen changed property. void screenChanged(BScreen &screen); -- cgit v0.11.2