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 <davidedmundson@kde.org>
This commit is contained in:
Lu YaNing 2025-05-15 19:06:34 +08:00
parent 1f6352010d
commit 555bda1736
3 changed files with 41 additions and 10 deletions

View File

@ -311,16 +311,25 @@ QSharedPointer<QWaylandBuffer> QWaylandCursor::cursorBitmapBuffer(QWaylandDispla
void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) 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 // Create the buffer here so we don't have to create one per input device
QSharedPointer<QWaylandBuffer> bitmapBuffer; QSharedPointer<QWaylandBuffer> bitmapBuffer;
if (cursor && cursor->shape() == Qt::BitmapCursor) if (cursor && cursor->shape() == Qt::BitmapCursor)
bitmapBuffer = cursorBitmapBuffer(mDisplay, cursor); bitmapBuffer = cursorBitmapBuffer(mDisplay, cursor);
int fallbackOutputScale = qCeil(window->handle()->devicePixelRatio()); QWaylandWindow *waylandWindow = static_cast<QWaylandWindow*>(window->handle());
const auto seats = mDisplay->inputDevices(); if (!waylandWindow)
for (auto *seat : seats) return;
seat->setCursor(cursor, bitmapBuffer, fallbackOutputScale);
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) void QWaylandCursor::pointerEvent(const QMouseEvent &event)

View File

@ -1522,16 +1522,31 @@ void QWaylandWindow::setScale(qreal newScale)
#if QT_CONFIG(cursor) #if QT_CONFIG(cursor)
void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor) void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor)
{ {
int fallbackBufferScale = qCeil(devicePixelRatio()); setStoredCursor(cursor);
device->setCursor(&cursor, {}, fallbackBufferScale); applyCursor(device, cursor);
} }
void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device) void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device)
{ {
if (const QCursor *overrideCursor = QGuiApplication::overrideCursor()) if (const QCursor *overrideCursor = QGuiApplication::overrideCursor())
setMouseCursor(device, *overrideCursor); applyCursor(device, *overrideCursor);
else else if (mHasStoredCursor)
setMouseCursor(device, window()->cursor()); 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 #endif

View File

@ -194,6 +194,8 @@ public:
#if QT_CONFIG(cursor) #if QT_CONFIG(cursor)
void setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor); void setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor);
void restoreMouseCursor(QWaylandInputDevice *device); void restoreMouseCursor(QWaylandInputDevice *device);
void setStoredCursor(const QCursor &cursor);
void applyCursor(QWaylandInputDevice *device, const QCursor &cursor);
#endif #endif
QWaylandWindow *transientParent() const; QWaylandWindow *transientParent() const;
@ -353,6 +355,11 @@ protected:
std::unique_ptr<ColorManagementSurface> mColorManagementSurface; std::unique_ptr<ColorManagementSurface> mColorManagementSurface;
QSurfaceFormat mSurfaceFormat; QSurfaceFormat mSurfaceFormat;
#if QT_CONFIG(cursor)
QCursor mStoredCursor;
bool mHasStoredCursor = false;
#endif
private: private:
void setGeometry_helper(const QRect &rect); void setGeometry_helper(const QRect &rect);
void initWindow(); void initWindow();