Skip to content

Commit 2146944

Browse files
committed
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
1 parent f1777d0 commit 2146944

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

panels/dock/pluginmanagerextension.cpp

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@
1515
#include <QtWaylandCompositor/QWaylandResource>
1616
#include <QtWaylandCompositor/QWaylandCompositor>
1717
#include <QtWaylandCompositor/QWaylandView>
18+
#include <QtWaylandCompositor/QWaylandBufferRef>
1819

1920
#include <QJsonObject>
2021
#include <QJsonParseError>
22+
#include <QGuiApplication>
23+
#include <QCursor>
24+
#include <QPixmap>
2125

2226
#define protected public
2327
#include <private/qwaylandcompositor_p.h>
28+
#include <private/qwaylandsurface_p.h>
2429
#undef protected
2530
#include <qpa/qwindowsysteminterface_p.h>
2631

@@ -709,13 +714,50 @@ void PluginManager::setupMouseFocusListener()
709714

710715
QObject::connect(seat, &QWaylandSeat::mouseFocusChanged, this,
711716
[seat](QWaylandView *newFocus, QWaylandView *oldFocus) {
712-
Q_UNUSED(oldFocus);
713-
if(!newFocus)
714-
return;
717+
// Restore default cursor when mouse leaves all plugin areas
718+
if (!newFocus && oldFocus) {
719+
qApp->restoreOverrideCursor();
720+
}
721+
722+
if (newFocus) {
723+
if (auto surface = newFocus->surface()) {
724+
seat->setKeyboardFocus(surface);
725+
}
726+
}
727+
});
715728

716-
if (auto surface = newFocus->surface()) {
717-
qDebug()<<"setKeyboardFocus";
718-
seat->setKeyboardFocus(surface);
729+
// Handle client cursor requests and apply cursor changes to the host window
730+
QObject::connect(seat, &QWaylandSeat::cursorSurfaceRequested, this,
731+
[this](QWaylandSurface *surface, int hotspotX, int hotspotY) {
732+
// Disconnect previous connection
733+
if (m_cursorSurfaceConn) {
734+
QObject::disconnect(m_cursorSurfaceConn);
735+
m_cursorSurfaceConn = {};
719736
}
737+
738+
if (!surface) {
739+
qApp->restoreOverrideCursor();
740+
return;
741+
}
742+
743+
auto updateCursor = [surface, hotspotX, hotspotY]() {
744+
QWaylandSurfacePrivate *surf = QWaylandSurfacePrivate::get(surface);
745+
QWaylandBufferRef buf = surf->bufferRef;
746+
if (!buf.hasBuffer()) {
747+
return;
748+
}
749+
QImage image = buf.image();
750+
if (!image.isNull() && image.width() > 0 && image.height() > 0) {
751+
QPixmap pixmap = QPixmap::fromImage(image);
752+
QCursor cursor(QPixmap::fromImage(image), hotspotX, hotspotY);
753+
if (qApp->overrideCursor()) {
754+
qApp->changeOverrideCursor(cursor);
755+
} else {
756+
qApp->setOverrideCursor(cursor);
757+
}
758+
}
759+
};
760+
// Listen to surface redraw signal to grab cursor after buffer is updated
761+
m_cursorSurfaceConn = QObject::connect(surface, &QWaylandSurface::redraw, updateCursor);
720762
});
721763
}

panels/dock/pluginmanagerextension_p.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ private Q_SLOTS:
117117
uint32_t m_dockColorTheme = 0;
118118
QSize m_dockSize;
119119
int m_popupMinHeight = 0;
120+
QMetaObject::Connection m_cursorSurfaceConn = {};
120121
};
121122

122123
class PluginSurface : public QWaylandShellSurfaceTemplate<PluginSurface>, public QtWaylandServer::plugin

0 commit comments

Comments
 (0)