diff --git a/autotests/decorationbuttontest.cpp b/autotests/decorationbuttontest.cpp --- a/autotests/decorationbuttontest.cpp +++ b/autotests/decorationbuttontest.cpp @@ -60,6 +60,8 @@ void testMenuDoubleClick(); void testMenuPressAndHold(); void testApplicationMenu(); + void testContains_data(); + void testContains(); }; void DecorationButtonTest::testButton() @@ -1342,5 +1344,36 @@ QCOMPARE(pressedChangedSpy.last().first().toBool(), false); } +void DecorationButtonTest::testContains_data() +{ + QTest::addColumn("pos"); + QTest::addColumn("contains"); + + // Button geometry: QRectF(0, 0, 10, 10). + QTest::newRow("on left edge") << QPointF(0, 5) << true; + QTest::newRow("on top edge") << QPointF(5, 0) << true; + QTest::newRow("on right edge") << QPointF(9, 5) << true; + QTest::newRow("on bottom edge") << QPointF(5, 9) << true; + QTest::newRow("inside") << QPointF(5, 5) << true; + QTest::newRow("outside 1") << QPointF(-1, 5) << false; + QTest::newRow("outside 2") << QPointF(5, -1) << false; + QTest::newRow("outside 3") << QPointF(10, 5) << false; + QTest::newRow("outside 4") << QPointF(5, 10) << false; +} + +void DecorationButtonTest::testContains() +{ + MockBridge bridge; + MockDecoration mockDecoration(&bridge); + + MockButton button(KDecoration2::DecorationButtonType::Custom, &mockDecoration); + button.setGeometry(QRectF(0, 0, 10, 10)); + button.setEnabled(true); + button.setVisible(true); + + QFETCH(QPointF, pos); + QTEST(button.contains(pos), "contains"); +} + QTEST_MAIN(DecorationButtonTest) #include "decorationbuttontest.moc" diff --git a/src/decoration.cpp b/src/decoration.cpp --- a/src/decoration.cpp +++ b/src/decoration.cpp @@ -330,7 +330,7 @@ continue; } const bool hovered = button->isHovered(); - const bool contains = button->geometry().contains(event->pos()); + const bool contains = button->contains(event->posF()); if (!hovered && contains) { QHoverEvent e(QEvent::HoverEnter, event->posF(), event->oldPosF(), event->modifiers()); QCoreApplication::instance()->sendEvent(button, &e); @@ -383,7 +383,7 @@ void Decoration::wheelEvent(QWheelEvent *event) { for (DecorationButton *button : d->buttons) { - if (button->geometry().contains(event->posF())) { + if (button->contains(event->posF())) { QCoreApplication::instance()->sendEvent(button, event); event->setAccepted(true); } diff --git a/src/decorationbutton.h b/src/decorationbutton.h --- a/src/decorationbutton.h +++ b/src/decorationbutton.h @@ -113,6 +113,11 @@ bool isCheckable() const; DecorationButtonType type() const; + /** + * Returns @c true if @p pos is inside of the button, otherwise returns @c false. + **/ + bool contains(const QPointF &pos) const; + Qt::MouseButtons acceptedButtons() const; void setAcceptedButtons(Qt::MouseButtons buttons); diff --git a/src/decorationbutton.cpp b/src/decorationbutton.cpp --- a/src/decorationbutton.cpp +++ b/src/decorationbutton.cpp @@ -445,6 +445,11 @@ #undef DELEGATE +bool DecorationButton::contains(const QPointF &pos) const +{ + return d->geometry.toRect().contains(pos.toPoint()); +} + bool DecorationButton::event(QEvent *event) { switch (event->type()) { @@ -476,16 +481,16 @@ void DecorationButton::hoverEnterEvent(QHoverEvent *event) { - if (!d->enabled || !d->visible || !d->geometry.contains(event->posF())) { + if (!d->enabled || !d->visible || !contains(event->posF())) { return; } d->setHovered(true); event->setAccepted(true); } void DecorationButton::hoverLeaveEvent(QHoverEvent *event) { - if (!d->enabled || !d->visible || !d->hovered || d->geometry.contains(event->posF())) { + if (!d->enabled || !d->visible || !d->hovered || contains(event->posF())) { return; } d->setHovered(false); @@ -502,15 +507,15 @@ if (!d->enabled || !d->visible || !d->hovered) { return; } - if (!d->geometry.contains(event->localPos())) { + if (!contains(event->localPos())) { d->setHovered(false); event->setAccepted(true); } } void DecorationButton::mousePressEvent(QMouseEvent *event) { - if (!d->enabled || !d->visible || !d->geometry.contains(event->localPos()) || !d->acceptedButtons.testFlag(event->button())) { + if (!d->enabled || !d->visible || !contains(event->localPos()) || !d->acceptedButtons.testFlag(event->button())) { return; } d->setPressed(event->button(), true); @@ -533,7 +538,7 @@ if (!d->enabled || !d->visible || !d->isPressed(event->button())) { return; } - if (d->geometry.contains(event->localPos())) { + if (contains(event->localPos())) { if (!d->pressAndHold || event->button() != Qt::LeftButton) { emit clicked(event->button()); } else {