Fix start move through drag distance on window decoration

We need to call handleMoveResize on the mouse move with button down.

Auto tests adjusted to include all possible directions.
This commit is contained in:
Martin Gräßlin 2016-03-11 12:48:01 +01:00
parent 7777f0c507
commit 0b9e6a4aa2
5 changed files with 32 additions and 13 deletions

View file

@ -1379,9 +1379,10 @@ void AbstractClient::layoutDecorationRects(QRect &left, QRect &top, QRect &right
borderRight(), r.height() - top.height() - bottom.height()); borderRight(), r.height() - top.height() - bottom.height());
} }
void AbstractClient::processDecorationMove() void AbstractClient::processDecorationMove(const QPoint &localPos, const QPoint &globalPos)
{ {
if (isMoveResizePointerButtonDown()) { if (isMoveResizePointerButtonDown()) {
handleMoveResize(localPos.x(), localPos.y(), globalPos.x(), globalPos.y());
return; return;
} }
// TODO: handle modifiers // TODO: handle modifiers

View file

@ -523,7 +523,7 @@ public:
bool decorationHasAlpha() const; bool decorationHasAlpha() const;
void triggerDecorationRepaint(); void triggerDecorationRepaint();
virtual void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom) const; virtual void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom) const;
void processDecorationMove(); void processDecorationMove(const QPoint &localPos, const QPoint &globalPos);
bool processDecorationButtonPress(QMouseEvent *event, bool ignoreMenu = false); bool processDecorationButtonPress(QMouseEvent *event, bool ignoreMenu = false);
void processDecorationButtonRelease(QMouseEvent *event); void processDecorationButtonRelease(QMouseEvent *event);

View file

