wayland: Adjust kwin to PointerInterface changes

This commit is contained in:
Vlad Zahorodnii 2021-02-22 12:51:26 +02:00
parent c812ffbe1d
commit 83388295c8
5 changed files with 83 additions and 62 deletions

View file

@ -341,7 +341,8 @@ void PointerInputTest::testUpdateFocusAfterScreenChange()
AbstractClient *window = workspace()->activeClient(); AbstractClient *window = workspace()->activeClient();
QVERIFY(window); QVERIFY(window);
QVERIFY(window->frameGeometry().contains(Cursors::self()->mouse()->pos())); QVERIFY(window->frameGeometry().contains(Cursors::self()->mouse()->pos()));
QTRY_COMPARE(enteredSpy.count(), 1); QVERIFY(enteredSpy.wait());
QCOMPARE(enteredSpy.count(), 1);
// move the cursor to the second screen // move the cursor to the second screen
Cursors::self()->mouse()->setPos(1500, 300); Cursors::self()->mouse()->setPos(1500, 300);
@ -363,7 +364,8 @@ void PointerInputTest::testUpdateFocusAfterScreenChange()
QVERIFY(window->frameGeometry().contains(Cursors::self()->mouse()->pos())); QVERIFY(window->frameGeometry().contains(Cursors::self()->mouse()->pos()));
// and we should get an enter event // and we should get an enter event
QTRY_COMPARE(enteredSpy.count(), 2); QVERIFY(enteredSpy.wait());
QCOMPARE(enteredSpy.count(), 2);
} }
void PointerInputTest::testModifierClickUnrestrictedMove_data() void PointerInputTest::testModifierClickUnrestrictedMove_data()

View file

@ -181,7 +181,6 @@ void XWaylandInputTest::testPointerEnterLeaveSsd()
QVERIFY(enteredSpy.isEmpty()); QVERIFY(enteredSpy.isEmpty());
Cursors::self()->mouse()->setPos(client->frameGeometry().center()); Cursors::self()->mouse()->setPos(client->frameGeometry().center());
QCOMPARE(waylandServer()->seat()->focusedPointerSurface(), client->surface()); QCOMPARE(waylandServer()->seat()->focusedPointerSurface(), client->surface());
QVERIFY(waylandServer()->seat()->focusedPointer());
QVERIFY(enteredSpy.wait()); QVERIFY(enteredSpy.wait());
QCOMPARE(enteredSpy.last().first(), client->frameGeometry().center() - client->clientPos()); QCOMPARE(enteredSpy.last().first(), client->frameGeometry().center() - client->clientPos());
@ -277,7 +276,6 @@ void XWaylandInputTest::testPointerEventLeaveCsd()
QVERIFY(enteredSpy.isEmpty()); QVERIFY(enteredSpy.isEmpty());
Cursors::self()->mouse()->setPos(client->frameGeometry().center()); Cursors::self()->mouse()->setPos(client->frameGeometry().center());
QCOMPARE(waylandServer()->seat()->focusedPointerSurface(), client->surface()); QCOMPARE(waylandServer()->seat()->focusedPointerSurface(), client->surface());
QVERIFY(waylandServer()->seat()->focusedPointer());
QVERIFY(enteredSpy.wait()); QVERIFY(enteredSpy.wait());
QCOMPARE(enteredSpy.last().first(), QPoint(59, 104)); QCOMPARE(enteredSpy.last().first(), QPoint(59, 104));

View file

