on xenial help sign in
update inputinfo api to the latest upstream snapshot

* Import latest update of api from gerrit. * drop all the old mock code * instead of mocking the whole api, add mocks for the backend only. This should simplify future updates and moving to upstream implementation a lot. * update tests to use new mocking system Approved by: Lukáš Tinkl

commit2ba00290dcf913fef9dc0a31ae421e84051f98b7 authorMichael Zanetti <michael.zanetti@canonical.com> dateThu 12 Nov 2015, 20:40 (11 years ago) parent1bdd994e7ed685
24 files changed+682−858
plugins/Unity/InputInfo/CMakeLists.txt+1−1 plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux.cpp+131−83 plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux_p.h+13−6 plugins/Unity/InputInfo/plugin.cpp+2−2 plugins/Unity/InputInfo/qdeclarativeinputdeviceinfo.cpp−143 tests/mocks/Unity/InputInfo/mockqdeclarativeinputdeviceinfo.cpp → plugins/Unity/InputInfo/qdeclarativeinputdevicemodel.cpp+77−54 plugins/Unity/InputInfo/qdeclarativeinputdeviceinfo_p.h → plugins/Unity/InputInfo/qdeclarativeinputdevicemodel_p.h+27−11 plugins/Unity/InputInfo/qinputinfo.cpp+129−18 plugins/Unity/InputInfo/qinputinfo.h+56−56 qml/Components/UnityInputInfo/UnityInputInfo.qml−93 qml/Components/UnityInputInfo/qmldir−1 qml/OrientedShell.qml+16−7 tests/mocks/Unity/InputInfo/CMakeLists.txt+7−2 tests/mocks/Unity/InputInfo/mockcontroller.cpp+35 tests/mocks/Unity/InputInfo/mockcontroller.h+34 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+17−3 tests/mocks/Unity/InputInfo/qinputdeviceinfo_mock.cpp+52 tests/mocks/Unity/InputInfo/qinputdeviceinfo_mock_p.h+58 tests/qmltests/Notifications/tst_Notifications.qml+5−6 tests/qmltests/Notifications/tst_SwipeToAct.qml+5−6 tests/qmltests/tst_OrientedShell.qml+17−9
plugins/Unity/InputInfo/CMakeLists.txt+1−1
@@ -21,7 +21,7 @@ include_directories(
2121set(InputInfo_SOURCES
2222 plugin.cpp
2323 qinputinfo.cpp
24− qdeclarativeinputdeviceinfo.cpp
24+ qdeclarativeinputdevicemodel.cpp
2525 linux/qinputdeviceinfo_linux.cpp
2626)
2727
plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux.cpp+131−83
@@ -47,39 +47,46 @@
4747#include <QDebug>
4848#include <QSocketNotifier>
4949#include <QTimer>
50+#include <QDir>
5051
51−QInputDeviceInfoPrivate::QInputDeviceInfoPrivate(QObject *parent) :
52− QObject(parent)
53− , udev(0)
52+QInputDeviceManagerPrivate::QInputDeviceManagerPrivate(QObject *parent) :
53+ QObject(parent),
54+ currentFilter(QInputDevice::Unknown),
55+ udevice(0)
5456{
55− QTimer::singleShot(250, this, &QInputDeviceInfoPrivate::init);
57+ QTimer::singleShot(250,this,SLOT(init()));
5658}
5759
58−void QInputDeviceInfoPrivate::init()
60+QInputDeviceManagerPrivate::~QInputDeviceManagerPrivate()
5961{
60− if (!udev)
61− udev = udev_new();
62+ udev_unref(udevice);
63+ udev_monitor_unref(udevMonitor);
64+}
65+
66+void QInputDeviceManagerPrivate::init()
67+{
68+ if (!udevice)
69+ udevice = udev_new();
6270
63− struct udev_list_entry *devices, *dev_list_entry;
64− struct udev_device *dev;
71+ udev_list_entry *devices;
72+ udev_list_entry *dev_list_entry;
73+ udev_device *dev;
6574
6675 QString subsystem = QStringLiteral("input");
6776 struct udev_enumerate *enumerate = 0;
6877
69− if (udev) {
78+ if (udevice) {
7079
71− udevMonitor = udev_monitor_new_from_netlink(udev, "udev");
80+ udevMonitor = udev_monitor_new_from_netlink(udevice, "udev");
7281 udev_monitor_filter_add_match_subsystem_devtype(udevMonitor, subsystem.toLatin1(), NULL);
73− enumerate = udev_enumerate_new(udev);
82+ enumerate = udev_enumerate_new(udevice);
7483 udev_enumerate_add_match_subsystem(enumerate, subsystem.toLatin1());
7584
76−
7785 udev_monitor_enable_receiving(udevMonitor);
7886 notifierFd = udev_monitor_get_fd(udevMonitor);
7987
8088 notifier = new QSocketNotifier(notifierFd, QSocketNotifier::Read, this);
81− connect(notifier, &QSocketNotifier::activated, this, &QInputDeviceInfoPrivate::onUDevChanges);
82−
89+ connect(notifier, SIGNAL(activated(int)), this, SLOT(onUDevChanges()));
8390
8491 udev_enumerate_scan_devices(enumerate);
8592 devices = udev_enumerate_get_list_entry(enumerate);
@@ -88,78 +95,80 @@ void QInputDeviceInfoPrivate::init()
8895 const char *path;
8996 path = udev_list_entry_get_name(dev_list_entry);
9097
91− dev = udev_device_new_from_syspath(udev, path);
92−
93− QString eventPath = QString::fromLatin1(udev_device_get_sysname(dev));
94−
98+ dev = udev_device_new_from_syspath(udevice, path);
9599 if (qstrcmp(udev_device_get_subsystem(dev), "input") == 0 ) {
96−
97− if (eventPath.contains(QStringLiteral("event"))) {
98− eventPath.prepend(QStringLiteral("/dev/input/"));
99−
100− QInputDevice *iDevice = addDevice(eventPath);
101− if (!iDevice)
102− continue;
103−
104− iDevice->setTypes(getInputTypes(dev));
105−
106− if (iDevice->switches().count() > 0 && iDevice->buttons().count() == 0)
107− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Switch);
108−
109− if (iDevice->buttons().count() > 0 && iDevice->types() == QInputDeviceInfo::Unknown)
110− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Button);
111−
112− deviceList.append(iDevice);
113− deviceMap.insert(eventPath,iDevice);
114− Q_EMIT newDevice(eventPath);
115−
100+ QInputDevice *iDevice = addDevice(dev);
101+ if (iDevice && !iDevice->devicePath().isEmpty()) {
102+ deviceMap.insert(iDevice->devicePath(),iDevice);
116103 }
117104 }
105+ udev_device_unref(dev);
118106 }
119107 udev_enumerate_unref(enumerate);
120108 }
109+ // udev_unref(udevice);
110+ Q_FOREACH (const QString &devicePath, deviceMap.keys()) {
111+ Q_EMIT deviceAdded(devicePath);
112+ }
121113 Q_EMIT ready();
122114}
123115
124−QInputDeviceInfo::InputTypes QInputDeviceInfoPrivate::getInputTypes( struct udev_device *dev)
116+QInputDevice::InputTypeFlags QInputDeviceManagerPrivate::getInputTypeFlags(struct udev_device *dev)
125117{
126− QInputDeviceInfo::InputTypes types = QInputDeviceInfo::Unknown;
127− if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"), "1") == 0 )
128− types |= QInputDeviceInfo::Keyboard;
129−
130− if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_MOUSE"), "1") == 0)
131− types |= QInputDeviceInfo::Mouse;
132−
133− if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD"), "1") == 0)
134− types |= QInputDeviceInfo::TouchPad;
135−
118+ QInputDevice::InputTypeFlags flags = QInputDevice::Unknown;
119+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEY"), "1") == 0 ) {
120+ flags |= QInputDevice::Button;
121+ }
122+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_MOUSE"), "1") == 0) {
123+ flags |= QInputDevice::Mouse;
124+ }
125+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD"), "1") == 0) {
126+ flags |= QInputDevice::TouchPad;
127+ }
136128 if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"), "1") == 0
137− || qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TABLET"), "1") == 0)
138− types |= QInputDeviceInfo::TouchScreen;
129+ || qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TABLET"), "1") == 0) {
130+ flags |= QInputDevice::TouchScreen;
131+ }
132+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"), "1") == 0 ) {
133+ flags |= QInputDevice::Keyboard;
134+ }
135+ if (!QString::fromLatin1(udev_device_get_property_value(dev, "SW")).isEmpty()) {
136+ flags |= QInputDevice::Switch;
137+ }
139138
140− return types;
139+ return flags;
141140}
142141
143−QInputDevice *QInputDeviceInfoPrivate::addDevice(const QString &path)
142+QInputDevice *QInputDeviceManagerPrivate::addDevice(struct udev_device *udev)
144143{
145− QInputDevice *inputDevice = new QInputDevice(this);
146− inputDevice->setDevicePath(path);
144+ QString eventPath = QString::fromLatin1(udev_device_get_sysname(udev));
147145
146+ if (eventPath.contains(QStringLiteral("event")))
147+ eventPath.prepend(QStringLiteral("/dev/input/"));
148+
149+ if (deviceMap.contains(eventPath)) {
150+ return Q_NULLPTR;
151+ }
148152 struct libevdev *dev = NULL;
149153 int fd;
150154 int rc = 1;
151− fd = open(path.toLatin1(), O_RDONLY|O_NONBLOCK);
155+ QInputDevice *inputDevice;
156+ inputDevice = addUdevDevice(udev);
157+ if (!inputDevice) {
158+ return Q_NULLPTR;
159+ }
160+ eventPath = inputDevice->devicePath();
152161
162+ fd = open(eventPath.toLatin1(), O_RDONLY|O_NONBLOCK);
153163 if (fd == -1) {
154164 return inputDevice;
155165 }
156166 rc = libevdev_new_from_fd(fd, &dev);
157167 if (rc < 0) {
158168 qWarning() << "Failed to init libevdev ("<< strerror(-rc) << ")";
159− return inputDevice;
169+ return Q_NULLPTR;
160170 }
161171
162− inputDevice->setName(QString::fromLatin1(libevdev_get_name(dev)));
163172 for (int i = 0; i < EV_MAX; i++) {
164173 if (i == EV_KEY || i == EV_SW || i == EV_REL
165174 || i == EV_REL || i == EV_ABS) {
@@ -183,54 +192,93 @@ QInputDevice *QInputDeviceInfoPrivate::addDevice(const QString &path)
183192 }
184193 }
185194 }
195+
186196 return inputDevice;
187197}
188198
189−void QInputDeviceInfoPrivate::removeDevice(const QString &path)
199+void QInputDeviceManagerPrivate::addDetails(struct udev_device *)
200+{
201+}
202+
203+void QInputDeviceManagerPrivate::removeDevice(const QString &path)
190204{
191− for (int i = 0; i < deviceList.size(); ++i) {
192− if (deviceList.at(i)->devicePath() == path) {
193− delete deviceList.takeAt(i);
194− deviceMap.remove(path);
195− Q_EMIT deviceRemoved(path);
205+ // this path is not a full evdev path
206+ Q_FOREACH (const QString devicePath, deviceMap.keys()) {
207+ if (devicePath.contains(path)) {
208+ deviceMap.remove(devicePath);
209+ Q_EMIT deviceRemoved(devicePath);
196210 }
197211 }
198212}
199213
200−void QInputDeviceInfoPrivate::onUDevChanges()
214+QInputDevice *QInputDeviceManagerPrivate::addUdevDevice(struct udev_device *udev)
201215{
202− struct udev_device *dev = udev_monitor_receive_device(udevMonitor);
216+ QInputDevice *iDevice;
217+
218+ struct udev_list_entry *list;
219+ struct udev_list_entry *node;
220+
221+ list = udev_device_get_properties_list_entry (udev);
222+ QString syspath = QString::fromLatin1(udev_device_get_syspath(udev));
223+ QDir sysdir(syspath);
224+
225+ QStringList infoList = sysdir.entryList(QStringList() << QStringLiteral("event*"),QDir::Dirs);
226+
227+ if (infoList.count() > 0) {
228+ QString token = infoList.at(0);
229+
230+ token.prepend(QStringLiteral("/dev/input/"));
231+ iDevice = new QInputDevice(this);
232+ iDevice->setDevicePath(token);
233+ } else {
234+ return Q_NULLPTR;
235+ }
236+ udev_list_entry_foreach (node, list) {
237+
238+ QString key = QString::fromLatin1(udev_list_entry_get_name(node));
239+ QString value = QString::fromLatin1(udev_list_entry_get_value(node));
240+
241+ if (key == QStringLiteral("NAME")) {
242+ iDevice->setName(value.remove(QStringLiteral("\"")));
243+ }
244+ }
245+ iDevice->setType(getInputTypeFlags(udev));
246+ return iDevice;
247+}
248+
249+void QInputDeviceManagerPrivate::onUDevChanges()
250+{
251+ if (!udevMonitor)
252+ return;
253+
254+ udev_device *dev = udev_monitor_receive_device(udevMonitor);
255+
203256 if (dev) {
204257 if (qstrcmp(udev_device_get_subsystem(dev), "input") == 0 ) {
205258 QString eventPath = QString::fromLatin1(udev_device_get_sysname(dev));
206259
207− if (eventPath.contains(QStringLiteral("input")))
208− return;
209−
210260 QString action = QString::fromStdString(udev_device_get_action(dev));
211261
212262 if (!eventPath.contains(QStringLiteral("/dev/input/")))
213263 eventPath.prepend(QStringLiteral("/dev/input/"));
214264
215265 if (action == QStringLiteral("add")) {
216−
217− QInputDevice *iDevice = addDevice(eventPath);
218− if (!iDevice)
219− return;
220−
221− iDevice->setTypes(getInputTypes(dev));
266+ if (deviceMap.contains(eventPath)){
222267 udev_device_unref(dev);
268+ return;
269+ }
223270
224− if (iDevice->switches().count() > 0 && iDevice->buttons().count() == 0)
225− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Switch);
226−
227− if (iDevice->buttons().count() > 0 && iDevice->types() == QInputDeviceInfo::Unknown)
228− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Button);
271+ QInputDevice *iDevice = addDevice(dev);
272+ if (!iDevice) {
273+ delete iDevice;
274+ return;
275+ }
276+ iDevice->setType(getInputTypeFlags(dev));
277+ udev_device_unref(dev);
229278
230− deviceList.append(iDevice);
231279 deviceMap.insert(eventPath,iDevice);
232280
233− Q_EMIT newDevice(eventPath);
281+ Q_EMIT deviceAdded(eventPath);
234282
235283 } else if (action == QStringLiteral("remove")) {
236284 removeDevice(eventPath);
plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux_p.h+13−6
@@ -58,30 +58,37 @@ public:
5858 QList <int> switches;
5959 QList <int> relativeAxis;
6060 QList <int> absoluteAxis;
61− QInputDeviceInfo::InputTypes types;
61+ QInputDevice::InputTypeFlags type;
6262};
6363
64−class QInputDeviceInfoPrivate : public QObject
64+class QInputDeviceManagerPrivate : public QObject
6565{
6666 Q_OBJECT
6767public:
68− explicit QInputDeviceInfoPrivate(QObject *parent = 0);
68+ explicit QInputDeviceManagerPrivate(QObject *parent = 0);
69+ ~QInputDeviceManagerPrivate();
6970 QVector <QInputDevice *> deviceList;
7071 QMap <QString, QInputDevice *> deviceMap;
72+ static QInputDeviceManagerPrivate * instance();
73+ QInputDevice::InputType currentFilter;
7174
7275Q_SIGNALS:
73− void newDevice(const QString &);
76+ void deviceAdded(const QString &);
7477 void deviceRemoved(const QString &);
7578 void ready();
7679
7780private:
78− struct udev *udev;
81+ QInputDevice *addDevice(struct udev_device *udev);
82+ QInputDevice *addUdevDevice(struct udev_device *);
83+
7984 QInputDevice *addDevice(const QString &path);
8085 void removeDevice(const QString &path);
8186 QSocketNotifier *notifier;
8287 int notifierFd;
8388 struct udev_monitor *udevMonitor;
84− QInputDeviceInfo::InputTypes getInputTypes( struct udev_device *);
89+ QInputDevice::InputTypeFlags getInputTypeFlags(struct udev_device *);
90+ struct udev *udevice;
91+ void addDetails(struct udev_device *);
8592
8693private Q_SLOTS:
8794 void onUDevChanges();
plugins/Unity/InputInfo/plugin.cpp+2−2
@@ -21,12 +21,12 @@
2121#include "plugin.h"
2222
2323// local
24−#include "qdeclarativeinputdeviceinfo_p.h"
24+#include "qdeclarativeinputdevicemodel_p.h"
2525
2626void InputInfoPlugin::registerTypes(const char *uri)
2727{
2828 int major = 0;
2929 int minor = 1;
30− qmlRegisterType<QDeclarativeInputDeviceInfo>(uri, major, minor, "InputDeviceInfo");
30+ qmlRegisterType<QDeclarativeInputDeviceModel>(uri, major, minor, "InputDeviceModel");
3131 qmlRegisterType<QInputDevice>(uri, major, minor, "InputInfo");
3232}
plugins/Unity/InputInfo/qdeclarativeinputdeviceinfo.cppdeleted−143
@@ -1,143 +0,0 @@
1−/****************************************************************************
2−**
3−** Copyright (C) 2015 Jolla.
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−#include "qdeclarativeinputdeviceinfo_p.h"
42−
43−QDeclarativeInputDeviceInfo::QDeclarativeInputDeviceInfo(QObject *parent) :
44− QAbstractListModel(parent),
45− deviceInfo(new QInputDeviceInfo)
46−{
47− connect(deviceInfo, &QInputDeviceInfo::ready, this, &QDeclarativeInputDeviceInfo::updateDeviceList);
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::updateDeviceList()
93−{
94− QVector <QInputDevice *> newDevices = deviceInfo->deviceList();
95−
96− int numNew = newDevices.count();
97−
98− for (int i = 0; i < numNew; i++) {
99− int j = inputDevices.indexOf(newDevices.value(i));
100− if (j == -1) {
101− // not found -> remove from list
102− beginInsertRows(QModelIndex(), i, i);
103− inputDevices.insert(i, newDevices.value(i));
104− endInsertRows();
105− } else if (i != j) {
106− // changed its position -> move it
107− QInputDevice* device = inputDevices.value(j);
108− beginMoveRows(QModelIndex(), j, j, QModelIndex(), i);
109− inputDevices.remove(j);
110− inputDevices.insert(i, device);
111− endMoveRows();
112− } else {
113− QModelIndex changedIndex(this->index(j, 0, QModelIndex()));
114− Q_EMIT dataChanged(changedIndex, changedIndex);
115− }
116− }
117−
118− int numOld = inputDevices.count();
119− if (numOld > numNew) {
120− beginRemoveRows(QModelIndex(), numNew, numOld - 1);
121− inputDevices.remove(numNew, numOld - numNew);
122− endRemoveRows();
123− }
124−}
125−
126−void QDeclarativeInputDeviceInfo::addedDevice(const QString &devicePath)
127−{
128− updateDeviceList();
129− Q_EMIT newDevice(devicePath);
130−}
131−
132−void QDeclarativeInputDeviceInfo::removedDevice(const QString &devicePath)
133−{
134− updateDeviceList();
135− Q_EMIT deviceRemoved(devicePath);
136−}
137−
138−QHash<int, QByteArray> QDeclarativeInputDeviceInfo::roleNames() const
139−{
140− QHash<int, QByteArray> roles;
141− roles.insert(ServiceRole, "service");
142− return roles;
143−}
tests/mocks/Unity/InputInfo/mockqdeclarativeinputdeviceinfo.cpp → plugins/Unity/InputInfo/qdeclarativeinputdevicemodel.cpprenamed+77−54
@@ -1,7 +1,6 @@
11/****************************************************************************
22**
33** Copyright (C) 2015 Jolla.
4−** Copyright (C) 2015 Canonical Ltd.
54** Contact: http://www.qt-project.org/legal
65**
76** This file is part of the QtSystems module of the Qt Toolkit.
@@ -39,39 +38,64 @@
3938** $QT_END_LICENSE$
4039**
4140****************************************************************************/
42−#include "mockqdeclarativeinputdeviceinfo_p.h"
41+#include "qdeclarativeinputdevicemodel_p.h"
42+#include "qinputinfo.h"
4343
44−QDeclarativeInputDeviceInfo::QDeclarativeInputDeviceInfo(QObject *parent) :
44+QDeclarativeInputDeviceModel::QDeclarativeInputDeviceModel(QObject *parent) :
4545 QAbstractListModel(parent),
46− deviceInfo(new QInputDeviceInfo)
46+ deviceInfo(new QInputDeviceManager),
47+ currentFilter(QInputDevice::Unknown)
4748{
48− connect(deviceInfo, &QInputDeviceInfo::deviceAdded,this,&QDeclarativeInputDeviceInfo::addedDevice);
49− connect(deviceInfo, &QInputDeviceInfo::deviceRemoved,this,&QDeclarativeInputDeviceInfo::removedDevice);
49+ connect(deviceInfo,SIGNAL(ready()),this,SLOT(updateDeviceList()));
50+ connect(deviceInfo, &QInputDeviceManager::deviceAdded,this,&QDeclarativeInputDeviceModel::addedDevice);
51+ connect(deviceInfo, &QInputDeviceManager::deviceRemoved,this,&QDeclarativeInputDeviceModel::removedDevice);
5052}
5153
52−QDeclarativeInputDeviceInfo::~QDeclarativeInputDeviceInfo()
54+QDeclarativeInputDeviceModel::~QDeclarativeInputDeviceModel()
5355{
5456 delete deviceInfo;
5557}
5658
57−QVariant QDeclarativeInputDeviceInfo::data(const QModelIndex &index, int role) const
59+QVariant QDeclarativeInputDeviceModel::data(const QModelIndex &index, int role) const
5860{
5961 switch (role) {
6062 case ServiceRole:
6163 return QVariant::fromValue(static_cast<QObject *>(inputDevices.value(index.row())));
62− }
64+ break;
65+ case NameRole:
66+ return QVariant::fromValue(static_cast<QString>(inputDevices.value(index.row())->name()));
67+ break;
68+ case DevicePathRole:
69+ return QVariant::fromValue(static_cast<QString>(inputDevices.value(index.row())->devicePath()));
70+ break;
71+ case ButtonsRole:
72+ return QVariant::fromValue(static_cast<QList <int> >(inputDevices.value(index.row())->buttons()));
73+ break;
74+ case SwitchesRole:
75+ return QVariant::fromValue(static_cast<QList <int> >(inputDevices.value(index.row())->switches()));
76+ break;
77+ case RelativeAxisRole:
78+ return QVariant::fromValue(static_cast<QList <int> >(inputDevices.value(index.row())->relativeAxis()));
79+ break;
80+ case AbsoluteAxisRole:
81+ return QVariant::fromValue(static_cast<QList <int> >(inputDevices.value(index.row())->absoluteAxis()));
82+ break;
83+ case TypesRole:
84+ return QVariant::fromValue(static_cast<int>(inputDevices.value(index.row())->type()));
85+ break;
86+ };
6387
6488 return QVariant();
6589}
6690
67−int QDeclarativeInputDeviceInfo::rowCount(const QModelIndex &parent) const
91+int QDeclarativeInputDeviceModel::rowCount(const QModelIndex &parent) const
6892{
6993 Q_UNUSED(parent);
7094
7195 return inputDevices.count();
7296}
7397
74−int QDeclarativeInputDeviceInfo::indexOf(const QString &devicePath) const
98+int QDeclarativeInputDeviceModel::indexOf(const QString &devicePath) const
7599{
76100 int idx(-1);
77101 Q_FOREACH (QInputDevice *device, inputDevices) {
@@ -82,56 +106,27 @@ int QDeclarativeInputDeviceInfo::indexOf(const QString &devicePath) const
82106 return -1;
83107}
84108
85−QInputDevice *QDeclarativeInputDeviceInfo::get(int index) const
109+QInputDevice *QDeclarativeInputDeviceModel::get(int index) const
86110{
87111 if (index < 0 || index > inputDevices.count())
88112 return 0;
89113 return inputDevices.value(index);
90114}
91115
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()
116+void QDeclarativeInputDeviceModel::updateDeviceList()
103117{
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();
118+ QVector <QInputDevice *> newDevices = deviceInfo->deviceListOfType(currentFilter);
125119
126120 int numNew = newDevices.count();
127121
128122 for (int i = 0; i < numNew; i++) {
129123 int j = inputDevices.indexOf(newDevices.value(i));
124+
130125 if (j == -1) {
131− // not found -> remove from list
132126 beginInsertRows(QModelIndex(), i, i);
133127 inputDevices.insert(i, newDevices.value(i));
134128 endInsertRows();
129+ Q_EMIT countChanged();
135130 } else if (i != j) {
136131 // changed its position -> move it
137132 QInputDevice* device = inputDevices.value(j);
@@ -139,10 +134,10 @@ void QDeclarativeInputDeviceInfo::updateDeviceList()
139134 inputDevices.remove(j);
140135 inputDevices.insert(i, device);
141136 endMoveRows();
142− } else {
143− QModelIndex changedIndex(this->index(j, 0, QModelIndex()));
144− Q_EMIT dataChanged(changedIndex, changedIndex);
145− }
137+ Q_EMIT countChanged();
138+ } //else {
139+ QModelIndex changedIndex(this->index(j, 0, QModelIndex()));
140+ Q_EMIT dataChanged(changedIndex, changedIndex);
146141 }
147142
148143 int numOld = inputDevices.count();
@@ -150,24 +145,52 @@ void QDeclarativeInputDeviceInfo::updateDeviceList()
150145 beginRemoveRows(QModelIndex(), numNew, numOld - 1);
151146 inputDevices.remove(numNew, numOld - numNew);
152147 endRemoveRows();
148+ Q_EMIT countChanged();
153149 }
154150}
155151
156−void QDeclarativeInputDeviceInfo::addedDevice(const QString &devicePath)
152+void QDeclarativeInputDeviceModel::addedDevice(const QString &devicePath)
157153{
158154 updateDeviceList();
159− Q_EMIT newDevice(devicePath);
155+ Q_EMIT deviceAdded(devicePath);
160156}
161157
162−void QDeclarativeInputDeviceInfo::removedDevice(const QString &devicePath)
158+void QDeclarativeInputDeviceModel::removedDevice(const QString &devicePath)
163159{
164160 updateDeviceList();
165161 Q_EMIT deviceRemoved(devicePath);
166162}
167163
168−QHash<int, QByteArray> QDeclarativeInputDeviceInfo::roleNames() const
164+QHash<int,QByteArray> QDeclarativeInputDeviceModel::roleNames() const
169165{
170166 QHash<int, QByteArray> roles;
171− roles.insert(ServiceRole, "service");
167+ roles[NameRole] = "name";
168+ roles[DevicePathRole] = "devicePath";
169+ roles[ButtonsRole] = "buttons";
170+ roles[SwitchesRole] = "switches";
171+ roles[RelativeAxisRole] = "rAxis";
172+ roles[AbsoluteAxisRole] = "aAxis";
173+ roles[TypesRole] = "types";
172174 return roles;
173175}
176+
177+/*
178+ * Returns the currently set device filter.
179+ * */
180+QInputDevice::InputType QDeclarativeInputDeviceModel::deviceFilter()
181+{
182+ return currentFilter;
183+}
184+
185+/*
186+ * Sets the current input device filter to filter.
187+ * */
188+void QDeclarativeInputDeviceModel::setDeviceFilter(QInputDevice::InputType filter)
189+{
190+ if (filter != currentFilter) {
191+ deviceInfo->setDeviceFilter(filter);
192+ currentFilter = filter;
193+ updateDeviceList();
194+ Q_EMIT deviceFilterChanged(filter);
195+ }
196+}
plugins/Unity/InputInfo/qdeclarativeinputdeviceinfo_p.h → plugins/Unity/InputInfo/qdeclarativeinputdevicemodel_p.hrenamed+27−11
@@ -39,48 +39,64 @@
3939**
4040****************************************************************************/
4141
42−#ifndef QDECLARATIVEINPUTDEVICEINFO_H
43−#define QDECLARATIVEINPUTDEVICEINFO_H
42+#ifndef QDECLARATIVEINPUTDEVICEMODEL_H
43+#define QDECLARATIVEINPUTDEVICEMODEL_H
4444
4545#include <QObject>
4646#include <QAbstractListModel>
4747#include "qinputinfo.h"
4848
49−class QDeclarativeInputDeviceInfo : public QAbstractListModel
49+class QDeclarativeInputDeviceModel : public QAbstractListModel
5050{
5151 Q_OBJECT
52− Q_DISABLE_COPY(QDeclarativeInputDeviceInfo)
52+ Q_DISABLE_COPY(QDeclarativeInputDeviceModel)
53+ Q_PROPERTY(QInputDevice::InputType deviceFilter READ deviceFilter WRITE setDeviceFilter NOTIFY deviceFilterChanged)
54+
55+ Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
5356
5457public:
5558 enum ItemRoles {
56− ServiceRole = Qt::UserRole + 1
59+ ServiceRole = Qt::UserRole + 1,
60+ NameRole,
61+ DevicePathRole,
62+ ButtonsRole,
63+ SwitchesRole,
64+ RelativeAxisRole,
65+ AbsoluteAxisRole,
66+ TypesRole
5767 };
5868
59− explicit QDeclarativeInputDeviceInfo(QObject *parent = 0);
60− virtual ~QDeclarativeInputDeviceInfo();
69+ explicit QDeclarativeInputDeviceModel(QObject *parent = 0);
70+ virtual ~QDeclarativeInputDeviceModel();
6171
6272 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
6373 int rowCount(const QModelIndex &parent = QModelIndex()) const;
6474
65− QHash<int, QByteArray> roleNames() const;
75+ void setDeviceFilter(QInputDevice::InputType filter);
76+ QInputDevice::InputType deviceFilter();
6677
6778 Q_INVOKABLE int indexOf(const QString &devicePath) const;
6879
6980 Q_INVOKABLE QInputDevice *get(int index) const;
81+ QHash<int, QByteArray> roleNames() const;
7082
7183Q_SIGNALS:
72− void newDevice(const QString &devicePath);
84+ void deviceAdded(const QString &devicePath);
7385 void deviceRemoved(const QString &devicePath);
86+ void deviceFilterChanged(const QInputDevice::InputType filter);
87+ void countChanged();
7488
7589public Q_SLOTS:
7690 void updateDeviceList();
7791private:
78− QInputDeviceInfo *deviceInfo;
92+ QInputDeviceManager *deviceInfo;
7993 QVector<QInputDevice *> inputDevices;
94+ QInputDevice::InputType currentFilter;
95+
8096private Q_SLOTS:
8197 void addedDevice(const QString &);
8298 void removedDevice(const QString &path);
8399
84100};
85101
86−#endif // QDECLARATIVEINPUTDEVICEINFO_H
102+#endif // QDECLARATIVEINPUTDEVICEMODEL_H
plugins/Unity/InputInfo/qinputinfo.cpp+129−18
@@ -41,16 +41,25 @@
4141
4242#include "qinputinfo.h"
4343
44−#if defined(Q_OS_LINUX)
44+#if defined(UNITY_MOCKS)
45+#include "qinputdeviceinfo_mock_p.h"
46+#elif defined(Q_OS_LINUX)
4547#include "linux/qinputdeviceinfo_linux_p.h"
4648#endif
4749
50+Q_GLOBAL_STATIC(QInputDeviceManagerPrivate, inputDeviceManagerPrivate)
51+
4852QT_BEGIN_NAMESPACE
4953
54+QInputDeviceManagerPrivate * QInputDeviceManagerPrivate::instance()
55+{
56+ QInputDeviceManagerPrivate *priv = inputDeviceManagerPrivate();
57+ return priv;
58+}
5059
5160QInputDevicePrivate::QInputDevicePrivate(QObject *parent) :
5261 QObject(parent),
53− types(QInputDeviceInfo::Unknown)
62+ type(QInputDevice::Unknown)
5463{
5564}
5665
@@ -60,100 +69,202 @@ QInputDevice::QInputDevice(QObject *parent) :
6069{
6170}
6271
72+/*
73+ * Returns the name of this input device.
74+ */
6375QString QInputDevice::name() const
6476{
6577 return d_ptr->name;
6678}
6779
80+/*
81+ * Sets the name of this input device to \b name.
82+ */
6883void QInputDevice::setName(const QString &name)
6984{
7085 d_ptr->name = name;
7186}
7287
88+/*
89+ * Returns the device path of this device.
90+ */
7391QString QInputDevice::devicePath() const
7492{
7593 return d_ptr->devicePath;
7694}
7795
96+/*
97+ * Sets the device ppath of this device to /b path.
98+ */
7899void QInputDevice::setDevicePath(const QString &path)
79100{
80101 d_ptr->devicePath = path;
81102}
82103
104+/*
105+ * Returns the number of buttons this device has.
106+ */
83107QList <int> QInputDevice::buttons() const
84108{
85109 return d_ptr->buttons;
86110}
87111
112+/*
113+ * Adds a button
114+ */
88115void QInputDevice::addButton(int buttonCode)
89116{
90117 d_ptr->buttons.append(buttonCode);
91118}
92119
120+/*
121+ * Returns the number of switch of this device.
122+ */
93123QList <int> QInputDevice::switches() const
94124{
95125 return d_ptr->switches;
96126}
97127
128+/*
129+ * Adds a switch
130+ */
98131void QInputDevice::addSwitch(int switchCode)
99132{
100133 d_ptr->switches.append(switchCode);
101134}
102135
136+/*
137+ * Returns a list of the relative axis of this device
138+ */
103139QList <int> QInputDevice::relativeAxis() const
104140{
105141 return d_ptr->relativeAxis;
106142}
107143
144+/*
145+ */
108146void QInputDevice::addRelativeAxis(int axisCode)
109147{
110148 d_ptr->relativeAxis.append(axisCode);
111149}
112150
151+/*
152+ * Returns a list of the absolute axis of this device
153+ */
113154QList <int> QInputDevice::absoluteAxis() const
114155{
115156 return d_ptr->absoluteAxis;
116157}
117158
159+/*
160+ */
118161void QInputDevice::addAbsoluteAxis(int axisCode)
119162{
120163 d_ptr->absoluteAxis.append(axisCode);
121164}
122165
123−QInputDeviceInfo::InputTypes QInputDevice::types()
166+/*
167+ * Returns a QInputDevice::InputTypeFlags of all the types of types.
168+ */
169+QInputDevice::InputTypeFlags QInputDevice::type() const
124170{
125− return d_ptr->types;
171+ return d_ptr->type;
126172}
127173
128−void QInputDevice::setTypes(QInputDeviceInfo::InputTypes types)
174+/*
175+ */
176+void QInputDevice::setType(QInputDevice::InputTypeFlags type) //? setTypes?
129177{
130− d_ptr->types = types;
178+ d_ptr->type = type;
131179}
132180
133−
134−QInputDeviceInfo::QInputDeviceInfo(QObject *parent) :
181+QInputDeviceManager::QInputDeviceManager(QObject *parent) :
135182 QObject(parent),
136− d_ptr(new QInputDeviceInfoPrivate(this))
183+ d_ptr(inputDeviceManagerPrivate)
137184{
138− connect(d_ptr, &QInputDeviceInfoPrivate::newDevice,this,&QInputDeviceInfo::addedDevice);
139− connect(d_ptr, &QInputDeviceInfoPrivate::deviceRemoved,this,&QInputDeviceInfo::deviceRemoved);
185+ connect(d_ptr, &QInputDeviceManagerPrivate::deviceAdded,this,&QInputDeviceManager::addedDevice);
186+ connect(d_ptr, &QInputDeviceManagerPrivate::deviceRemoved,this,&QInputDeviceManager::deviceRemoved);
140187
141− connect(d_ptr, &QInputDeviceInfoPrivate::ready, this, &QInputDeviceInfo::ready);
188+ connect(d_ptr,SIGNAL(ready()),this,SIGNAL(ready()));
142189}
143190
144−QVector <QInputDevice *> QInputDeviceInfo::deviceList()
191+/*
192+ * Returns a QMap of known input devices.
193+ */
194+QMap <QString, QInputDevice *> QInputDeviceManager::deviceMap()
145195{
146− return d_ptr->deviceList;
196+ return d_ptr->deviceMap;
147197}
148198
149−QMap <QString, QInputDevice *> QInputDeviceInfo::deviceMap()
199+/*
200+ */
201+void QInputDeviceManager::addedDevice(const QString & devicePath)
150202{
151− return d_ptr->deviceMap;
203+ Q_EMIT deviceAdded(devicePath);
152204}
153205
154−void QInputDeviceInfo::addedDevice(const QString & devicePath)
206+/*
207+ * Returns a QVector of InputDevices of type filter
208+ * */
209+QVector <QInputDevice *> QInputDeviceManager::deviceListOfType(QInputDevice::InputType filter)
155210{
156− Q_EMIT deviceAdded(devicePath);
211+ QVector <QInputDevice *> dList;
212+ QMapIterator<QString, QInputDevice *> i(d_ptr->deviceMap);
213+ while (i.hasNext()) {
214+ i.next();
215+ if (i.value()->type().testFlag(filter) || filter == QInputDevice::Unknown) {
216+ dList.append(i.value());
217+ }
218+ }
219+ return dList;
220+}
221+
222+/*
223+ * Returns the number of input devices with the currently set QInputDevice::InputType filter.
224+ * If no device filter has been set, returns number of all available input devices.
225+ * If filter has not been set, returns all available input devices
226+ */
227+int QInputDeviceManager::deviceCount() const
228+{
229+ return deviceCount(static_cast< QInputDevice::InputType >(d_ptr->currentFilter));
230+}
231+
232+/*
233+ * Returns the number of input devices of the type filter.
234+ */
235+int QInputDeviceManager::deviceCount(const QInputDevice::InputType filter) const
236+{
237+ int dList = 0;
238+ QMapIterator<QString, QInputDevice *> i(d_ptr->deviceMap);
239+ while (i.hasNext()) {
240+ i.next();
241+// qDebug() << i.value()->name() << i.value()->devicePath();
242+// qDebug() << i.value()->type() << i.value()->type().testFlag(filter);
243+
244+ if (i.value()->type().testFlag(filter)) {
245+ dList++;
246+ }
247+ }
248+ return dList;
249+}
250+
251+/*
252+ * Returns the currently set device filter.
253+ * */
254+QInputDevice::InputType QInputDeviceManager::deviceFilter()
255+{
256+ return d_ptr->currentFilter;
257+}
258+
259+/*
260+ * Sets the current input device filter to filter.
261+ * */
262+void QInputDeviceManager::setDeviceFilter(QInputDevice::InputType filter)
263+{
264+ if (filter != d_ptr->currentFilter) {
265+ d_ptr->currentFilter = filter;
266+ Q_EMIT deviceFilterChanged(filter);
267+ }
157268}
158269
159270QT_END_NAMESPACE
plugins/Unity/InputInfo/qinputinfo.h+56−56
@@ -48,15 +48,19 @@
4848#include <QSocketNotifier>
4949#include <QDebug>
5050
51−class QInputDeviceInfoPrivate;
51+class QInputDeviceManagerPrivate;
5252class QInputDevicePrivate;
5353class QInputDevice;
5454
55−class QInputDeviceInfoPrivate;
56−class QInputDeviceInfo : public QObject
55+class QInputDeviceManager;
56+
57+class QInputDevice : public QObject
5758{
5859 Q_OBJECT
59− Q_PROPERTY(int deviceCount READ deviceCount)
60+ Q_ENUMS(InputType)
61+ Q_FLAGS(InputType InputTypeFlags)
62+ friend class QInputDeviceManagerPrivate;
63+
6064public:
6165
6266 enum InputType {
@@ -69,67 +73,19 @@ public:
6973 Switch = 32
7074 };
7175 Q_ENUMS(InputType)
72− Q_FLAGS(InputTypes)
73− Q_DECLARE_FLAGS(InputTypes, InputType)
74−
75− explicit QInputDeviceInfo(QObject *parent = 0);
76−
77− Q_INVOKABLE QVector <QInputDevice *> deviceList();
78−
79− Q_INVOKABLE QMap <QString, QInputDevice *> deviceMap();
80− int deviceCount() { return deviceList().count(); }
81−Q_SIGNALS:
82−
83− void deviceAdded(const QString & devicePath);
84− void deviceRemoved(const QString & devicePath);
85−
86− void ready();
87−
88−public Q_SLOTS:
89− void addedDevice(const QString & devicePath);
90−
91−private:
92− Q_DISABLE_COPY(QInputDeviceInfo)
93−#if !defined(QT_SIMULATOR)
94− QInputDeviceInfoPrivate *const d_ptr;
95− Q_DECLARE_PRIVATE(QInputDeviceInfo)
96−#endif
97−};
98−
99−class QInputDevice : public QObject
100−{
101− friend class QInputDeviceInfoPrivate;
102− Q_OBJECT
103− Q_ENUMS(InputType)
104− Q_FLAGS(InputTypes)
105− Q_PROPERTY(QString name READ name NOTIFY nameChanged)
106− Q_PROPERTY(QString devicePath READ devicePath NOTIFY devicePathChanged)
107− Q_PROPERTY(QList <int> buttons READ buttons NOTIFY buttonsChanged)
108− Q_PROPERTY(QList <int> switches READ switches NOTIFY switchesChanged)
109− Q_PROPERTY(QList <int> relativeAxis READ relativeAxis NOTIFY relativeAxisChanged)
110− Q_PROPERTY(QList <int> absoluteAxis READ absoluteAxis NOTIFY absoluteAxisChanged)
111− Q_PROPERTY(QInputDeviceInfo::InputTypes types READ types NOTIFY typesChanged)
76+ Q_DECLARE_FLAGS(InputTypeFlags, InputType)
11277
113−public:
11478 explicit QInputDevice(QObject *parent = 0);
115−
11679 QString name() const;
11780 QString devicePath() const;
11881 QList <int> buttons() const; //keys event code
11982 QList <int> switches() const;
12083 QList <int> relativeAxis() const;
12184 QList <int> absoluteAxis() const;
85+ QInputDevice::InputTypeFlags type() const;
12286
123− QInputDeviceInfo::InputTypes types();
124−Q_SIGNALS:
125− void nameChanged();
126− void devicePathChanged();
127− void buttonsChanged();
128− void switchesChanged();
129− void relativeAxisChanged();
130− void absoluteAxisChanged();
131− void typesChanged();
13287private:
88+
13389 QInputDevicePrivate *d_ptr;
13490 void setName(const QString &);
13591 void setDevicePath(const QString &);
@@ -137,7 +93,51 @@ private:
13793 void addSwitch(int);
13894 void addRelativeAxis(int);
13995 void addAbsoluteAxis(int);
140− void setTypes(QInputDeviceInfo::InputTypes);
96+ void setType(QInputDevice::InputTypeFlags flags);
97+
98+};
99+
100+Q_DECLARE_METATYPE(QInputDevice::InputType)
101+Q_DECLARE_METATYPE(QInputDevice::InputTypeFlags)
102+
103+class QInputDeviceManagerPrivate;
104+
105+class QInputDeviceManager : public QObject
106+{
107+ Q_OBJECT
108+ Q_PROPERTY(int deviceCount READ deviceCount NOTIFY deviceCountChanged)
109+ Q_PROPERTY(QInputDevice::InputType deviceFilter READ deviceFilter WRITE setDeviceFilter NOTIFY deviceFilterChanged)
110+public:
111+
112+ explicit QInputDeviceManager(QObject *parent = 0);
113+
114+ int deviceCount() const;
115+ int deviceCount(const QInputDevice::InputType filter) const;
116+
117+ void setDeviceFilter(QInputDevice::InputType filter);
118+ QInputDevice::InputType deviceFilter();
119+
120+ QMap <QString, QInputDevice *> deviceMap();
121+ Q_INVOKABLE QVector <QInputDevice *> deviceListOfType(QInputDevice::InputType filter);
122+
123+Q_SIGNALS:
124+
125+ void deviceAdded(const QString & devicePath);
126+ void deviceRemoved(const QString & devicePath);
127+
128+ void ready();
129+ void deviceCountChanged(int count);
130+ void deviceFilterChanged(const QInputDevice::InputType filter);
131+
132+public Q_SLOTS:
133+ void addedDevice(const QString & devicePath);
134+
135+private:
136+ Q_DISABLE_COPY(QInputDeviceManager)
137+#if !defined(QT_SIMULATOR)
138+ QInputDeviceManagerPrivate *const d_ptr;
139+ Q_DECLARE_PRIVATE(QInputDeviceManager)
140+#endif
141141};
142142
143143#endif // QINPUTINFO_H
qml/Components/UnityInputInfo/UnityInputInfo.qmldeleted−93
@@ -1,93 +0,0 @@
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.4
20−import Unity.InputInfo 0.1
21−// Workaround https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1473471
22−import Ubuntu.Components 1.3
23−
24−Item {
25− id: root
26− readonly property alias mice: priv.miceCount
27− readonly property alias keyboards: priv.keyboardCount
28−
29− property alias inputInfo: inputInfo
30−
31− QtObject {
32− id: priv
33−
34− property var mice: []
35− property var keyboards: []
36−
37− property int miceCount: 0
38− property int keyboardCount: 0
39−
40− function addMouse(devicePath) {
41− mice.push(devicePath);
42− miceCount++;
43− }
44−
45− function addKeyboard(devicePath) {
46− keyboards.push(devicePath);
47− keyboardCount++;
48− }
49−
50− function removeDevice(devicePath) {
51− for (var i = 0; i < priv.mice.length; i++) {
52− if (priv.mice[i] == devicePath) {
53− priv.mice.splice(i, 1);
54− priv.miceCount--;
55− }
56− }
57− for (var i = 0; i < priv.keyboards.length; i++) {
58− if (priv.keyboards[i] == devicePath) {
59− priv.keyboards.splice(i, 1);
60− priv.keyboardCount--;
61− }
62− }
63− }
64− }
65−
66− InputDeviceInfo {
67− id: inputInfo
68− objectName: "inputDeviceInfo"
69−
70− onNewDevice: {
71− var device = inputInfo.get(inputInfo.indexOf(devicePath));
72− if (device === null) {
73− return;
74− }
75−
76− var hasMouse = (device.types & InputInfo.Mouse) == InputInfo.Mouse
77− var hasTouchpad = (device.types & InputInfo.TouchPad) == InputInfo.TouchPad
78− var hasKeyboard = (device.types & InputInfo.Keyboard) == InputInfo.Keyboard
79−
80− if (hasMouse || hasTouchpad) {
81− priv.addMouse(devicePath);
82− } else if (hasKeyboard) {
83− // Only accepting keyboards that do not claim to be a mouse too
84− // This will be a bit buggy for real hybrid devices, but doesn't
85− // fall for Microsoft mice that claim to be Keyboards too.
86− priv.addKeyboard(devicePath)
87− }
88− }
89− onDeviceRemoved: {
90− priv.removeDevice(devicePath)
91− }
92− }
93−}
qml/Components/UnityInputInfo/qmldirdeleted−1
@@ -1 +0,0 @@
1−singleton UnityInputInfo 1.0 UnityInputInfo.qml
qml/OrientedShell.qml+16−7
@@ -16,13 +16,12 @@
1616
1717import QtQuick 2.4
1818import QtQuick.Window 2.2
19+import Unity.InputInfo 0.1
1920import Unity.Session 0.1
2021import GSettings 1.0
2122import "Components"
22−import "Components/UnityInputInfo"
2323import "Rotation"
24−// Backup Workaround https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1473471
25−// in case we remove the UnityInputInfo import
24+// Workaround https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1473471
2625import Ubuntu.Components 1.3
2726
2827Rectangle {
@@ -64,6 +63,16 @@ Rectangle {
6463 property bool orientationLocked: OrientationLock.enabled
6564 property var orientationLock: OrientationLock
6665
66+ InputDeviceModel {
67+ id: miceModel
68+ deviceFilter: InputInfo.Mouse
69+ }
70+
71+ InputDeviceModel {
72+ id: keyboardsModel
73+ deviceFilter: InputInfo.Keyboard
74+ }
75+
6776 property int orientation
6877 onPhysicalOrientationChanged: {
6978 if (!orientationLocked) {
@@ -83,7 +92,7 @@ Rectangle {
8392 }
8493 // We need to manually update this on startup as the binding
8594 // below doesn't seem to have any effect at that stage
86− oskSettings.stayHidden = UnityInputInfo.keyboards > 0
95+ oskSettings.stayHidden = keyboardsModel.count > 0
8796 oskSettings.disableHeight = shell.usageScenario == "desktop"
8897 }
8998
@@ -96,7 +105,7 @@ Rectangle {
96105 Binding {
97106 target: oskSettings
98107 property: "stayHidden"
99− value: UnityInputInfo.keyboards > 0
108+ value: keyboardsModel.count > 0
100109 }
101110
102111 Binding {
@@ -174,7 +183,7 @@ Rectangle {
174183 nativeWidth: root.width
175184 nativeHeight: root.height
176185 mode: applicationArguments.mode
177− hasMouse: UnityInputInfo.mice > deviceConfiguration.ignoredMice
186+ hasMouse: miceModel.count > deviceConfiguration.ignoredMice
178187
179188 // TODO: Factor in the connected input devices (eg: physical keyboard, mouse, touchscreen),
180189 // what's the output device (eg: big TV, desktop monitor, phone display), etc.
@@ -188,7 +197,7 @@ Rectangle {
188197 return "tablet";
189198 }
190199 } else { // automatic
191− if (UnityInputInfo.mice > deviceConfiguration.ignoredMice) {
200+ if (miceModel.count > deviceConfiguration.ignoredMice) {
192201 return "desktop";
193202 } else {
194203 return deviceConfiguration.category;
tests/mocks/Unity/InputInfo/CMakeLists.txt+7−2
@@ -9,12 +9,17 @@ find_package(Qt5Quick REQUIRED)
99include_directories(
1010 ${CMAKE_CURRENT_SOURCE_DIR}
1111 ${CMAKE_CURRENT_BINARY_DIR}
12+ ${CMAKE_SOURCE_DIR}/plugins/Unity/InputInfo/
1213)
1314
15+add_definitions(-DUNITY_MOCKS)
16+
1417set(MockInputInfo_SOURCES
1518 plugin.cpp
16− mockqinputinfo.cpp
17− mockqdeclarativeinputdeviceinfo.cpp
19+ qinputdeviceinfo_mock.cpp
20+ mockcontroller.cpp
21+ ${CMAKE_SOURCE_DIR}/plugins/Unity/InputInfo/qinputinfo.cpp
22+ ${CMAKE_SOURCE_DIR}/plugins/Unity/InputInfo/qdeclarativeinputdevicemodel.cpp
1823)
1924
2025add_library(MockInputInfo SHARED
tests/mocks/Unity/InputInfo/mockcontroller.cppnew file+35
@@ -0,0 +1,35 @@
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+#include "mockcontroller.h"
18+
19+#include "qinputdeviceinfo_mock_p.h"
20+
21+MockController::MockController(QObject *parent):
22+ QObject(parent)
23+{
24+
25+}
26+
27+QInputDevice *MockController::addMockDevice(const QString &devicePath, QInputDevice::InputType type)
28+{
29+ return QInputDeviceManagerPrivate::instance()->addMockDevice(devicePath, type);
30+}
31+
32+void MockController::removeDevice(const QString &devicePath)
33+{
34+ QInputDeviceManagerPrivate::instance()->removeDevice(devicePath);
35+}
tests/mocks/Unity/InputInfo/mockcontroller.hnew file+34
@@ -0,0 +1,34 @@
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 MOCKCONTROLLER_H
18+#define MOCKCONTROLLER_H
19+
20+#include <QObject>
21+#include "qinputinfo.h"
22+
23+class MockController: public QObject
24+{
25+ Q_OBJECT
26+public:
27+ MockController(QObject *parent = 0);
28+ ~MockController() = default;
29+
30+ Q_INVOKABLE QInputDevice* addMockDevice(const QString &devicePath, QInputDevice::InputType type);
31+ Q_INVOKABLE void removeDevice(const QString &devicePath);
32+};
33+
34+#endif
tests/mocks/Unity/InputInfo/mockqdeclarativeinputdeviceinfo_p.hdeleted−94
@@ -1,94 +0,0 @@
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.cppdeleted−124
@@ -1,124 +0,0 @@
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.hdeleted−139
@@ -1,139 +0,0 @@
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.cpp+17−3
@@ -15,18 +15,32 @@
1515 */
1616
1717// Qt
18−#include <QtQml/qqml.h>
18+#include <QtQml>
1919
2020// self
2121#include "plugin.h"
2222
2323// local
24−#include "mockqdeclarativeinputdeviceinfo_p.h"
24+#include "qdeclarativeinputdevicemodel_p.h"
25+#include "mockcontroller.h"
26+
27+static QObject *backendProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
28+{
29+ Q_UNUSED(engine)
30+ Q_UNUSED(scriptEngine)
31+ return new MockController(engine);
32+}
2533
2634void InputInfoPlugin::registerTypes(const char *uri)
2735{
2836 int major = 0;
2937 int minor = 1;
30− qmlRegisterType<QDeclarativeInputDeviceInfo>(uri, major, minor, "InputDeviceInfo");
38+ qmlRegisterType<QDeclarativeInputDeviceModel>(uri, major, minor, "InputDeviceModel");
3139 qmlRegisterType<QInputDevice>(uri, major, minor, "InputInfo");
40+
41+ // We can't register the MockInputDeviceBackend directly because QML wants to delete singletons on its own
42+ // Given that MockInputDeviceBackend is a Q_GLOBAL_STATIC it will also be cleaned up by other Qt internals
43+ // This leads to a double-free on shutdown. So let's add a proxy to control the MockBackend through QML:
44+ // MockController
45+ qmlRegisterSingletonType<MockController>(uri, major, minor, "MockInputDeviceBackend", backendProvider);
3246}
tests/mocks/Unity/InputInfo/qinputdeviceinfo_mock.cppnew file+52
@@ -0,0 +1,52 @@
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+#include "qinputdeviceinfo_mock_p.h"
18+
19+#include <QTimer>
20+#include <QDebug>
21+
22+QInputDeviceManagerPrivate::QInputDeviceManagerPrivate(QObject *parent) :
23+ QObject(parent),
24+ currentFilter(QInputDevice::Unknown)
25+{
26+ QTimer::singleShot(1, SIGNAL(ready()));
27+}
28+
29+QInputDeviceManagerPrivate::~QInputDeviceManagerPrivate()
30+{
31+}
32+
33+QInputDevice *QInputDeviceManagerPrivate::addMockDevice(const QString &devicePath, QInputDevice::InputType type)
34+{
35+ QInputDevice *inputDevice = new QInputDevice(this);
36+ inputDevice->setDevicePath(devicePath);
37+ inputDevice->setName("Mock Device " + devicePath);
38+ inputDevice->setType(type);
39+ deviceMap.insert(devicePath, inputDevice);
40+ Q_EMIT deviceAdded(devicePath);
41+ return inputDevice;
42+}
43+
44+void QInputDeviceManagerPrivate::removeDevice(const QString &path)
45+{
46+ Q_FOREACH (const QString devicePath, deviceMap.keys()) {
47+ if (devicePath.contains(path)) {
48+ deviceMap.remove(devicePath);
49+ Q_EMIT deviceRemoved(devicePath);
50+ }
51+ }
52+}
tests/mocks/Unity/InputInfo/qinputdeviceinfo_mock_p.hnew file+58
@@ -0,0 +1,58 @@
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 QINPUTDEVICEINFO_MOCK_H
18+#define QINPUTDEVICEINFO_MOCK_H
19+
20+#include <QObject>
21+#include "qinputinfo.h"
22+
23+class QInputDevicePrivate : public QObject
24+{
25+ Q_OBJECT
26+public:
27+ explicit QInputDevicePrivate(QObject *parent = 0);
28+
29+ QString name;
30+ QString devicePath;
31+ QList <int> buttons; //keys
32+ QList <int> switches;
33+ QList <int> relativeAxis;
34+ QList <int> absoluteAxis;
35+ QInputDevice::InputTypeFlags type;
36+};
37+
38+class QInputDeviceManagerPrivate : public QObject
39+{
40+ Q_OBJECT
41+public:
42+ explicit QInputDeviceManagerPrivate(QObject *parent = 0);
43+ ~QInputDeviceManagerPrivate();
44+ QVector <QInputDevice *> deviceList;
45+ QMap <QString, QInputDevice *> deviceMap;
46+ static QInputDeviceManagerPrivate * instance();
47+ QInputDevice::InputType currentFilter;
48+
49+ Q_INVOKABLE QInputDevice* addMockDevice(const QString &devicePath, QInputDevice::InputType type);
50+ Q_INVOKABLE void removeDevice(const QString &devicePath);
51+
52+Q_SIGNALS:
53+ void deviceAdded(const QString &);
54+ void deviceRemoved(const QString &);
55+ void ready();
56+};
57+
58+#endif // QINPUTDEVICEINFO_MOCK_H
tests/qmltests/Notifications/tst_Notifications.qml+5−6
@@ -19,7 +19,6 @@ import QtQuick.Layouts 1.1
1919import QtTest 1.0
2020import ".."
2121import "../../../qml/Notifications"
22−import "../../../qml/Components/UnityInputInfo"
2322import Ubuntu.Components 1.3
2423import Unity.Test 0.1
2524import Unity.Notifications 1.0
@@ -188,7 +187,7 @@ Item {
188187
189188 anchors.fill: parent
190189 model: mockModel
191− hasMouse: UnityInputInfo.mice > 0 // for testing, we add/remove only a mock mouse
190+ hasMouse: false
192191 }
193192 }
194193
@@ -264,9 +263,9 @@ Item {
264263 id: fakeMouseCB
265264 onClicked: {
266265 if (checked) {
267− UnityInputInfo.inputInfo.addMockMouse();
266+ notifications.hasMouse = true;
268267 } else {
269− UnityInputInfo.inputInfo.removeMockMouse();
268+ notifications.hasMouse = false;
270269 }
271270 }
272271 }
@@ -695,7 +694,7 @@ Item {
695694 }
696695
697696 function test_clickToClose_data() { // reuse the data
698− UnityInputInfo.inputInfo.addMockMouse();
697+ notifications.hasMouse = true;
699698 return test_NotificationRenderer_data();
700699 }
701700
@@ -726,7 +725,7 @@ Item {
726725 }
727726
728727 function cleanupTestCase() {
729− UnityInputInfo.inputInfo.removeMockMouse();
728+ notifications.hasMouse = false;
730729 }
731730 }
732731 }
tests/qmltests/Notifications/tst_SwipeToAct.qml+5−6
@@ -19,7 +19,6 @@ import QtQuick.Layouts 1.1
1919import QtTest 1.0
2020import ".."
2121import "../../../qml/Notifications"
22−import "../../../qml/Components/UnityInputInfo"
2322import Ubuntu.Components 1.3
2423import Unity.Test 0.1
2524import Unity.Notifications 1.0
@@ -112,7 +111,7 @@ Item {
112111
113112 anchors.fill: parent
114113 model: mockModel
115− hasMouse: UnityInputInfo.mice > 0 // for testing, we add/remove only a mock mouse
114+ hasMouse: false
116115 }
117116 }
118117
@@ -152,9 +151,9 @@ Item {
152151 id: fakeMouseCB
153152 onClicked: {
154153 if (checked) {
155− UnityInputInfo.inputInfo.addMockMouse();
154+ notifications.hasMouse = true;
156155 } else {
157− UnityInputInfo.inputInfo.removeMockMouse();
156+ notifications.hasMouse = false;
158157 }
159158 }
160159 }
@@ -301,7 +300,7 @@ Item {
301300 }
302301
303302 // add a mock mouse, test clicking the left/right buttons
304− UnityInputInfo.inputInfo.addMockMouse();
303+ notifications.hasMouse = true;
305304 var leftButton = findChild(swipeButton, "leftButton");
306305 var rightButton = findChild(swipeButton, "rightButton");
307306
@@ -316,7 +315,7 @@ Item {
316315 compare(actionSpy.signalArguments[0][0], data.actions.data(1, ActionModel.RoleActionId), "got wrong id for negative action");
317316 actionSpy.clear();
318317 }
319− UnityInputInfo.inputInfo.removeMockMouse();
318+ notifications.hasMouse = false;
320319 }
321320 }
322321 }
tests/qmltests/tst_OrientedShell.qml+17−9
@@ -26,7 +26,6 @@ import Powerd 0.1
2626import Unity.InputInfo 0.1
2727
2828import "../../qml"
29−import "../../qml/Components/UnityInputInfo"
3029
3130Rectangle {
3231 id: root
@@ -56,6 +55,15 @@ Rectangle {
5655 property bool disableHeight: false
5756 }
5857
58+ InputDeviceModel {
59+ id: miceModel
60+ deviceFilter: InputInfo.Mouse
61+ }
62+ InputDeviceModel {
63+ id: keyboardsModel
64+ deviceFilter: InputInfo.Keyboard
65+ }
66+
5967 property int physicalOrientation0
6068 property int physicalOrientation90
6169 property int physicalOrientation180
@@ -329,14 +337,14 @@ Rectangle {
329337 text: "Add mouse"
330338 activeFocusOnPress: false
331339 onClicked: {
332− UnityInputInfo.inputInfo.addMockMouse()
340+ MockInputDeviceBackend.addMockDevice("/mouse" + miceModel.count, InputInfo.Mouse)
333341 }
334342 }
335343 Button {
336344 text: "Remove mouse"
337345 activeFocusOnPress: false
338346 onClicked: {
339− UnityInputInfo.inputInfo.removeMockMouse()
347+ MockInputDeviceBackend.removeDevice("/mouse" + (miceModel.count - 1))
340348 }
341349 }
342350 }
@@ -345,14 +353,14 @@ Rectangle {
345353 text: "Add kbd"
346354 activeFocusOnPress: false
347355 onClicked: {
348− UnityInputInfo.inputInfo.addMockKeyboard()
356+ MockInputDeviceBackend.addMockDevice("/kbd" + keyboardsModel.count, InputInfo.Keyboard)
349357 }
350358 }
351359 Button {
352360 activeFocusOnPress: false
353361 text: "Remove kbd"
354362 onClicked: {
355− UnityInputInfo.inputInfo.removeMockKeyboard()
363+ MockInputDeviceBackend.removeDevice("/kbd" + (keyboardsModel.count - 1))
356364 }
357365 }
358366 }
@@ -977,19 +985,19 @@ Rectangle {
977985 tryCompare(shell, "usageScenario", "phone");
978986 tryCompare(mockOskSettings, "stayHidden", false);
979987
980− UnityInputInfo.inputInfo.addMockKeyboard();
988+ MockInputDeviceBackend.addMockDevice("/kbd0", InputInfo.Keyboard);
981989 tryCompare(shell, "usageScenario", "phone");
982990 tryCompare(mockOskSettings, "stayHidden", true);
983991
984− UnityInputInfo.inputInfo.addMockMouse();
992+ MockInputDeviceBackend.addMockDevice("/mouse0", InputInfo.Mouse);
985993 tryCompare(shell, "usageScenario", "desktop");
986994 tryCompare(mockOskSettings, "stayHidden", true);
987995
988− UnityInputInfo.inputInfo.removeMockKeyboard();
996+ MockInputDeviceBackend.removeDevice("/kbd0");
989997 tryCompare(shell, "usageScenario", "desktop");
990998 tryCompare(mockOskSettings, "stayHidden", false);
991999
992− UnityInputInfo.inputInfo.removeMockMouse();
1000+ MockInputDeviceBackend.removeDevice("/mouse0");
9931001 tryCompare(shell, "usageScenario", "phone");
9941002 tryCompare(mockOskSettings, "stayHidden", false);
9951003 }