Merge lp:~lukas-kde/qtmir/wheelEvent into lp:qtmir

Proposed by Lukáš Tinkl
Status: Merged
Approved by: Gerry Boland
Approved revision: 389
Merged at revision: 396
Proposed branch: lp:~lukas-kde/qtmir/wheelEvent
Merge into: lp:qtmir
Prerequisite: lp:~unity-team/qtmir/touch_tracing
Diff against target: 268 lines (+111/-17)
8 files modified
src/modules/Unity/Application/mirsurface.cpp (+38/-8)
src/modules/Unity/Application/mirsurface.h (+1/-0)
src/modules/Unity/Application/mirsurfaceinterface.h (+1/-0)
src/modules/Unity/Application/mirsurfaceitem.cpp (+5/-1)
src/platforms/mirserver/qteventfeeder.cpp (+54/-7)
src/platforms/mirserver/qteventfeeder.h (+6/-0)
tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h (+5/-1)
tests/modules/common/fake_mirsurface.h (+1/-0)
To merge this branch: bzr merge lp:~lukas-kde/qtmir/wheelEvent
Reviewer Review Type Date Requested Status
Daniel d'Andrada (community) Abstain
Gerry Boland (community) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+274313@code.launchpad.net

This proposal supersedes a proposal from 2015-10-01.

Commit message

Implement support for mouse wheel events; correctly pass around buttons

Description of the change

Implement support for mouse wheel events; also correctly pass around buttons

Cf. https://bugs.launchpad.net/ubuntu/+source/qtmir/+bug/1497091

* Are there any related MPs required for this MP to build/function as expected? Please list.

https://code.launchpad.net/~lukas-kde/qtubuntu/wheelEvent/+merge/273149

* Did you perform an exploratory manual test run of your code change and any related functionality?

Yes

* Did you make sure that your branch does not contain spurious tags?

Yes

* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?

Yes

* If you changed the UI, has there been a design review?

N/A

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

"""
-pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=8)
+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application>=8)
"""

The unity-api versioning scheme is made so that qtmir and unity8 depend on a *specific* version of the API. That's meant solely ensure that qtmir and unity8 are kept in sync. There's absolutely no guarantee (or effort to towards it) that a given version is backward or forward compatible.

review: Needs Fixing
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

> """
> -pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=8)
> +pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application>=8)
> """
>
> The unity-api versioning scheme is made so that qtmir and unity8 depend on a
> *specific* version of the API. That's meant solely ensure that qtmir and
> unity8 are kept in sync. There's absolutely no guarantee (or effort to towards
> it) that a given version is backward or forward compatible.

Got it, fixed

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

Could you please move "getMirButtonsFromQt(qtEvent->buttons())" into a separate variable like it's being done for timestamp and modifiers?

The mir::events::make_event() call is already messy from having such a large number of parameters. Using those helper variables improve readability and I think won't impact performance as I bet they will be optimized away by the compiler.

Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

> Could you please move "getMirButtonsFromQt(qtEvent->buttons())" into a
> separate variable like it's being done for timestamp and modifiers?
>
> The mir::events::make_event() call is already messy from having such a large
> number of parameters. Using those helper variables improve readability and I
> think won't impact performance as I bet they will be optimized away by the
> compiler.

Done

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

the handleWheelEvent() line in qteventfeeder.h is way too long. Please avoid going beyond 120 chars. It's our coding style (which, by the way, I couldn't find it right now).

That's the last nitpick I have with this MP. :)

Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

> the handleWheelEvent() line in qteventfeeder.h is way too long. Please avoid
> going beyond 120 chars. It's our coding style (which, by the way, I couldn't
> find it right now).
>
> That's the last nitpick I have with this MP. :)

Fixed

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

> > the handleWheelEvent() line in qteventfeeder.h is way too long. Please avoid
> > going beyond 120 chars. It's our coding style (which, by the way, I couldn't
> > find it right now).
> >
> > That's the last nitpick I have with this MP. :)
>
> Fixed

Thanks!

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~lukas-kde/qtmir/wheelEvent updated
389. By Lukáš Tinkl

merge lp:~unity-team/qtmir/touch_tracing

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

LGTM