@ -58,6 +58,23 @@
namespace KWin namespace KWin
{ {
static KWaylandServer::PointerAxisSource kwinAxisSourceToKWaylandAxisSource(InputRedirection::PointerAxisSource source)
{
switch (source) {
case KWin::InputRedirection::PointerAxisSourceWheel:
return KWaylandServer::PointerAxisSource::Wheel;
case KWin::InputRedirection::PointerAxisSourceFinger:
return KWaylandServer::PointerAxisSource::Finger;
case KWin::InputRedirection::PointerAxisSourceContinuous:
return KWaylandServer::PointerAxisSource::Continuous;
case KWin::InputRedirection::PointerAxisSourceWheelTilt:
return KWaylandServer::PointerAxisSource::WheelTilt;
case KWin::InputRedirection::PointerAxisSourceUnknown:
default:
return KWaylandServer::PointerAxisSource::Unknown;
}
}
InputEventFilter::InputEventFilter() = default; InputEventFilter::InputEventFilter() = default;
InputEventFilter::~InputEventFilter() InputEventFilter::~InputEventFilter()
@ -268,12 +285,18 @@ public:
if (pointerSurfaceAllowed()) { if (pointerSurfaceAllowed()) {
// TODO: should the pointer position always stay in sync, i.e. not do the check? // TODO: should the pointer position always stay in sync, i.e. not do the check?
seat->setPointerPos(event->screenPos().toPoint()); seat->setPointerPos(event->screenPos().toPoint());
seat->pointerFrame();
} }
} else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) { } else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) {
if (pointerSurfaceAllowed()) { if (pointerSurfaceAllowed()) {
// TODO: can we leak presses/releases here when we move the mouse in between from an allowed surface to // TODO: can we leak presses/releases here when we move the mouse in between from an allowed surface to
// disallowed one or vice versa? // disallowed one or vice versa?
event->type() == QEvent::MouseButtonPress ? seat->pointerButtonPressed(nativeButton) : seat->pointerButtonReleased(nativeButton); if (event->type() == QEvent::MouseButtonPress) {
seat->pointerButtonPressed(nativeButton);
} else {
seat->pointerButtonReleased(nativeButton);
}
seat->pointerFrame();
} }
} }
return true; return true;
@ -284,9 +307,11 @@ public:
} }
auto seat = waylandServer()->seat(); auto seat = waylandServer()->seat();
if (pointerSurfaceAllowed()) { if (pointerSurfaceAllowed()) {
seat->setTimestamp(event->timestamp()); const WheelEvent *wheelEvent = static_cast<WheelEvent *>(event);
const Qt::Orientation orientation = event->angleDelta().x() == 0 ? Qt::Vertical : Qt::Horizontal; seat->setTimestamp(wheelEvent->timestamp());
seat->pointerAxis(orientation, orientation == Qt::Horizontal ? event->angleDelta().x() : event->angleDelta().y()); seat->pointerAxis(wheelEvent->orientation(), wheelEvent->delta(), wheelEvent->discreteDelta(),
kwinAxisSourceToKWaylandAxisSource(wheelEvent->axisSource()));
seat->pointerFrame();
} }
return true; return true;
} }
@ -1378,13 +1403,16 @@ public:
if (e->delta() != QSizeF()) { if (e->delta() != QSizeF()) {
seat->relativePointerMotion(e->delta(), e->deltaUnaccelerated(), e->timestampMicroseconds()); seat->relativePointerMotion(e->delta(), e->deltaUnaccelerated(), e->timestampMicroseconds());
} }
seat->pointerFrame();
break; break;
} }
case QEvent::MouseButtonPress: case QEvent::MouseButtonPress:
seat->pointerButtonPressed(nativeButton); seat->pointerButtonPressed(nativeButton);
seat->pointerFrame();
break; break;
case QEvent::MouseButtonRelease: case QEvent::MouseButtonRelease:
seat->pointerButtonReleased(nativeButton); seat->pointerButtonReleased(nativeButton);
seat->pointerFrame();
break; break;
default: default:
break; break;
@ -1395,26 +1423,9 @@ public:
auto seat = waylandServer()->seat(); auto seat = waylandServer()->seat();
seat->setTimestamp(event->timestamp()); seat->setTimestamp(event->timestamp());
auto _event = static_cast<WheelEvent *>(event); auto _event = static_cast<WheelEvent *>(event);
KWaylandServer::PointerAxisSource source; seat->pointerAxis(_event->orientation(), _event->delta(), _event->discreteDelta(),
switch (_event->axisSource()) { kwinAxisSourceToKWaylandAxisSource(_event->axisSource()));
case KWin::InputRedirection::PointerAxisSourceWheel: seat->pointerFrame();
source = KWaylandServer::PointerAxisSource::Wheel;
break;
case KWin::InputRedirection::PointerAxisSourceFinger:
source = KWaylandServer::PointerAxisSource::Finger;
break;
case KWin::InputRedirection::PointerAxisSourceContinuous:
source = KWaylandServer::PointerAxisSource::Continuous;
break;
case KWin::InputRedirection::PointerAxisSourceWheelTilt:
source = KWaylandServer::PointerAxisSource::WheelTilt;
break;
case KWin::InputRedirection::PointerAxisSourceUnknown:
default:
source = KWaylandServer::PointerAxisSource::Unknown;
break;
}
seat->pointerAxisV5(_event->orientation(), _event->delta(), _event->discreteDelta(), source);
return true; return true;
} }
bool keyEvent(QKeyEvent *event) override { bool keyEvent(QKeyEvent *event) override {
@ -1880,6 +1891,7 @@ public:
case QEvent::MouseMove: { case QEvent::MouseMove: {
const auto pos = input()->globalPointer(); const auto pos = input()->globalPointer();
seat->setPointerPos(pos); seat->setPointerPos(pos);
seat->pointerFrame();
const auto eventPos = event->globalPos(); const auto eventPos = event->globalPos();
// TODO: use InputDeviceHandler::at() here and check isClient()? // TODO: use InputDeviceHandler::at() here and check isClient()?
@ -1909,9 +1921,11 @@ public:
} }
case QEvent::MouseButtonPress: case QEvent::MouseButtonPress:
seat->pointerButtonPressed(nativeButton); seat->pointerButtonPressed(nativeButton);
seat->pointerFrame();
break; break;
case QEvent::MouseButtonRelease: case QEvent::MouseButtonRelease:
seat->pointerButtonReleased(nativeButton); seat->pointerButtonReleased(nativeButton);
seat->pointerFrame();
break; break;
default: default:
break; break;

View file

@ -929,7 +929,8 @@ CursorImage::CursorImage(PointerInputRedirection *parent)
: QObject(parent) : QObject(parent)
, m_pointer(parent) , m_pointer(parent)
{ {
connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::focusedPointerChanged, this, &CursorImage::update); connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::hasPointerChanged,
this, &CursorImage::handlePointerChanged);
connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::dragStarted, this, &CursorImage::updateDrag); connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::dragStarted, this, &CursorImage::updateDrag);
connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::dragEnded, this, connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::dragEnded, this,
[this] { [this] {
@ -959,6 +960,8 @@ CursorImage::CursorImage(PointerInputRedirection *parent)
updateMoveResize(); updateMoveResize();
// TODO: update effects // TODO: update effects
}); });
handlePointerChanged();
} }
CursorImage::~CursorImage() = default; CursorImage::~CursorImage() = default;
@ -972,25 +975,13 @@ void CursorImage::markAsRendered()
icon->surface()->frameRendered(m_surfaceRenderedTimer.elapsed()); icon->surface()->frameRendered(m_surfaceRenderedTimer.elapsed());
} }
} }
auto p = waylandServer()->seat()->dragPointer(); }
if (!p) { if (m_currentSource != CursorSource::LockScreen
return; && m_currentSource != CursorSource::PointerSurface
} && m_currentSource != CursorSource::DragAndDrop) {
auto c = p->cursor();
if (!c) {
return;
}
auto cursorSurface = c->surface();
if (cursorSurface.isNull()) {
return;
}
cursorSurface->frameRendered(m_surfaceRenderedTimer.elapsed());
return; return;
} }
if (m_currentSource != CursorSource::LockScreen && m_currentSource != CursorSource::PointerSurface) { auto p = waylandServer()->seat()->pointer();
return;
}
auto p = waylandServer()->seat()->focusedPointer();
if (!p) { if (!p) {
return; return;
} }
@ -999,22 +990,34 @@ void CursorImage::markAsRendered()
return; return;
} }
auto cursorSurface = c->surface(); auto cursorSurface = c->surface();
if (cursorSurface.isNull()) { if (!cursorSurface) {
return; return;
} }
cursorSurface->frameRendered(m_surfaceRenderedTimer.elapsed()); cursorSurface->frameRendered(m_surfaceRenderedTimer.elapsed());
} }
void CursorImage::update() void CursorImage::handlePointerChanged()
{
KWaylandServer::PointerInterface *pointer = waylandServer()->seat()->pointer();
if (pointer) {
connect(pointer, &KWaylandServer::PointerInterface::focusedSurfaceChanged,
this, &CursorImage::handleFocusedSurfaceChanged);
}
}
void CursorImage::handleFocusedSurfaceChanged()
{ {
if (s_cursorUpdateBlocking) { if (s_cursorUpdateBlocking) {
return; return;
} }
using namespace KWaylandServer;
KWaylandServer::PointerInterface *pointer = waylandServer()->seat()->pointer();
disconnect(m_serverCursor.connection); disconnect(m_serverCursor.connection);
auto p = waylandServer()->seat()->focusedPointer();
if (p) { if (pointer->focusedSurface()) {
m_serverCursor.connection = connect(p, &PointerInterface::cursorChanged, this, &CursorImage::updateServerCursor); m_serverCursor.connection = connect(pointer, &KWaylandServer::PointerInterface::cursorChanged,
this, &CursorImage::updateServerCursor);
} else { } else {
m_serverCursor.connection = QMetaObject::Connection(); m_serverCursor.connection = QMetaObject::Connection();
reevaluteSource(); reevaluteSource();
@ -1064,7 +1067,7 @@ void CursorImage::updateServerCursor()
m_serverCursor.cursor = {}; m_serverCursor.cursor = {};
reevaluteSource(); reevaluteSource();
const bool needsEmit = m_currentSource == CursorSource::LockScreen || m_currentSource == CursorSource::PointerSurface; const bool needsEmit = m_currentSource == CursorSource::LockScreen || m_currentSource == CursorSource::PointerSurface;
auto p = waylandServer()->seat()->focusedPointer(); auto p = waylandServer()->seat()->pointer();
if (!p) { if (!p) {
if (needsEmit) { if (needsEmit) {
emit changed(); emit changed();
@ -1079,13 +1082,13 @@ void CursorImage::updateServerCursor()
return; return;
} }
auto cursorSurface = c->surface(); auto cursorSurface = c->surface();
if (cursorSurface.isNull()) { if (!cursorSurface) {
if (needsEmit) { if (needsEmit) {
emit changed(); emit changed();
} }
return; return;
} }
auto buffer = cursorSurface.data()->buffer(); auto buffer = cursorSurface->buffer();
if (!buffer) { if (!buffer) {
if (needsEmit) { if (needsEmit) {
emit changed(); emit changed();
@ -1138,8 +1141,9 @@ void CursorImage::updateDrag()
disconnect(m_drag.connection); disconnect(m_drag.connection);
m_drag.cursor = {}; m_drag.cursor = {};
reevaluteSource(); reevaluteSource();
if (auto p = waylandServer()->seat()->dragPointer()) { if (waylandServer()->seat()->isDragPointer()) {
m_drag.connection = connect(p, &PointerInterface::cursorChanged, this, &CursorImage::updateDragCursor); KWaylandServer::PointerInterface *pointer = waylandServer()->seat()->pointer();
m_drag.connection = connect(pointer, &PointerInterface::cursorChanged, this, &CursorImage::updateDragCursor);
} else { } else {
m_drag.connection = QMetaObject::Connection(); m_drag.connection = QMetaObject::Connection();
} }
@ -1160,7 +1164,7 @@ void CursorImage::updateDragCursor()
} }
} }
} }
auto p = waylandServer()->seat()->dragPointer(); auto p = waylandServer()->seat()->pointer();
if (!p) { if (!p) {
if (needsEmit) { if (needsEmit) {
emit changed(); emit changed();
@ -1175,13 +1179,13 @@ void CursorImage::updateDragCursor()
return; return;
} }
auto cursorSurface = c->surface(); auto cursorSurface = c->surface();
if (cursorSurface.isNull()) { if (!cursorSurface) {
if (needsEmit) { if (needsEmit) {
emit changed(); emit changed();
} }
return; return;
} }
auto buffer = cursorSurface.data()->buffer(); auto buffer = cursorSurface->buffer();
if (!buffer) { if (!buffer) {
if (needsEmit) { if (needsEmit) {
emit changed(); emit changed();
@ -1345,7 +1349,8 @@ void CursorImage::reevaluteSource()
setSource(CursorSource::Decoration); setSource(CursorSource::Decoration);
return; return;
} }
if (m_pointer->focus() && waylandServer()->seat()->focusedPointer()) { const KWaylandServer::PointerInterface *pointer = waylandServer()->seat()->pointer();
if (pointer && pointer->focusedSurface()) {
setSource(CursorSource::PointerSurface); setSource(CursorSource::PointerSurface);
return; return;
} }

View file

@ -212,7 +212,6 @@ Q_SIGNALS:
private: private:
void reevaluteSource(); void reevaluteSource();
void update();
void updateServerCursor(); void updateServerCursor();
void updateDecoration(); void updateDecoration();
void updateDecorationCursor(); void updateDecorationCursor();
@ -220,6 +219,9 @@ private:
void updateDrag(); void updateDrag();
void updateDragCursor(); void updateDragCursor();
void handlePointerChanged();
void handleFocusedSurfaceChanged();
void loadThemeCursor(CursorShape shape, WaylandCursorImage::Image *image); void loadThemeCursor(CursorShape shape, WaylandCursorImage::Image *image);
void loadThemeCursor(const QByteArray &shape, WaylandCursorImage::Image *image); void loadThemeCursor(const QByteArray &shape, WaylandCursorImage::Image *image);