commit:     62fc0fc01e6db9b48defe9233f687b4b96dc1fba
Author:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
AuthorDate: Sat Feb  3 17:51:25 2018 +0000
Commit:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
CommitDate: Sat Feb  3 18:48:38 2018 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=62fc0fc0

dev-qt/qtgui: Fix desktop icon hover

Recommended by KDE.

See also: 
https://mail.kde.org/pipermail/kde-distro-packagers/2018-February/000303.html
See also: https://bugreports.qt.io/browse/QTBUG-66103
See also: https://codereview.qt-project.org/#/c/215939/

Package-Manager: Portage-2.3.24, Repoman-2.3.6

 dev-qt/qtgui/files/qtgui-5.9.4-qsimpledrag.patch | 170 ++++++++++++++++++++++
 dev-qt/qtgui/qtgui-5.9.4-r1.ebuild               | 173 +++++++++++++++++++++++
 2 files changed, 343 insertions(+)

diff --git a/dev-qt/qtgui/files/qtgui-5.9.4-qsimpledrag.patch 
b/dev-qt/qtgui/files/qtgui-5.9.4-qsimpledrag.patch
new file mode 100644
index 00000000000..60d2ec424f4
--- /dev/null
+++ b/dev-qt/qtgui/files/qtgui-5.9.4-qsimpledrag.patch
@@ -0,0 +1,170 @@
+From 4a7771f206d4b29be549d3827c36a46679d90de6 Mon Sep 17 00:00:00 2001
+From: Eike Hein <h...@kde.org>
+Date: Sun, 7 Jan 2018 13:02:01 +0900
+Subject: [PATCH] QSimpleDrag: Fix mouse release coords for delayed event
+ transmission
+
+On platforms such as XCB, the drag cursor pixmap is shown via a window
+(a QShapedPixmapWindow) under the cursor.
+
+The mouse button release event at the end of the drag is received in
+this QXcbWindow, but intercepted by an event filter that QSimpleDrag
+installs on the QApplication. It then resends it unmodified(!) after
+the drag has ended and the drag pixmap window destroyed, causing it to
+be delivered to the new top-level window.
+
+The local coordinates in the unmodified QMouseEvent are local to the
+drag pixmap window and don't match the window it is delayed-transmitted
+to.
+
+This ends up having fatal, user-visible effects particularly in Qt
+Quick: QQuickWindow synthesizes a hover event once per frame using
+the last received mouse coordinates, here: the release posted by
+QSimpleDrag. This is done to update the hover event state for items
+under the cursor when the mouse hasn't moved (e.g. QQuickMouseArea::
+containsMouse). The bogus event coordinates in the release event then
+usually end up causing an item near the top-left of the QQuickWindow
+to assume it is hovered (because drag pixmap windows tend to be small),
+even when the mouse cursor is actually far away from it at the end of
+the drag.
+
+This shows up e.g. in the Plasma 5 desktop, where dragging an icon
+on the desktop will cause the icon at the top-left of the screen (if
+any) to switch to hovered state, as the release coordinates on the
+drag pixmap window (showing a dragged icon) fall into the geometry
+of the top-left icon.
+
+QSimpleDrag contains a topLevelAt() function to find the top-level
+window under the global cursor coordinates that is not the drag
+pixmap window. This is used by the drop event delivery code.
+
+This patch uses this function to find the relevant top-level window,
+then asks it to map the global cusor coordinates to its local
+coordinate system, then synthesizes a new QMouseEvent with local
+coordinates computed in this fashion. As a result the window now
+gets a release event with coordinates that make sense and are
+correct.
+
+Task-number: QTBUG-66103
+Change-Id: I04ebe6ccd4a991fdd4b540ff0227973ea8896a9d
+Reviewed-by: Eike Hein <h...@kde.org>
+Reviewed-by: Shawn Rutledge <shawn.rutle...@qt.io>
+---
+ src/gui/kernel/qsimpledrag.cpp | 32 +++++++++++++++++++++++++++-----
+ src/gui/kernel/qsimpledrag_p.h |  6 +++---
+ 2 files changed, 30 insertions(+), 8 deletions(-)
+
+diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
+index a1e25dc..87d3ba5 100644
+--- a/src/gui/kernel/qsimpledrag.cpp
++++ b/src/gui/kernel/qsimpledrag.cpp
+@@ -58,6 +58,7 @@
+ 
+ #include <QtCore/QEventLoop>
+ #include <QtCore/QDebug>
++#include <QtCore/QLoggingCategory>
+ 
+ #include <private/qguiapplication_p.h>
+ #include <private/qdnd_p.h>
+@@ -69,6 +70,8 @@ QT_BEGIN_NAMESPACE
+ 
+ #ifndef QT_NO_DRAGANDDROP
+ 
++Q_LOGGING_CATEGORY(lcDnd, "qt.gui.dnd")
++
+ static QWindow* topLevelAt(const QPoint &pos)
+ {
+     QWindowList list = QGuiApplication::topLevelWindows();
+@@ -94,10 +97,10 @@ static QWindow* topLevelAt(const QPoint &pos)
+ */
+ 
+ QBasicDrag::QBasicDrag() :
+-    m_restoreCursor(false), m_eventLoop(0),
++    m_current_window(nullptr), m_restoreCursor(false), m_eventLoop(nullptr),
+     m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
+-    m_drag(0), m_drag_icon_window(0), m_useCompositing(true),
+-    m_screen(Q_NULLPTR)
++    m_drag(nullptr), m_drag_icon_window(nullptr), m_useCompositing(true),
++    m_screen(nullptr)
+ {
+ }
+ 
+@@ -161,6 +164,7 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
+             return true; // Eat all mouse move events
+         }
+         case QEvent::MouseButtonRelease:
++        {
+             disableEventFilter();
+             if (canDrop()) {
+                 QPoint nativePosition = getNativeMousePos(e, 
m_drag_icon_window);
+@@ -169,8 +173,25 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
+                 cancel();
+             }
+             exitDndEventLoop();
+-            QCoreApplication::postEvent(o, new 
QMouseEvent(*static_cast<QMouseEvent *>(e)));
++
++            // If a QShapedPixmapWindow (drag feedback) is being dragged 
along, the
++            // mouse event's localPos() will be relative to that, which is 
useless.
++            // We want a position relative to the window where the drag ends, 
if possible (?).
++            // If there is no such window (belonging to this Qt application),
++            // make the event relative to the window where the drag started. 
(QTBUG-66103)
++            const QMouseEvent *release = static_cast<QMouseEvent *>(e);
++            const QWindow *releaseWindow = topLevelAt(release->globalPos());
++            qCDebug(lcDnd) << "mouse released over" << releaseWindow << 
"after drag from" << m_current_window << "globalPos" << release->globalPos();
++            if (!releaseWindow)
++                releaseWindow = m_current_window;
++            QPoint releaseWindowPos = (releaseWindow ? 
releaseWindow->mapFromGlobal(release->globalPos()) : release->globalPos());
++            QMouseEvent *newRelease = new QMouseEvent(release->type(),
++                releaseWindowPos, releaseWindowPos, release->screenPos(),
++                release->button(), release->buttons(),
++                release->modifiers(), release->source());
++            QCoreApplication::postEvent(o, newRelease);
+             return true; // defer mouse release events until drag event loop 
has returned
++        }
+         case QEvent::MouseButtonDblClick:
+         case QEvent::Wheel:
+             return true;
+@@ -349,7 +370,7 @@ static inline QPoint fromNativeGlobalPixels(const QPoint 
&point)
+     into account.
+ */
+ 
+-QSimpleDrag::QSimpleDrag() : m_current_window(0)
++QSimpleDrag::QSimpleDrag()
+ {
+ }
+ 
+@@ -373,6 +394,7 @@ void QSimpleDrag::startDrag()
+         updateCursor(Qt::IgnoreAction);
+     }
+     setExecutedDropAction(Qt::IgnoreAction);
++    qCDebug(lcDnd) << "drag began from" << m_current_window<< "cursor pos" << 
QCursor::pos() << "can drop?" << canDrop();
+ }
+ 
+ void QSimpleDrag::cancel()
+diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
+index 0b8a0bc..bbd7f7f 100644
+--- a/src/gui/kernel/qsimpledrag_p.h
++++ b/src/gui/kernel/qsimpledrag_p.h
+@@ -105,6 +105,9 @@ protected:
+ 
+     QDrag *drag() const { return m_drag; }
+ 
++protected:
++    QWindow *m_current_window;
++
+ private:
+     void enableEventFilter();
+     void disableEventFilter();
+@@ -132,9 +135,6 @@ protected:
+     virtual void cancel() Q_DECL_OVERRIDE;
+     virtual void move(const QPoint &globalPos) Q_DECL_OVERRIDE;
+     virtual void drop(const QPoint &globalPos) Q_DECL_OVERRIDE;
+-
+-private:
+-    QWindow *m_current_window;
+ };
+ 
+ #endif // QT_NO_DRAGANDDROP
+-- 
+2.7.4
+

