Merge lp:~unity-team/qtmir/1510571.ms-timestamp-compression into lp:qtmir

Proposed by Nick Dedekind
Status: Merged
Approved by: Gerry Boland
Approved revision: 384
Merged at revision: 403
Proposed branch: lp:~unity-team/qtmir/1510571.ms-timestamp-compression
Merge into: lp:qtmir
Diff against target: 265 lines (+62/-42)
5 files modified
src/common/timestamp_impl.h (+6/-5)
src/modules/Unity/Application/mirsurface.cpp (+4/-4)
src/platforms/mirserver/qteventfeeder.cpp (+11/-13)
tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp (+15/-0)
tests/modules/General/timestamp_test.cpp (+26/-20)
To merge this branch: bzr merge lp:~unity-team/qtmir/1510571.ms-timestamp-compression
Reviewer Review Type Date Requested Status
Gerry Boland (community) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+276112@code.launchpad.net

Commit message

Hand Qt millisecond timestamps rather than nanosecond.

Description of the change

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

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

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

To post a comment you must log in.
Revision history for this message
Michael Terry (mterry) wrote :

I tested this and it worked fine. Fixed my problem with https://code.launchpad.net/~mterry/unity8/shutdown-dialog-on-resume/+merge/275240

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 :

Tested here too. Works good and code-change logical.

