From 202573e946bcf3e1a6b855853705adeea44bf0b9 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Thu, 30 Apr 2015 22:07:49 +0300 Subject: [PATCH 1/6] Don't generate spurious selection events By calling destroy() on the active wl_data_source before replacing it with a new one and calling set_selection() we trigger a spurious selection(null) event before the one with the offer for the source we are going to set. Change-Id: I6c2f2fd029fa523312b9892c6a5050805dfa83b0 Reviewed-by: Pier Luigi Fiorini Reviewed-by: Laszlo Agocs --- src/plugins/platforms/wayland/qwaylanddatadevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/wayland/qwaylanddatadevice.cpp b/src/plugins/platforms/wayland/qwaylanddatadevice.cpp index 03a8c4b83ec..a3e084a0c10 100644 --- a/src/plugins/platforms/wayland/qwaylanddatadevice.cpp +++ b/src/plugins/platforms/wayland/qwaylanddatadevice.cpp @@ -94,10 +94,10 @@ QWaylandDataSource *QWaylandDataDevice::selectionSource() const void QWaylandDataDevice::setSelectionSource(QWaylandDataSource *source) { - m_selectionSource.reset(source); if (source) connect(source, &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::selectionSourceCancelled); set_selection(source ? source->object() : Q_NULLPTR, m_inputDevice->serial()); + m_selectionSource.reset(source); } QWaylandDataOffer *QWaylandDataDevice::dragOffer() const From 9369a931d0b1ddc6b0ea2d17a2ec57ff8122e013 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Thu, 30 Apr 2015 19:44:58 +0300 Subject: [PATCH 2/6] Fix a corner case freed memory use/crash QWaylandDisplay::flushRequests() does not only flush them, but also dispatches the pending events. If we have two wl_data_device.selection events in the queue we must not dispatch the second one while we are dealing with the first one because that will replace the data offer and delete us while we're in QWaylandMimeData::retrieveData_sys(). Change-Id: Ib58ca571867faa2633daa9ec94fe7094df02e9fd Reviewed-by: Laszlo Agocs --- src/plugins/platforms/wayland/qwaylanddataoffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/wayland/qwaylanddataoffer.cpp b/src/plugins/platforms/wayland/qwaylanddataoffer.cpp index dd28f787041..167b647d6aa 100644 --- a/src/plugins/platforms/wayland/qwaylanddataoffer.cpp +++ b/src/plugins/platforms/wayland/qwaylanddataoffer.cpp @@ -136,7 +136,7 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T } m_dataOffer->receive(mime, pipefd[1]); - m_display->flushRequests(); + wl_display_flush(m_display->wl_display()); close(pipefd[1]); From 58f3c602f01cc647dd97304f4c395174f7ceece1 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Fri, 24 Apr 2015 20:51:14 +0300 Subject: [PATCH 3/6] bradient: Activate the decoration's buttons on mouse release, not press Change-Id: I5a161119b20301a405bdde9bbea6bfbdcc4b9fa0 Reviewed-by: Pier Luigi Fiorini Reviewed-by: Laszlo Agocs --- .../plugins/decorations/bradient/main.cpp | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/wayland/plugins/decorations/bradient/main.cpp b/src/plugins/platforms/wayland/plugins/decorations/bradient/main.cpp index 00a91e242a7..ea298699385 100644 --- a/src/plugins/platforms/wayland/plugins/decorations/bradient/main.cpp +++ b/src/plugins/platforms/wayland/plugins/decorations/bradient/main.cpp @@ -116,6 +116,14 @@ static const char * const qt_normalizeup_xpm[] = { # define BUTTON_WIDTH 22 #endif +enum Button +{ + None, + Close, + Maximize, + Minimize +}; + class Q_WAYLAND_CLIENT_EXPORT QWaylandBradientDecoration : public QWaylandAbstractDecoration { public: @@ -130,6 +138,7 @@ private: void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); void processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); + bool clickButton(Qt::MouseButtons b, Button btn); QRectF closeButtonRect() const; QRectF maximizeButtonRect() const; @@ -138,12 +147,14 @@ private: QColor m_foregroundColor; QColor m_backgroundColor; QStaticText m_windowTitle; + Button m_clicking; }; QWaylandBradientDecoration::QWaylandBradientDecoration() : QWaylandAbstractDecoration() + , m_clicking(None) { QPalette palette; m_foregroundColor = palette.color(QPalette::Active, QPalette::HighlightedText); @@ -315,18 +326,37 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device) #endif } +bool QWaylandBradientDecoration::clickButton(Qt::MouseButtons b, Button btn) +{ + if (isLeftClicked(b)) { + m_clicking = btn; + return false; + } else if (isLeftReleased(b)) { + if (m_clicking == btn) { + m_clicking = None; + return true; + } else { + m_clicking = None; + } + } + return false; +} + bool QWaylandBradientDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) { Q_UNUSED(global); // Figure out what area mouse is in - if (closeButtonRect().contains(local) && isLeftClicked(b)) { - QWindowSystemInterface::handleCloseEvent(window()); - } else if (maximizeButtonRect().contains(local) && isLeftClicked(b)) { - window()->setWindowState(waylandWindow()->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized); - } else if (minimizeButtonRect().contains(local) && isLeftClicked(b)) { - window()->setWindowState(Qt::WindowMinimized); + if (closeButtonRect().contains(local)) { + if (clickButton(b, Close)) + QWindowSystemInterface::handleCloseEvent(window()); + } else if (maximizeButtonRect().contains(local)) { + if (clickButton(b, Maximize)) + window()->setWindowState(waylandWindow()->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized); + } else if (minimizeButtonRect().contains(local)) { + if (clickButton(b, Minimize)) + window()->setWindowState(Qt::WindowMinimized); } else if (local.y() <= margins().top()) { processMouseTop(inputDevice,local,b,mods); } else if (local.y() > window()->height() - margins().bottom() + margins().top()) { From 7d54e5527e630474a891b27ea6247eabfbd4e9ea Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Sat, 9 May 2015 10:29:15 +0300 Subject: [PATCH 4/6] Fix wheel events when the decorations are enabled We must offset the wheel events' position, as we do with the other types of mouse events. Change-Id: If85e93ffe95304c7dee4c2a3ff195a73243a8182 Reviewed-by: Pier Luigi Fiorini Reviewed-by: Laszlo Agocs --- .../platforms/wayland/qwaylandinputdevice.cpp | 15 +++++++++++---- .../platforms/wayland/qwaylandinputdevice_p.h | 13 ++++++++++++- src/plugins/platforms/wayland/qwaylandwindow.cpp | 6 ++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 76ae258696b..009ef670e7d 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -494,6 +494,15 @@ void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time } } +class WheelEvent : public QWaylandPointerEvent +{ +public: + WheelEvent(ulong t, const QPointF &l, const QPointF &g, const QPoint &pd, const QPoint &ad) + : QWaylandPointerEvent(QWaylandPointerEvent::Wheel, t, l, g, pd, ad) + { + } +}; + void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, int32_t value) { QWaylandWindow *window = mFocus; @@ -517,10 +526,8 @@ void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, in angleDelta.setY(valueDelta); } - QWindowSystemInterface::handleWheelEvent(window->window(), - time, mSurfacePos, - mGlobalPos, pixelDelta, - angleDelta); + WheelEvent e(time, mSurfacePos, mGlobalPos, pixelDelta, angleDelta); + window->handleMouse(mParent, e); } #ifndef QT_NO_WAYLAND_XKB diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice_p.h b/src/plugins/platforms/wayland/qwaylandinputdevice_p.h index 23172ad3c93..6f3b25c06b1 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice_p.h +++ b/src/plugins/platforms/wayland/qwaylandinputdevice_p.h @@ -259,7 +259,8 @@ class QWaylandPointerEvent public: enum Type { Enter, - Motion + Motion, + Wheel }; inline QWaylandPointerEvent(Type t, ulong ts, const QPointF &l, const QPointF &g, Qt::MouseButtons b, Qt::KeyboardModifiers m) : type(t) @@ -269,6 +270,14 @@ public: , buttons(b) , modifiers(m) {} + inline QWaylandPointerEvent(Type t, ulong ts, const QPointF &l, const QPointF &g, const QPoint &pd, const QPoint &ad) + : type(t) + , timestamp(ts) + , local(l) + , global(g) + , pixelDelta(pd) + , angleDelta(ad) + {} Type type; ulong timestamp; @@ -276,6 +285,8 @@ public: QPointF global; Qt::MouseButtons buttons; Qt::KeyboardModifiers modifiers; + QPoint pixelDelta; + QPoint angleDelta; }; } diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index a775080a37b..922b1ee00e5 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -625,6 +625,9 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylan case QWaylandPointerEvent::Motion: QWindowSystemInterface::handleMouseEvent(window(), e.timestamp, e.local, e.global, e.buttons, e.modifiers); break; + case QWaylandPointerEvent::Wheel: + QWindowSystemInterface::handleWheelEvent(window(), e.timestamp, e.local, e.global, e.pixelDelta, e.angleDelta); + break; } } @@ -684,6 +687,9 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe case QWaylandPointerEvent::Motion: QWindowSystemInterface::handleMouseEvent(window(), e.timestamp, localTranslated, globalTranslated, e.buttons, e.modifiers); break; + case QWaylandPointerEvent::Wheel: + QWindowSystemInterface::handleWheelEvent(window(), e.timestamp, localTranslated, globalTranslated, e.pixelDelta, e.angleDelta); + break; } mMouseEventsInContentArea = true; From 36d1c47e6646a06fb8b36471648ad1752f4906de Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 5 Jun 2015 11:55:46 +0200 Subject: [PATCH 5/6] Fix typo that leads to mis-evaluation of an expression. Change-Id: I5d6eedeb3dfb80ca9df7ca27e29ad6604dbfe683 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/wayland/qwaylandabstractdecoration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/wayland/qwaylandabstractdecoration.cpp b/src/plugins/platforms/wayland/qwaylandabstractdecoration.cpp index 7698ff75082..54a990b2d71 100644 --- a/src/plugins/platforms/wayland/qwaylandabstractdecoration.cpp +++ b/src/plugins/platforms/wayland/qwaylandabstractdecoration.cpp @@ -147,7 +147,7 @@ void QWaylandAbstractDecoration::startMove(QWaylandInputDevice *inputDevice, Qt: bool QWaylandAbstractDecoration::isLeftClicked(Qt::MouseButtons newMouseButtonState) { Q_D(QWaylandAbstractDecoration); - if ((!d->m_mouseButtons & Qt::LeftButton) && (newMouseButtonState & Qt::LeftButton)) + if (!(d->m_mouseButtons & Qt::LeftButton) && (newMouseButtonState & Qt::LeftButton)) return true; return false; } From bc63ed702ffc8c0cd42df98b2b8c57017df238d7 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Sun, 7 Jun 2015 14:56:45 +0200 Subject: [PATCH 6/6] Fix input devices leak in client Change-Id: I28200698706168308e450b2cd3cfa99df517f9b7 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/wayland/qwaylanddisplay.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index c3925f5c446..eb431cf0d21 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -165,6 +165,9 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) QWaylandDisplay::~QWaylandDisplay(void) { + qDeleteAll(mInputDevices); + mInputDevices.clear(); + foreach (QWaylandScreen *screen, mScreens) { mWaylandIntegration->destroyScreen(screen); }