Changeset View
Changeset View
Standalone View
Standalone View
input.cpp
Show First 20 Lines • Show All 1454 Lines • ▼ Show 20 Line(s) | |||||
1455 | class DragAndDropInputFilter : public InputEventFilter | 1455 | class DragAndDropInputFilter : public InputEventFilter | ||
1456 | { | 1456 | { | ||
1457 | public: | 1457 | public: | ||
1458 | bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override { | 1458 | bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override { | ||
1459 | auto seat = waylandServer()->seat(); | 1459 | auto seat = waylandServer()->seat(); | ||
1460 | if (!seat->isDragPointer()) { | 1460 | if (!seat->isDragPointer()) { | ||
1461 | return false; | 1461 | return false; | ||
1462 | } | 1462 | } | ||
1463 | if (seat->isDragTouch()) { | ||||
1464 | return true; | ||||
1465 | } | ||||
1463 | seat->setTimestamp(event->timestamp()); | 1466 | seat->setTimestamp(event->timestamp()); | ||
1464 | switch (event->type()) { | 1467 | switch (event->type()) { | ||
1465 | case QEvent::MouseMove: { | 1468 | case QEvent::MouseMove: { | ||
1466 | const auto pos = input()->globalPointer(); | 1469 | const auto pos = input()->globalPointer(); | ||
1467 | seat->setPointerPos(pos); | 1470 | seat->setPointerPos(pos); | ||
1468 | if (Toplevel *t = input()->pointer()->at()) { | 1471 | if (Toplevel *t = input()->pointer()->at()) { | ||
1469 | // TODO: consider decorations | 1472 | // TODO: consider decorations | ||
1470 | if (t->surface() != seat->dragSurface()) { | 1473 | if (t->surface() != seat->dragSurface()) { | ||
Show All 15 Lines | 1488 | case QEvent::MouseButtonRelease: | |||
1486 | seat->pointerButtonReleased(nativeButton); | 1489 | seat->pointerButtonReleased(nativeButton); | ||
1487 | break; | 1490 | break; | ||
1488 | default: | 1491 | default: | ||
1489 | break; | 1492 | break; | ||
1490 | } | 1493 | } | ||
1491 | // TODO: should we pass through effects? | 1494 | // TODO: should we pass through effects? | ||
1492 | return true; | 1495 | return true; | ||
1493 | } | 1496 | } | ||
1497 | | ||||
1498 | bool touchDown(quint32 id, const QPointF &pos, quint32 time) override { | ||||
1499 | auto seat = waylandServer()->seat(); | ||||
1500 | if (seat->isDragPointer()) { | ||||
1501 | return true; | ||||
1502 | } | ||||
1503 | if (!seat->isDragTouch()) { | ||||
1504 | return false; | ||||
1505 | } | ||||
1506 | if (m_touchId != id) { | ||||
1507 | return true; | ||||
1508 | } | ||||
1509 | seat->setTimestamp(time); | ||||
1510 | input()->touch()->insertId(id, seat->touchDown(pos)); | ||||
1511 | return true; | ||||
1512 | } | ||||
1513 | bool touchMotion(quint32 id, const QPointF &pos, quint32 time) override { | ||||
1514 | auto seat = waylandServer()->seat(); | ||||
1515 | if (seat->isDragPointer()) { | ||||
1516 | return true; | ||||
1517 | } | ||||
1518 | if (!seat->isDragTouch()) { | ||||
1519 | return false; | ||||
1520 | } | ||||
1521 | if (m_touchId < 0) { | ||||
davidedmundson: So we base the ID of the touch performing the drag based on the first movement after a client… | |||||
Isn't that what the comment below is about? Where do you see a problem in regards to safety? The ID is only used to specify the drag performing touch point while the touch sequence is ongoing. romangg: Isn't that what the comment below is about? Where do you see a problem in regards to safety? | |||||
one could press two fingers, one starts a drag then they move the second davidedmundson: one could press two fingers, one starts a drag then they move the second | |||||
And where do you see a problem in regards to safety? The comment below indicates that this is a corner case I deemed not to be important in this first implementation of touch drag and to be looked into later. So is there a safety issue, which would then of course make it important? As it is now it would just use in this unlikely event the other touch point as "anchor" of the drag. romangg: And where do you see a problem in regards to safety? The comment below indicates that this is a… | |||||
1522 | // We take for now the first id appearing as a move after a drag | ||||
1523 | // started. We can optimize by specifying the id the drag is | ||||
1524 | // associated with by implementing a key-value getter in KWayland. | ||||
1525 | m_touchId = id; | ||||
1526 | } | ||||
1527 | if (m_touchId != id) { | ||||
1528 | return true; | ||||
1529 | } | ||||
1530 | seat->setTimestamp(time); | ||||
1531 | const qint32 kwaylandId = input()->touch()->mappedId(id); | ||||
1532 | if (kwaylandId == -1) { | ||||
1533 | return true; | ||||
1534 | } | ||||
1535 | | ||||
1536 | seat->touchMove(kwaylandId, pos); | ||||
davidedmundson: should this come after we activate the client? | |||||
I have either argument for or against it. I tested it this way and it worked. romangg: I have either argument for or against it. I tested it this way and it worked. | |||||
1537 | | ||||
1538 | if (Toplevel *t = input()->findToplevel(pos.toPoint())) { | ||||
1539 | // TODO: consider decorations | ||||
1540 | if (t->surface() != seat->dragSurface()) { | ||||
1541 | if (AbstractClient *c = qobject_cast<AbstractClient*>(t)) { | ||||
1542 | workspace()->activateClient(c); | ||||
1543 | } | ||||
1544 | seat->setDragTarget(t->surface(), pos, t->inputTransformation()); | ||||
1545 | } | ||||
1546 | } else { | ||||
1547 | // no window at that place, if we have a surface we need to reset | ||||
1548 | seat->setDragTarget(nullptr); | ||||
1549 | } | ||||
1550 | return true; | ||||
1551 | } | ||||
1552 | bool touchUp(quint32 id, quint32 time) override { | ||||
1553 | auto seat = waylandServer()->seat(); | ||||
1554 | if (!seat->isDragTouch()) { | ||||
1555 | return false; | ||||
1556 | } | ||||
1557 | seat->setTimestamp(time); | ||||
1558 | const qint32 kwaylandId = input()->touch()->mappedId(id); | ||||
1559 | if (kwaylandId != -1) { | ||||
1560 | seat->touchUp(kwaylandId); | ||||
1561 | input()->touch()->removeId(id); | ||||
1562 | } | ||||
1563 | if (m_touchId == id) { | ||||
1564 | m_touchId = -1; | ||||
1565 | } | ||||
1566 | return true; | ||||
1567 | } | ||||
1568 | private: | ||||
1569 | qint32 m_touchId = -1; | ||||
1494 | }; | 1570 | }; | ||
1495 | 1571 | | |||
1496 | KWIN_SINGLETON_FACTORY(InputRedirection) | 1572 | KWIN_SINGLETON_FACTORY(InputRedirection) | ||
1497 | 1573 | | |||
1498 | static const QString s_touchpadComponent = QStringLiteral("kcm_touchpad"); | 1574 | static const QString s_touchpadComponent = QStringLiteral("kcm_touchpad"); | ||
1499 | 1575 | | |||
1500 | InputRedirection::InputRedirection(QObject *parent) | 1576 | InputRedirection::InputRedirection(QObject *parent) | ||
1501 | : QObject(parent) | 1577 | : QObject(parent) | ||
▲ Show 20 Lines • Show All 765 Lines • Show Last 20 Lines |
So we base the ID of the touch performing the drag based on the first movement after a client creates a grab.
Is that safe?
We know the serial in dragStarted can we take the touch ID from d->globalTouch.ids.key(serial) and then expose that in SeatInterface?