diff --git a/dev-qt/qtgui/qtgui-5.9.4-r1.ebuild 
b/dev-qt/qtgui/qtgui-5.9.4-r1.ebuild
new file mode 100644
index 00000000000..97069b8f2c4
--- /dev/null
+++ b/dev-qt/qtgui/qtgui-5.9.4-r1.ebuild
@@ -0,0 +1,173 @@
+# Copyright 1999-2018 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=6
+QT5_MODULE="qtbase"
+inherit qt5-build
+
+DESCRIPTION="The GUI module and platform plugins for the Qt5 framework"
+
+if [[ ${QT5_BUILD_TYPE} == release ]]; then
+       KEYWORDS="~amd64 ~arm ~arm64 ~hppa ~ppc ~ppc64 ~x86"
+fi
+
+# TODO: linuxfb
+
+IUSE="accessibility dbus egl eglfs evdev +gif gles2 ibus
+       jpeg +libinput +png tslib tuio +udev vnc +xcb"
+REQUIRED_USE="
+       || ( eglfs xcb )
+       accessibility? ( dbus xcb )
+       eglfs? ( egl )
+       ibus? ( dbus )
+       libinput? ( udev )
+       xcb? ( gles2? ( egl ) )
+"
+
+RDEPEND="
+       dev-libs/glib:2
+       ~dev-qt/qtcore-${PV}
+       media-libs/fontconfig
+       >=media-libs/freetype-2.6.1:2
+       >=media-libs/harfbuzz-1.0.6:=
+       >=sys-libs/zlib-1.2.5
+       virtual/opengl
+       dbus? ( ~dev-qt/qtdbus-${PV} )
+       egl? ( media-libs/mesa[egl] )
+       eglfs? (
+               media-libs/mesa[gbm]
+               x11-libs/libdrm
+       )
+       evdev? ( sys-libs/mtdev )
+       gles2? ( media-libs/mesa[gles2] )
+       jpeg? ( virtual/jpeg:0 )
+       libinput? (
+               dev-libs/libinput:=
+               x11-libs/libxkbcommon
+       )
+       png? ( media-libs/libpng:0= )
+       tslib? ( x11-libs/tslib )
+       tuio? ( ~dev-qt/qtnetwork-${PV} )
+       udev? ( virtual/libudev:= )
+       vnc? ( ~dev-qt/qtnetwork-${PV} )
+       xcb? (
+               x11-libs/libICE
+               x11-libs/libSM
+               x11-libs/libX11
+               >=x11-libs/libXi-1.7.5
+               >=x11-libs/libxcb-1.10:=[xkb]
+               >=x11-libs/libxkbcommon-0.4.1[X]
+               x11-libs/xcb-util-image
+               x11-libs/xcb-util-keysyms
+               x11-libs/xcb-util-renderutil
+               x11-libs/xcb-util-wm
+       )
+"
+DEPEND="${RDEPEND}
+       evdev? ( sys-kernel/linux-headers )
+       udev? ( sys-kernel/linux-headers )
+"
+PDEPEND="
+       ibus? ( app-i18n/ibus )
+"
+
+PATCHES=(
+       "${FILESDIR}/${P}-qsimpledrag.patch" # QTBUG-66103
+)
+
+QT5_TARGET_SUBDIRS=(
+       src/gui
+       src/openglextensions
+       src/platformheaders
+       src/platformsupport
+       src/plugins/generic
+       src/plugins/imageformats
+       src/plugins/platforms
+       src/plugins/platforminputcontexts
+)
+
+QT5_GENTOO_CONFIG=(
+       accessibility:accessibility-atspi-bridge
+       egl
+       eglfs
+       eglfs:eglfs_egldevice:
+       eglfs:eglfs_gbm:
+       evdev
+       evdev:mtdev:
+       :fontconfig
+       :system-freetype:FREETYPE
+       !:no-freetype:
+       !gif:no-gif:
+       gles2::OPENGL_ES
+       gles2:opengles2:OPENGL_ES_2
+       !:no-gui:
+       :system-harfbuzz:HARFBUZZ
+       !:no-harfbuzz:
+       jpeg:system-jpeg:IMAGEFORMAT_JPEG
+       !jpeg:no-jpeg:
+       libinput
+       libinput:xkbcommon-evdev:
+       :opengl
+       png:png:
+       png:system-png:IMAGEFORMAT_PNG
+       !png:no-png:
+       tslib
+       udev:libudev:
+       xcb:xcb:
+       xcb:xcb-glx:
+       xcb:xcb-plugin:
+       xcb:xcb-render:
+       xcb:xcb-sm:
+       xcb:xcb-xlib:
+       xcb:xinput2:
+       xcb::XKB
+)
+
+QT5_GENTOO_PRIVATE_CONFIG=(
+       :gui
+)
+
+src_prepare() {
+       # egl_x11 is activated when both egl and xcb are enabled
+       use egl && QT5_GENTOO_CONFIG+=(xcb:egl_x11) || 
QT5_GENTOO_CONFIG+=(egl:egl_x11)
+
+       qt_use_disable_config dbus dbus \
+               src/platformsupport/themes/genericunix/genericunix.pri
+
+       qt_use_disable_config tuio udpsocket src/plugins/generic/generic.pro
+
+       qt_use_disable_mod ibus dbus \
+               src/plugins/platforminputcontexts/platforminputcontexts.pro
+
+       use vnc || sed -i -e '/SUBDIRS += vnc/d' \
+               src/plugins/platforms/platforms.pro || die
+
+       qt5-build_src_prepare
+}
+
+src_configure() {
+       local myconf=(
+               $(usex dbus -dbus-linked '')
+               $(qt_use egl)
+               $(qt_use eglfs)
+               $(usex eglfs '-gbm -kms' '')
+               $(qt_use evdev)
+               $(qt_use evdev mtdev)
+               -fontconfig
+               -system-freetype
+               $(usex gif '' -no-gif)
+               -gui
+               -system-harfbuzz
+               $(qt_use jpeg libjpeg system)
+               $(qt_use libinput)
+               $(qt_use libinput xkbcommon-evdev)
+               -opengl $(usex gles2 es2 desktop)
+               $(qt_use png libpng system)
+               $(qt_use tslib)
+               $(qt_use udev libudev)
+               $(qt_use xcb xcb system)
+               $(qt_use xcb xkbcommon-x11 system)
+               $(usex xcb '-xcb-xlib -xinput2 -xkb' '')
+       )
+       qt5-build_src_configure
+}

Reply via email to