review: Approve
Revision history for this message
Daniel d'Andrada (dandrader) :
review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/modules/Unity/Application/mirsurface.cpp'
2--- src/modules/Unity/Application/mirsurface.cpp 2015-10-14 13:36:55 +0000
3+++ src/modules/Unity/Application/mirsurface.cpp 2015-10-14 13:36:55 +0000
4@@ -50,18 +50,29 @@
5 return m_mods;
6 }
7
8+MirPointerButtons
9+getMirButtonsFromQt(Qt::MouseButtons buttons)
10+{
11+ MirPointerButtons result = 0;
12+ if (buttons & Qt::LeftButton)
13+ result |= mir_pointer_button_primary;
14+ if (buttons & Qt::RightButton)
15+ result |= mir_pointer_button_secondary;
16+ if (buttons & Qt::MiddleButton)
17+ result |= mir_pointer_button_tertiary;
18+ if (buttons & Qt::BackButton)
19+ result |= mir_pointer_button_back;
20+ if (buttons & Qt::ForwardButton)
21+ result |= mir_pointer_button_forward;
22+
23+ return result;
24+}
25+
26 mir::EventUPtr makeMirEvent(QMouseEvent *qtEvent, MirPointerAction action)
27 {
28 auto timestamp = uncompressTimestamp<ulong>(qtEvent->timestamp());
29 auto modifiers = getMirModifiersFromQt(qtEvent->modifiers());
30-
31- MirPointerButtons buttons = 0;
32- if (qtEvent->buttons() & Qt::LeftButton)
33- buttons |= mir_pointer_button_primary;
34- if (qtEvent->buttons() & Qt::RightButton)
35- buttons |= mir_pointer_button_secondary;
36- if (qtEvent->buttons() & Qt::MidButton)
37- buttons |= mir_pointer_button_tertiary;
38+ auto buttons = getMirButtonsFromQt(qtEvent->buttons());
39
40 return mir::events::make_event(0 /*DeviceID */, timestamp, 0 /* mac */, modifiers, action,
41 buttons, qtEvent->x(), qtEvent->y(), 0, 0, 0, 0);
42@@ -77,6 +88,18 @@
43 buttons, qtEvent->posF().x(), qtEvent->posF().y(), 0, 0, 0, 0);
44 }
45
46+mir::EventUPtr makeMirEvent(QWheelEvent *qtEvent)
47+{
48+ auto timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds(qtEvent->timestamp()));
49+ auto modifiers = getMirModifiersFromQt(qtEvent->modifiers());
50+ auto buttons = getMirButtonsFromQt(qtEvent->buttons());
51+
52+ return mir::events::make_event(0 /*DeviceID */, timestamp, 0 /* mac */, modifiers, mir_pointer_action_motion,
53+ buttons, qtEvent->x(), qtEvent->y(),
54+ qtEvent->angleDelta().x(), qtEvent->angleDelta().y(),
55+ 0, 0);
56+}
57+
58 mir::EventUPtr makeMirEvent(QKeyEvent *qtEvent)
59 {
60 MirKeyboardAction action = mir_keyboard_action_down;
61@@ -574,6 +597,13 @@
62 event->accept();
63 }
64
65+void MirSurface::wheelEvent(QWheelEvent *event)
66+{
67+ auto ev = makeMirEvent(event);
68+ m_surface->consume(*ev);
69+ event->accept();
70+}
71+
72 void MirSurface::keyPressEvent(QKeyEvent *qtEvent)
73 {
74 auto ev = makeMirEvent(qtEvent);
75
76=== modified file 'src/modules/Unity/Application/mirsurface.h'
77--- src/modules/Unity/Application/mirsurface.h 2015-10-14 13:36:55 +0000
78+++ src/modules/Unity/Application/mirsurface.h 2015-10-14 13:36:55 +0000
79@@ -100,6 +100,7 @@
80 void hoverEnterEvent(QHoverEvent *event) override;
81 void hoverLeaveEvent(QHoverEvent *event) override;
82 void hoverMoveEvent(QHoverEvent *event) override;
83+ void wheelEvent(QWheelEvent *event) override;
84
85 void keyPressEvent(QKeyEvent *event) override;
86 void keyReleaseEvent(QKeyEvent *event) override;
87
88=== modified file 'src/modules/Unity/Application/mirsurfaceinterface.h'
89--- src/modules/Unity/Application/mirsurfaceinterface.h 2015-10-14 13:36:55 +0000
90+++ src/modules/Unity/Application/mirsurfaceinterface.h 2015-10-14 13:36:55 +0000
91@@ -67,6 +67,7 @@
92 virtual void hoverEnterEvent(QHoverEvent *event) = 0;
93 virtual void hoverLeaveEvent(QHoverEvent *event) = 0;
94 virtual void hoverMoveEvent(QHoverEvent *event) = 0;
95+ virtual void wheelEvent(QWheelEvent *event) = 0;
96
97 virtual void keyPressEvent(QKeyEvent *event) = 0;
98 virtual void keyReleaseEvent(QKeyEvent *event) = 0;
99
100=== modified file 'src/modules/Unity/Application/mirsurfaceitem.cpp'
101--- src/modules/Unity/Application/mirsurfaceitem.cpp 2015-10-14 13:36:55 +0000
102+++ src/modules/Unity/Application/mirsurfaceitem.cpp 2015-10-14 13:36:55 +0000
103@@ -298,7 +298,11 @@
104
105 void MirSurfaceItem::wheelEvent(QWheelEvent *event)
106 {
107- Q_UNUSED(event);
108+ if (m_consumesInput && m_surface && m_surface->live()) {
109+ m_surface->wheelEvent(event);
110+ } else {
111+ event->ignore();
112+ }
113 }
114
115 void MirSurfaceItem::hoverEnterEvent(QHoverEvent *event)
116
117=== modified file 'src/platforms/mirserver/qteventfeeder.cpp'
118--- src/platforms/mirserver/qteventfeeder.cpp 2015-10-14 13:36:55 +0000
119+++ src/platforms/mirserver/qteventfeeder.cpp 2015-10-14 13:36:55 +0000
120@@ -416,7 +416,8 @@
121 QWindowSystemInterface::handleTouchEvent(window, timestamp, device, points, mods);
122 }
123
124- void handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) override
125+ void handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons,
126+ Qt::KeyboardModifiers modifiers) override
127 {
128 // Send to the first screen that handles the mouse event
129 // TODO: Have a mechanism to tell which screen currently has the logical mouse pointer
130@@ -434,6 +435,25 @@
131 }
132 }
133
134+ void handleWheelEvent(ulong timestamp, const QPointF &localPoint, const QPointF &globalPoint,
135+ QPoint pixelDelta, QPoint angleDelta,
136+ Qt::KeyboardModifiers mods, Qt::ScrollPhase phase) override
137+ {
138+ QWindowSystemInterface::handleWheelEvent(m_screenController->getWindowForPoint(localPoint.toPoint()),
139+ timestamp, localPoint, globalPoint,
140+ pixelDelta, angleDelta, mods, phase);
141+ }
142+
143+ void handleEnterEvent(const QPointF &localPoint, const QPointF &globalPoint) override
144+ {
145+ QWindowSystemInterface::handleEnterEvent(m_screenController->getWindowForPoint(localPoint.toPoint()), localPoint, globalPoint);
146+ }
147+
148+ void handleLeaveEvent(const QPointF &localPoint) override
149+ {
150+ QWindowSystemInterface::handleLeaveEvent(m_screenController->getWindowForPoint(localPoint.toPoint()));
151+ }
152+
153 private:
154 QSharedPointer<ScreenController> m_screenController;
155 };
156@@ -496,7 +516,7 @@
157
158 Qt::KeyboardModifiers getQtModifiersFromMir(MirInputEventModifiers modifiers)
159 {
160- int qtModifiers = Qt::NoModifier;
161+ Qt::KeyboardModifiers qtModifiers = Qt::NoModifier;
162 if (modifiers & mir_input_event_modifier_shift) {
163 qtModifiers |= Qt::ShiftModifier;
164 }
165@@ -509,7 +529,7 @@
166 if (modifiers & mir_input_event_modifier_meta) {
167 qtModifiers |= Qt::MetaModifier;
168 }
169- return static_cast<Qt::KeyboardModifiers>(qtModifiers);
170+ return qtModifiers;
171 }
172
173 Qt::MouseButtons getQtMouseButtonsfromMirPointerEvent(MirPointerEvent const* pev)
174@@ -533,17 +553,44 @@
175 void QtEventFeeder::dispatchPointer(MirInputEvent const* ev)
176 {
177 auto timestamp = qtmir::compressTimestamp<ulong>(std::chrono::nanoseconds(mir_input_event_get_event_time(ev)));
178-
179 auto pev = mir_input_event_get_pointer_event(ev);
180+ auto action = mir_pointer_event_action(pev);
181 qCDebug(QTMIR_MIR_INPUT) << "Received" << qPrintable(mirPointerEventToString(pev));
182
183 auto modifiers = getQtModifiersFromMir(mir_pointer_event_modifiers(pev));
184- auto buttons = getQtMouseButtonsfromMirPointerEvent(pev);
185
186 auto movement = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x),
187 mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y));
188-
189- mQtWindowSystem->handleMouseEvent(timestamp, movement, buttons, modifiers);
190+ auto local_point = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x),
191+ mir_pointer_event_axis_value(pev, mir_pointer_axis_y));
192+
193+ switch (action) {
194+ case mir_pointer_action_button_up:
195+ case mir_pointer_action_button_down:
196+ case mir_pointer_action_motion:
197+ {
198+ const float hDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_hscroll);
199+ const float vDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll);
200+
201+ if (hDelta != 0 || vDelta != 0) {
202+ const QPoint angleDelta = QPoint(hDelta * 15, vDelta * 15);
203+ mQtWindowSystem->handleWheelEvent(timestamp, local_point, local_point,
204+ QPoint(), angleDelta, modifiers, Qt::ScrollUpdate);
205+ } else {
206+ auto buttons = getQtMouseButtonsfromMirPointerEvent(pev);
207+ mQtWindowSystem->handleMouseEvent(timestamp, movement, buttons, modifiers);
208+ }
209+ break;
210+ }
211+ case mir_pointer_action_enter:
212+ mQtWindowSystem->handleEnterEvent(local_point, local_point);
213+ break;
214+ case mir_pointer_action_leave:
215+ mQtWindowSystem->handleLeaveEvent(local_point);
216+ break;
217+ default:
218+ qCDebug(QTMIR_MIR_INPUT) << "Unrecognized pointer event";
219+ }
220 }
221
222 void QtEventFeeder::dispatchKey(MirInputEvent const* event)
223
224=== modified file 'src/platforms/mirserver/qteventfeeder.h'
225--- src/platforms/mirserver/qteventfeeder.h 2015-10-14 13:36:55 +0000
226+++ src/platforms/mirserver/qteventfeeder.h 2015-10-14 13:36:55 +0000
227@@ -52,6 +52,12 @@
228 Qt::KeyboardModifiers mods = Qt::NoModifier) = 0;
229 virtual void handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons,
230 Qt::KeyboardModifiers modifiers) = 0;
231+ virtual void handleWheelEvent(ulong timestamp, const QPointF &localPoint, const QPointF &globalPoint,
232+ QPoint pixelDelta, QPoint angleDelta,
233+ Qt::KeyboardModifiers mods = Qt::NoModifier,
234+ Qt::ScrollPhase phase = Qt::ScrollUpdate) = 0;
235+ virtual void handleEnterEvent(const QPointF &localPoint = QPointF(), const QPointF &globalPoint = QPointF()) = 0;
236+ virtual void handleLeaveEvent(const QPointF &localPoint = QPointF()) = 0;
237 };
238
239 QtEventFeeder(const QSharedPointer<ScreenController> &screenController);
240
241=== modified file 'tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h'
242--- tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h 2015-10-14 13:36:55 +0000
243+++ tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h 2015-10-14 13:36:55 +0000
244@@ -41,7 +41,11 @@
245 MOCK_METHOD5(handleTouchEvent, void(QWindow *window, ulong timestamp, QTouchDevice *device,
246 const QList<struct QWindowSystemInterface::TouchPoint> &points,
247 Qt::KeyboardModifiers mods));
248- MOCK_METHOD4(handleMouseEvent, void(ulong, QPointF, Qt::MouseButtons, Qt::KeyboardModifiers));
249+ MOCK_METHOD4(handleMouseEvent, void(ulong timestamp, QPointF point, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers));
250+ MOCK_METHOD7(handleWheelEvent, void(ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta,
251+ Qt::KeyboardModifiers mods, Qt::ScrollPhase phase));
252+ MOCK_METHOD2(handleEnterEvent, void(const QPointF &localPoint, const QPointF& globalPoint));
253+ MOCK_METHOD1(handleLeaveEvent, void(const QPointF &localPoint));
254 };
255
256 namespace testing
257
258=== modified file 'tests/modules/common/fake_mirsurface.h'
259--- tests/modules/common/fake_mirsurface.h 2015-10-14 13:36:55 +0000
260+++ tests/modules/common/fake_mirsurface.h 2015-10-14 13:36:55 +0000
261@@ -146,6 +146,7 @@
262 void hoverEnterEvent(QHoverEvent *) override {}
263 void hoverLeaveEvent(QHoverEvent *) override {}
264 void hoverMoveEvent(QHoverEvent *) override {}
265+ void wheelEvent(QWheelEvent *) override {}
266
267 void keyPressEvent(QKeyEvent *) override {}
268 void keyReleaseEvent(QKeyEvent *) override {}

Subscribers

People subscribed via source and target branches