From 214694432e4442a517a1a9b37d273ede725d98ec Mon Sep 17 00:00:00 2001 From: Wang Yu Date: Wed, 24 Dec 2025 10:09:56 +0800 Subject: [PATCH] fix: cursor not changing when hovering over hyperlinks in dock plugins - Handle cursorSurfaceRequested to apply client cursor to host window - Restore default cursor when mouse leaves plugin areas Log: cursor not changing when hovering over hyperlinks in dock plugins pms: BUG-307589 --- panels/dock/pluginmanagerextension.cpp | 54 +++++++++++++++++++++++--- panels/dock/pluginmanagerextension_p.h | 1 + 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/panels/dock/pluginmanagerextension.cpp b/panels/dock/pluginmanagerextension.cpp index 9c17a9948..9d8b94562 100644 --- a/panels/dock/pluginmanagerextension.cpp +++ b/panels/dock/pluginmanagerextension.cpp @@ -15,12 +15,17 @@ #include #include #include +#include #include #include +#include +#include +#include #define protected public #include +#include #undef protected #include @@ -709,13 +714,50 @@ void PluginManager::setupMouseFocusListener() QObject::connect(seat, &QWaylandSeat::mouseFocusChanged, this, [seat](QWaylandView *newFocus, QWaylandView *oldFocus) { - Q_UNUSED(oldFocus); - if(!newFocus) - return; + // Restore default cursor when mouse leaves all plugin areas + if (!newFocus && oldFocus) { + qApp->restoreOverrideCursor(); + } + + if (newFocus) { + if (auto surface = newFocus->surface()) { + seat->setKeyboardFocus(surface); + } + } + }); - if (auto surface = newFocus->surface()) { - qDebug()<<"setKeyboardFocus"; - seat->setKeyboardFocus(surface); + // Handle client cursor requests and apply cursor changes to the host window + QObject::connect(seat, &QWaylandSeat::cursorSurfaceRequested, this, + [this](QWaylandSurface *surface, int hotspotX, int hotspotY) { + // Disconnect previous connection + if (m_cursorSurfaceConn) { + QObject::disconnect(m_cursorSurfaceConn); + m_cursorSurfaceConn = {}; } + + if (!surface) { + qApp->restoreOverrideCursor(); + return; + } + + auto updateCursor = [surface, hotspotX, hotspotY]() { + QWaylandSurfacePrivate *surf = QWaylandSurfacePrivate::get(surface); + QWaylandBufferRef buf = surf->bufferRef; + if (!buf.hasBuffer()) { + return; + } + QImage image = buf.image(); + if (!image.isNull() && image.width() > 0 && image.height() > 0) { + QPixmap pixmap = QPixmap::fromImage(image); + QCursor cursor(QPixmap::fromImage(image), hotspotX, hotspotY); + if (qApp->overrideCursor()) { + qApp->changeOverrideCursor(cursor); + } else { + qApp->setOverrideCursor(cursor); + } + } + }; + // Listen to surface redraw signal to grab cursor after buffer is updated + m_cursorSurfaceConn = QObject::connect(surface, &QWaylandSurface::redraw, updateCursor); }); } diff --git a/panels/dock/pluginmanagerextension_p.h b/panels/dock/pluginmanagerextension_p.h index eb86beab1..b61c9eb77 100644 --- a/panels/dock/pluginmanagerextension_p.h +++ b/panels/dock/pluginmanagerextension_p.h @@ -117,6 +117,7 @@ private Q_SLOTS: uint32_t m_dockColorTheme = 0; QSize m_dockSize; int m_popupMinHeight = 0; + QMetaObject::Connection m_cursorSurfaceConn = {}; }; class PluginSurface : public QWaylandShellSurfaceTemplate, public QtWaylandServer::plugin