on xenial help sign in
Make use of QInputDeviceInfo in order to automatically switch between usage modes and hide the OSK.

Approved by: Lukáš Tinkl

commit625c5d077f9a1ee572197ab8e96175ca66185bb7 authorMichael Zanetti <michael.zanetti@canonical.com> dateThu 2 Jul 2015, 16:09 (11 years ago) parent23ba6461cf027f
15 files changed+823−7
data/com.canonical.Unity8.gschema.xml+2−1 qml/Components/UnityInputInfo/UnityInputInfo.qml+91 qml/Components/UnityInputInfo/qmldir+1 qml/DeviceConfiguration.qml+12 qml/OrientedShell.qml+32−5 tests/mocks/Unity/CMakeLists.txt+1 tests/mocks/Unity/InputInfo/CMakeLists.txt+26 tests/mocks/Unity/InputInfo/mockqdeclarativeinputdeviceinfo.cpp+173 tests/mocks/Unity/InputInfo/mockqdeclarativeinputdeviceinfo_p.h+94 tests/mocks/Unity/InputInfo/mockqinputinfo.cpp+124 tests/mocks/Unity/InputInfo/mockqinputinfo.h+139 tests/mocks/Unity/InputInfo/plugin.cpp+32 tests/mocks/Unity/InputInfo/plugin.h+30 tests/mocks/Unity/InputInfo/qmldir+2 tests/qmltests/tst_OrientedShell.qml+64−1
data/com.canonical.Unity8.gschema.xml+2−1
@@ -2,11 +2,12 @@
22 <enum id="usage-mode-enum">
33 <value nick="Staged" value="0" />
44 <value nick="Windowed" value="1" />
5+ <value nick="Automatic" value="2" />
56 </enum>
67
78 <schema path="/com/canonical/unity8/" id="com.canonical.Unity8" gettext-domain="unity8">
89 <key enum="usage-mode-enum" name="usage-mode">
9− <default>"Staged"</default>
10+ <default>"Automatic"</default>
1011 <summary>The usage mode.</summary>
1112 <description>The usage mode chosen will affect the Window Management behaviour.</description>
1213 </key>
qml/Components/UnityInputInfo/UnityInputInfo.qmlnew file+91
@@ -0,0 +1,91 @@
1+/*
2+ * Copyright 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 Lesser 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 Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+pragma Singleton
18+
19+import QtQuick 2.3
20+import Unity.InputInfo 0.1
21+
22+Item {
23+ id: root
24+ readonly property alias mice: priv.miceCount
25+ readonly property alias keyboards: priv.keyboardCount
26+
27+ property alias inputInfo: inputInfo
28+
29+ QtObject {
30+ id: priv
31+
32+ property var mice: []
33+ property var keyboards: []
34+
35+ property int miceCount: 0
36+ property int keyboardCount: 0
37+
38+ function addMouse(devicePath) {
39+ mice.push(devicePath);
40+ miceCount++;
41+ }
42+
43+ function addKeyboard(devicePath) {
44+ keyboards.push(devicePath);
45+ keyboardCount++;
46+ }
47+
48+ function removeDevice(devicePath) {
49+ for (var i = 0; i < priv.mice.length; i++) {
50+ if (priv.mice[i] == devicePath) {
51+ priv.mice.splice(i, 1);
52+ priv.miceCount--;
53+ }
54+ }
55+ for (var i = 0; i < priv.keyboards.length; i++) {
56+ if (priv.keyboards[i] == devicePath) {
57+ priv.keyboards.splice(i, 1);
58+ priv.keyboardCount--;
59+ }
60+ }
61+ }
62+ }
63+
64+ InputDeviceInfo {
65+ id: inputInfo
66+ objectName: "inputDeviceInfo"
67+
68+ onNewDevice: {
69+ var device = inputInfo.get(inputInfo.indexOf(devicePath));
70+ if (device === null) {
71+ return;
72+ }
73+
74+ var hasMouse = (device.types & InputInfo.Mouse) == InputInfo.Mouse
75+ var hasTouchpad = (device.types & InputInfo.TouchPad) == InputInfo.TouchPad
76+ var hasKeyboard = (device.types & InputInfo.Keyboard) == InputInfo.Keyboard
77+
78+ if (hasMouse || hasTouchpad) {
79+ priv.addMouse(devicePath);
80+ } else if (hasKeyboard) {
81+ // Only accepting keyboards that do not claim to be a mouse too
82+ // This will be a bit buggy for real hybrid devices, but doesn't
83+ // fall for Microsoft mice that claim to be Keyboards too.
84+ priv.addKeyboard(devicePath)
85+ }
86+ }
87+ onDeviceRemoved: {
88+ priv.removeDevice(devicePath)
89+ }
90+ }
91+}
qml/Components/UnityInputInfo/qmldirnew file+1
@@ -0,0 +1 @@
1+singleton UnityInputInfo 1.0 UnityInputInfo.qml
qml/DeviceConfiguration.qml+12
@@ -32,6 +32,8 @@ StateGroup {
3232 // "phone", "tablet" or "desktop"
3333 property string category: "phone"
3434
35+ property int ignoredMice: 0
36+
3537
3638 property alias name: root.state
3739
@@ -54,6 +56,16 @@ StateGroup {
5456 | Qt.InvertedLandscapeOrientation
5557 }
5658 },
59+ State {
60+ name: "arale"
61+ PropertyChanges {
62+ target: root
63+ supportedOrientations: Qt.PortraitOrientation
64+ | Qt.LandscapeOrientation
65+ | Qt.InvertedLandscapeOrientation
66+ ignoredMice: 1
67+ }
68+ },
5769 State {
5870 name: "manta"
5971 PropertyChanges {
qml/OrientedShell.qml+32−5
@@ -19,6 +19,7 @@ import QtQuick.Window 2.0
1919import Unity.Session 0.1
2020import GSettings 1.0
2121import "Components"
22+import "Components/UnityInputInfo"
2223import "Rotation"
2324
2425Rectangle {
@@ -40,8 +41,11 @@ Rectangle {
4041 name: applicationArguments.deviceName
4142 }
4243
44+
4345 // to be overwritten by tests
4446 property var usageModeSettings: GSettings { schema.id: "com.canonical.Unity8" }
47+ property var oskSettings: GSettings { schema.id: "com.canonical.keyboard.maliit" }
48+
4549 property int physicalOrientation: Screen.orientation
4650 property bool orientationLocked: OrientationLock.enabled
4751 property var orientationLock: OrientationLock
@@ -63,6 +67,22 @@ Rectangle {
6367 if (orientationLocked) {
6468 orientation = orientationLock.savedOrientation;
6569 }
70+ // We need to manually update this on startup as the binding
71+ // below doesn't seem to have any effect at that stage
72+ oskSettings.stayHidden = UnityInputInfo.keyboards > 0
73+ oskSettings.disableHeight = shell.usageScenario == "desktop"
74+ }
75+
76+ Binding {
77+ target: oskSettings
78+ property: "stayHidden"
79+ value: UnityInputInfo.keyboards > 0
80+ }
81+
82+ Binding {
83+ target: oskSettings
84+ property: "disableHeight"
85+ value: shell.usageScenario == "desktop"
6686 }
6787
6888 readonly property int supportedOrientations: shell.supportedOrientations
@@ -142,11 +162,18 @@ Rectangle {
142162 usageScenario: {
143163 if (root.usageModeSettings.usageMode === "Windowed") {
144164 return "desktop";
145− } else if (root.usageModeSettings.usageMode === "Staged"
146− && deviceConfiguration.category === "desktop") {
147− return "tablet";
148− } else {
149− return deviceConfiguration.category;
165+ } else if (root.usageModeSettings.usageMode === "Staged") {
166+ if (deviceConfiguration.category === "phone") {
167+ return "phone";
168+ } else {
169+ return "tablet";
170+ }
171+ } else { // automatic
172+ if (UnityInputInfo.mice > deviceConfiguration.ignoredMice) {
173+ return "desktop";
174+ } else {
175+ return deviceConfiguration.category;
176+ }
150177 }
151178 }
152179
tests/mocks/Unity/CMakeLists.txt+1
@@ -1,6 +1,7 @@
11add_subdirectory(Application)
22add_subdirectory(Connectivity)
33add_subdirectory(Indicators)
4+add_subdirectory(InputInfo)
45add_subdirectory(Launcher)
56add_subdirectory(Notifications)
67add_subdirectory(DashCommunicator)
tests/mocks/Unity/InputInfo/CMakeLists.txtnew file+26
@@ -0,0 +1,26 @@
1+# TODO: This is a copy of the plugin in plugins/Unity/InputInfo which in
2+# turn is a copy of the WIP upstream InputInfo API. This needs to be updated
3+# and brought in sync if our snapshot is updated.
4+# Long term goal is to merge the InputInfo API upstream.
5+
6+find_package(Qt5Core REQUIRED)
7+find_package(Qt5Quick REQUIRED)
8+
9+include_directories(
10+ ${CMAKE_CURRENT_SOURCE_DIR}
11+ ${CMAKE_CURRENT_BINARY_DIR}
12+)
13+
14+set(MockInputInfo_SOURCES
15+ plugin.cpp
16+ mockqinputinfo.cpp
17+ mockqdeclarativeinputdeviceinfo.cpp
18+)
19+
20+add_library(MockInputInfo SHARED
21+ ${MockInputInfo_SOURCES}
22+)
23+
24+qt5_use_modules(MockInputInfo Core Qml Quick)
25+
26+add_unity8_mock(Unity.InputInfo 0.1 Unity/InputInfo TARGETS MockInputInfo)
tests/mocks/Unity/InputInfo/mockqdeclarativeinputdeviceinfo.cppnew file+173
@@ -0,0 +1,173 @@
1+/****************************************************************************
2+**
3+** Copyright (C) 2015 Jolla.
4+** Copyright (C) 2015 Canonical Ltd.
5+** Contact: http://www.qt-project.org/legal
6+**
7+** This file is part of the QtSystems module of the Qt Toolkit.
8+**
9+** $QT_BEGIN_LICENSE:LGPL$
10+** Commercial License Usage
11+** Licensees holding valid commercial Qt licenses may use this file in
12+** accordance with the commercial license agreement provided with the
13+** Software or, alternatively, in accordance with the terms contained in
14+** a written agreement between you and Digia. For licensing terms and
15+** conditions see http://qt.digia.com/licensing. For further information
16+** use the contact form at http://qt.digia.com/contact-us.
17+**
18+** GNU Lesser General Public License Usage
19+** Alternatively, this file may be used under the terms of the GNU Lesser
20+** General Public License version 2.1 as published by the Free Software
21+** Foundation and appearing in the file LICENSE.LGPL included in the
22+** packaging of this file. Please review the following information to
23+** ensure the GNU Lesser General Public License version 2.1 requirements
24+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25+**
26+** In addition, as a special exception, Digia gives you certain additional
27+** rights. These rights are described in the Digia Qt LGPL Exception
28+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29+**
30+** GNU General Public License Usage
31+** Alternatively, this file may be used under the terms of the GNU
32+** General Public License version 3.0 as published by the Free Software
33+** Foundation and appearing in the file LICENSE.GPL included in the
34+** packaging of this file. Please review the following information to
35+** ensure the GNU General Public License version 3.0 requirements will be
36+** met: http://www.gnu.org/copyleft/gpl.html.
37+**
38+**
39+** $QT_END_LICENSE$
40+**
41+****************************************************************************/
42+#include "mockqdeclarativeinputdeviceinfo_p.h"
43+
44+QDeclarativeInputDeviceInfo::QDeclarativeInputDeviceInfo(QObject *parent) :
45+ QAbstractListModel(parent),
46+ deviceInfo(new QInputDeviceInfo)
47+{
48+ connect(deviceInfo, &QInputDeviceInfo::deviceAdded,this,&QDeclarativeInputDeviceInfo::addedDevice);
49+ connect(deviceInfo, &QInputDeviceInfo::deviceRemoved,this,&QDeclarativeInputDeviceInfo::removedDevice);
50+}
51+
52+QDeclarativeInputDeviceInfo::~QDeclarativeInputDeviceInfo()
53+{
54+ delete deviceInfo;
55+}
56+
57+QVariant QDeclarativeInputDeviceInfo::data(const QModelIndex &index, int role) const
58+{
59+ switch (role) {
60+ case ServiceRole:
61+ return QVariant::fromValue(static_cast<QObject *>(inputDevices.value(index.row())));
62+ }
63+
64+ return QVariant();
65+}
66+
67+int QDeclarativeInputDeviceInfo::rowCount(const QModelIndex &parent) const
68+{
69+ Q_UNUSED(parent);
70+
71+ return inputDevices.count();
72+}
73+
74+int QDeclarativeInputDeviceInfo::indexOf(const QString &devicePath) const
75+{
76+ int idx(-1);
77+ Q_FOREACH (QInputDevice *device, inputDevices) {
78+ idx++;
79+ if (device->devicePath() == devicePath) return idx;
80+ }
81+
82+ return -1;
83+}
84+
85+QInputDevice *QDeclarativeInputDeviceInfo::get(int index) const
86+{
87+ if (index < 0 || index > inputDevices.count())
88+ return 0;
89+ return inputDevices.value(index);
90+}
91+
92+void QDeclarativeInputDeviceInfo::addMockMouse()
93+{
94+ deviceInfo->addMockDevice(QInputDeviceInfo::Mouse);
95+}
96+
97+void QDeclarativeInputDeviceInfo::addMockKeyboard()
98+{
99+ deviceInfo->addMockDevice(QInputDeviceInfo::Keyboard);
100+}
101+
102+void QDeclarativeInputDeviceInfo::removeMockMouse()
103+{
104+ for (int i = 0; i < inputDevices.count(); i++) {
105+ if (inputDevices.at(i)->types().testFlag(QInputDeviceInfo::Mouse)) {
106+ deviceInfo->removeMockDevice(i);
107+ return;
108+ }
109+ }
110+}
111+
112+void QDeclarativeInputDeviceInfo::removeMockKeyboard()
113+{
114+ for (int i = 0; i < inputDevices.count(); i++) {
115+ if (inputDevices.at(i)->types().testFlag(QInputDeviceInfo::Keyboard)) {
116+ deviceInfo->removeMockDevice(i);
117+ return;
118+ }
119+ }
120+}
121+
122+void QDeclarativeInputDeviceInfo::updateDeviceList()
123+{
124+ QVector <QInputDevice *> newDevices = deviceInfo->deviceList();
125+
126+ int numNew = newDevices.count();
127+
128+ for (int i = 0; i < numNew; i++) {
129+ int j = inputDevices.indexOf(newDevices.value(i));
130+ if (j == -1) {
131+ // not found -> remove from list
132+ beginInsertRows(QModelIndex(), i, i);
133+ inputDevices.insert(i, newDevices.value(i));
134+ endInsertRows();
135+ } else if (i != j) {
136+ // changed its position -> move it
137+ QInputDevice* device = inputDevices.value(j);
138+ beginMoveRows(QModelIndex(), j, j, QModelIndex(), i);
139+ inputDevices.remove(j);
140+ inputDevices.insert(i, device);
141+ endMoveRows();
142+ } else {
143+ QModelIndex changedIndex(this->index(j, 0, QModelIndex()));
144+ Q_EMIT dataChanged(changedIndex, changedIndex);
145+ }
146+ }
147+
148+ int numOld = inputDevices.count();
149+ if (numOld > numNew) {
150+ beginRemoveRows(QModelIndex(), numNew, numOld - 1);
151+ inputDevices.remove(numNew, numOld - numNew);
152+ endRemoveRows();
153+ }
154+}
155+
156+void QDeclarativeInputDeviceInfo::addedDevice(const QString &devicePath)
157+{
158+ updateDeviceList();
159+ Q_EMIT newDevice(devicePath);
160+}
161+
162+void QDeclarativeInputDeviceInfo::removedDevice(const QString &devicePath)
163+{
164+ updateDeviceList();
165+ Q_EMIT deviceRemoved(devicePath);
166+}
167+
168+QHash<int, QByteArray> QDeclarativeInputDeviceInfo::roleNames() const
169+{
170+ QHash<int, QByteArray> roles;
171+ roles.insert(ServiceRole, "service");
172+ return roles;
173+}
tests/mocks/Unity/InputInfo/mockqdeclarativeinputdeviceinfo_p.hnew file+94
@@ -0,0 +1,94 @@
1+/****************************************************************************
2+**
3+** Copyright (C) 2015 Jolla.
4+** Copyright (C) 2015 Canoncal Ltd.
5+** Contact: http://www.qt-project.org/legal
6+**
7+** This file is part of the QtSystems module of the Qt Toolkit.
8+**
9+** $QT_BEGIN_LICENSE:LGPL$
10+** Commercial License Usage
11+** Licensees holding valid commercial Qt licenses may use this file in
12+** accordance with the commercial license agreement provided with the
13+** Software or, alternatively, in accordance with the terms contained in
14+** a written agreement between you and Digia. For licensing terms and
15+** conditions see http://qt.digia.com/licensing. For further information
16+** use the contact form at http://qt.digia.com/contact-us.
17+**
18+** GNU Lesser General Public License Usage
19+** Alternatively, this file may be used under the terms of the GNU Lesser
20+** General Public License version 2.1 as published by the Free Software
21+** Foundation and appearing in the file LICENSE.LGPL included in the
22+** packaging of this file. Please review the following information to
23+** ensure the GNU Lesser General Public License version 2.1 requirements
24+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25+**
26+** In addition, as a special exception, Digia gives you certain additional
27+** rights. These rights are described in the Digia Qt LGPL Exception
28+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29+**
30+** GNU General Public License Usage
31+** Alternatively, this file may be used under the terms of the GNU
32+** General Public License version 3.0 as published by the Free Software
33+** Foundation and appearing in the file LICENSE.GPL included in the
34+** packaging of this file. Please review the following information to
35+** ensure the GNU General Public License version 3.0 requirements will be
36+** met: http://www.gnu.org/copyleft/gpl.html.
37+**
38+**
39+** $QT_END_LICENSE$
40+**
41+****************************************************************************/
42+
43+#ifndef QDECLARATIVEINPUTDEVICEINFO_H
44+#define QDECLARATIVEINPUTDEVICEINFO_H
45+
46+#include <QObject>
47+#include <QAbstractListModel>
48+#include "mockqinputinfo.h"
49+
50+class QDeclarativeInputDeviceInfo : public QAbstractListModel
51+{
52+ Q_OBJECT
53+ Q_DISABLE_COPY(QDeclarativeInputDeviceInfo)
54+
55+public:
56+ enum ItemRoles {
57+ ServiceRole = Qt::UserRole + 1
58+ };
59+
60+ explicit QDeclarativeInputDeviceInfo(QObject *parent = 0);
61+ virtual ~QDeclarativeInputDeviceInfo();
62+
63+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
64+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
65+
66+ QHash<int, QByteArray> roleNames() const;
67+
68+ Q_INVOKABLE int indexOf(const QString &devicePath) const;
69+
70+ Q_INVOKABLE QInputDevice *get(int index) const;
71+
72+ // For testing
73+ Q_INVOKABLE void addMockMouse();
74+ Q_INVOKABLE void addMockKeyboard();
75+ Q_INVOKABLE void removeMockMouse();
76+ Q_INVOKABLE void removeMockKeyboard();
77+
78+Q_SIGNALS:
79+ void newDevice(const QString &devicePath);
80+ void deviceRemoved(const QString &devicePath);
81+
82+public Q_SLOTS:
83+ void updateDeviceList();
84+
85+private:
86+ QInputDeviceInfo *deviceInfo;
87+ QVector<QInputDevice *> inputDevices;
88+private Q_SLOTS:
89+ void addedDevice(const QString &);
90+ void removedDevice(const QString &path);
91+
92+};
93+
94+#endif // QDECLARATIVEINPUTDEVICEINFO_H
tests/mocks/Unity/InputInfo/mockqinputinfo.cppnew file+124
@@ -0,0 +1,124 @@
1+/****************************************************************************
2+**
3+** Copyright (C) 2015 Canonical, Ltd. and/or its subsidiary(-ies).
4+** Contact: http://www.qt-project.org/legal
5+**
6+** This file is part of the QtSystems module of the Qt Toolkit.
7+**
8+** $QT_BEGIN_LICENSE:LGPL$
9+** Commercial License Usage
10+** Licensees holding valid commercial Qt licenses may use this file in
11+** accordance with the commercial license agreement provided with the
12+** Software or, alternatively, in accordance with the terms contained in
13+** a written agreement between you and Digia. For licensing terms and
14+** conditions see http://qt.digia.com/licensing. For further information
15+** use the contact form at http://qt.digia.com/contact-us.
16+**
17+** GNU Lesser General Public License Usage
18+** Alternatively, this file may be used under the terms of the GNU Lesser
19+** General Public License version 2.1 as published by the Free Software
20+** Foundation and appearing in the file LICENSE.LGPL included in the
21+** packaging of this file. Please review the following information to
22+** ensure the GNU Lesser General Public License version 2.1 requirements
23+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24+**
25+** In addition, as a special exception, Digia gives you certain additional
26+** rights. These rights are described in the Digia Qt LGPL Exception
27+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28+**
29+** GNU General Public License Usage
30+** Alternatively, this file may be used under the terms of the GNU
31+** General Public License version 3.0 as published by the Free Software
32+** Foundation and appearing in the file LICENSE.GPL included in the
33+** packaging of this file. Please review the following information to
34+** ensure the GNU General Public License version 3.0 requirements will be
35+** met: http://www.gnu.org/copyleft/gpl.html.
36+**
37+**
38+** $QT_END_LICENSE$
39+**
40+****************************************************************************/
41+
42+#include "mockqinputinfo.h"
43+
44+
45+QInputDevice::QInputDevice(QObject *parent) :
46+ QObject(parent)
47+{
48+}
49+
50+QString QInputDevice::name() const
51+{
52+ return m_name;
53+}
54+
55+void QInputDevice::setName(const QString &name)
56+{
57+ m_name = name;
58+}
59+
60+QString QInputDevice::devicePath() const
61+{
62+ return m_devicePath;
63+}
64+
65+void QInputDevice::setDevicePath(const QString &path)
66+{
67+ m_devicePath = path;
68+}
69+
70+QList <int> QInputDevice::buttons() const
71+{
72+ return {1, 2 ,3};
73+}
74+
75+QList <int> QInputDevice::switches() const
76+{
77+ return {};
78+}
79+
80+QList <int> QInputDevice::relativeAxis() const
81+{
82+ return {};
83+}
84+
85+QList <int> QInputDevice::absoluteAxis() const
86+{
87+ return {};
88+}
89+
90+QInputDeviceInfo::InputTypes QInputDevice::types()
91+{
92+ return m_types;
93+}
94+
95+void QInputDevice::setTypes(QInputDeviceInfo::InputTypes types)
96+{
97+ m_types = types;
98+}
99+
100+QInputDeviceInfo::QInputDeviceInfo(QObject *parent) :
101+ QObject(parent)
102+{
103+}
104+
105+QVector <QInputDevice *> QInputDeviceInfo::deviceList()
106+{
107+ return m_list;
108+}
109+
110+void QInputDeviceInfo::removeMockDevice(int index)
111+{
112+ QInputDevice *device = m_list.takeAt(index);
113+ Q_EMIT deviceRemoved(device->devicePath());
114+ device->deleteLater();
115+}
116+
117+void QInputDeviceInfo::addMockDevice(QInputDeviceInfo::InputType inputType)
118+{
119+ QInputDevice *device = new QInputDevice(this);
120+ device->setDevicePath("/mock/device/" + QString::number(m_counter++));
121+ device->setTypes({inputType});
122+ m_list.append(device);
123+ Q_EMIT deviceAdded(device->devicePath());
124+}
tests/mocks/Unity/InputInfo/mockqinputinfo.hnew file+139
@@ -0,0 +1,139 @@
1+/****************************************************************************
2+**
3+** Copyright (C) 2015 Canonical, Ltd. and/or its subsidiary(-ies).
4+** Contact: http://www.qt-project.org/legal
5+**
6+** This file is part of the QtSystems module of the Qt Toolkit.
7+**
8+** $QT_BEGIN_LICENSE:LGPL$
9+** Commercial License Usage
10+** Licensees holding valid commercial Qt licenses may use this file in
11+** accordance with the commercial license agreement provided with the
12+** Software or, alternatively, in accordance with the terms contained in
13+** a written agreement between you and Digia. For licensing terms and
14+** conditions see http://qt.digia.com/licensing. For further information
15+** use the contact form at http://qt.digia.com/contact-us.
16+**
17+** GNU Lesser General Public License Usage
18+** Alternatively, this file may be used under the terms of the GNU Lesser
19+** General Public License version 2.1 as published by the Free Software
20+** Foundation and appearing in the file LICENSE.LGPL included in the
21+** packaging of this file. Please review the following information to
22+** ensure the GNU Lesser General Public License version 2.1 requirements
23+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24+**
25+** In addition, as a special exception, Digia gives you certain additional
26+** rights. These rights are described in the Digia Qt LGPL Exception
27+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28+**
29+** GNU General Public License Usage
30+** Alternatively, this file may be used under the terms of the GNU
31+** General Public License version 3.0 as published by the Free Software
32+** Foundation and appearing in the file LICENSE.GPL included in the
33+** packaging of this file. Please review the following information to
34+** ensure the GNU General Public License version 3.0 requirements will be
35+** met: http://www.gnu.org/copyleft/gpl.html.
36+**
37+**
38+** $QT_END_LICENSE$
39+**
40+****************************************************************************/
41+
42+#ifndef MOCKQINPUTINFO_H
43+#define MOCKQINPUTINFO_H
44+
45+#include <QObject>
46+#include <QVector>
47+#include <QMap>
48+#include <QSocketNotifier>
49+#include <QDebug>
50+
51+class QInputDevicePrivate;
52+class QInputDevice;
53+
54+class QInputDeviceInfoPrivate;
55+class QInputDeviceInfo : public QObject
56+{
57+ Q_OBJECT
58+ Q_PROPERTY(int deviceCount READ deviceCount)
59+public:
60+
61+ enum InputType {
62+ Unknown = 0,
63+ Button = 1,
64+ Mouse = 2,
65+ TouchPad = 4,
66+ TouchScreen = 8,
67+ Keyboard = 16,
68+ Switch = 32
69+ };
70+ Q_ENUMS(InputType)
71+ Q_FLAGS(InputTypes)
72+ Q_DECLARE_FLAGS(InputTypes, InputType)
73+
74+ explicit QInputDeviceInfo(QObject *parent = 0);
75+
76+ Q_INVOKABLE QVector <QInputDevice *> deviceList();
77+
78+ int deviceCount() { return deviceList().count(); }
79+
80+ Q_INVOKABLE void addMockDevice(InputType inputType);
81+ Q_INVOKABLE void removeMockDevice(int index);
82+
83+Q_SIGNALS:
84+
85+ void deviceAdded(const QString & devicePath);
86+ void deviceRemoved(const QString & devicePath);
87+
88+private:
89+ QVector<QInputDevice*> m_list;
90+
91+ int m_counter = 0;
92+};
93+
94+class QInputDevice : public QObject
95+{
96+ friend class QInputDeviceInfoPrivate;
97+ Q_OBJECT
98+ Q_ENUMS(InputType)
99+ Q_FLAGS(InputTypes)
100+ Q_PROPERTY(QString name READ name NOTIFY nameChanged)
101+ Q_PROPERTY(QString devicePath READ devicePath NOTIFY devicePathChanged)
102+ Q_PROPERTY(QList <int> buttons READ buttons NOTIFY buttonsChanged)
103+ Q_PROPERTY(QList <int> switches READ switches NOTIFY switchesChanged)
104+ Q_PROPERTY(QList <int> relativeAxis READ relativeAxis NOTIFY relativeAxisChanged)
105+ Q_PROPERTY(QList <int> absoluteAxis READ absoluteAxis NOTIFY absoluteAxisChanged)
106+ Q_PROPERTY(QInputDeviceInfo::InputTypes types READ types NOTIFY typesChanged)
107+
108+public:
109+ explicit QInputDevice(QObject *parent = 0);
110+
111+ QString name() const;
112+ QString devicePath() const;
113+ QList <int> buttons() const; //keys event code
114+ QList <int> switches() const;
115+ QList <int> relativeAxis() const;
116+ QList <int> absoluteAxis() const;
117+
118+ QInputDeviceInfo::InputTypes types();
119+Q_SIGNALS:
120+ void nameChanged();
121+ void devicePathChanged();
122+ void buttonsChanged();
123+ void switchesChanged();
124+ void relativeAxisChanged();
125+ void absoluteAxisChanged();
126+ void typesChanged();
127+private:
128+ void setName(const QString &name);
129+ void setTypes(QInputDeviceInfo::InputTypes types);
130+ void setDevicePath(const QString &path);
131+
132+ QString m_name;
133+ QInputDeviceInfo::InputTypes m_types;
134+ QString m_devicePath;
135+
136+ friend class QInputDeviceInfo;
137+};
138+
139+#endif // MOCKQINPUTINFO_H
tests/mocks/Unity/InputInfo/plugin.cppnew file+32
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright 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 Lesser 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 Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+// Qt
18+#include <QtQml/qqml.h>
19+
20+// self
21+#include "plugin.h"
22+
23+// local
24+#include "mockqdeclarativeinputdeviceinfo_p.h"
25+
26+void InputInfoPlugin::registerTypes(const char *uri)
27+{
28+ int major = 0;
29+ int minor = 1;
30+ qmlRegisterType<QDeclarativeInputDeviceInfo>(uri, major, minor, "InputDeviceInfo");
31+ qmlRegisterType<QInputDevice>(uri, major, minor, "InputInfo");
32+}
tests/mocks/Unity/InputInfo/plugin.hnew file+30
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright 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 Lesser 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 Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef INPUTINFO_PLUGIN_H
18+#define INPUTINFO_PLUGIN_H
19+
20+#include <QtQml/QQmlExtensionPlugin>
21+
22+class InputInfoPlugin : public QQmlExtensionPlugin
23+{
24+ Q_OBJECT
25+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
26+public:
27+ void registerTypes(const char *uri);
28+};
29+
30+#endif // INPUTINFO_PLUGIN_H
tests/mocks/Unity/InputInfo/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Unity.InputInfo
2+plugin MockInputInfo
tests/qmltests/tst_OrientedShell.qml+64−1
@@ -23,8 +23,10 @@ import Unity.Application 0.1
2323import Unity.Test 0.1
2424import LightDM 0.1 as LightDM
2525import Powerd 0.1
26+import Unity.InputInfo 0.1
2627
2728import "../../qml"
29+import "../../qml/Components/UnityInputInfo"
2830
2931Rectangle {
3032 id: root
@@ -48,6 +50,11 @@ Rectangle {
4850 property string usageMode: usageModeSelector.model[usageModeSelector.selectedIndex]
4951 }
5052
53+ QtObject{
54+ id: mockOskSettings
55+ property bool stayHidden: false;
56+ }
57+
5158 property int physicalOrientation0
5259 property int physicalOrientation90
5360 property int physicalOrientation180
@@ -119,6 +126,7 @@ Rectangle {
119126 OrientedShell {
120127 anchors.fill: parent
121128 usageModeSettings: mockUsageModeSettings
129+ oskSettings: mockOskSettings
122130 physicalOrientation: root.physicalOrientation0
123131 orientationLocked: orientationLockedCheckBox.checked
124132 orientationLock: mockOrientationLock
@@ -294,6 +302,35 @@ Rectangle {
294302 }
295303 }
296304 }
305+
306+ Row {
307+ Button {
308+ text: "Add mouse"
309+ onClicked: {
310+ UnityInputInfo.inputInfo.addMockMouse()
311+ }
312+ }
313+ Button {
314+ text: "Remove mouse"
315+ onClicked: {
316+ UnityInputInfo.inputInfo.removeMockMouse()
317+ }
318+ }
319+ }
320+ Row {
321+ Button {
322+ text: "Add kbd"
323+ onClicked: {
324+ UnityInputInfo.inputInfo.addMockKeyboard()
325+ }
326+ }
327+ Button {
328+ text: "Remove kbd"
329+ onClicked: {
330+ UnityInputInfo.inputInfo.removeMockKeyboard()
331+ }
332+ }
333+ }
297334 }
298335 }
299336
@@ -887,6 +924,33 @@ Rectangle {
887924 tryCompare(shell, "transformRotationAngle", 0);
888925 }
889926
927+ function test_attachRemoveInputDevices() {
928+ usageModeSelector.selectedIndex = 2;
929+ tryCompare(mockUsageModeSettings, "usageMode", "Automatic")
930+
931+ loadShell("mako")
932+ var shell = findChild(orientedShell, "shell");
933+
934+ tryCompare(shell, "usageScenario", "phone");
935+ tryCompare(mockOskSettings, "stayHidden", false);
936+
937+ UnityInputInfo.inputInfo.addMockKeyboard();
938+ tryCompare(shell, "usageScenario", "phone");
939+ tryCompare(mockOskSettings, "stayHidden", true);
940+
941+ UnityInputInfo.inputInfo.addMockMouse();
942+ tryCompare(shell, "usageScenario", "desktop");
943+ tryCompare(mockOskSettings, "stayHidden", true);
944+
945+ UnityInputInfo.inputInfo.removeMockKeyboard();
946+ tryCompare(shell, "usageScenario", "desktop");
947+ tryCompare(mockOskSettings, "stayHidden", false);
948+
949+ UnityInputInfo.inputInfo.removeMockMouse();
950+ tryCompare(shell, "usageScenario", "phone");
951+ tryCompare(mockOskSettings, "stayHidden", false);
952+ }
953+
890954 // angle - rotation angle in degrees clockwise, relative to the primary orientation.
891955 function rotateTo(angle) {
892956 switch (angle) {
@@ -1136,5 +1200,4 @@ Rectangle {
11361200 return found;
11371201 }
11381202 }
1139−
11401203}