From 75eeae6b42ccf9d553ccc77c3efcf69470540120 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Tue, 25 Apr 2017 11:32:03 +0100 Subject: [PATCH] Update the ungrab mouse hack for Qt5.8 --- applets/appmenu/lib/appmenuapplet.cpp | 27 +++++++++++++++++++++++--- applets/systemtray/systemtray.cpp | 28 ++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/applets/appmenu/lib/appmenuapplet.cpp b/applets/appmenu/lib/appmenuapplet.cpp index 9aaf5cc68..a88122dd0 100644 --- a/applets/appmenu/lib/appmenuapplet.cpp +++ b/applets/appmenu/lib/appmenuapplet.cpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include AppMenuApplet::AppMenuApplet(QObject *parent, const QVariantList &data) : Plasma::Applet(parent, data) @@ -159,10 +161,29 @@ void AppMenuApplet::trigger(QQuickItem *ctx, int idx) QMenu *actionMenu = createMenu(idx); if (actionMenu) { - if (ctx && ctx->window() && ctx->window()->mouseGrabberItem()) { - // FIXME event forge thing enters press and hold move mode :/ - ctx->window()->mouseGrabberItem()->ungrabMouse(); + //this is a workaround where Qt will fail to realise a mouse has been released + // this happens if a window which does not accept focus spawns a new window that takes focus and X grab + // whilst the mouse is depressed + // https://bugreports.qt.io/browse/QTBUG-59044 + // this causes the next click to go missing + + //by releasing manually we avoid that situation + auto ungrabMouseHack = [ctx]() { + if (ctx && ctx->window() && ctx->window()->mouseGrabberItem()) { + // FIXME event forge thing enters press and hold move mode :/ + ctx->window()->mouseGrabberItem()->ungrabMouse(); + } + }; + + //pre 5.8.0 QQuickWindow code is "item->grabMouse(); sendEvent(item, mouseEvent)" + //post 5.8.0 QQuickWindow code is sendEvent(item, mouseEvent); item->grabMouse() + if (QVersionNumber::fromString(qVersion()) > QVersionNumber(5, 8, 0)) { + QTimer::singleShot(0, this, ungrabMouseHack); + } + else { + ungrabMouseHack(); } + //end workaround const auto &geo = ctx->window()->screen()->availableVirtualGeometry(); diff --git a/applets/systemtray/systemtray.cpp b/applets/systemtray/systemtray.cpp index 098395d06..ec921e7c6 100644 --- a/applets/systemtray/systemtray.cpp +++ b/applets/systemtray/systemtray.cpp @@ -22,7 +22,8 @@ #include #include - +#include +#include #include #include @@ -163,9 +164,30 @@ void SystemTray::showPlasmoidMenu(QQuickItem *appletInterface, int x, int y) connect(this, &QObject::destroyed, desktopMenu, &QMenu::close); desktopMenu->setAttribute(Qt::WA_DeleteOnClose); - if (appletInterface->window() && appletInterface->window()->mouseGrabberItem()) { - appletInterface->window()->mouseGrabberItem()->ungrabMouse(); + //this is a workaround where Qt will fail to realise a mouse has been released + + // this happens if a window which does not accept focus spawns a new window that takes focus and X grab + // whilst the mouse is depressed + // https://bugreports.qt.io/browse/QTBUG-59044 + // this causes the next click to go missing + + //by releasing manually we avoid that situation + auto ungrabMouseHack = [appletInterface]() { + if (appletInterface->window() && appletInterface->window()->mouseGrabberItem()) { + appletInterface->window()->mouseGrabberItem()->ungrabMouse(); + } + }; + + //pre 5.8.0 QQuickWindow code is "item->grabMouse(); sendEvent(item, mouseEvent)" + //post 5.8.0 QQuickWindow code is sendEvent(item, mouseEvent); item->grabMouse() + if (QVersionNumber::fromString(qVersion()) > QVersionNumber(5, 8, 0)) { + QTimer::singleShot(0, appletInterface, ungrabMouseHack); + } + else { + ungrabMouseHack(); } + //end workaround + emit applet->contextualActionsAboutToShow(); foreach (QAction *action, applet->contextualActions()) {