From 555bda173621e18ae15117677ed3f314cee4a6bb Mon Sep 17 00:00:00 2001 From: Lu YaNing Date: Thu, 15 May 2025 19:06:34 +0800 Subject: [PATCH] Client: add cursor state management When tooltip window is shown and dismissed under Wayland, the cursor state Add cursor state storage and application logic to ensure cursor state is properly updated when changing cursors on focused Fixes: QTBUG-135938 Change-Id: I8c3520bcb785cea03cddd1eb91e58b9d253b4fe0 Reviewed-by: David Edmundson --- .../platforms/wayland/qwaylandcursor.cpp | 19 ++++++++++---- .../platforms/wayland/qwaylandwindow.cpp | 25 +++++++++++++++---- .../platforms/wayland/qwaylandwindow_p.h | 7 ++++++ 3 files changed, 41 insertions(+), 10 deletions(-) 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();