@@ -25,14 +25,15 @@ class FakeElapsedTimer : public AbstractElapsedTimer {
2525public:
2626 static qint64 msecsSinceEpoch;
2727
28− FakeElapsedTimer() { start(); }
28+ FakeElapsedTimer() {}
2929
30− void start() override { m_msecsSinceReference = msecsSinceEpoch; }
30+ void start() override { m_msecsSinceReference = msecsSinceEpoch; m_valid = true; }
3131 qint64 msecsSinceReference() const override { return m_msecsSinceReference; }
32− qint64 elapsed() const override { return msecsSinceEpoch - m_msecsSinceReference; }
32+ qint64 elapsed() const override { return m_valid ? msecsSinceEpoch - m_msecsSinceReference : qrand(); }
3333
3434private:
3535 qint64 m_msecsSinceReference;
36+ bool m_valid{false};
3637};
3738qint64 FakeElapsedTimer::msecsSinceEpoch = 0;
3839
@@ -48,11 +49,14 @@ public:
4849 int interval() const override;
4950 void setInterval(int msecs) override;
5051 void start() override;
52+ void stop() override;
53+ bool isRunning() const override;
5154 bool isSingleShot() const override;
5255 void setSingleShot(bool value) override;
5356private:
5457 int m_interval;
5558 bool m_singleShot;
59+ bool m_isRunning;
5660 qint64 m_nextTimeoutTime;
5761};
5862
@@ -85,6 +89,8 @@ private Q_SLOTS:
8589 void tapWhileTouching();
8690 void multipleHomeKeys();
8791
92+ void repeatedSuperPress();
93+
8894private:
8995 void passTime(qint64 timeSpanMs);
9096
@@ -98,11 +104,10 @@ void WindowInputMonitorTest::init()
98104
99105void WindowInputMonitorTest::cleanup()
100106{
101− delete m_fakeTimerFactory;
107+ delete m_fakeTimerFactory;
102108 m_fakeTimerFactory = nullptr;
103109}
104110
105−
106111void WindowInputMonitorTest::passTime(qint64 timeSpanMs)
107112{
108113 qint64 finalTime = FakeElapsedTimer::msecsSinceEpoch + timeSpanMs;
@@ -133,7 +138,7 @@ void WindowInputMonitorTest::touchTapTouch()
133138 QFETCH(int, silenceAfterTap);
134139 QFETCH(int, expectedActivatedCount);
135140 QFETCH(Qt::Key, key);
136− WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
141+ WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(this), new FakeElapsedTimer);
137142 QSignalSpy activatedSpy(&homeKeyWatcher, &WindowInputMonitor::homeKeyActivated);
138143 QVERIFY(activatedSpy.isValid());
139144
@@ -194,7 +199,7 @@ void WindowInputMonitorTest::touchTapTouch()
194199
195200void WindowInputMonitorTest::tapWhileTouching()
196201{
197− WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
202+ WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(this), new FakeElapsedTimer);
198203 QSignalSpy activatedSpy(&homeKeyWatcher, &WindowInputMonitor::homeKeyActivated);
199204 QVERIFY(activatedSpy.isValid());
200205
@@ -229,7 +234,7 @@ void WindowInputMonitorTest::tapWhileTouching()
229234 */
230235void WindowInputMonitorTest::multipleHomeKeys()
231236{
232− WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
237+ WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(this), new FakeElapsedTimer);
233238 QSignalSpy activatedSpy(&homeKeyWatcher, &WindowInputMonitor::homeKeyActivated);
234239 QVERIFY(activatedSpy.isValid());
235240
@@ -258,12 +263,64 @@ void WindowInputMonitorTest::multipleHomeKeys()
258263 QCOMPARE(activatedSpy.count(), 1);
259264}
260265
266+// regression test for lp:1607427
267+void WindowInputMonitorTest::repeatedSuperPress()
268+{
269+ WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(this), new FakeElapsedTimer);
270+ QSignalSpy activatedSpy(&homeKeyWatcher, &WindowInputMonitor::homeKeyActivated);
271+ QVERIFY(activatedSpy.isValid());
272+
273+ // 1st try
274+ passTime(1000);
275+ {
276+ QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Super_L, Qt::NoModifier);
277+ homeKeyWatcher.update(&keyEvent);
278+ }
279+ passTime(50);
280+ {
281+ QKeyEvent keyEvent(QEvent::KeyRelease, Qt::Key_Super_L, Qt::NoModifier);
282+ homeKeyWatcher.update(&keyEvent);
283+ }
284+ passTime(1000);
285+ QCOMPARE(activatedSpy.count(), 1);
286+
287+ // a touch event in between
288+ {
289+ QTouchEvent touchEvent(QEvent::TouchBegin);
290+ homeKeyWatcher.update(&touchEvent);
291+ }
292+ {
293+ QTouchEvent touchEvent(QEvent::TouchUpdate);
294+ homeKeyWatcher.update(&touchEvent);
295+ }
296+ {
297+ QTouchEvent touchEvent(QEvent::TouchEnd);
298+ homeKeyWatcher.update(&touchEvent);
299+ }
300+
301+ passTime(1000);
302+ // 2nd try
303+ activatedSpy.clear();
304+ {
305+ QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Super_L, Qt::NoModifier);
306+ homeKeyWatcher.update(&keyEvent);
307+ }
308+ passTime(50);
309+ {
310+ QKeyEvent keyEvent(QEvent::KeyRelease, Qt::Key_Super_L, Qt::NoModifier);
311+ homeKeyWatcher.update(&keyEvent);
312+ }
313+ passTime(1000);
314+ QCOMPARE(activatedSpy.count(), 1);
315+}
316+
261317/////////////////////////////////// FakeTimer //////////////////////////////////
262318
263319FakeTimer::FakeTimer(QObject *parent)
264320 : UnityUtil::AbstractTimer(parent)
265321 , m_interval(0)
266322 , m_singleShot(true)
323+ , m_isRunning(false)
267324{
268325}
269326
@@ -285,10 +342,20 @@ void FakeTimer::update()
285342
286343void FakeTimer::start()
287344{
288− AbstractTimer::start();
345+ m_isRunning = true;
289346 m_nextTimeoutTime = FakeElapsedTimer::msecsSinceEpoch + (qint64)interval();
290347}
291348
349+void FakeTimer::stop()
350+{
351+ m_isRunning = false;
352+}
353+
354+bool FakeTimer::isRunning() const
355+{
356+ return m_isRunning;
357+}
358+
292359int FakeTimer::interval() const
293360{
294361 return m_interval;