on xenial help sign in
Tapping home key shows unity8-dash home
commite9f3c91ffaada94b824cdccdc8f25ee8f14ad542 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateFri 17 Apr 2015, 09:44 (12 years ago) parent7478eb8
11 files changed+718−4
plugins/Utils/CMakeLists.txt+3 plugins/Utils/ElapsedTimer.cpp+21 plugins/Utils/ElapsedTimer.h+65 plugins/Utils/Timer.cpp+160 plugins/Utils/Timer.h+112 plugins/Utils/homekeywatcher.cpp+105 plugins/Utils/homekeywatcher.h+73 plugins/Utils/plugin.cpp+3−4 qml/Shell.qml+4 tests/plugins/Utils/CMakeLists.txt+1 tests/plugins/Utils/homekeywatchertest.cpp+171
plugins/Utils/CMakeLists.txt+3
@@ -9,11 +9,14 @@ include_directories(
99
1010set(QMLPLUGIN_SRC
1111 constants.cpp
12+ homekeywatcher.cpp
1213 inputwatcher.cpp
1314 qlimitproxymodelqml.cpp
1415 unitysortfilterproxymodelqml.cpp
1516 relativetimeformatter.cpp
1617 timeformatter.cpp
18+ Timer.cpp
19+ ElapsedTimer.cpp
1720 unitymenumodelpaths.cpp
1821 windowkeysfilter.cpp
1922 easingcurve.cpp
plugins/Utils/ElapsedTimer.cppnew file+21
@@ -0,0 +1,21 @@
1+/*
2+ * Copyright (C) 2015 - Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU Lesser General Public License, as
6+ * published by the Free Software Foundation; either version 2.1 or 3.0
7+ * of the License.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the applicable version of the GNU Lesser General Public
13+ * License for more details.
14+ *
15+ * You should have received a copy of both the GNU Lesser General Public
16+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
17+ */
18+
19+#include "ElapsedTimer.h"
20+
21+qint64 UnityUtil::FakeElapsedTimer::msecsSinceEpoch = 0;
plugins/Utils/ElapsedTimer.hnew file+65
@@ -0,0 +1,65 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU Lesser General Public License, as
6+ * published by the Free Software Foundation; either version 2.1 or 3.0
7+ * of the License.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the applicable version of the GNU Lesser General Public
13+ * License for more details.
14+ *
15+ * You should have received a copy of both the GNU Lesser General Public
16+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
17+ */
18+
19+#ifndef UNITYUTIL_ELAPSEDTIMER_H
20+#define UNITYUTIL_ELAPSEDTIMER_H
21+
22+#include <QElapsedTimer>
23+
24+namespace UnityUtil {
25+
26+class AbstractElapsedTimer {
27+public:
28+ virtual ~AbstractElapsedTimer() {}
29+ virtual void start() = 0;
30+ virtual qint64 msecsSinceReference() const = 0;
31+ virtual qint64 elapsed() const = 0;
32+};
33+
34+/*
35+ A QElapsedTimer wrapper
36+ */
37+class ElapsedTimer : public AbstractElapsedTimer {
38+public:
39+ void start() override { m_timer.start(); }
40+ qint64 msecsSinceReference() const override { return m_timer.msecsSinceReference(); }
41+ qint64 elapsed() const override { return m_timer.elapsed(); }
42+private:
43+ QElapsedTimer m_timer;
44+};
45+
46+/*
47+ A fake ElapsedTimer, useful for tests
48+ */
49+class FakeElapsedTimer : public AbstractElapsedTimer {
50+public:
51+ static qint64 msecsSinceEpoch;
52+
53+ FakeElapsedTimer() { start(); }
54+
55+ void start() override { m_msecsSinceReference = msecsSinceEpoch; }
56+ qint64 msecsSinceReference() const override { return m_msecsSinceReference; }
57+ qint64 elapsed() const override { return msecsSinceEpoch - m_msecsSinceReference; }
58+
59+private:
60+ qint64 m_msecsSinceReference;
61+};
62+
63+} // namespace UnityUtil
64+
65+#endif // UNITYUTIL_ELAPSEDTIMER_H
plugins/Utils/Timer.cppnew file+160
@@ -0,0 +1,160 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "Timer.h"
18+
19+namespace UnityUtil {
20+
21+Timer::Timer(QObject *parent) : AbstractTimer(parent)
22+{
23+ m_timer.setSingleShot(true);
24+ connect(&m_timer, &QTimer::timeout, this, &AbstractTimer::timeout);
25+}
26+
27+int Timer::interval() const
28+{
29+ return m_timer.interval();
30+}
31+
32+void Timer::setInterval(int msecs)
33+{
34+ m_timer.setInterval(msecs);
35+}
36+
37+void Timer::start()
38+{
39+ m_timer.start();
40+ AbstractTimer::start();
41+}
42+
43+void Timer::stop()
44+{
45+ m_timer.stop();
46+ AbstractTimer::stop();
47+}
48+
49+bool Timer::isSingleShot() const
50+{
51+ return m_timer.isSingleShot();
52+}
53+
54+void Timer::setSingleShot(bool value)
55+{
56+ m_timer.setSingleShot(value);
57+}
58+
59+/////////////////////////////////// FakeTimer //////////////////////////////////
60+
61+FakeTimer::FakeTimer(QObject *parent)
62+ : UnityUtil::AbstractTimer(parent)
63+ , m_interval(0)
64+ , m_singleShot(true)
65+{
66+}
67+
68+void FakeTimer::update()
69+{
70+ if (!isRunning()) {
71+ return;
72+ }
73+
74+ if (m_nextTimeoutTime <= FakeElapsedTimer::msecsSinceEpoch) {
75+ if (isSingleShot()) {
76+ stop();
77+ } else {
78+ m_nextTimeoutTime += interval();
79+ }
80+ Q_EMIT timeout();
81+ }
82+}
83+
84+void FakeTimer::start()
85+{
86+ AbstractTimer::start();
87+ m_nextTimeoutTime = FakeElapsedTimer::msecsSinceEpoch + (qint64)interval();
88+}
89+
90+int FakeTimer::interval() const
91+{
92+ return m_interval;
93+}
94+
95+void FakeTimer::setInterval(int msecs)
96+{
97+ m_interval = msecs;
98+}
99+
100+bool FakeTimer::isSingleShot() const
101+{
102+ return m_singleShot;
103+}
104+
105+void FakeTimer::setSingleShot(bool value)
106+{
107+ m_singleShot = value;
108+}
109+
110+/////////////////////////////////// FakeTimerFactory //////////////////////////////////
111+
112+FakeTimerFactory::FakeTimerFactory()
113+{
114+}
115+
116+FakeTimerFactory::~FakeTimerFactory()
117+{
118+ for (int i = 0; i < timers.count(); ++i) {
119+ FakeTimer *timer = timers[i].data();
120+ if (timer) {
121+ delete timer;
122+ }
123+ }
124+}
125+
126+void FakeTimerFactory::updateTime(qint64 targetTime)
127+{
128+ qint64 minTimeoutTime = targetTime;
129+
130+ for (int i = 0; i < timers.count(); ++i) {
131+ FakeTimer *timer = timers[i].data();
132+ if (timer && timer->isRunning() && timer->nextTimeoutTime() < minTimeoutTime) {
133+ minTimeoutTime = timer->nextTimeoutTime();
134+ }
135+ }
136+
137+ FakeElapsedTimer::msecsSinceEpoch = minTimeoutTime;
138+
139+ for (int i = 0; i < timers.count(); ++i) {
140+ FakeTimer *timer = timers[i].data();
141+ if (timer) {
142+ timer->update();
143+ }
144+ }
145+
146+ if (FakeElapsedTimer::msecsSinceEpoch < targetTime) {
147+ updateTime(targetTime);
148+ }
149+}
150+
151+AbstractTimer *FakeTimerFactory::create(QObject *parent)
152+{
153+ FakeTimer *fakeTimer = new FakeTimer(parent);
154+
155+ timers.append(fakeTimer);
156+
157+ return fakeTimer;
158+}
159+
160+} // namespace UnityUtil
plugins/Utils/Timer.hnew file+112
@@ -0,0 +1,112 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef UNITYUTIL_TIMER_H
18+#define UNITYUTIL_TIMER_H
19+
20+#include "ElapsedTimer.h"
21+
22+#include <QObject>
23+#include <QPointer>
24+#include <QTimer>
25+
26+namespace UnityUtil {
27+
28+/* Defines an interface for a Timer. Useful for tests. */
29+class AbstractTimer : public QObject
30+{
31+ Q_OBJECT
32+public:
33+ AbstractTimer(QObject *parent) : QObject(parent), m_isRunning(false) {}
34+ virtual int interval() const = 0;
35+ virtual void setInterval(int msecs) = 0;
36+ virtual void start() { m_isRunning = true; }
37+ virtual void stop() { m_isRunning = false; }
38+ bool isRunning() const { return m_isRunning; }
39+ virtual bool isSingleShot() const = 0;
40+ virtual void setSingleShot(bool value) = 0;
41+Q_SIGNALS:
42+ void timeout();
43+private:
44+ bool m_isRunning;
45+};
46+
47+/* Essentially a QTimer wrapper */
48+class Timer : public AbstractTimer
49+{
50+ Q_OBJECT
51+public:
52+ Timer(QObject *parent = nullptr);
53+
54+ int interval() const override;
55+ void setInterval(int msecs) override;
56+ void start() override;
57+ void stop() override;
58+ bool isSingleShot() const override;
59+ void setSingleShot(bool value) override;
60+private:
61+ QTimer m_timer;
62+};
63+
64+/* For tests */
65+class FakeTimer : public AbstractTimer
66+{
67+ Q_OBJECT
68+public:
69+ FakeTimer(QObject *parent = nullptr);
70+
71+ void update();
72+ qint64 nextTimeoutTime() const { return m_nextTimeoutTime; }
73+
74+ int interval() const override;
75+ void setInterval(int msecs) override;
76+ void start() override;
77+ bool isSingleShot() const override;
78+ void setSingleShot(bool value) override;
79+private:
80+ int m_interval;
81+ bool m_singleShot;
82+ qint64 m_nextTimeoutTime;
83+};
84+
85+class AbstractTimerFactory
86+{
87+public:
88+ virtual ~AbstractTimerFactory() {}
89+ virtual AbstractTimer *create(QObject *parent = nullptr) = 0;
90+};
91+
92+class TimerFactory : public AbstractTimerFactory
93+{
94+public:
95+ AbstractTimer *create(QObject *parent = nullptr) override { return new Timer(parent); }
96+};
97+
98+class FakeTimerFactory : public AbstractTimerFactory
99+{
100+public:
101+ FakeTimerFactory();
102+ virtual ~FakeTimerFactory();
103+
104+ void updateTime(qint64 targetTime);
105+
106+ AbstractTimer *create(QObject *parent = nullptr) override;
107+ QList<QPointer<FakeTimer>> timers;
108+};
109+
110+} // namespace UnityUtil
111+
112+#endif // UNITYUTIL_TIMER_H
plugins/Utils/homekeywatcher.cppnew file+105
@@ -0,0 +1,105 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "homekeywatcher.h"
18+
19+#include <QQuickWindow>
20+
21+using namespace UnityUtil;
22+
23+HomeKeyWatcher::HomeKeyWatcher(QQuickItem *parent)
24+ : HomeKeyWatcher(new Timer, new ElapsedTimer, parent)
25+{
26+}
27+
28+HomeKeyWatcher::HomeKeyWatcher(UnityUtil::AbstractTimer *timer,
29+ UnityUtil::AbstractElapsedTimer *elapsedTimer,
30+ QQuickItem *parent)
31+ : QQuickItem(parent)
32+ , m_windowBeingTouched(false)
33+ , m_windowLastTouchedTimer(elapsedTimer)
34+ , m_emitActivatedIfNoTouchesAroundTimer(timer)
35+{
36+ connect(this, &QQuickItem::windowChanged,
37+ this, &HomeKeyWatcher::setupFilterOnWindow);
38+
39+ connect(m_emitActivatedIfNoTouchesAroundTimer, &UnityUtil::AbstractTimer::timeout,
40+ this, &HomeKeyWatcher::emitActivatedIfNoTouchesAround);
41+ m_emitActivatedIfNoTouchesAroundTimer->setInterval(msecsWithoutTouches);
42+}
43+
44+HomeKeyWatcher::~HomeKeyWatcher()
45+{
46+ delete m_windowLastTouchedTimer;
47+ delete m_emitActivatedIfNoTouchesAroundTimer;
48+}
49+
50+bool HomeKeyWatcher::eventFilter(QObject *watched, QEvent *event)
51+{
52+ Q_ASSERT(!m_filteredWindow.isNull());
53+ Q_ASSERT(watched == static_cast<QObject*>(m_filteredWindow.data()));
54+ Q_UNUSED(watched);
55+
56+ update(event);
57+
58+ // We're only monitoring, never filtering out events
59+ return false;
60+}
61+
62+void HomeKeyWatcher::update(QEvent *event)
63+{
64+ if (event->type() == QEvent::KeyPress) {
65+ QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
66+
67+ if (keyEvent->key() == Qt::Key_Home && !keyEvent->isAutoRepeat()
68+ && !m_windowBeingTouched
69+ && m_windowLastTouchedTimer->elapsed() >= msecsWithoutTouches) {
70+ m_emitActivatedIfNoTouchesAroundTimer->start();
71+ }
72+
73+ } else if (event->type() == QEvent::TouchBegin) {
74+
75+ m_emitActivatedIfNoTouchesAroundTimer->stop();
76+ m_windowBeingTouched = true;
77+
78+ } else if (event->type() == QEvent::TouchEnd) {
79+
80+ m_windowBeingTouched = false;
81+ m_windowLastTouchedTimer->start();
82+ }
83+}
84+
85+void HomeKeyWatcher::setupFilterOnWindow(QQuickWindow *window)
86+{
87+ if (!m_filteredWindow.isNull()) {
88+ m_filteredWindow->removeEventFilter(this);
89+ m_filteredWindow.clear();
90+ }
91+
92+ if (window) {
93+ window->installEventFilter(this);
94+ m_filteredWindow = window;
95+ }
96+}
97+
98+void HomeKeyWatcher::emitActivatedIfNoTouchesAround()
99+{
100+ if (!m_windowBeingTouched && (m_windowLastTouchedTimer->elapsed() > msecsWithoutTouches)) {
101+ Q_EMIT activated();
102+ }
103+}
104+
105+#include "homekeywatcher.moc"
plugins/Utils/homekeywatcher.hnew file+73
@@ -0,0 +1,73 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef UNITY_HOMEKEYWATCHER_H
18+#define UNITY_HOMEKEYWATCHER_H
19+
20+#include <QQuickItem>
21+#include <QPointer>
22+
23+#include "Timer.h"
24+#include "ElapsedTimer.h"
25+
26+/*
27+ Signals when the home key seems to be have been intentionally tapped.
28+
29+ It only says the home key has been activated if it has been tapped in isolation,
30+ that is, without being accompanied by touches on the screen. Home key taps that
31+ happen along with (or immediately after, or immediately before) touches on the
32+ screen are considered to have happened unintentionally and are thus ignored.
33+
34+ Rationale being that it's easy to accidentally hit the home key while performing
35+ a swipe from a screen edge, for instance. That's particularly the case when the
36+ home key is a capacitive key.
37+ */
38+class HomeKeyWatcher : public QQuickItem
39+{
40+ Q_OBJECT
41+public:
42+
43+ HomeKeyWatcher(QQuickItem *parent = 0);
44+
45+ // for testing
46+ HomeKeyWatcher(UnityUtil::AbstractTimer *timer,
47+ UnityUtil::AbstractElapsedTimer *elapsedTimer,
48+ QQuickItem *parent = 0);
49+
50+ virtual ~HomeKeyWatcher();
51+
52+ bool eventFilter(QObject *watched, QEvent *event);
53+
54+ void update(QEvent *event);
55+
56+ const qint64 msecsWithoutTouches = 150;
57+
58+Q_SIGNALS:
59+ // Emitted when the home key has been intentionally tapped
60+ void activated();
61+
62+private Q_SLOTS:
63+ void setupFilterOnWindow(QQuickWindow *window);
64+ void emitActivatedIfNoTouchesAround();
65+
66+private:
67+ QPointer<QQuickWindow> m_filteredWindow;
68+ bool m_windowBeingTouched;
69+ UnityUtil::AbstractElapsedTimer *m_windowLastTouchedTimer;
70+ UnityUtil::AbstractTimer *m_emitActivatedIfNoTouchesAroundTimer;
71+};
72+
73+#endif // UNITY_HOMEKEYWATCHER_H
plugins/Utils/plugin.cpp+3−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2012 Canonical, Ltd.
2+ * Copyright (C) 2012-2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -12,8 +12,6 @@
1212 *
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Author: Michał Sawicz <michal.sawicz@canonical.com>
1715 */
1816
1917// Qt
@@ -21,11 +19,11 @@
2119#include <QDBusConnection>
2220#include <QQmlContext>
2321#include <QtQuick/QQuickWindow>
24−#include <QDebug>
2522// self
2623#include "plugin.h"
2724
2825// local
26+#include "homekeywatcher.h"
2927#include "inputwatcher.h"
3028#include "qlimitproxymodelqml.h"
3129#include "unitysortfilterproxymodelqml.h"
@@ -54,6 +52,7 @@ static QObject *createConstants(QQmlEngine *engine, QJSEngine *scriptEngine)
5452void UtilsPlugin::registerTypes(const char *uri)
5553{
5654 Q_ASSERT(uri == QLatin1String("Utils"));
55+ qmlRegisterType<HomeKeyWatcher>(uri, 0, 1, "HomeKeyWatcher");
5756 qmlRegisterType<QAbstractItemModel>();
5857 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
5958 qmlRegisterType<UnitySortFilterProxyModelQML>(uri, 0, 1, "UnitySortFilterProxyModel");
qml/Shell.qml+4
@@ -180,6 +180,10 @@ Item {
180180 Keys.onReleased: physicalKeysMapper.onKeyReleased(event);
181181 }
182182
183+ HomeKeyWatcher {
184+ onActivated: shell.showHome()
185+ }
186+
183187 Item {
184188 id: stages
185189 objectName: "stages"
tests/plugins/Utils/CMakeLists.txt+1
@@ -25,6 +25,7 @@ run_tests(
2525 qlimitproxymodeltest
2626 unitysortfilterproxymodeltest
2727 timeformattertest
28+ homekeywatchertest
2829 )
2930
3031# plain qml test
tests/plugins/Utils/homekeywatchertest.cppnew file+171
@@ -0,0 +1,171 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "homekeywatcher.h"
18+
19+#include <QTest>
20+#include <QSignalSpy>
21+
22+using namespace UnityUtil;
23+
24+class HomeKeyWatcherTest : public QObject {
25+ Q_OBJECT
26+private Q_SLOTS:
27+ void init(); // called right before each and every test function is executed
28+ void cleanup(); // called right after each and every test function is executed
29+
30+ void touchTapTouch_data();
31+ void touchTapTouch();
32+
33+ void tapWhileTouching();
34+
35+private:
36+ void passTime(qint64 timeSpanMs);
37+
38+ FakeTimerFactory *m_fakeTimerFactory;
39+};
40+
41+void HomeKeyWatcherTest::init()
42+{
43+ m_fakeTimerFactory = new FakeTimerFactory;
44+}
45+
46+void HomeKeyWatcherTest::cleanup()
47+{
48+ delete m_fakeTimerFactory;
49+ m_fakeTimerFactory = nullptr;
50+}
51+
52+
53+void HomeKeyWatcherTest::passTime(qint64 timeSpanMs)
54+{
55+ qint64 finalTime = FakeElapsedTimer::msecsSinceEpoch + timeSpanMs;
56+ m_fakeTimerFactory->updateTime(finalTime);
57+}
58+
59+void HomeKeyWatcherTest::touchTapTouch_data()
60+{
61+ QTest::addColumn<int>("silenceBeforeTap");
62+ QTest::addColumn<int>("tapDuration");
63+ QTest::addColumn<int>("silenceAfterTap");
64+ QTest::addColumn<int>("expectedActivatedCount");
65+
66+ QTest::newRow("tap followed by touch") << 2000 << 50 << 10 << 0;
67+ QTest::newRow("touch, tap and touch") << 10 << 50 << 10 << 0;
68+ QTest::newRow("touch followed by tap") << 10 << 50 << 2000 << 0;
69+ QTest::newRow("touch followed by long tap") << 10 << 500 << 2000 << 0;
70+ QTest::newRow("isolated tap") << 1000 << 50 << 1000 << 1;
71+}
72+
73+void HomeKeyWatcherTest::touchTapTouch()
74+{
75+ QFETCH(int, silenceBeforeTap);
76+ QFETCH(int, tapDuration);
77+ QFETCH(int, silenceAfterTap);
78+ QFETCH(int, expectedActivatedCount);
79+ HomeKeyWatcher homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
80+ QSignalSpy activatedSpy(&homeKeyWatcher, SIGNAL(activated()));
81+ QVERIFY(activatedSpy.isValid());
82+
83+ {
84+ QTouchEvent touchEvent(QEvent::TouchBegin);
85+ homeKeyWatcher.update(&touchEvent);
86+ }
87+ passTime(100);
88+ {
89+ QTouchEvent touchEvent(QEvent::TouchUpdate);
90+ homeKeyWatcher.update(&touchEvent);
91+ }
92+ passTime(100);
93+ {
94+ QTouchEvent touchEvent(QEvent::TouchEnd);
95+ homeKeyWatcher.update(&touchEvent);
96+ }
97+
98+ passTime(silenceBeforeTap);
99+
100+ {
101+ QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::NoModifier);
102+ homeKeyWatcher.update(&keyEvent);
103+ }
104+ int tapTime = 0;
105+ while (tapTime < tapDuration) {
106+ passTime(10);
107+ tapTime += 10;
108+ if (tapTime + 10 >= tapDuration) {
109+ QKeyEvent keyEvent(QEvent::KeyRelease, Qt::Key_Home, Qt::NoModifier);
110+ homeKeyWatcher.update(&keyEvent);
111+ } else {
112+ QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::NoModifier, QString(), true /*autorepeat*/);
113+ homeKeyWatcher.update(&keyEvent);
114+ }
115+ }
116+
117+ passTime(silenceAfterTap);
118+
119+ {
120+ QTouchEvent touchEvent(QEvent::TouchBegin);
121+ homeKeyWatcher.update(&touchEvent);
122+ }
123+ passTime(100);
124+ {
125+ QTouchEvent touchEvent(QEvent::TouchUpdate);
126+ homeKeyWatcher.update(&touchEvent);
127+ }
128+ passTime(100);
129+ {
130+ QTouchEvent touchEvent(QEvent::TouchEnd);
131+ homeKeyWatcher.update(&touchEvent);
132+ }
133+ passTime(1000);
134+
135+ QCOMPARE(activatedSpy.count(), expectedActivatedCount);
136+}
137+
138+void HomeKeyWatcherTest::tapWhileTouching()
139+{
140+ HomeKeyWatcher homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
141+ QSignalSpy activatedSpy(&homeKeyWatcher, SIGNAL(activated()));
142+ QVERIFY(activatedSpy.isValid());
143+
144+ {
145+ QTouchEvent touchEvent(QEvent::TouchBegin);
146+ homeKeyWatcher.update(&touchEvent);
147+ }
148+ passTime(1000);
149+ {
150+ QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::NoModifier);
151+ homeKeyWatcher.update(&keyEvent);
152+ }
153+ passTime(100);
154+ {
155+ QKeyEvent keyEvent(QEvent::KeyRelease, Qt::Key_Home, Qt::NoModifier);
156+ homeKeyWatcher.update(&keyEvent);
157+ }
158+ passTime(1000);
159+ {
160+ QTouchEvent touchEvent(QEvent::TouchEnd);
161+ homeKeyWatcher.update(&touchEvent);
162+ }
163+ passTime(1000);
164+
165+
166+ QCOMPARE(activatedSpy.count(), 0);
167+}
168+
169+QTEST_GUILESS_MAIN(HomeKeyWatcherTest)
170+
171+#include "homekeywatchertest.moc"