Merge lp:~lukas-kde/qtmir/wheelEvent into lp:qtmir
- wheelEvent
- Merge into trunk
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 | ||||
Related bugs: |
|
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:/
* Are there any related MPs required for this MP to build/function as expected? Please list.
https:/
* 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
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
"""
-pkg_check_
+pkg_check_
"""
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.
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
> """
> -pkg_check_
> +pkg_check_
> """
>
> 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
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:384
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
Could you please move "getMirButtonsF
The mir::events:
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
> Could you please move "getMirButtonsF
> separate variable like it's being done for timestamp and modifiers?
>
> The mir::events:
> 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
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:385
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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. :)
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
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:386
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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!
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:388
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 389. By Lukáš Tinkl
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:389
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) : | # |
Preview Diff
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 {} |
PASSED: Continuous integration, rev:383 jenkins. qa.ubuntu. com/job/ qtmir-ci/ 475/ jenkins. qa.ubuntu. com/job/ qtmir-vivid- amd64-ci/ 171 jenkins. qa.ubuntu. com/job/ qtmir-vivid- armhf-ci/ 171 jenkins. qa.ubuntu. com/job/ qtmir-vivid- armhf-ci/ 171/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ qtmir-vivid- i386-ci/ 53 jenkins. qa.ubuntu. com/job/ qtmir-wily- amd64-ci/ 208 jenkins. qa.ubuntu. com/job/ qtmir-wily- armhf-ci/ 208 jenkins. qa.ubuntu. com/job/ qtmir-wily- armhf-ci/ 208/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ qtmir-wily- i386-ci/ 53
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/qtmir- ci/475/ rebuild
http://