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 <davidedmundson@kde.org>
This commit is contained in:
Niccolò Venerandi 2024-06-03 12:19:59 +02:00 committed by Niccolo Venerandi
parent df83f3e568
commit 6c836fe5fb
3 changed files with 21 additions and 0 deletions

View File

@ -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<QWaylandWindow *>(shapedPixmapWindow()->handle());
if (m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(), drag()->supportedActions(), icon)) {

View File

@ -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:

View File

@ -92,6 +92,7 @@ public:
#if QT_CONFIG(cursor)
void setCursor(const QCursor *cursor, const QSharedPointer<QWaylandBuffer> &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<QWaylandSurface> mFocus;