From 322bc6a377f9b015492b824773d54df0ae098d6c Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Sun, 18 Jan 2015 15:04:29 +0200 Subject: [PATCH 1/9] Make sure we send a valid initial resize Change-Id: Ib9a0152f83af433354d32ef4a8a233e5551ded8c Reviewed-by: Laszlo Agocs --- src/plugins/platforms/wayland/qwaylandwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 6c4a339f1e0..965511528c1 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -208,7 +208,7 @@ void QWaylandWindow::setGeometry(const QRect &rect) { setGeometry_helper(rect); - if (window()->isVisible()) { + if (window()->isVisible() && rect.isValid()) { if (mWindowDecoration) mWindowDecoration->update(); @@ -336,7 +336,7 @@ void QWaylandWindow::requestResize() { QMutexLocker lock(&mResizeLock); - if (mCanResize) { + if (mCanResize || !mSentInitialResize) { doResize(); } From 5d36ed33c706a52464ebf100480b07b01a54c5a8 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Tue, 27 Jan 2015 19:44:52 +0200 Subject: [PATCH 2/9] Fix pasting from sources advertising the utf8 charset Some clients use "text/plain;charset=utf8" as the mimetype for the clipboard instead of just "text/plain". Since we support Utf8 accept it as a valid type. Change-Id: Icd540f0ff507ed9917b374f3b40fbdc259ce9ee2 Reviewed-by: Robin Burchell --- .../platforms/wayland/qwaylanddataoffer.cpp | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylanddataoffer.cpp b/src/plugins/platforms/wayland/qwaylanddataoffer.cpp index 4ad73dc7e77..ab3642bf47c 100644 --- a/src/plugins/platforms/wayland/qwaylanddataoffer.cpp +++ b/src/plugins/platforms/wayland/qwaylanddataoffer.cpp @@ -51,6 +51,11 @@ QT_BEGIN_NAMESPACE +static QString utf8Text() +{ + return QStringLiteral("text/plain;charset=utf-8"); +} + QWaylandDataOffer::QWaylandDataOffer(QWaylandDisplay *display, struct ::wl_data_offer *offer) : QtWayland::wl_data_offer(offer) , m_mimeData(new QWaylandMimeData(this, display)) @@ -100,7 +105,13 @@ void QWaylandMimeData::appendFormat(const QString &mimeType) bool QWaylandMimeData::hasFormat_sys(const QString &mimeType) const { - return m_types.contains(mimeType); + if (m_types.contains(mimeType)) + return true; + + if (mimeType == QStringLiteral("text/plain") && m_types.contains(utf8Text())) + return true; + + return false; } QStringList QWaylandMimeData::formats_sys() const @@ -115,8 +126,14 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T if (m_data.contains(mimeType)) return m_data.value(mimeType); - if (!m_types.contains(mimeType)) - return QVariant(); + QString mime = mimeType; + + if (!m_types.contains(mimeType)) { + if (mimeType == QStringLiteral("text/plain") && m_types.contains(utf8Text())) + mime = utf8Text(); + else + return QVariant(); + } int pipefd[2]; if (::pipe2(pipefd, O_CLOEXEC|O_NONBLOCK) == -1) { @@ -124,7 +141,7 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T return QVariant(); } - m_dataOffer->receive(mimeType, pipefd[1]); + m_dataOffer->receive(mime, pipefd[1]); m_display->flushRequests(); close(pipefd[1]); From f58cc97806d7adb85849fec8b1a56bb48756022f Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Thu, 29 Jan 2015 21:10:25 +0200 Subject: [PATCH 3/9] Send mouse events with the correct modifiers Change-Id: I33da2681bc2315b3dc7de16fa80c45e26a478caa Reviewed-by: Robin Burchell --- src/plugins/platforms/wayland/qwaylandinputdevice.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 39d1705c0c7..30bc6029ba9 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -419,7 +419,7 @@ void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial, struct wl_surf QWaylandWindow *grab = QWaylandWindow::mouseGrab(); if (!grab) { window->handleMouseEnter(mParent); - window->handleMouse(mParent, mParent->mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + window->handleMouse(mParent, mParent->mTime, mSurfacePos, mGlobalPos, mButtons, mParent->modifiers()); } } @@ -468,9 +468,9 @@ void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surf // so we just set it outside of the window boundaries. pos = QPointF(-1, -1); global = grab->window()->mapToGlobal(pos.toPoint()); - grab->handleMouse(mParent, time, pos, global, mButtons, Qt::NoModifier); + grab->handleMouse(mParent, time, pos, global, mButtons, mParent->modifiers()); } else - window->handleMouse(mParent, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + window->handleMouse(mParent, time, mSurfacePos, mGlobalPos, mButtons, mParent->modifiers()); } void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time, @@ -514,9 +514,9 @@ void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time if (grab && grab != mFocus) { QPointF pos = QPointF(-1, -1); QPointF global = grab->window()->mapToGlobal(pos.toPoint()); - grab->handleMouse(mParent, time, pos, global, mButtons, Qt::NoModifier); + grab->handleMouse(mParent, time, pos, global, mButtons, mParent->modifiers()); } else if (window) - window->handleMouse(mParent, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + window->handleMouse(mParent, time, mSurfacePos, mGlobalPos, mButtons, mParent->modifiers()); } void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, int32_t value) From d62f2bc4e7596a7ec74aa405f1282e9ade7fe817 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Fri, 30 Jan 2015 19:31:00 +0200 Subject: [PATCH 4/9] Make all the screens virtual siblings Wayland outputs fit the definition of virtual sibling screens so make the platform screen subclass so. Change-Id: Id3f2592653f6309406185589f70127f2b74065ac Reviewed-by: Laszlo Agocs --- src/plugins/platforms/wayland/qwaylandscreen.cpp | 8 ++++++++ src/plugins/platforms/wayland/qwaylandscreen_p.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp index 6e48c442e43..ad10b7a0264 100644 --- a/src/plugins/platforms/wayland/qwaylandscreen.cpp +++ b/src/plugins/platforms/wayland/qwaylandscreen.cpp @@ -113,6 +113,14 @@ QDpi QWaylandScreen::logicalDpi() const return QPlatformScreen::logicalDpi(); } +QList QWaylandScreen::virtualSiblings() const +{ + QList list; + foreach (QWaylandScreen *screen, mWaylandDisplay->screens()) + list << screen; + return list; +} + void QWaylandScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) { foreach (QWindow *window, QGuiApplication::allWindows()) { diff --git a/src/plugins/platforms/wayland/qwaylandscreen_p.h b/src/plugins/platforms/wayland/qwaylandscreen_p.h index d3173e0c9a1..9338c2717c1 100644 --- a/src/plugins/platforms/wayland/qwaylandscreen_p.h +++ b/src/plugins/platforms/wayland/qwaylandscreen_p.h @@ -68,6 +68,7 @@ public: QSizeF physicalSize() const Q_DECL_OVERRIDE; QDpi logicalDpi() const Q_DECL_OVERRIDE; + QList virtualSiblings() const Q_DECL_OVERRIDE; void setOrientationUpdateMask(Qt::ScreenOrientations mask); From ef259af2db0d7c58a534cc877eebef3e20d4ebda Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Wed, 4 Feb 2015 20:02:59 +0200 Subject: [PATCH 5/9] Fix deadlock when starting a drag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie2fdc56bffb97ce04ffad11ea7a7686dc09a06cc Reviewed-by: Robin Burchell Reviewed-by: Jørgen Lind --- src/plugins/platforms/wayland/qwaylanddnd.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/wayland/qwaylanddnd.cpp b/src/plugins/platforms/wayland/qwaylanddnd.cpp index 996e647ccdc..e38e23da92f 100644 --- a/src/plugins/platforms/wayland/qwaylanddnd.cpp +++ b/src/plugins/platforms/wayland/qwaylanddnd.cpp @@ -71,13 +71,20 @@ QMimeData * QWaylandDrag::platformDropData() void QWaylandDrag::startDrag() { + bool cancel = false; if (!shapedPixmapWindow()) { QBasicDrag::startDrag(); - QBasicDrag::cancel(); + // Don't call cancel() here, since that will hide 'shapedPixmapWindow()', and + // QWaylandWindow::setVisible(false) will flush the window system queue, + // ending up trying to render the window, which doesn't have a role yet, + // and so blocking waiting for a frame callback. + cancel = true; } QWaylandWindow *icon = static_cast(shapedPixmapWindow()->handle()); m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(), icon); + if (cancel) + QBasicDrag::cancel(); QBasicDrag::startDrag(); } From ccc23106b9a415910b622609934a8e7d16682556 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Wed, 4 Feb 2015 22:00:35 +0200 Subject: [PATCH 6/9] Do not send invisible key characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xkb_keysym_to_utf32() will return 0 if the keysym does not have a unicode representation. Task-number: QTBUG-44012 Change-Id: I85a13b58c7f0b9765c7d67db6568a90629bcfbfa Reviewed-by: Jørgen Lind --- src/plugins/platforms/wayland/qwaylandinputdevice.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 30bc6029ba9..b2dfd757db2 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -778,7 +778,8 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, Qt::KeyboardModifiers modifiers = mParent->modifiers(); uint utf32 = xkb_keysym_to_utf32(sym); - text = QString::fromUcs4(&utf32, 1); + if (utf32) + text = QString::fromUcs4(&utf32, 1); qtkey = keysymToQtKey(sym, modifiers, text); From b52533db8338714e2639860963dd76514ff22d8d Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Sat, 7 Feb 2015 19:29:19 +0200 Subject: [PATCH 7/9] Fix copying text to non-qt clients Like we do for pasting, set the mime type of text to "text/plain;charset=utf-8" too besides "text/plain". This allows copying text to clients such as weston example clients or Xwayland. Change-Id: I8a24f32d93e438f16db662e7c09b09ddd7578768 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/wayland/qwaylandclipboard.cpp | 4 ++++ src/plugins/platforms/wayland/qwaylandinputdevice.cpp | 1 + 2 files changed, 5 insertions(+) diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp index c40f023b55a..355a7163a80 100644 --- a/src/plugins/platforms/wayland/qwaylandclipboard.cpp +++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp @@ -86,6 +86,10 @@ void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) if (!inputDevice || !inputDevice->dataDevice()) return; + static const QString plain = QStringLiteral("text/plain"); + static const QString utf8 = QStringLiteral("text/plain;charset=utf-8"); + if (data && data->hasFormat(plain) && !data->hasFormat(utf8)) + data->setData(utf8, data->data(plain)); inputDevice->dataDevice()->setSelectionSource(data ? new QWaylandDataSource(mDisplay->dndSelectionHandler(), data) : 0); emitChanged(mode); diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index b2dfd757db2..ad369bb324f 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -761,6 +761,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; QString text; int qtkey = key + 8; // qt-compositor substracts 8 for some reason + mParent->mSerial = serial; if (!window) { // We destroyed the keyboard focus surface, but the server From 817633a83136e0442557a0bf3b2955e602289385 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Sun, 18 Jan 2015 15:53:46 +0200 Subject: [PATCH 8/9] Fix popup menus with no parent windows The QMenu API doesn't play well with Wayland. You can do: QMenu menu; menu.popup(someGlobalPos); which is completely broken on wayland. If some popup window doesn't have a transient parent use the current focus window for that. Fixes right-click popups in qdbusviewer and other apps. Change-Id: I3227f4ec27431ca8ec156971cbfdbf1e848a0527 Reviewed-by: Laszlo Agocs --- .../platforms/wayland/qwaylandwindow.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 965511528c1..13408b25924 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -226,14 +226,21 @@ void QWaylandWindow::setGeometry(const QRect &rect) void QWaylandWindow::setVisible(bool visible) { if (visible) { - if (window()->type() == Qt::Popup && transientParent()) { + if (window()->type() == Qt::Popup) { QWaylandWindow *parent = transientParent(); - mMouseDevice = parent->mMouseDevice; - mMouseSerial = parent->mMouseSerial; + if (!parent) { + // Try with the current focus window. It may be the wrong one but we need to have + // some parent to have popups act as popups. + parent = mDisplay->currentInputDevice()->pointerFocus(); + } + if (parent) { + mMouseDevice = parent->mMouseDevice; + mMouseSerial = parent->mMouseSerial; - QWaylandWlShellSurface *wlshellSurface = dynamic_cast(mShellSurface); - if (mMouseDevice && wlshellSurface) { - wlshellSurface->setPopup(transientParent(), mMouseDevice, mMouseSerial); + QWaylandWlShellSurface *wlshellSurface = dynamic_cast(mShellSurface); + if (mMouseDevice && wlshellSurface) { + wlshellSurface->setPopup(parent, mMouseDevice, mMouseSerial); + } } } From 520cb3e95e4679f32789987dde35ddecb9162657 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sat, 6 Sep 2014 22:55:07 +0200 Subject: [PATCH 9/9] Sanitize popup behavior. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Popups are pretty important for widget apps. Menus, combobox dropdows and such are all popups. Currently they are completely borked when activated via keyboard or touch. This is because of the bizarre set_popup request in the protocol, and Weston's current implementation, that ignore the fact that a popup can be opened as a result of a keyboard event too or may not originate from an input event at all. Pass the last input device and serial we have seen, regardless of the type, by tracking it globally in the QWaylandDisplay. With this patch menus and such will not freeze the application anymore when activated with keyboard or touch without sending a mouse event to the window first. The behavior is still broken in some ways, especially with keyboard due to immediately getting a popup_done, but at least applications remain usable. Task-number: QTBUG-41142 Task-number: QTBUG-41147 Change-Id: I18de501004ae8a62ff8667e72225d08c2d3ba491 Reviewed-by: Laszlo Agocs Reviewed-by: Jørgen Lind --- .../platforms/wayland/qwaylanddisplay.cpp | 10 +++++++++ .../platforms/wayland/qwaylanddisplay_p.h | 8 +++++++ .../platforms/wayland/qwaylandinputdevice.cpp | 8 +++++-- .../platforms/wayland/qwaylandwindow.cpp | 22 +++++-------------- .../platforms/wayland/qwaylandwindow_p.h | 2 -- .../wayland/qwaylandwlshellsurface.cpp | 8 ++++++- 6 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index fda2c204e66..9dedabda344 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -128,6 +128,9 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) , mQtKeyExtension(0) , mTextInputManager(0) , mHardwareIntegration(0) + , mLastInputSerial(0) + , mLastInputDevice(0) + , mLastInputWindow(0) { qRegisterMetaType("uint32_t"); @@ -359,4 +362,11 @@ bool QWaylandDisplay::supportsWindowDecoration() const return integrationSupport; } +void QWaylandDisplay::setLastInputDevice(QWaylandInputDevice *device, uint32_t serial, QWaylandWindow *win) +{ + mLastInputDevice = device; + mLastInputSerial = serial; + mLastInputWindow = win; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/qwaylanddisplay_p.h b/src/plugins/platforms/wayland/qwaylanddisplay_p.h index 8d1d26bba24..d9619e6f1f5 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay_p.h +++ b/src/plugins/platforms/wayland/qwaylanddisplay_p.h @@ -159,6 +159,11 @@ public: bool supportsWindowDecoration() const; + uint32_t lastInputSerial() const { return mLastInputSerial; } + QWaylandInputDevice *lastInputDevice() const { return mLastInputDevice; } + QWaylandWindow *lastInputWindow() const { return mLastInputWindow; } + void setLastInputDevice(QWaylandInputDevice *device, uint32_t serial, QWaylandWindow *window); + public slots: void blockingReadEvents(); void flushRequests(); @@ -200,6 +205,9 @@ private: bool mScreensInitialized; QList mGlobals; int mCompositorVersion; + uint32_t mLastInputSerial; + QWaylandInputDevice *mLastInputDevice; + QWaylandWindow *mLastInputWindow; void registry_global(uint32_t id, const QString &interface, uint32_t version) Q_DECL_OVERRIDE; void registry_global_remove(uint32_t id) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index ad369bb324f..14575146da8 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -476,7 +476,6 @@ void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surf void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { - Q_UNUSED(serial); QWaylandWindow *window = mFocus; Qt::MouseButton qt_button; @@ -509,6 +508,8 @@ void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time mParent->mTime = time; mParent->mSerial = serial; + if (state) + mParent->mQDisplay->setLastInputDevice(mParent, serial, window); QWaylandWindow *grab = QWaylandWindow::mouseGrab(); if (grab && grab != mFocus) { @@ -754,7 +755,6 @@ void QWaylandInputDevice::Keyboard::focusCallback(void *data, struct wl_callback void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { - Q_UNUSED(serial); QWaylandWindow *window = mFocus; uint32_t code = key + 8; bool isDown = state != 0; @@ -769,6 +769,9 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, return; } + if (isDown) + mParent->mQDisplay->setLastInputDevice(mParent, serial, window); + #ifndef QT_NO_WAYLAND_XKB if (!mXkbMap) return; @@ -875,6 +878,7 @@ void QWaylandInputDevice::Touch::touch_down(uint32_t serial, mParent->mTime = time; mParent->mSerial = serial; mFocus = QWaylandWindow::fromWlSurface(surface); + mParent->mQDisplay->setLastInputDevice(mParent, serial, mFocus); mParent->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed); } diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 13408b25924..976ebba15c3 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -88,8 +88,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mResizeDirty(false) , mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP")) , mSentInitialResize(false) - , mMouseDevice(0) - , mMouseSerial(0) , mState(Qt::WindowNoState) , mBackingStore(Q_NULLPTR) { @@ -229,18 +227,14 @@ void QWaylandWindow::setVisible(bool visible) if (window()->type() == Qt::Popup) { QWaylandWindow *parent = transientParent(); if (!parent) { - // Try with the current focus window. It may be the wrong one but we need to have - // some parent to have popups act as popups. - parent = mDisplay->currentInputDevice()->pointerFocus(); + // Try with the current focus window. It should be the right one and anyway + // better than having no parent at all. + parent = mDisplay->lastInputWindow(); } if (parent) { - mMouseDevice = parent->mMouseDevice; - mMouseSerial = parent->mMouseSerial; - QWaylandWlShellSurface *wlshellSurface = dynamic_cast(mShellSurface); - if (mMouseDevice && wlshellSurface) { - wlshellSurface->setPopup(parent, mMouseDevice, mMouseSerial); - } + if (wlshellSurface) + wlshellSurface->setPopup(parent, mDisplay->lastInputDevice(), mDisplay->lastInputSerial()); } } @@ -579,7 +573,7 @@ QWaylandWindow *QWaylandWindow::transientParent() const if (window()->transientParent()) { // Take the top level window here, since the transient parent may be a QWidgetWindow // or some other window without a shell surface, which is then not able to get mouse - // events, nor set mMouseSerial and mMouseDevice. + // events. return static_cast(topLevelWindow(window()->transientParent())->handle()); } return 0; @@ -587,10 +581,6 @@ QWaylandWindow *QWaylandWindow::transientParent() const void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) { - if (b != Qt::NoButton) { - mMouseSerial = inputDevice->serial(); - mMouseDevice = inputDevice; - } if (mWindowDecoration) { handleMouseEventWithDecoration(inputDevice, timestamp,local,global,b,mods); diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index 6c32bc3ef2f..9ad6fe2f81a 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -220,8 +220,6 @@ protected: QPoint mOffset; QIcon mWindowIcon; - QWaylandInputDevice *mMouseDevice; - int mMouseSerial; Qt::WindowState mState; diff --git a/src/plugins/platforms/wayland/qwaylandwlshellsurface.cpp b/src/plugins/platforms/wayland/qwaylandwlshellsurface.cpp index 86115fa38b2..39505e1d8fb 100644 --- a/src/plugins/platforms/wayland/qwaylandwlshellsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandwlshellsurface.cpp @@ -187,8 +187,14 @@ void QWaylandWlShellSurface::updateTransientParent(QWindow *parent) void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial) { QWaylandWindow *parent_wayland_window = parent; - if (!parent_wayland_window) + if (!parent_wayland_window) { + qWarning("setPopup called without parent window"); return; + } + if (!device) { + qWarning("setPopup called without input device"); + return; + } // set_popup expects a position relative to the parent QPoint transientPos = m_window->geometry().topLeft(); // this is absolute