Gentoo Archives: gentoo-commits

From: Andreas Sturmlechner <asturm@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: dev-qt/qtgui/, dev-qt/qtgui/files/
Date: Sat, 03 Feb 2018 18:49:35
Message-Id: 1517683718.62fc0fc01e6db9b48defe9233f687b4b96dc1fba.asturm@gentoo
1 commit: 62fc0fc01e6db9b48defe9233f687b4b96dc1fba
2 Author: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
3 AuthorDate: Sat Feb 3 17:51:25 2018 +0000
4 Commit: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
5 CommitDate: Sat Feb 3 18:48:38 2018 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=62fc0fc0
7
8 dev-qt/qtgui: Fix desktop icon hover
9
10 Recommended by KDE.
11
12 See also: https://mail.kde.org/pipermail/kde-distro-packagers/2018-February/000303.html
13 See also: https://bugreports.qt.io/browse/QTBUG-66103
14 See also: https://codereview.qt-project.org/#/c/215939/
15
16 Package-Manager: Portage-2.3.24, Repoman-2.3.6
17
18 dev-qt/qtgui/files/qtgui-5.9.4-qsimpledrag.patch | 170 ++++++++++++++++++++++
19 dev-qt/qtgui/qtgui-5.9.4-r1.ebuild | 173 +++++++++++++++++++++++
20 2 files changed, 343 insertions(+)
21
22 diff --git a/dev-qt/qtgui/files/qtgui-5.9.4-qsimpledrag.patch b/dev-qt/qtgui/files/qtgui-5.9.4-qsimpledrag.patch
23 new file mode 100644
24 index 00000000000..60d2ec424f4
25 --- /dev/null
26 +++ b/dev-qt/qtgui/files/qtgui-5.9.4-qsimpledrag.patch
27 @@ -0,0 +1,170 @@
28 +From 4a7771f206d4b29be549d3827c36a46679d90de6 Mon Sep 17 00:00:00 2001
29 +From: Eike Hein <hein@×××.org>
30 +Date: Sun, 7 Jan 2018 13:02:01 +0900
31 +Subject: [PATCH] QSimpleDrag: Fix mouse release coords for delayed event
32 + transmission
33 +
34 +On platforms such as XCB, the drag cursor pixmap is shown via a window
35 +(a QShapedPixmapWindow) under the cursor.
36 +
37 +The mouse button release event at the end of the drag is received in
38 +this QXcbWindow, but intercepted by an event filter that QSimpleDrag
39 +installs on the QApplication. It then resends it unmodified(!) after
40 +the drag has ended and the drag pixmap window destroyed, causing it to
41 +be delivered to the new top-level window.
42 +
43 +The local coordinates in the unmodified QMouseEvent are local to the
44 +drag pixmap window and don't match the window it is delayed-transmitted
45 +to.
46 +
47 +This ends up having fatal, user-visible effects particularly in Qt
48 +Quick: QQuickWindow synthesizes a hover event once per frame using
49 +the last received mouse coordinates, here: the release posted by
50 +QSimpleDrag. This is done to update the hover event state for items
51 +under the cursor when the mouse hasn't moved (e.g. QQuickMouseArea::
52 +containsMouse). The bogus event coordinates in the release event then
53 +usually end up causing an item near the top-left of the QQuickWindow
54 +to assume it is hovered (because drag pixmap windows tend to be small),
55 +even when the mouse cursor is actually far away from it at the end of
56 +the drag.
57 +
58 +This shows up e.g. in the Plasma 5 desktop, where dragging an icon
59 +on the desktop will cause the icon at the top-left of the screen (if
60 +any) to switch to hovered state, as the release coordinates on the
61 +drag pixmap window (showing a dragged icon) fall into the geometry
62 +of the top-left icon.
63 +
64 +QSimpleDrag contains a topLevelAt() function to find the top-level
65 +window under the global cursor coordinates that is not the drag
66 +pixmap window. This is used by the drop event delivery code.
67 +
68 +This patch uses this function to find the relevant top-level window,
69 +then asks it to map the global cusor coordinates to its local
70 +coordinate system, then synthesizes a new QMouseEvent with local
71 +coordinates computed in this fashion. As a result the window now
72 +gets a release event with coordinates that make sense and are
73 +correct.
74 +
75 +Task-number: QTBUG-66103
76 +Change-Id: I04ebe6ccd4a991fdd4b540ff0227973ea8896a9d
77 +Reviewed-by: Eike Hein <hein@×××.org>
78 +Reviewed-by: Shawn Rutledge <shawn.rutledge@××.io>
79 +---
80 + src/gui/kernel/qsimpledrag.cpp | 32 +++++++++++++++++++++++++++-----
81 + src/gui/kernel/qsimpledrag_p.h | 6 +++---
82 + 2 files changed, 30 insertions(+), 8 deletions(-)
83 +
84 +diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
85 +index a1e25dc..87d3ba5 100644
86 +--- a/src/gui/kernel/qsimpledrag.cpp
87 ++++ b/src/gui/kernel/qsimpledrag.cpp
88 +@@ -58,6 +58,7 @@
89 +
90 + #include <QtCore/QEventLoop>
91 + #include <QtCore/QDebug>
92 ++#include <QtCore/QLoggingCategory>
93 +
94 + #include <private/qguiapplication_p.h>
95 + #include <private/qdnd_p.h>
96 +@@ -69,6 +70,8 @@ QT_BEGIN_NAMESPACE
97 +
98 + #ifndef QT_NO_DRAGANDDROP
99 +
100 ++Q_LOGGING_CATEGORY(lcDnd, "qt.gui.dnd")
101 ++
102 + static QWindow* topLevelAt(const QPoint &pos)
103 + {
104 + QWindowList list = QGuiApplication::topLevelWindows();
105 +@@ -94,10 +97,10 @@ static QWindow* topLevelAt(const QPoint &pos)
106 + */
107 +
108 + QBasicDrag::QBasicDrag() :
109 +- m_restoreCursor(false), m_eventLoop(0),
110 ++ m_current_window(nullptr), m_restoreCursor(false), m_eventLoop(nullptr),
111 + m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
112 +- m_drag(0), m_drag_icon_window(0), m_useCompositing(true),
113 +- m_screen(Q_NULLPTR)
114 ++ m_drag(nullptr), m_drag_icon_window(nullptr), m_useCompositing(true),
115 ++ m_screen(nullptr)
116 + {
117 + }
118 +
119 +@@ -161,6 +164,7 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
120 + return true; // Eat all mouse move events
121 + }
122 + case QEvent::MouseButtonRelease:
123 ++ {
124 + disableEventFilter();
125 + if (canDrop()) {
126 + QPoint nativePosition = getNativeMousePos(e, m_drag_icon_window);
127 +@@ -169,8 +173,25 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
128 + cancel();
129 + }
130 + exitDndEventLoop();
131 +- QCoreApplication::postEvent(o, new QMouseEvent(*static_cast<QMouseEvent *>(e)));
132 ++
133 ++ // If a QShapedPixmapWindow (drag feedback) is being dragged along, the
134 ++ // mouse event's localPos() will be relative to that, which is useless.
135 ++ // We want a position relative to the window where the drag ends, if possible (?).
136 ++ // If there is no such window (belonging to this Qt application),
137 ++ // make the event relative to the window where the drag started. (QTBUG-66103)
138 ++ const QMouseEvent *release = static_cast<QMouseEvent *>(e);
139 ++ const QWindow *releaseWindow = topLevelAt(release->globalPos());
140 ++ qCDebug(lcDnd) << "mouse released over" << releaseWindow << "after drag from" << m_current_window << "globalPos" << release->globalPos();
141 ++ if (!releaseWindow)
142 ++ releaseWindow = m_current_window;
143 ++ QPoint releaseWindowPos = (releaseWindow ? releaseWindow->mapFromGlobal(release->globalPos()) : release->globalPos());
144 ++ QMouseEvent *newRelease = new QMouseEvent(release->type(),
145 ++ releaseWindowPos, releaseWindowPos, release->screenPos(),
146 ++ release->button(), release->buttons(),
147 ++ release->modifiers(), release->source());
148 ++ QCoreApplication::postEvent(o, newRelease);
149 + return true; // defer mouse release events until drag event loop has returned
150 ++ }
151 + case QEvent::MouseButtonDblClick:
152 + case QEvent::Wheel:
153 + return true;
154 +@@ -349,7 +370,7 @@ static inline QPoint fromNativeGlobalPixels(const QPoint &point)
155 + into account.
156 + */
157 +
158 +-QSimpleDrag::QSimpleDrag() : m_current_window(0)
159 ++QSimpleDrag::QSimpleDrag()
160 + {
161 + }
162 +
163 +@@ -373,6 +394,7 @@ void QSimpleDrag::startDrag()
164 + updateCursor(Qt::IgnoreAction);
165 + }
166 + setExecutedDropAction(Qt::IgnoreAction);
167 ++ qCDebug(lcDnd) << "drag began from" << m_current_window<< "cursor pos" << QCursor::pos() << "can drop?" << canDrop();
168 + }
169 +
170 + void QSimpleDrag::cancel()
171 +diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
172 +index 0b8a0bc..bbd7f7f 100644
173 +--- a/src/gui/kernel/qsimpledrag_p.h
174 ++++ b/src/gui/kernel/qsimpledrag_p.h
175 +@@ -105,6 +105,9 @@ protected:
176 +
177 + QDrag *drag() const { return m_drag; }
178 +
179 ++protected:
180 ++ QWindow *m_current_window;
181 ++
182 + private:
183 + void enableEventFilter();
184 + void disableEventFilter();
185 +@@ -132,9 +135,6 @@ protected:
186 + virtual void cancel() Q_DECL_OVERRIDE;
187 + virtual void move(const QPoint &globalPos) Q_DECL_OVERRIDE;
188 + virtual void drop(const QPoint &globalPos) Q_DECL_OVERRIDE;
189 +-
190 +-private:
191 +- QWindow *m_current_window;
192 + };
193 +
194 + #endif // QT_NO_DRAGANDDROP
195 +--
196 +2.7.4
197 +
198
199 diff --git a/dev-qt/qtgui/qtgui-5.9.4-r1.ebuild b/dev-qt/qtgui/qtgui-5.9.4-r1.ebuild
200 new file mode 100644
201 index 00000000000..97069b8f2c4
202 --- /dev/null
203 +++ b/dev-qt/qtgui/qtgui-5.9.4-r1.ebuild
204 @@ -0,0 +1,173 @@
205 +# Copyright 1999-2018 Gentoo Foundation
206 +# Distributed under the terms of the GNU General Public License v2
207 +
208 +EAPI=6
209 +QT5_MODULE="qtbase"
210 +inherit qt5-build
211 +
212 +DESCRIPTION="The GUI module and platform plugins for the Qt5 framework"
213 +
214 +if [[ ${QT5_BUILD_TYPE} == release ]]; then
215 + KEYWORDS="~amd64 ~arm ~arm64 ~hppa ~ppc ~ppc64 ~x86"
216 +fi
217 +
218 +# TODO: linuxfb
219 +
220 +IUSE="accessibility dbus egl eglfs evdev +gif gles2 ibus
221 + jpeg +libinput +png tslib tuio +udev vnc +xcb"
222 +REQUIRED_USE="
223 + || ( eglfs xcb )
224 + accessibility? ( dbus xcb )
225 + eglfs? ( egl )
226 + ibus? ( dbus )
227 + libinput? ( udev )
228 + xcb? ( gles2? ( egl ) )
229 +"
230 +
231 +RDEPEND="
232 + dev-libs/glib:2
233 + ~dev-qt/qtcore-${PV}
234 + media-libs/fontconfig
235 + >=media-libs/freetype-2.6.1:2
236 + >=media-libs/harfbuzz-1.0.6:=
237 + >=sys-libs/zlib-1.2.5
238 + virtual/opengl
239 + dbus? ( ~dev-qt/qtdbus-${PV} )
240 + egl? ( media-libs/mesa[egl] )
241 + eglfs? (
242 + media-libs/mesa[gbm]
243 + x11-libs/libdrm
244 + )
245 + evdev? ( sys-libs/mtdev )
246 + gles2? ( media-libs/mesa[gles2] )
247 + jpeg? ( virtual/jpeg:0 )
248 + libinput? (
249 + dev-libs/libinput:=
250 + x11-libs/libxkbcommon
251 + )
252 + png? ( media-libs/libpng:0= )
253 + tslib? ( x11-libs/tslib )
254 + tuio? ( ~dev-qt/qtnetwork-${PV} )
255 + udev? ( virtual/libudev:= )
256 + vnc? ( ~dev-qt/qtnetwork-${PV} )
257 + xcb? (
258 + x11-libs/libICE
259 + x11-libs/libSM
260 + x11-libs/libX11
261 + >=x11-libs/libXi-1.7.5
262 + >=x11-libs/libxcb-1.10:=[xkb]
263 + >=x11-libs/libxkbcommon-0.4.1[X]
264 + x11-libs/xcb-util-image
265 + x11-libs/xcb-util-keysyms
266 + x11-libs/xcb-util-renderutil
267 + x11-libs/xcb-util-wm
268 + )
269 +"
270 +DEPEND="${RDEPEND}
271 + evdev? ( sys-kernel/linux-headers )
272 + udev? ( sys-kernel/linux-headers )
273 +"
274 +PDEPEND="
275 + ibus? ( app-i18n/ibus )
276 +"
277 +
278 +PATCHES=(
279 + "${FILESDIR}/${P}-qsimpledrag.patch" # QTBUG-66103
280 +)
281 +
282 +QT5_TARGET_SUBDIRS=(
283 + src/gui
284 + src/openglextensions
285 + src/platformheaders
286 + src/platformsupport
287 + src/plugins/generic
288 + src/plugins/imageformats
289 + src/plugins/platforms
290 + src/plugins/platforminputcontexts
291 +)
292 +
293 +QT5_GENTOO_CONFIG=(
294 + accessibility:accessibility-atspi-bridge
295 + egl
296 + eglfs
297 + eglfs:eglfs_egldevice:
298 + eglfs:eglfs_gbm:
299 + evdev
300 + evdev:mtdev:
301 + :fontconfig
302 + :system-freetype:FREETYPE
303 + !:no-freetype:
304 + !gif:no-gif:
305 + gles2::OPENGL_ES
306 + gles2:opengles2:OPENGL_ES_2
307 + !:no-gui:
308 + :system-harfbuzz:HARFBUZZ
309 + !:no-harfbuzz:
310 + jpeg:system-jpeg:IMAGEFORMAT_JPEG
311 + !jpeg:no-jpeg:
312 + libinput
313 + libinput:xkbcommon-evdev:
314 + :opengl
315 + png:png:
316 + png:system-png:IMAGEFORMAT_PNG
317 + !png:no-png:
318 + tslib
319 + udev:libudev:
320 + xcb:xcb:
321 + xcb:xcb-glx:
322 + xcb:xcb-plugin:
323 + xcb:xcb-render:
324 + xcb:xcb-sm:
325 + xcb:xcb-xlib:
326 + xcb:xinput2:
327 + xcb::XKB
328 +)
329 +
330 +QT5_GENTOO_PRIVATE_CONFIG=(
331 + :gui
332 +)
333 +
334 +src_prepare() {
335 + # egl_x11 is activated when both egl and xcb are enabled
336 + use egl && QT5_GENTOO_CONFIG+=(xcb:egl_x11) || QT5_GENTOO_CONFIG+=(egl:egl_x11)
337 +
338 + qt_use_disable_config dbus dbus \
339 + src/platformsupport/themes/genericunix/genericunix.pri
340 +
341 + qt_use_disable_config tuio udpsocket src/plugins/generic/generic.pro
342 +
343 + qt_use_disable_mod ibus dbus \
344 + src/plugins/platforminputcontexts/platforminputcontexts.pro
345 +
346 + use vnc || sed -i -e '/SUBDIRS += vnc/d' \
347 + src/plugins/platforms/platforms.pro || die
348 +
349 + qt5-build_src_prepare
350 +}
351 +
352 +src_configure() {
353 + local myconf=(
354 + $(usex dbus -dbus-linked '')
355 + $(qt_use egl)
356 + $(qt_use eglfs)
357 + $(usex eglfs '-gbm -kms' '')
358 + $(qt_use evdev)
359 + $(qt_use evdev mtdev)
360 + -fontconfig
361 + -system-freetype
362 + $(usex gif '' -no-gif)
363 + -gui
364 + -system-harfbuzz
365 + $(qt_use jpeg libjpeg system)
366 + $(qt_use libinput)
367 + $(qt_use libinput xkbcommon-evdev)
368 + -opengl $(usex gles2 es2 desktop)
369 + $(qt_use png libpng system)
370 + $(qt_use tslib)
371 + $(qt_use udev libudev)
372 + $(qt_use xcb xcb system)
373 + $(qt_use xcb xkbcommon-x11 system)
374 + $(usex xcb '-xcb-xlib -xinput2 -xkb' '')
375 + )
376 + qt5-build_src_configure
377 +}