[kicker] Cache position of hover enter events before replaying

The triangle mouse blocks events that happen within a given region and
conditions, then replays those events when those conditions get broken.

If we intercept an enter event, we capture that under
m_interceptedHoverItem so that if conditions change we can replay that
hover enter event before we then start sending move events.

Currently we replay that hover event using the current mouse position.
This causes an issue for kickoff that has additional code to look for
actual move events in order to avoid selecting the current item on
scroll. Both codepaths are correct standalone, but together form a bug.

This patch caches the relative position of a HoverEnter event. Should we
replay the enter event, we do so with the position of the enter. We then
can replay a HoverMove to get the up-to-date location.

BUG: 447278
wilder-5.24
David Edmundson 4 years ago
parent 594b933a1e
commit 6f809058a6
  1. 10
      applets/kicker/plugin/trianglemousefilter.cpp
  2. 5
      applets/kicker/plugin/trianglemousefilter.h

@ -19,8 +19,14 @@ TriangleMouseFilter::TriangleMouseFilter(QQuickItem *parent)
if (!m_interceptedHoverItem) {
return;
}
if (m_interceptedHoverEnterPosition) {
const auto targetPosition = mapToItem(m_interceptedHoverItem, m_interceptedHoverEnterPosition.value());
QHoverEvent e(QEvent::HoverEnter, targetPosition, targetPosition);
qApp->sendEvent(m_interceptedHoverItem, &e);
m_interceptedHoverEnterPosition.reset();
}
const auto targetPosition = mapToItem(m_interceptedHoverItem, m_lastCursorPosition);
QHoverEvent e(QEvent::HoverEnter, targetPosition, targetPosition);
QHoverEvent e(QEvent::HoverMove, targetPosition, targetPosition);
qApp->sendEvent(m_interceptedHoverItem, &e);
});
};
@ -45,6 +51,7 @@ bool TriangleMouseFilter::childMouseEventFilter(QQuickItem *item, QEvent *event)
if (filterContains(position)) {
if (event->type() == QEvent::HoverEnter) {
m_interceptedHoverEnterPosition = position;
m_interceptedHoverItem = item;
}
@ -62,6 +69,7 @@ bool TriangleMouseFilter::childMouseEventFilter(QQuickItem *item, QEvent *event)
// if using this in a more general setting we might want to make this guarded by an option
if (event->type() == QEvent::HoverEnter && !m_interceptionPos) {
m_interceptedHoverItem = item;
m_interceptedHoverEnterPosition = position;
if (m_filterTimeout > 0) {
m_resetTimer.start(m_filterTimeout);
}

@ -60,9 +60,10 @@ protected:
private:
bool filterContains(const QPointF &p) const;
QTimer m_resetTimer;
std::optional<QPointF> m_interceptionPos;
std::optional<QPointF> m_interceptionPos; // point where we started intercepting
QPointF m_lastCursorPosition;
QPointer<QQuickItem> m_interceptedHoverItem;
QPointer<QQuickItem> m_interceptedHoverItem; // item newly entered but the enter event was intercepted
std::optional<QPointF> m_interceptedHoverEnterPosition; // position of intercepted enter events
Qt::Edge m_edge = Qt::RightEdge;
int m_filterTimeout = 300;
};

Loading…
Cancel
Save