From 6c836fe5fb3e3b504ef2c35a733c76d548fd54a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Venerandi?= Date: Mon, 3 Jun 2024 12:19:59 +0200 Subject: [PATCH] Emit a LeaveEvent on drag and drop start All focused windows will now receive a LeaveEvent when a drag and drop starts. This makes sure that the dragged element does not preserve any hover decoration during the drag and drop, and that other elements that happen to take place of the dragged elements don't become hovered too. Pick-to: 6.7 6.8 Change-Id: I0924fff987f143aff11284c808027dd210b48c2b Reviewed-by: David Edmundson --- src/plugins/platforms/wayland/qwaylanddnd.cpp | 5 +++++ .../platforms/wayland/qwaylandinputdevice.cpp | 14 ++++++++++++++ .../platforms/wayland/qwaylandinputdevice_p.h | 2 ++ 3 files changed, 21 insertions(+) diff --git a/src/plugins/platforms/wayland/qwaylanddnd.cpp b/src/plugins/platforms/wayland/qwaylanddnd.cpp index 5ea1e0d3376..096d7e5b586 100644 --- a/src/plugins/platforms/wayland/qwaylanddnd.cpp +++ b/src/plugins/platforms/wayland/qwaylanddnd.cpp @@ -28,6 +28,11 @@ QWaylandDrag::~QWaylandDrag() void QWaylandDrag::startDrag() { + // Some compositors do not send a pointer leave before starting a drag, some do. + // This is discussed upstream at: https://gitlab.freedesktop.org/wayland/wayland/-/issues/444 + // For consistency between compositors we emit the leave event here, upon drag start. + m_display->currentInputDevice()->handleStartDrag(); + QBasicDrag::startDrag(); QWaylandWindow *icon = static_cast(shapedPixmapWindow()->handle()); if (m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(), drag()->supportedActions(), icon)) { diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index ce04971ba6f..416894fd439 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -528,6 +528,12 @@ void QWaylandInputDevice::handleEndDrag() mPointer->releaseButtons(); } +void QWaylandInputDevice::handleStartDrag() +{ + if (mPointer) + mPointer->leavePointers(); +} + #if QT_CONFIG(wayland_datadevice) void QWaylandInputDevice::setDataDevice(QWaylandDataDevice *device) { @@ -886,6 +892,14 @@ void QWaylandInputDevice::Pointer::releaseButtons() } } +void QWaylandInputDevice::Pointer::leavePointers() +{ + if (auto *window = focusWindow()) { + LeaveEvent e(focusWindow(), mSurfacePos, mGlobalPos); + window->handleMouse(mParent, e); + } +} + class WheelEvent : public QWaylandPointerEvent { public: diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice_p.h b/src/plugins/platforms/wayland/qwaylandinputdevice_p.h index becd5f9be04..91bcf405c53 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice_p.h +++ b/src/plugins/platforms/wayland/qwaylandinputdevice_p.h @@ -92,6 +92,7 @@ public: #if QT_CONFIG(cursor) void setCursor(const QCursor *cursor, const QSharedPointer &cachedBuffer = {}, int fallbackOutputScale = 1); #endif + void handleStartDrag(); void handleEndDrag(); #if QT_CONFIG(wayland_datadevice) @@ -320,6 +321,7 @@ private: public: void releaseButtons(); + void leavePointers(); QWaylandInputDevice *mParent = nullptr; QPointer mFocus;