on xenial help sign in
Switch Surface focus also with mouse clicks
commita6e7ec545ecd93df0fb83e2e19c2620a6a93be89 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateWed 11 Mar 2015, 20:12 (12 years ago) parentedd4d67
5 files changed+186−6
plugins/Utils/CMakeLists.txt+1 plugins/Utils/inputwatcher.cpp+114 plugins/Utils/inputwatcher.h+56 plugins/Utils/plugin.cpp+2 qml/Stages/SurfaceContainer.qml+13−6
plugins/Utils/CMakeLists.txt+1
@@ -8,6 +8,7 @@ include_directories(
88)
99
1010set(QMLPLUGIN_SRC
11+ inputwatcher.cpp
1112 qlimitproxymodelqml.cpp
1213 unitysortfilterproxymodelqml.cpp
1314 relativetimeformatter.cpp
plugins/Utils/inputwatcher.cppnew file+114
@@ -0,0 +1,114 @@
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+
18+#include "inputwatcher.h"
19+
20+#include <QMouseEvent>
21+
22+InputWatcher::InputWatcher(QObject *parent)
23+ : QObject(parent)
24+ , m_mousePressed(false)
25+ , m_touchPressed(false)
26+{
27+}
28+
29+QObject *InputWatcher::target() const
30+{
31+ return m_target;
32+}
33+
34+void InputWatcher::setTarget(QObject *value)
35+{
36+ if (m_target == value) {
37+ return;
38+ }
39+
40+ if (m_target) {
41+ m_target->removeEventFilter(this);
42+ }
43+
44+ setMousePressed(false);
45+ setTouchPressed(false);
46+
47+ m_target = value;
48+ m_target->installEventFilter(this);
49+}
50+
51+bool InputWatcher::pressed() const
52+{
53+ return m_mousePressed || m_touchPressed;
54+}
55+
56+bool InputWatcher::eventFilter(QObject* /*watched*/, QEvent *event)
57+{
58+ switch (event->type()) {
59+ case QEvent::TouchBegin:
60+ setTouchPressed(true);
61+ break;
62+ case QEvent::TouchEnd:
63+ setTouchPressed(false);
64+ break;
65+ case QEvent::MouseButtonPress:
66+ {
67+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
68+ if (mouseEvent->button() == Qt::LeftButton) {
69+ setMousePressed(true);
70+ }
71+ }
72+ break;
73+ case QEvent::MouseButtonRelease:
74+ {
75+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
76+ if (mouseEvent->button() == Qt::LeftButton) {
77+ setMousePressed(false);
78+ }
79+ }
80+ break;
81+ default:
82+ // Not interested
83+ break;
84+ }
85+
86+ // We never filter them out. We are just watching.
87+ return false;
88+}
89+
90+void InputWatcher::setMousePressed(bool value)
91+{
92+ if (value == m_mousePressed) {
93+ return;
94+ }
95+
96+ bool oldPressed = pressed();
97+ m_mousePressed = value;
98+ if (pressed() != oldPressed) {
99+ Q_EMIT pressedChanged(pressed());
100+ }
101+}
102+
103+void InputWatcher::setTouchPressed(bool value)
104+{
105+ if (value == m_touchPressed) {
106+ return;
107+ }
108+
109+ bool oldPressed = pressed();
110+ m_touchPressed = value;
111+ if (pressed() != oldPressed) {
112+ Q_EMIT pressedChanged(pressed());
113+ }
114+}
plugins/Utils/inputwatcher.hnew file+56
@@ -0,0 +1,56 @@
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+
18+#ifndef UNITY_INPUTWATCHER_H
19+#define UNITY_INPUTWATCHER_H
20+
21+#include <QObject>
22+#include <QPointer>
23+
24+/*
25+ Monitors the target object for input events to figure out whether it's pressed
26+ or not.
27+ */
28+class InputWatcher : public QObject
29+{
30+ Q_OBJECT
31+ Q_PROPERTY(QObject* target READ target WRITE setTarget NOTIFY targetChanged)
32+ Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
33+public:
34+ InputWatcher(QObject *parent = nullptr);
35+
36+ QObject *target() const;
37+ void setTarget(QObject *value);
38+
39+ bool pressed() const;
40+
41+ bool eventFilter(QObject *watched, QEvent *event) override;
42+
43+Q_SIGNALS:
44+ void targetChanged(QObject *value);
45+ void pressedChanged(bool value);
46+
47+private:
48+ void setMousePressed(bool value);
49+ void setTouchPressed(bool value);
50+
51+ bool m_mousePressed;
52+ bool m_touchPressed;
53+ QPointer<QObject> m_target;
54+};
55+
56+#endif // UNITY_INPUTWATCHER_H
plugins/Utils/plugin.cpp+2
@@ -26,6 +26,7 @@
2626#include "plugin.h"
2727
2828// local
29+#include "inputwatcher.h"
2930#include "qlimitproxymodelqml.h"
3031#include "unitysortfilterproxymodelqml.h"
3132#include "relativetimeformatter.h"
@@ -55,6 +56,7 @@ void UtilsPlugin::registerTypes(const char *uri)
5556 qmlRegisterType<EasingCurve>(uri, 0, 1, "EasingCurve");
5657 qmlRegisterType<RelativeTimeFormatter>(uri, 0, 1, "RelativeTimeFormatter");
5758 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
59+ qmlRegisterType<InputWatcher>(uri, 0, 1, "InputWatcher");
5860}
5961
6062void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
qml/Stages/SurfaceContainer.qml+13−6
@@ -17,6 +17,7 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 1.1
1919import Ubuntu.Gestures 0.1 // For TouchGate
20+import Utils 0.1 // for InputWatcher
2021
2122FocusScope {
2223 id: root
@@ -45,17 +46,23 @@ FocusScope {
4546 Binding { target: surface; property: "enabled"; value: root.interactive; when: surface }
4647 Binding { target: surface; property: "antialiasing"; value: !root.interactive; when: surface }
4748
49+ InputWatcher {
50+ target: root.surface
51+ onPressedChanged: {
52+ if (pressed) {
53+ root.focus = true;
54+ if (root.interactive) {
55+ root.forceActiveFocus();
56+ }
57+ }
58+ }
59+ }
60+
4861 TouchGate {
4962 targetItem: surface
5063 anchors.fill: root
5164 enabled: root.surface ? root.surface.enabled : false
5265 z: 2
53− onPressed: {
54− root.focus = true;
55− if (root.interactive) {
56− root.forceActiveFocus();
57− }
58− }
5966 }
6067
6168 states: [