diff --git a/src/plugins/platforms/wayland/qwaylandcursor.cpp b/src/plugins/platforms/wayland/qwaylandcursor.cpp index 00b1d7df2a3..7a25b10bd4d 100644 --- a/src/plugins/platforms/wayland/qwaylandcursor.cpp +++ b/src/plugins/platforms/wayland/qwaylandcursor.cpp @@ -311,16 +311,25 @@ QSharedPointer QWaylandCursor::cursorBitmapBuffer(QWaylandDispla void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) { - Q_UNUSED(window); + if (!window) + return; // Create the buffer here so we don't have to create one per input device QSharedPointer bitmapBuffer; if (cursor && cursor->shape() == Qt::BitmapCursor) bitmapBuffer = cursorBitmapBuffer(mDisplay, cursor); - int fallbackOutputScale = qCeil(window->handle()->devicePixelRatio()); - const auto seats = mDisplay->inputDevices(); - for (auto *seat : seats) - seat->setCursor(cursor, bitmapBuffer, fallbackOutputScale); + QWaylandWindow *waylandWindow = static_cast(window->handle()); + if (!waylandWindow) + return; + + if (cursor) { + waylandWindow->setStoredCursor(*cursor); + + for (QWaylandInputDevice *device : mDisplay->inputDevices()) { + if (device->pointer() && device->pointer()->focusWindow() == waylandWindow) + device->setCursor(cursor, bitmapBuffer, qCeil(waylandWindow->devicePixelRatio())); + } + } } void QWaylandCursor::pointerEvent(const QMouseEvent &event) diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index d6fd087c256..b4097354a8f 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -1522,16 +1522,31 @@ void QWaylandWindow::setScale(qreal newScale) #if QT_CONFIG(cursor) void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor) { - int fallbackBufferScale = qCeil(devicePixelRatio()); - device->setCursor(&cursor, {}, fallbackBufferScale); + setStoredCursor(cursor); + applyCursor(device, cursor); } void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device) { if (const QCursor *overrideCursor = QGuiApplication::overrideCursor()) - setMouseCursor(device, *overrideCursor); - else - setMouseCursor(device, window()->cursor()); + applyCursor(device, *overrideCursor); + else if (mHasStoredCursor) + applyCursor(device, mStoredCursor); +} + +void QWaylandWindow::setStoredCursor(const QCursor &cursor) { + if (mHasStoredCursor && mStoredCursor == cursor) + return; + mStoredCursor = cursor; + mHasStoredCursor = true; +} + +void QWaylandWindow::applyCursor(QWaylandInputDevice *device, const QCursor &cursor) { + if (!device || !device->pointer() || device->pointer()->focusWindow() != this) + return; + + int fallbackBufferScale = qCeil(devicePixelRatio()); + device->setCursor(&cursor, {}, fallbackBufferScale); } #endif diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index 06d8dbed38b..b28e087ff4a 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -194,6 +194,8 @@ public: #if QT_CONFIG(cursor) void setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor); void restoreMouseCursor(QWaylandInputDevice *device); + void setStoredCursor(const QCursor &cursor); + void applyCursor(QWaylandInputDevice *device, const QCursor &cursor); #endif QWaylandWindow *transientParent() const; @@ -353,6 +355,11 @@ protected: std::unique_ptr mColorManagementSurface; QSurfaceFormat mSurfaceFormat; +#if QT_CONFIG(cursor) + QCursor mStoredCursor; + bool mHasStoredCursor = false; +#endif + private: void setGeometry_helper(const QRect &rect); void initWindow();