Unity 8
HomeKeyWatcher.cpp
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_homeKeyPressed(false)
34  , m_windowLastTouchedTimer(elapsedTimer)
35  , m_activationTimer(timer)
36 {
37  m_windowLastTouchedTimer->start();
38 
39  connect(this, &QQuickItem::windowChanged,
40  this, &HomeKeyWatcher::setupFilterOnWindow);
41 
42  connect(m_activationTimer, &UnityUtil::AbstractTimer::timeout,
43  this, &HomeKeyWatcher::emitActivatedIfNoTouchesAround);
44  m_activationTimer->setInterval(msecsWithoutTouches);
45 }
46 
47 HomeKeyWatcher::~HomeKeyWatcher()
48 {
49  delete m_windowLastTouchedTimer;
50  delete m_activationTimer;
51 }
52 
53 bool HomeKeyWatcher::eventFilter(QObject *watched, QEvent *event)
54 {
55  Q_ASSERT(!m_filteredWindow.isNull());
56  Q_ASSERT(watched == static_cast<QObject*>(m_filteredWindow.data()));
57  Q_UNUSED(watched);
58 
59  update(event);
60 
61  // We're only monitoring, never filtering out events
62  return false;
63 }
64 
65 void HomeKeyWatcher::update(QEvent *event)
66 {
67  if (event->type() == QEvent::KeyPress) {
68  QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
69 
70  m_homeKeyPressed = true;
71 
72  if (keyEvent->key() == Qt::Key_Super_L && !keyEvent->isAutoRepeat()
73  && !m_windowBeingTouched
74  && m_windowLastTouchedTimer->elapsed() >= msecsWithoutTouches) {
75  m_activationTimer->start();
76  }
77 
78  } else if (event->type() == QEvent::KeyRelease) {
79  QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
80 
81  if (keyEvent->key() == Qt::Key_Super_L) {
82  m_homeKeyPressed = false;
83  }
84 
85  } else if (event->type() == QEvent::TouchBegin) {
86 
87  m_activationTimer->stop();
88  m_windowBeingTouched = true;
89 
90  } else if (event->type() == QEvent::TouchEnd) {
91 
92  m_windowBeingTouched = false;
93  m_windowLastTouchedTimer->start();
94  }
95 }
96 
97 void HomeKeyWatcher::setupFilterOnWindow(QQuickWindow *window)
98 {
99  if (!m_filteredWindow.isNull()) {
100  m_filteredWindow->removeEventFilter(this);
101  m_filteredWindow.clear();
102  }
103 
104  if (window) {
105  window->installEventFilter(this);
106  m_filteredWindow = window;
107  }
108 }
109 
110 void HomeKeyWatcher::emitActivatedIfNoTouchesAround()
111 {
112  if (!m_homeKeyPressed && !m_windowBeingTouched &&
113  (m_windowLastTouchedTimer->elapsed() > msecsWithoutTouches)) {
114  Q_EMIT activated();
115  }
116 }