@ -58,6 +58,7 @@ private Q_SLOTS:
void testAxis(); void testAxis();
void testDoubleClick(); void testDoubleClick();
void testHover(); void testHover();
void testPressToMove_data();
void testPressToMove(); void testPressToMove();
private: private:
@ -325,46 +326,63 @@ void DecorationInputTest::testHover()
QCOMPARE(c->cursor(), Qt::ArrowCursor); QCOMPARE(c->cursor(), Qt::ArrowCursor);
} }
void DecorationInputTest::testPressToMove_data()
{
QTest::addColumn<QPoint>("offset");
QTest::addColumn<QPoint>("offset2");
QTest::addColumn<QPoint>("offset3");
QTest::newRow("To right") << QPoint(10, 0) << QPoint(20, 0) << QPoint(30, 0);
QTest::newRow("To left") << QPoint(-10, 0) << QPoint(-20, 0) << QPoint(-30, 0);
QTest::newRow("To bottom") << QPoint(0, 10) << QPoint(0, 20) << QPoint(0, 30);
QTest::newRow("To top") << QPoint(0, -10) << QPoint(0, -20) << QPoint(0, -30);
}
void DecorationInputTest::testPressToMove() void DecorationInputTest::testPressToMove()
{ {
AbstractClient *c = showWindow(); AbstractClient *c = showWindow();
QVERIFY(c); QVERIFY(c);
QVERIFY(c->isDecorated()); QVERIFY(c->isDecorated());
QVERIFY(!c->noBorder()); QVERIFY(!c->noBorder());
c->move(screens()->geometry(0).center() - QPoint(c->width()/2, c->height()/2));
QSignalSpy startMoveResizedSpy(c, &AbstractClient::clientStartUserMovedResized); QSignalSpy startMoveResizedSpy(c, &AbstractClient::clientStartUserMovedResized);
QVERIFY(startMoveResizedSpy.isValid()); QVERIFY(startMoveResizedSpy.isValid());
QSignalSpy clientFinishUserMovedResizedSpy(c, &AbstractClient::clientFinishUserMovedResized); QSignalSpy clientFinishUserMovedResizedSpy(c, &AbstractClient::clientFinishUserMovedResized);
QVERIFY(clientFinishUserMovedResizedSpy.isValid()); QVERIFY(clientFinishUserMovedResizedSpy.isValid());
quint32 timestamp = 1; quint32 timestamp = 1;
MOTION(QPoint(c->geometry().center().x(), c->clientPos().y() / 2)); MOTION(QPoint(c->geometry().center().x(), c->y() + c->clientPos().y() / 2));
QCOMPARE(c->cursor(), Qt::ArrowCursor); QCOMPARE(c->cursor(), Qt::ArrowCursor);
PRESS; PRESS;
QVERIFY(!c->isMove()); QVERIFY(!c->isMove());
MOTION(QPoint(c->geometry().center().x() + 10, c->clientPos().y() / 2)); QFETCH(QPoint, offset);
const int oldX = c->x(); MOTION(QPoint(c->geometry().center().x(), c->y() + c->clientPos().y() / 2) + offset);
QTRY_VERIFY(c->isMove()); const QPoint oldPos = c->pos();
QVERIFY(c->isMove());
QCOMPARE(startMoveResizedSpy.count(), 1); QCOMPARE(startMoveResizedSpy.count(), 1);
RELEASE; RELEASE;
QTRY_VERIFY(!c->isMove()); QTRY_VERIFY(!c->isMove());
QCOMPARE(clientFinishUserMovedResizedSpy.count(), 1); QCOMPARE(clientFinishUserMovedResizedSpy.count(), 1);
QEXPECT_FAIL("", "Just trigger move doesn't move the window", Continue); QEXPECT_FAIL("", "Just trigger move doesn't move the window", Continue);
QCOMPARE(c->x(), oldX + 10); QCOMPARE(c->pos(), oldPos + offset);
// again // again
PRESS; PRESS;
QVERIFY(!c->isMove()); QVERIFY(!c->isMove());
MOTION(QPoint(c->geometry().center().x() + 20, c->clientPos().y() / 2)); QFETCH(QPoint, offset2);
QTRY_VERIFY(c->isMove()); MOTION(QPoint(c->geometry().center().x(), c->y() + c->clientPos().y() / 2) + offset2);
QVERIFY(c->isMove());
QCOMPARE(startMoveResizedSpy.count(), 2); QCOMPARE(startMoveResizedSpy.count(), 2);
MOTION(QPoint(c->geometry().center().x() + 30, c->clientPos().y() / 2)); QFETCH(QPoint, offset3);
MOTION(QPoint(c->geometry().center().x(), c->y() + c->clientPos().y() / 2) + offset3);
RELEASE; RELEASE;
QTRY_VERIFY(!c->isMove()); QTRY_VERIFY(!c->isMove());
QCOMPARE(clientFinishUserMovedResizedSpy.count(), 2); QCOMPARE(clientFinishUserMovedResizedSpy.count(), 2);
QCOMPARE(c->x(), oldX + 20); // TODO: the offset should also be included
QCOMPARE(c->pos(), oldPos + offset2 + offset3);
} }
} }

View file

@ -432,7 +432,7 @@ public:
} }
QHoverEvent e(QEvent::HoverMove, p, p); QHoverEvent e(QEvent::HoverMove, p, p);
QCoreApplication::instance()->sendEvent(decoration->decoration(), &e); QCoreApplication::instance()->sendEvent(decoration->decoration(), &e);
decoration->client()->processDecorationMove(); decoration->client()->processDecorationMove(p.toPoint(), event->globalPos());
return true; return true;
} }
case QEvent::MouseButtonPress: case QEvent::MouseButtonPress:

View file

@ -396,7 +396,7 @@ void PointerInputRedirection::updateDecoration(Toplevel *t)
const QPointF p = m_pos - t->pos(); const QPointF p = m_pos - t->pos();
QHoverEvent event(QEvent::HoverMove, p, p); QHoverEvent event(QEvent::HoverMove, p, p);
QCoreApplication::instance()->sendEvent(m_decoration->decoration(), &event); QCoreApplication::instance()->sendEvent(m_decoration->decoration(), &event);
m_decoration->client()->processDecorationMove(); m_decoration->client()->processDecorationMove(p.toPoint(), m_pos.toPoint());
} }
} }