Send hoverLeave or hoverMotion after touch up on decoration
Summary: On touch down a first hover motion is sent to the decoration. Thus e.g. a button enters the hovered state. On touch release so far the decoration did not get a leave event resulting in the button still being hovered. This change ensures the leave event is sent or if the pointer is also on the decoration a motion to the pointer position is sent. BUG: 386231 FIXED-IN: 5.12.3 Test Plan: New test case and manual testing to verify that the maximize button is no longer hovered after touch down/up on it Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #plasma Differential Revision: https://phabricator.kde.org/D10308
This commit is contained in:
parent
5795fc8cc0
commit
911176a887
3 changed files with 88 additions and 1 deletions
|
@ -76,6 +76,8 @@ private Q_SLOTS:
|
|||
void testModifierClickUnrestrictedMove();
|
||||
void testModifierScrollOpacity_data();
|
||||
void testModifierScrollOpacity();
|
||||
void testTouchEvents_data();
|
||||
void testTouchEvents();
|
||||
|
||||
private:
|
||||
AbstractClient *showWindow(Test::ShellSurfaceType type);
|
||||
|
@ -757,6 +759,81 @@ void DecorationInputTest::testModifierScrollOpacity()
|
|||
}
|
||||
}
|
||||
|
||||
void DecorationInputTest::testTouchEvents_data()
|
||||
{
|
||||
QTest::addColumn<Test::ShellSurfaceType>("type");
|
||||
|
||||
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
|
||||
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
|
||||
QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
|
||||
}
|
||||
|
||||
class EventHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EventHelper() : QObject() {}
|
||||
~EventHelper() override = default;
|
||||
|
||||
bool eventFilter(QObject *watched, QEvent *event) override
|
||||
{
|
||||
Q_UNUSED(watched)
|
||||
if (event->type() == QEvent::HoverMove) {
|
||||
emit hoverMove();
|
||||
} else if (event->type() == QEvent::HoverLeave) {
|
||||
emit hoverLeave();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void hoverMove();
|
||||
void hoverLeave();
|
||||
};
|
||||
|
||||
void DecorationInputTest::testTouchEvents()
|
||||
{
|
||||
// this test verifies that the decoration gets a hover leave event on touch release
|
||||
// see BUG 386231
|
||||
QFETCH(Test::ShellSurfaceType, type);
|
||||
AbstractClient *c = showWindow(type);
|
||||
QVERIFY(c);
|
||||
QVERIFY(c->isDecorated());
|
||||
QVERIFY(!c->noBorder());
|
||||
|
||||
EventHelper helper;
|
||||
c->decoration()->installEventFilter(&helper);
|
||||
QSignalSpy hoverMoveSpy(&helper, &EventHelper::hoverMove);
|
||||
QVERIFY(hoverMoveSpy.isValid());
|
||||
QSignalSpy hoverLeaveSpy(&helper, &EventHelper::hoverLeave);
|
||||
QVERIFY(hoverLeaveSpy.isValid());
|
||||
|
||||
quint32 timestamp = 1;
|
||||
const QPoint tapPoint(c->geometry().center().x(), c->clientPos().y() / 2);
|
||||
|
||||
QVERIFY(!input()->touch()->decoration());
|
||||
kwinApp()->platform()->touchDown(0, tapPoint, timestamp++);
|
||||
QVERIFY(input()->touch()->decoration());
|
||||
QCOMPARE(input()->touch()->decoration()->decoration(), c->decoration());
|
||||
QCOMPARE(hoverMoveSpy.count(), 1);
|
||||
QCOMPARE(hoverLeaveSpy.count(), 0);
|
||||
kwinApp()->platform()->touchUp(0, timestamp++);
|
||||
QCOMPARE(hoverMoveSpy.count(), 1);
|
||||
QCOMPARE(hoverLeaveSpy.count(), 1);
|
||||
|
||||
QCOMPARE(c->isMove(), false);
|
||||
|
||||
// let's check that a hover motion is sent if the pointer is on deco, when touch release
|
||||
Cursor::setPos(tapPoint);
|
||||
QCOMPARE(hoverMoveSpy.count(), 2);
|
||||
kwinApp()->platform()->touchDown(0, tapPoint, timestamp++);
|
||||
QCOMPARE(hoverMoveSpy.count(), 3);
|
||||
QCOMPARE(hoverLeaveSpy.count(), 1);
|
||||
kwinApp()->platform()->touchUp(0, timestamp++);
|
||||
QCOMPARE(hoverMoveSpy.count(), 4);
|
||||
QCOMPARE(hoverLeaveSpy.count(), 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WAYLANDTEST_MAIN(KWin::DecorationInputTest)
|
||||
|
|
|
@ -560,7 +560,7 @@ void QuickTilingTest::testQuickTilingTouchMoveXdgShell()
|
|||
QCOMPARE(quickTileChangedSpy.count(), 1);
|
||||
QTEST(c->quickTileMode(), "expectedMode");
|
||||
QVERIFY(configureRequestedSpy.wait());
|
||||
QCOMPARE(configureRequestedSpy.count(), 5);
|
||||
QTRY_COMPARE(configureRequestedSpy.count(), 5);
|
||||
QCOMPARE(false, configureRequestedSpy.last().first().toSize().isEmpty());
|
||||
}
|
||||
|
||||
|
|
10
input.cpp
10
input.cpp
|
@ -1130,6 +1130,16 @@ public:
|
|||
e.setAccepted(false);
|
||||
QCoreApplication::sendEvent(decoration->decoration(), &e);
|
||||
decoration->client()->processDecorationButtonRelease(&e);
|
||||
if (input()->pointer()->decoration() == decoration) {
|
||||
// send motion to current pointer position
|
||||
const QPointF p = input()->pointer()->pos() - decoration->client()->pos();
|
||||
QHoverEvent event(QEvent::HoverMove, p, p);
|
||||
QCoreApplication::instance()->sendEvent(decoration->decoration(), &event);
|
||||
} else {
|
||||
// send leave
|
||||
QHoverEvent event(QEvent::HoverLeave, QPointF(), QPointF());
|
||||
QCoreApplication::instance()->sendEvent(decoration->decoration(), &event);
|
||||
}
|
||||
}
|
||||
|
||||
m_lastGlobalTouchPos = QPointF();
|
||||
|
|
Loading…
Reference in a new issue