review: Approve
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Glad to report this also fixes mouse double click events.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/common/timestamp_impl.h'
2--- src/common/timestamp_impl.h 2015-09-16 17:04:52 +0000
3+++ src/common/timestamp_impl.h 2015-10-29 12:01:23 +0000
4@@ -8,20 +8,21 @@
5
6 namespace qtmir {
7
8+typedef std::chrono::duration<ulong, std::milli> Timestamp;
9+
10 template<typename T>
11 T compressTimestamp(std::chrono::nanoseconds timestamp)
12 {
13 std::chrono::nanoseconds startTime = getStartTime(timestamp);
14- std::chrono::nanoseconds result = timestamp - startTime;
15
16- if (std::numeric_limits<std::chrono::nanoseconds::rep>::max() > std::numeric_limits<T>::max() &&
17- result > std::chrono::nanoseconds(std::numeric_limits<T>::max())) {
18+ if (std::chrono::nanoseconds::max() > T::max() &&
19+ timestamp - startTime > std::chrono::nanoseconds(T::max())) {
20 // we've overflowed the boundaries of the millisecond type.
21 resetStartTime(timestamp);
22- return 0;
23+ return T(0);
24 }
25
26- return result.count();
27+ return std::chrono::duration_cast<T>(timestamp - startTime);
28 }
29
30 template<typename T>
31
32=== modified file 'src/modules/Unity/Application/mirsurface.cpp'
33--- src/modules/Unity/Application/mirsurface.cpp 2015-10-21 11:47:03 +0000
34+++ src/modules/Unity/Application/mirsurface.cpp 2015-10-29 12:01:23 +0000
35@@ -70,7 +70,7 @@
36
37 mir::EventUPtr makeMirEvent(QMouseEvent *qtEvent, MirPointerAction action)
38 {
39- auto timestamp = uncompressTimestamp<ulong>(qtEvent->timestamp());
40+ auto timestamp = uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtEvent->timestamp()));
41 auto modifiers = getMirModifiersFromQt(qtEvent->modifiers());
42 auto buttons = getMirButtonsFromQt(qtEvent->buttons());
43
44@@ -80,7 +80,7 @@
45
46 mir::EventUPtr makeMirEvent(QHoverEvent *qtEvent, MirPointerAction action)
47 {
48- auto timestamp = uncompressTimestamp<ulong>(qtEvent->timestamp());
49+ auto timestamp = uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtEvent->timestamp()));
50
51 MirPointerButtons buttons = 0;
52
53@@ -117,7 +117,7 @@
54 if (qtEvent->isAutoRepeat())
55 action = mir_keyboard_action_repeat;
56
57- return mir::events::make_event(0 /* DeviceID */, uncompressTimestamp<ulong>(qtEvent->timestamp()),
58+ return mir::events::make_event(0 /* DeviceID */, uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtEvent->timestamp())),
59 0 /* mac */, action, qtEvent->nativeVirtualKey(),
60 qtEvent->nativeScanCode(),
61 qtEvent->nativeModifiers());
62@@ -129,7 +129,7 @@
63 ulong qtTimestamp)
64 {
65 auto modifiers = getMirModifiersFromQt(qmods);
66- auto ev = mir::events::make_event(0, uncompressTimestamp<ulong>(qtTimestamp),
67+ auto ev = mir::events::make_event(0, uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtTimestamp)),
68 0 /* mac */, modifiers);
69
70 for (int i = 0; i < qtTouchPoints.count(); ++i) {
71
72=== modified file 'src/platforms/mirserver/qteventfeeder.cpp'
73--- src/platforms/mirserver/qteventfeeder.cpp 2015-10-14 13:36:25 +0000
74+++ src/platforms/mirserver/qteventfeeder.cpp 2015-10-29 12:01:23 +0000
75@@ -552,7 +552,7 @@
76
77 void QtEventFeeder::dispatchPointer(MirInputEvent const* ev)
78 {
79- auto timestamp = qtmir::compressTimestamp<ulong>(std::chrono::nanoseconds(mir_input_event_get_event_time(ev)));
80+ auto timestamp = qtmir::compressTimestamp<qtmir::Timestamp>(std::chrono::nanoseconds(mir_input_event_get_event_time(ev)));
81 auto pev = mir_input_event_get_pointer_event(ev);
82 auto action = mir_pointer_event_action(pev);
83 qCDebug(QTMIR_MIR_INPUT) << "Received" << qPrintable(mirPointerEventToString(pev));
84@@ -574,11 +574,11 @@
85
86 if (hDelta != 0 || vDelta != 0) {
87 const QPoint angleDelta = QPoint(hDelta * 15, vDelta * 15);
88- mQtWindowSystem->handleWheelEvent(timestamp, local_point, local_point,
89+ mQtWindowSystem->handleWheelEvent(timestamp.count(), local_point, local_point,
90 QPoint(), angleDelta, modifiers, Qt::ScrollUpdate);
91 } else {
92 auto buttons = getQtMouseButtonsfromMirPointerEvent(pev);
93- mQtWindowSystem->handleMouseEvent(timestamp, movement, buttons, modifiers);
94+ mQtWindowSystem->handleMouseEvent(timestamp.count(), movement, buttons, modifiers);
95 }
96 break;
97 }
98@@ -595,7 +595,7 @@
99
100 void QtEventFeeder::dispatchKey(MirInputEvent const* event)
101 {
102- auto timestamp = qtmir::compressTimestamp<ulong>(std::chrono::nanoseconds(mir_input_event_get_event_time(event)));
103+ auto timestamp = qtmir::compressTimestamp<qtmir::Timestamp>(std::chrono::nanoseconds(mir_input_event_get_event_time(event)));
104
105 auto kev = mir_input_event_get_keyboard_event(event);
106 xkb_keysym_t xk_sym = mir_keyboard_event_key_code(kev);
107@@ -634,7 +634,7 @@
108 mir_keyboard_event_key_code(kev),
109 mir_keyboard_event_modifiers(kev),
110 text, is_auto_rep);
111- qKeyEvent.setTimestamp(timestamp);
112+ qKeyEvent.setTimestamp(timestamp.count());
113 if (context->filterEvent(&qKeyEvent)) {
114 qCDebug(QTMIR_MIR_INPUT) << "Received" << qPrintable(mirKeyboardEventToString(kev))
115 << "but not dispatching as it was filtered out by input context";
116@@ -646,7 +646,7 @@
117 << ". Dispatching to " << mQtWindowSystem->focusedWindow();
118
119 mQtWindowSystem->handleExtendedKeyEvent(mQtWindowSystem->focusedWindow(),
120- timestamp, keyType, keyCode, modifiers,
121+ timestamp.count(), keyType, keyCode, modifiers,
122 mir_keyboard_event_scan_code(kev),
123 mir_keyboard_event_key_code(kev),
124 mir_keyboard_event_modifiers(kev), text, is_auto_rep);
125@@ -654,9 +654,9 @@
126
127 void QtEventFeeder::dispatchTouch(MirInputEvent const* event)
128 {
129- auto timestamp = std::chrono::nanoseconds(mir_input_event_get_event_time(event));
130+ auto timestamp = qtmir::compressTimestamp<qtmir::Timestamp>(std::chrono::nanoseconds(mir_input_event_get_event_time(event)));
131
132- tracepoint(qtmirserver, touchEventDispatch_start, timestamp.count());
133+ tracepoint(qtmirserver, touchEventDispatch_start, std::chrono::nanoseconds(timestamp).count());
134
135 auto tev = mir_input_event_get_touch_event(event);
136 qCDebug(QTMIR_MIR_INPUT) << "Received" << qPrintable(mirTouchEventToString(tev));
137@@ -714,21 +714,19 @@
138 }
139 }
140
141- auto compressedTimestamp = qtmir::compressTimestamp<ulong>(timestamp);
142-
143 // Qt needs a happy, sane stream of touch events. So let's make sure we're not forwarding
144 // any insanity.
145- validateTouches(window, compressedTimestamp, touchPoints);
146+ validateTouches(window, timestamp.count(), touchPoints);
147
148 // Touch event propagation.
149 qCDebug(QTMIR_MIR_INPUT) << "Sending to Qt" << qPrintable(touchesToString(touchPoints));
150 mQtWindowSystem->handleTouchEvent(window,
151 //scales down the nsec_t (int64) to fit a ulong, precision lost but time difference suitable
152- compressedTimestamp,
153+ timestamp.count(),
154 mTouchDevice,
155 touchPoints);
156
157- tracepoint(qtmirserver, touchEventDispatch_end, timestamp.count());
158+ tracepoint(qtmirserver, touchEventDispatch_end, std::chrono::nanoseconds(timestamp).count());
159 }
160
161 void QtEventFeeder::start()
162
163=== modified file 'tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp'
164--- tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp 2015-10-21 11:46:33 +0000
165+++ tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp 2015-10-29 12:01:23 +0000
166@@ -265,3 +265,18 @@
167
168 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
169 }
170+
171+TEST_F(QtEventFeederTest, TimestampInMilliseconds)
172+{
173+ setIrrelevantMockWindowSystemExpectations();
174+ EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,0,_,_,_)).Times(1);
175+ auto ev1 = mev::make_event(MirInputDeviceId(), std::chrono::milliseconds(123), 0 /* mac */, 0);
176+ qtEventFeeder->dispatch(*ev1);
177+ ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
178+
179+ setIrrelevantMockWindowSystemExpectations();
180+ EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,2,_,_,_)).Times(1);
181+ auto ev2 = mev::make_event(MirInputDeviceId(), std::chrono::milliseconds(125), 0 /* mac */, 0);
182+ qtEventFeeder->dispatch(*ev2);
183+ ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
184+}
185
186=== modified file 'tests/modules/General/timestamp_test.cpp'
187--- tests/modules/General/timestamp_test.cpp 2015-09-16 16:19:00 +0000
188+++ tests/modules/General/timestamp_test.cpp 2015-10-29 12:01:23 +0000
189@@ -24,49 +24,55 @@
190
191 using namespace qtmir;
192
193-TEST(TimestampTest, TestCompressAndUncompress)
194+class TimestampTest: public ::testing::Test
195+{
196+protected:
197+ virtual void SetUp() {
198+ resetStartTime(std::chrono::nanoseconds(0));
199+ }
200+};
201+
202+TEST_F(TimestampTest, TestCompressAndUncompress)
203 {
204 using namespace testing;
205
206- int argc = 0;
207- QCoreApplication app(argc, NULL);
208-
209 std::chrono::time_point<std::chrono::system_clock> now;
210 now = std::chrono::system_clock::now();
211 auto original_timestamp = now.time_since_epoch();
212
213- std::chrono::nanoseconds addToTimestamp(0);
214+ qtmir::Timestamp addToTimestamp(0);
215+
216 for (int i = 0; i < 100; i++) {
217 auto timestamp = original_timestamp + addToTimestamp;
218
219- ulong compressedTimestamp = qtmir::compressTimestamp<ulong>(timestamp);
220-
221- EXPECT_EQ(addToTimestamp.count(), compressedTimestamp);
222- EXPECT_EQ(qtmir::uncompressTimestamp<ulong>(compressedTimestamp), timestamp);
223-
224- addToTimestamp += std::chrono::milliseconds(1);
225+ qtmir::Timestamp compressedTimestamp = qtmir::compressTimestamp<qtmir::Timestamp>(timestamp);
226+
227+ EXPECT_EQ(addToTimestamp, compressedTimestamp);
228+ EXPECT_EQ(qtmir::uncompressTimestamp<qtmir::Timestamp>(compressedTimestamp), timestamp);
229+
230+ addToTimestamp += std::chrono::seconds(1);
231 }
232 }
233
234-TEST(TimestampTest, TestOverflowWhenExceeding32bitCompression)
235+TEST_F(TimestampTest, TestOverflowWhenExceeding32bitCompression)
236 {
237 using namespace testing;
238
239- int argc = 0;
240- QCoreApplication app(argc, NULL);
241-
242 std::chrono::time_point<std::chrono::system_clock> now;
243 now = std::chrono::system_clock::now();
244 auto timestamp = now.time_since_epoch();
245
246+ typedef std::chrono::duration<quint32, std::milli> Timestamp32bit;
247+
248 // Do first compression. This will result in qield of 0 as seen in TestCompressUncompress
249- quint32 compressedTimestamp = qtmir::compressTimestamp<quint32>(timestamp);
250+ auto compressedTimestamp = qtmir::compressTimestamp<Timestamp32bit>(timestamp);
251
252 // Add the quint32 limit +1 to get an overflow when we compress the timestamp
253- timestamp += std::chrono::nanoseconds(std::numeric_limits<quint32>::max()) + std::chrono::nanoseconds(1);
254- compressedTimestamp = qtmir::compressTimestamp<quint32>(timestamp);
255+ timestamp += Timestamp32bit::max() + std::chrono::nanoseconds(1);
256+
257+ compressedTimestamp = qtmir::compressTimestamp<Timestamp32bit>(timestamp);
258
259- EXPECT_EQ(0, compressedTimestamp);
260+ EXPECT_EQ(0, compressedTimestamp.count());
261 // ensure the uncompression will yields the original timestamp
262- EXPECT_EQ(qtmir::uncompressTimestamp<quint32>(compressedTimestamp), timestamp);
263+ EXPECT_EQ(qtmir::uncompressTimestamp<Timestamp32bit>(compressedTimestamp), timestamp);
264 }
265\ No newline at end of file

Subscribers

People subscribed via source and target branches