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.
This commit is contained in:
Thomas Lübking 2016-08-14 13:42:27 +02:00 committed by Mathias Gumz
parent fe8ff87292
commit 10a9574738
4 changed files with 70 additions and 81 deletions

View file

@ -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<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::buttonPressEvent(XButtonEvent &be) {
}
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::leaveNotifyEvent(XCrossingEvent &ev) {
if (m_rc_auto_raise)
m_layeritem->moveToLayer(m_rc_layernum->getNum());
if (! doAutoHide())
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();
}
void Slit::enterNotifyEvent(XCrossingEvent &ce) {
if (!m_rc_auto_hide && isHidden()) {
toggleHidden();
}
if (!m_timer.isTiming() && (m_rc_auto_hide && isHidden()) ||
(m_rc_auto_raise && m_layeritem->getLayerNum() != ResourceLayer::ABOVE_DOCK))
m_timer.start();
}
void Slit::leaveNotifyEvent(XCrossingEvent &event) {
if (m_slitmenu.isVisible())
return;
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 @@ 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);

View file

@ -134,6 +134,7 @@ private:
void screenSizeChanged(BScreen &screen);
void updateAlpha();
void updateCrossingState();
void clearWindow();
void setupMenu();

View file

@ -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<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 @@ 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;
} else {
if (m_rc_auto_hide && !isHidden())
toggleHidden();
if (m_rc_auto_raise)
m_layeritem.moveToLayer(m_rc_layernum->getNum());
}
}
void Toolbar::enterNotifyEvent(XCrossingEvent &ce) {
Fluxbox::instance()->keys()->doAction(ce.type, ce.state, 0, Keys::ON_TOOLBAR);
if (!m_rc_auto_hide && isHidden()) {
toggleHidden();
}
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 || m_rc_auto_raise) && !m_hide_timer.isTiming())
m_hide_timer.start();
}
void Toolbar::leaveNotifyEvent(XCrossingEvent &event) {
// 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_raise)
m_layeritem.moveToLayer(m_rc_layernum->getNum());
Fluxbox::instance()->keys()->doAction(event.type, event.state, 0,
Keys::ON_TOOLBAR);
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);
}

View file

@ -143,6 +143,8 @@ private:
void updateStrut();
void updateAlpha();
void updateCrossingState();
/// Called when the screen changed property.
void screenChanged(BScreen &screen);