diff options
-rw-r--r-- | src/client/qwaylandinputdevice.cpp | 34 | ||||
-rw-r--r-- | src/client/qwaylandinputdevice_p.h | 5 |
2 files changed, 36 insertions, 3 deletions
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index 3b26dc427..3f0d61d6a 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -143,6 +143,12 @@ QWaylandWindow *QWaylandInputDevice::Keyboard::focusWindow() const QWaylandInputDevice::Pointer::Pointer(QWaylandInputDevice *seat) : mParent(seat) { +#if QT_CONFIG(cursor) + mCursor.frameTimer.setSingleShot(true); + mCursor.frameTimer.callOnTimeout([&]() { + cursorTimerCallback(); + }); +#endif } QWaylandInputDevice::Pointer::~Pointer() @@ -224,7 +230,7 @@ public: if (animated) { m_frameCallback.reset(new WlCallback(frame(), [this](uint32_t time){ Q_UNUSED(time); - m_pointer->updateCursor(); + m_pointer->cursorFrameCallback(); })); } commit(); @@ -328,7 +334,8 @@ void QWaylandInputDevice::Pointer::updateCursor() uint time = seat()->mCursor.animationTimer.elapsed(); if (struct ::wl_cursor *waylandCursor = mCursor.theme->cursor(shape)) { - int frame = wl_cursor_frame(waylandCursor, time); + uint duration = 0; + int frame = wl_cursor_frame_and_duration(waylandCursor, time, &duration); ::wl_cursor_image *image = waylandCursor->images[frame]; struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); @@ -339,7 +346,12 @@ void QWaylandInputDevice::Pointer::updateCursor() int bufferScale = mCursor.themeBufferScale; QPoint hotspot = QPoint(image->hotspot_x, image->hotspot_y) / bufferScale; QSize size = QSize(image->width, image->height) / bufferScale; - bool animated = waylandCursor->image_count > 1 && image->delay > 0; + bool animated = duration > 0; + if (animated) { + mCursor.gotFrameCallback = false; + mCursor.gotTimerCallback = false; + mCursor.frameTimer.start(duration); + } getOrCreateCursorSurface()->update(buffer, hotspot, size, bufferScale, animated); return; } @@ -354,6 +366,22 @@ CursorSurface *QWaylandInputDevice::Pointer::getOrCreateCursorSurface() return mCursor.surface.get(); } +void QWaylandInputDevice::Pointer::cursorTimerCallback() +{ + mCursor.gotTimerCallback = true; + if (mCursor.gotFrameCallback) { + updateCursor(); + } +} + +void QWaylandInputDevice::Pointer::cursorFrameCallback() +{ + mCursor.gotFrameCallback = true; + if (mCursor.gotTimerCallback) { + updateCursor(); + } +} + #endif // QT_CONFIG(cursor) QWaylandInputDevice::Touch::Touch(QWaylandInputDevice *p) diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h index 60d6f2c17..a567c57b4 100644 --- a/src/client/qwaylandinputdevice_p.h +++ b/src/client/qwaylandinputdevice_p.h @@ -286,6 +286,8 @@ public: int idealCursorScale() const; void updateCursorTheme(); void updateCursor(); + void cursorTimerCallback(); + void cursorFrameCallback(); CursorSurface *getOrCreateCursorSurface(); #endif QWaylandInputDevice *seat() const { return mParent; } @@ -325,6 +327,9 @@ public: QWaylandCursorTheme *theme = nullptr; int themeBufferScale = 0; QScopedPointer<CursorSurface> surface; + QTimer frameTimer; + bool gotFrameCallback = false; + bool gotTimerCallback = false; } mCursor; #endif QPointF mSurfacePos; |