all repos — fluxbox @ 10a957473803e87f119c363dc19efe92ea938a1d

custom fork of the fluxbox windowmanager

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.
Thomas Lübking thomas.luebking@gmail.com
commit

10a957473803e87f119c363dc19efe92ea938a1d

parent

fe8ff8729299a4fd4371394d3ca9102ece22fefb

4 files changed, 66 insertions(+), 77 deletions(-)

jump to
M src/Slit.ccsrc/Slit.cc

@@ -272,8 +272,8 @@ frame.window.move(-frame.window.width(), -frame.window.height());

// setup timer m_timer.setTimeout(200L * FbTk::FbTime::IN_MILLISECONDS); // default timeout m_timer.fireOnce(true); - FbTk::RefCount<FbTk::Command<void> > toggle_hidden(new FbTk::SimpleCommand<Slit>(*this, &Slit::toggleHidden)); - m_timer.setCommand(toggle_hidden); + FbTk::RefCount<FbTk::Command<void> > ucs(new FbTk::SimpleCommand<Slit>(*this, &Slit::updateCrossingState)); + m_timer.setCommand(ucs); FbTk::EventManager::instance()->add(*this, frame.window);

@@ -958,44 +958,46 @@ }

} -void Slit::enterNotifyEvent(XCrossingEvent &) { - if (m_rc_auto_raise) - m_layeritem->moveToLayer(ResourceLayer::ABOVE_DOCK); +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 (! doAutoHide()) - return; - - if (isHidden()) { - if (! m_timer.isTiming()) - m_timer.start(); + 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;

@@ -1050,16 +1052,6 @@ frame.window.clear();

} 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);
M src/Slit.hhsrc/Slit.hh

@@ -134,6 +134,7 @@ /// Called when screen has changed

void screenSizeChanged(BScreen &screen); void updateAlpha(); + void updateCrossingState(); void clearWindow(); void setupMenu();
M src/Toolbar.ccsrc/Toolbar.cc

@@ -250,8 +250,8 @@ frame.grab_x = frame.grab_y = 0;

// setup hide timer m_hide_timer.setTimeout(Fluxbox::instance()->getAutoRaiseDelay() * FbTk::FbTime::IN_MILLISECONDS); - FbTk::RefCount<FbTk::Command<void> > toggle_hidden(new FbTk::SimpleCommand<Toolbar>(*this, &Toolbar::toggleHidden)); - m_hide_timer.setCommand(toggle_hidden); + FbTk::RefCount<FbTk::Command<void> > ucs(new FbTk::SimpleCommand<Toolbar>(*this, &Toolbar::updateCrossingState)); + m_hide_timer.setCommand(ucs); m_hide_timer.fireOnce(true);

@@ -523,55 +523,49 @@ .placementStrategy()

.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); }
M src/Toolbar.hhsrc/Toolbar.hh

@@ -143,6 +143,8 @@ void clearStrut();

void updateStrut(); void updateAlpha(); + void updateCrossingState(); + /// Called when the screen changed property. void screenChanged(BScreen &screen);