Lomiri
WindowInputMonitor.cpp
1 /*
2  * Copyright (C) 2015-2016 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 "WindowInputMonitor.h"
18 
19 #include <QQuickWindow>
20 
21 using namespace LomiriUtil;
22 
23 WindowInputMonitor::WindowInputMonitor(QQuickItem *parent)
24  : WindowInputMonitor(new Timer, new ElapsedTimer, parent)
25 {
26 }
27 
28 WindowInputMonitor::WindowInputMonitor(LomiriUtil::AbstractTimer *timer,
30  QQuickItem *parent)
31  : QQuickItem(parent)
32  , m_windowBeingTouched(false)
33  , m_windowLastTouchedTimer(elapsedTimer)
34  , m_activationTimer(timer)
35 {
36  m_windowLastTouchedTimer->start();
37 
38  connect(this, &QQuickItem::windowChanged,
39  this, &WindowInputMonitor::setupFilterOnWindow);
40 
41  connect(m_activationTimer, &LomiriUtil::AbstractTimer::timeout,
42  this, &WindowInputMonitor::emitActivatedIfNoTouchesAround);
43  m_activationTimer->setInterval(msecsWithoutTouches);
44  m_activationTimer->setSingleShot(true);
45 }
46 
47 WindowInputMonitor::~WindowInputMonitor()
48 {
49  delete m_windowLastTouchedTimer;
50  delete m_activationTimer;
51 }
52 
53 bool WindowInputMonitor::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 WindowInputMonitor::update(QEvent *event)
66 {
67  if (event->type() == QEvent::KeyPress) {
68  QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
69 
70  if (m_pressedHomeKey == 0 && m_homeKeys.contains(keyEvent->key()) && !keyEvent->isAutoRepeat()
71  && !m_activationTimer->isRunning()
72  && !m_windowBeingTouched
73  && m_windowLastTouchedTimer->elapsed() >= msecsWithoutTouches) {
74  m_pressedHomeKey = keyEvent->key();
75  m_activationTimer->start();
76  } else if (m_pressedHomeKey != 0 && !m_homeKeys.contains(keyEvent->key())) {
77  // something else came in... cancel activation
78  m_activationTimer->stop();
79  }
80 
81  } else if (event->type() == QEvent::KeyRelease) {
82  QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
83 
84  if (keyEvent->key() == m_pressedHomeKey) {
85  m_pressedHomeKey = 0;
86  }
87 
88  } else if (event->type() == QEvent::TouchBegin) {
89 
90  m_activationTimer->stop();
91  m_windowBeingTouched = true;
92  Q_EMIT touchBegun();
93 
94  } else if (event->type() == QEvent::TouchEnd) {
95 
96  m_windowBeingTouched = false;
97  m_windowLastTouchedTimer->start();
98 
99  QTouchEvent * touchEv = static_cast<QTouchEvent *>(event);
100  if (touchEv && !touchEv->touchPoints().isEmpty()) {
101  const QPointF pos = touchEv->touchPoints().last().screenPos();
102  Q_EMIT touchEnded(pos);
103  }
104  }
105 }
106 
107 void WindowInputMonitor::setupFilterOnWindow(QQuickWindow *window)
108 {
109  if (!m_filteredWindow.isNull()) {
110  m_filteredWindow->removeEventFilter(this);
111  m_filteredWindow.clear();
112  }
113 
114  if (window) {
115  window->installEventFilter(this);
116  m_filteredWindow = window;
117  }
118 }
119 
120 void WindowInputMonitor::emitActivatedIfNoTouchesAround()
121 {
122  if (m_pressedHomeKey == 0 && !m_windowBeingTouched &&
123  (m_windowLastTouchedTimer->elapsed() > msecsWithoutTouches)) {
124  Q_EMIT homeKeyActivated();
125  }
126 }
WindowInputMonitor
Definition: WindowInputMonitor.h:34
LomiriUtil::AbstractTimer
Definition: Timer.h:29
LomiriUtil::AbstractElapsedTimer
Definition: ElapsedTimer.h:29
LomiriUtil::ElapsedTimer
Definition: ElapsedTimer.h:40
LomiriUtil::Timer
Definition: Timer.h:46