Merge lp:~osomon/webbrowser-app/bottom-edge-mouse into lp:webbrowser-app

Proposed by Olivier Tilloy
Status: Merged
Approved by: Olivier Tilloy
Approved revision: 1340
Merged at revision: 1339
Proposed branch: lp:~osomon/webbrowser-app/bottom-edge-mouse
Merge into: lp:webbrowser-app
Diff against target: 1518 lines (+1284/-27)
19 files modified
debian/control (+3/-0)
debian/rules (+3/-1)
debian/webbrowser-app-apparmor.manifest (+2/-1)
src/app/CMakeLists.txt (+1/-0)
src/app/browserapplication.cpp (+5/-0)
src/app/unity8/README (+11/-3)
src/app/unity8/plugins/CMakeLists.txt (+1/-0)
src/app/unity8/plugins/Unity/CMakeLists.txt (+1/-0)
src/app/unity8/plugins/Unity/InputInfo/CMakeLists.txt (+40/-0)
src/app/unity8/plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux.cpp (+291/-0)
src/app/unity8/plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux_p.h (+98/-0)
src/app/unity8/plugins/Unity/InputInfo/plugin.cpp (+32/-0)
src/app/unity8/plugins/Unity/InputInfo/plugin.h (+30/-0)
src/app/unity8/plugins/Unity/InputInfo/qdeclarativeinputdevicemodel.cpp (+196/-0)
src/app/unity8/plugins/Unity/InputInfo/qdeclarativeinputdevicemodel_p.h (+102/-0)
src/app/unity8/plugins/Unity/InputInfo/qinputinfo.cpp (+270/-0)
src/app/unity8/plugins/Unity/InputInfo/qinputinfo.h (+143/-0)
src/app/unity8/plugins/Unity/InputInfo/qmldir (+3/-0)
src/app/webbrowser/Browser.qml (+52/-22)
To merge this branch: bzr merge lp:~osomon/webbrowser-app/bottom-edge-mouse
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Jamie Strandboge Approve
Review via email: mp+284283@code.launchpad.net

Commit message

In narrow mode, when a mouse is connected, turn the bottom edge hint into a clickable bottom edge bar.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1332. By Olivier Tilloy

Add missing build dependency.

1333. By Olivier Tilloy

In narrow mode, when a mouse is connected, turn the bottom edge hint into a clickable bottom edge bar.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1334. By Olivier Tilloy

Merge the latest changes from trunk, and resolve a minor conflict.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

Testing on device, I’m getting apparmor denials which prevent the Unity.InputInfo plugin from working. Disabling the apparmor profile makes it work.
The following additional rules appear to be needed:

  /sys/class/ r,
  /sys/class/input/ r,
  /sys/devices/**/input*/ r,
  /sys/devices/**/input*/** r,

1335. By Olivier Tilloy

Remove the "Open tabs" and "New tab" actions from the drawer menu.
 - In wide mode, they are useless because there is a visible tab bar.
 - In narrow mode, if there is a mouse connected the bottom edge bar opens the tabs view, and if there is no mouse the bottom edge hint opens it.

1336. By Olivier Tilloy

Also detect touchpads.

1337. By Olivier Tilloy

Add apparmor rules to allow InputInfo to work.

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

With the "/sys/devices/**/input*/" change to read_path, you don't need /sys/devices/**/input*/** in your sed. '/sys/class/ r,' and '/sys/bus/ r,' in the sed are good though.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1338. By Olivier Tilloy

Simpler sed rule.

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

The apparmor changes look fine. Thanks!

review: Approve
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

FYI, the other changes to debian/ look good too.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1339. By Olivier Tilloy

Escape $ in debian/rules.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1340. By Olivier Tilloy

Also allow read access to /run/udev/data/**, so that input device capabilities can be discovered.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2015-12-15 15:38:35 +0000
3+++ debian/control 2016-01-29 09:32:29 +0000
4@@ -10,8 +10,11 @@
5 dh-apparmor,
6 dh-translations,
7 hardening-wrapper,
8+ libevdev-dev,
9 liboxideqt-qmlplugin (>= 1.9),
10 libqt5sql5-sqlite,
11+ libudev-dev,
12+ pkg-config,
13 python3-all,
14 python3-flake8,
15 qml-module-qt-labs-folderlistmodel,
16
17=== modified file 'debian/rules'
18--- debian/rules 2015-10-22 15:07:44 +0000
19+++ debian/rules 2016-01-29 09:32:29 +0000
20@@ -14,7 +14,9 @@
21 aa-easyprof -m ./debian/webbrowser-app-apparmor.manifest --no-verify | \
22 egrep -v '(# Click packages|CLICK_DIR)' | \
23 sed 's/@{APP_PKGNAME}_@{APP_APPNAME}_@{APP_VERSION}/@{APP_PKGNAME}/g' | \
24- sed 's#/run/shm/\.org\.chromium\.Chromium\.\*#/{dev,run}/shm/.org.chromium.Chromium.*#g' \
25+ sed 's#/run/shm/\.org\.chromium\.Chromium\.\*#/{dev,run}/shm/.org.chromium.Chromium.*#g' | \
26+ egrep -v 'deny /run/udev/data/\*\* r,' | \
27+ sed 's#^}$$#\n /sys/class/ r,\n /sys/class/input/ r,\n /run/udev/data/** r,\n}#g' \
28 > ./debian/usr.bin.webbrowser-app
29 apparmor_parser -QTK ./debian/usr.bin.webbrowser-app
30
31
32=== modified file 'debian/webbrowser-app-apparmor.manifest'
33--- debian/webbrowser-app-apparmor.manifest 2015-10-26 11:28:31 +0000
34+++ debian/webbrowser-app-apparmor.manifest 2016-01-29 09:32:29 +0000
35@@ -32,7 +32,8 @@
36 "/usr/share/applications/",
37 "/custom/vendor/here/location-provider/consent/*.html",
38 "@{HOME}/.local/share/applications/",
39- "@{HOME}/Downloads/"
40+ "@{HOME}/Downloads/",
41+ "/sys/devices/**/input*/"
42 ],
43 "write_path": [
44 "@{HOME}/Downloads/"
45
46=== modified file 'src/app/CMakeLists.txt'
47--- src/app/CMakeLists.txt 2016-01-13 16:23:16 +0000
48+++ src/app/CMakeLists.txt 2016-01-29 09:32:29 +0000
49@@ -37,6 +37,7 @@
50 Qt5::Quick
51 Qt5::Widgets
52 UbuntuGesturesQml
53+ InputInfo
54 )
55
56 file(GLOB QML_FILES *.qml)
57
58=== modified file 'src/app/browserapplication.cpp'
59--- src/app/browserapplication.cpp 2016-01-15 10:06:31 +0000
60+++ src/app/browserapplication.cpp 2016-01-29 09:32:29 +0000
61@@ -37,6 +37,7 @@
62 #include "TouchRegistry.h"
63 #include "Ubuntu/Gestures/Direction.h"
64 #include "Ubuntu/Gestures/DirectionalDragArea.h"
65+#include "Unity/InputInfo/qdeclarativeinputdevicemodel_p.h"
66
67 BrowserApplication::BrowserApplication(int& argc, char** argv)
68 : QApplication(argc, argv)
69@@ -165,6 +166,10 @@
70 qmlRegisterSingletonType<Direction>(gesturesUri, 0, 1, "Direction", Direction_singleton_factory);
71 qmlRegisterType<DirectionalDragArea>(gesturesUri, 0, 1, "DirectionalDragArea");
72
73+ const char* inputInfoUri = "Unity.InputInfo";
74+ qmlRegisterType<QDeclarativeInputDeviceModel>(inputInfoUri, 0, 1, "InputDeviceModel");
75+ qmlRegisterType<QInputDevice>(inputInfoUri, 0, 1, "InputInfo");
76+
77 m_engine = new QQmlEngine;
78 connect(m_engine, SIGNAL(quit()), SLOT(quit()));
79 if (!isRunningInstalled()) {
80
81=== modified file 'src/app/unity8/README'
82--- src/app/unity8/README 2015-03-17 15:14:11 +0000
83+++ src/app/unity8/README 2016-01-29 09:32:29 +0000
84@@ -1,11 +1,19 @@
85 Code in this directory was copied over from unity8.
86+
87+Ubuntu.Gestures:
88 - first import: 2015-02-04, at revision 1583 of lp:unity8
89 - last sync: 2015-03-17, at revision 1663 of lp:unity8
90
91+Unity.InputInfo:
92+ - first import: 2016-01-28, at revision 2143 of lp:unity8
93+
94 The structure of the directories has been kept identical, to ease syncing the
95 code in the future. Minor changes were made to the build system to integrate it
96 with the existing webbrowser-app code base.
97
98-The goal is to eventually have those components moved over to the UITK, thus
99-removing the need for a copy here. See
100-https://docs.google.com/a/canonical.com/document/d/1_ljZunMXWqJfrBGEkCp0peVD8gq6-E4ZMFpuH0PVKRc.
101+As of 2015-12-09, the SwipeArea component is available in the UITK, so we should
102+start using it instead of building a local copy of Ubuntu.Gestures. This is
103+currently blocked on https://launchpad.net/bugs/1459362.
104+
105+The Unity.InputInfo plugin should be replaced by an upstream Qt API in the near
106+future.
107
108=== modified file 'src/app/unity8/plugins/CMakeLists.txt'
109--- src/app/unity8/plugins/CMakeLists.txt 2015-02-04 10:56:38 +0000
110+++ src/app/unity8/plugins/CMakeLists.txt 2016-01-29 09:32:29 +0000
111@@ -1,1 +1,2 @@
112 add_subdirectory(Ubuntu)
113+add_subdirectory(Unity)
114
115=== added directory 'src/app/unity8/plugins/Unity'
116=== added file 'src/app/unity8/plugins/Unity/CMakeLists.txt'
117--- src/app/unity8/plugins/Unity/CMakeLists.txt 1970-01-01 00:00:00 +0000
118+++ src/app/unity8/plugins/Unity/CMakeLists.txt 2016-01-29 09:32:29 +0000
119@@ -0,0 +1,1 @@
120+add_subdirectory(InputInfo)
121
122=== added directory 'src/app/unity8/plugins/Unity/InputInfo'
123=== added file 'src/app/unity8/plugins/Unity/InputInfo/CMakeLists.txt'
124--- src/app/unity8/plugins/Unity/InputInfo/CMakeLists.txt 1970-01-01 00:00:00 +0000
125+++ src/app/unity8/plugins/Unity/InputInfo/CMakeLists.txt 2016-01-29 09:32:29 +0000
126@@ -0,0 +1,40 @@
127+# This is a temporary snapshot of the WIP QInputInfo API as we
128+# require this in unity now but upstream isn't finished yet.
129+# Eventually this should be dropped in favor of the upstream
130+# QInputInfo API.
131+
132+project(InputInfo)
133+
134+find_package(Qt5Core REQUIRED)
135+find_package(Qt5Quick REQUIRED)
136+
137+include(FindPkgConfig)
138+pkg_check_modules(LIBUDEV REQUIRED libudev)
139+pkg_check_modules(LIBEVDEV REQUIRED libevdev)
140+
141+include_directories(
142+ ${CMAKE_CURRENT_SOURCE_DIR}
143+ ${CMAKE_CURRENT_BINARY_DIR}
144+ ${LIBUDEV_INCLUDE_DIRS}
145+ ${LIBEVDEV_INCLUDE_DIRS}
146+)
147+
148+set(InputInfo_SOURCES
149+ plugin.cpp
150+ qinputinfo.cpp
151+ qdeclarativeinputdevicemodel.cpp
152+ linux/qinputdeviceinfo_linux.cpp
153+)
154+
155+add_library(InputInfo STATIC
156+ ${InputInfo_SOURCES}
157+)
158+
159+target_link_libraries(InputInfo
160+ ${LIBUDEV_LDFLAGS}
161+ ${LIBEVDEV_LDFLAGS}
162+)
163+
164+qt5_use_modules(InputInfo Core Qml Quick)
165+
166+#add_unity8_plugin(Unity.InputInfo 0.1 Unity/InputInfo TARGETS InputInfo)
167
168=== added directory 'src/app/unity8/plugins/Unity/InputInfo/linux'
169=== added file 'src/app/unity8/plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux.cpp'
170--- src/app/unity8/plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux.cpp 1970-01-01 00:00:00 +0000
171+++ src/app/unity8/plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux.cpp 2016-01-29 09:32:29 +0000
172@@ -0,0 +1,291 @@
173+/****************************************************************************
174+**
175+** Copyright (C) 2014 Canonical, Ltd. and/or its subsidiary(-ies).
176+** Contact: http://www.qt-project.org/legal
177+**
178+** This file is part of the QtSystems module of the Qt Toolkit.
179+**
180+** $QT_BEGIN_LICENSE:LGPL$
181+** Commercial License Usage
182+** Licensees holding valid commercial Qt licenses may use this file in
183+** accordance with the commercial license agreement provided with the
184+** Software or, alternatively, in accordance with the terms contained in
185+** a written agreement between you and Digia. For licensing terms and
186+** conditions see http://qt.digia.com/licensing. For further information
187+** use the contact form at http://qt.digia.com/contact-us.
188+**
189+** GNU Lesser General Public License Usage
190+** Alternatively, this file may be used under the terms of the GNU Lesser
191+** General Public License version 2.1 as published by the Free Software
192+** Foundation and appearing in the file LICENSE.LGPL included in the
193+** packaging of this file. Please review the following information to
194+** ensure the GNU Lesser General Public License version 2.1 requirements
195+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
196+**
197+** In addition, as a special exception, Digia gives you certain additional
198+** rights. These rights are described in the Digia Qt LGPL Exception
199+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
200+**
201+** GNU General Public License Usage
202+** Alternatively, this file may be used under the terms of the GNU
203+** General Public License version 3.0 as published by the Free Software
204+** Foundation and appearing in the file LICENSE.GPL included in the
205+** packaging of this file. Please review the following information to
206+** ensure the GNU General Public License version 3.0 requirements will be
207+** met: http://www.gnu.org/copyleft/gpl.html.
208+**
209+**
210+** $QT_END_LICENSE$
211+**
212+****************************************************************************/
213+
214+#include "qinputdeviceinfo_linux_p.h"
215+
216+#include <libudev.h>
217+#include <libevdev/libevdev.h>
218+#include <fcntl.h>
219+#include <QDebug>
220+#include <QSocketNotifier>
221+#include <QTimer>
222+#include <QDir>
223+
224+QInputDeviceManagerPrivate::QInputDeviceManagerPrivate(QObject *parent) :
225+ QObject(parent),
226+ currentFilter(QInputDevice::Unknown),
227+ udevice(0)
228+{
229+ QTimer::singleShot(250,this,SLOT(init()));
230+}
231+
232+QInputDeviceManagerPrivate::~QInputDeviceManagerPrivate()
233+{
234+ udev_unref(udevice);
235+ udev_monitor_unref(udevMonitor);
236+}
237+
238+void QInputDeviceManagerPrivate::init()
239+{
240+ if (!udevice)
241+ udevice = udev_new();
242+
243+ udev_list_entry *devices;
244+ udev_list_entry *dev_list_entry;
245+ udev_device *dev;
246+
247+ QString subsystem = QStringLiteral("input");
248+ struct udev_enumerate *enumerate = 0;
249+
250+ if (udevice) {
251+
252+ udevMonitor = udev_monitor_new_from_netlink(udevice, "udev");
253+ udev_monitor_filter_add_match_subsystem_devtype(udevMonitor, subsystem.toLatin1(), NULL);
254+ enumerate = udev_enumerate_new(udevice);
255+ udev_enumerate_add_match_subsystem(enumerate, subsystem.toLatin1());
256+
257+ udev_monitor_enable_receiving(udevMonitor);
258+ notifierFd = udev_monitor_get_fd(udevMonitor);
259+
260+ notifier = new QSocketNotifier(notifierFd, QSocketNotifier::Read, this);
261+ connect(notifier, SIGNAL(activated(int)), this, SLOT(onUDevChanges()));
262+
263+ udev_enumerate_scan_devices(enumerate);
264+ devices = udev_enumerate_get_list_entry(enumerate);
265+
266+ udev_list_entry_foreach(dev_list_entry, devices) {
267+ const char *path;
268+ path = udev_list_entry_get_name(dev_list_entry);
269+
270+ dev = udev_device_new_from_syspath(udevice, path);
271+ if (qstrcmp(udev_device_get_subsystem(dev), "input") == 0 ) {
272+ QInputDevice *iDevice = addDevice(dev);
273+ if (iDevice && !iDevice->devicePath().isEmpty()) {
274+ deviceMap.insert(iDevice->devicePath(),iDevice);
275+ }
276+ }
277+ udev_device_unref(dev);
278+ }
279+ udev_enumerate_unref(enumerate);
280+ }
281+ // udev_unref(udevice);
282+ Q_FOREACH (const QString &devicePath, deviceMap.keys()) {
283+ Q_EMIT deviceAdded(devicePath);
284+ }
285+ Q_EMIT ready();
286+}
287+
288+QInputDevice::InputTypeFlags QInputDeviceManagerPrivate::getInputTypeFlags(struct udev_device *dev)
289+{
290+ QInputDevice::InputTypeFlags flags = QInputDevice::Unknown;
291+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEY"), "1") == 0 ) {
292+ flags |= QInputDevice::Button;
293+ }
294+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_MOUSE"), "1") == 0) {
295+ flags |= QInputDevice::Mouse;
296+ }
297+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD"), "1") == 0) {
298+ flags |= QInputDevice::TouchPad;
299+ }
300+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"), "1") == 0
301+ || qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TABLET"), "1") == 0) {
302+ flags |= QInputDevice::TouchScreen;
303+ }
304+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"), "1") == 0 ) {
305+ flags |= QInputDevice::Keyboard;
306+ }
307+ if (!QString::fromLatin1(udev_device_get_property_value(dev, "SW")).isEmpty()) {
308+ flags |= QInputDevice::Switch;
309+ }
310+
311+ return flags;
312+}
313+
314+QInputDevice *QInputDeviceManagerPrivate::addDevice(struct udev_device *udev)
315+{
316+ QString eventPath = QString::fromLatin1(udev_device_get_sysname(udev));
317+
318+ if (eventPath.contains(QStringLiteral("event")))
319+ eventPath.prepend(QStringLiteral("/dev/input/"));
320+
321+ if (deviceMap.contains(eventPath)) {
322+ return Q_NULLPTR;
323+ }
324+ struct libevdev *dev = NULL;
325+ int fd;
326+ int rc = 1;
327+ QInputDevice *inputDevice;
328+ inputDevice = addUdevDevice(udev);
329+ if (!inputDevice) {
330+ return Q_NULLPTR;
331+ }
332+ eventPath = inputDevice->devicePath();
333+
334+ qDebug() << "Input device added:" << inputDevice->name() << inputDevice->devicePath() << inputDevice->type();
335+
336+ fd = open(eventPath.toLatin1(), O_RDONLY|O_NONBLOCK);
337+ if (fd == -1) {
338+ return inputDevice;
339+ }
340+ rc = libevdev_new_from_fd(fd, &dev);
341+ if (rc < 0) {
342+ qWarning() << "Failed to init libevdev ("<< strerror(-rc) << ")";
343+ return Q_NULLPTR;
344+ }
345+
346+ for (int i = 0; i < EV_MAX; i++) {
347+ if (i == EV_KEY || i == EV_SW || i == EV_REL
348+ || i == EV_REL || i == EV_ABS) {
349+ for (int j = 0; j < libevdev_event_type_get_max(i); j++) {
350+ if (libevdev_has_event_code(dev, i, j)) {
351+ switch (i) {
352+ case EV_KEY:
353+ inputDevice->addButton(j);
354+ break;
355+ case EV_SW:
356+ inputDevice->addSwitch(j);
357+ break;
358+ case EV_REL:
359+ inputDevice->addRelativeAxis(j);
360+ break;
361+ case EV_ABS:
362+ inputDevice->addAbsoluteAxis(j);
363+ break;
364+ };
365+ }
366+ }
367+ }
368+ }
369+
370+ return inputDevice;
371+}
372+
373+void QInputDeviceManagerPrivate::addDetails(struct udev_device *)
374+{
375+}
376+
377+void QInputDeviceManagerPrivate::removeDevice(const QString &path)
378+{
379+ // this path is not a full evdev path
380+ Q_FOREACH (const QString devicePath, deviceMap.keys()) {
381+ if (devicePath.contains(path)) {
382+ qDebug() << "Input device removed:" << deviceMap.value(devicePath)->name() << devicePath << deviceMap.value(devicePath)->type();
383+ deviceMap.remove(devicePath);
384+ Q_EMIT deviceRemoved(devicePath);
385+ }
386+ }
387+}
388+
389+QInputDevice *QInputDeviceManagerPrivate::addUdevDevice(struct udev_device *udev)
390+{
391+ QInputDevice *iDevice;
392+
393+ struct udev_list_entry *list;
394+ struct udev_list_entry *node;
395+
396+ list = udev_device_get_properties_list_entry (udev);
397+ QString syspath = QString::fromLatin1(udev_device_get_syspath(udev));
398+ QDir sysdir(syspath);
399+
400+ QStringList infoList = sysdir.entryList(QStringList() << QStringLiteral("event*"),QDir::Dirs);
401+
402+ if (infoList.count() > 0) {
403+ QString token = infoList.at(0);
404+
405+ token.prepend(QStringLiteral("/dev/input/"));
406+ iDevice = new QInputDevice(this);
407+ iDevice->setDevicePath(token);
408+ } else {
409+ return Q_NULLPTR;
410+ }
411+ udev_list_entry_foreach (node, list) {
412+
413+ QString key = QString::fromLatin1(udev_list_entry_get_name(node));
414+ QString value = QString::fromLatin1(udev_list_entry_get_value(node));
415+
416+ if (key == QStringLiteral("NAME")) {
417+ iDevice->setName(value.remove(QStringLiteral("\"")));
418+ }
419+ }
420+ iDevice->setType(getInputTypeFlags(udev));
421+ return iDevice;
422+}
423+
424+void QInputDeviceManagerPrivate::onUDevChanges()
425+{
426+ if (!udevMonitor)
427+ return;
428+
429+ udev_device *dev = udev_monitor_receive_device(udevMonitor);
430+
431+ if (dev) {
432+ if (qstrcmp(udev_device_get_subsystem(dev), "input") == 0 ) {
433+ QString eventPath = QString::fromLatin1(udev_device_get_sysname(dev));
434+
435+ QString action = QString::fromStdString(udev_device_get_action(dev));
436+
437+ if (!eventPath.contains(QStringLiteral("/dev/input/")))
438+ eventPath.prepend(QStringLiteral("/dev/input/"));
439+
440+ if (action == QStringLiteral("add")) {
441+ if (deviceMap.contains(eventPath)){
442+ udev_device_unref(dev);
443+ return;
444+ }
445+
446+ QInputDevice *iDevice = addDevice(dev);
447+ if (!iDevice) {
448+ delete iDevice;
449+ return;
450+ }
451+ iDevice->setType(getInputTypeFlags(dev));
452+ udev_device_unref(dev);
453+
454+ deviceMap.insert(eventPath,iDevice);
455+
456+ Q_EMIT deviceAdded(eventPath);
457+
458+ } else if (action == QStringLiteral("remove")) {
459+ removeDevice(eventPath);
460+ }
461+ }
462+ }
463+}
464
465=== added file 'src/app/unity8/plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux_p.h'
466--- src/app/unity8/plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux_p.h 1970-01-01 00:00:00 +0000
467+++ src/app/unity8/plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux_p.h 2016-01-29 09:32:29 +0000
468@@ -0,0 +1,98 @@
469+/****************************************************************************
470+**
471+** Copyright (C) 2014 Canonical, Ltd. and/or its subsidiary(-ies).
472+** Contact: http://www.qt-project.org/legal
473+**
474+** This file is part of the QtSystems module of the Qt Toolkit.
475+**
476+** $QT_BEGIN_LICENSE:LGPL$
477+** Commercial License Usage
478+** Licensees holding valid commercial Qt licenses may use this file in
479+** accordance with the commercial license agreement provided with the
480+** Software or, alternatively, in accordance with the terms contained in
481+** a written agreement between you and Digia. For licensing terms and
482+** conditions see http://qt.digia.com/licensing. For further information
483+** use the contact form at http://qt.digia.com/contact-us.
484+**
485+** GNU Lesser General Public License Usage
486+** Alternatively, this file may be used under the terms of the GNU Lesser
487+** General Public License version 2.1 as published by the Free Software
488+** Foundation and appearing in the file LICENSE.LGPL included in the
489+** packaging of this file. Please review the following information to
490+** ensure the GNU Lesser General Public License version 2.1 requirements
491+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
492+**
493+** In addition, as a special exception, Digia gives you certain additional
494+** rights. These rights are described in the Digia Qt LGPL Exception
495+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
496+**
497+** GNU General Public License Usage
498+** Alternatively, this file may be used under the terms of the GNU
499+** General Public License version 3.0 as published by the Free Software
500+** Foundation and appearing in the file LICENSE.GPL included in the
501+** packaging of this file. Please review the following information to
502+** ensure the GNU General Public License version 3.0 requirements will be
503+** met: http://www.gnu.org/copyleft/gpl.html.
504+**
505+**
506+** $QT_END_LICENSE$
507+**
508+****************************************************************************/
509+
510+#ifndef QINPUTDEVICEINFO_LINUX_P_H
511+#define QINPUTDEVICEINFO_LINUX_P_H
512+
513+#include <QObject>
514+#include "qinputinfo.h"
515+#include <libudev.h>
516+
517+class QInputDevicePrivate : public QObject
518+{
519+ Q_OBJECT
520+public:
521+ explicit QInputDevicePrivate(QObject *parent = 0);
522+
523+ QString name;
524+ QString devicePath;
525+ QList <int> buttons; //keys
526+ QList <int> switches;
527+ QList <int> relativeAxis;
528+ QList <int> absoluteAxis;
529+ QInputDevice::InputTypeFlags type;
530+};
531+
532+class QInputDeviceManagerPrivate : public QObject
533+{
534+ Q_OBJECT
535+public:
536+ explicit QInputDeviceManagerPrivate(QObject *parent = 0);
537+ ~QInputDeviceManagerPrivate();
538+ QVector <QInputDevice *> deviceList;
539+ QMap <QString, QInputDevice *> deviceMap;
540+ static QInputDeviceManagerPrivate * instance();
541+ QInputDevice::InputType currentFilter;
542+
543+Q_SIGNALS:
544+ void deviceAdded(const QString &);
545+ void deviceRemoved(const QString &);
546+ void ready();
547+
548+private:
549+ QInputDevice *addDevice(struct udev_device *udev);
550+ QInputDevice *addUdevDevice(struct udev_device *);
551+
552+ QInputDevice *addDevice(const QString &path);
553+ void removeDevice(const QString &path);
554+ QSocketNotifier *notifier;
555+ int notifierFd;
556+ struct udev_monitor *udevMonitor;
557+ QInputDevice::InputTypeFlags getInputTypeFlags(struct udev_device *);
558+ struct udev *udevice;
559+ void addDetails(struct udev_device *);
560+
561+private Q_SLOTS:
562+ void onUDevChanges();
563+ void init();
564+};
565+
566+#endif // QINPUTDEVICEINFO_LINUX_P_H
567
568=== added file 'src/app/unity8/plugins/Unity/InputInfo/plugin.cpp'
569--- src/app/unity8/plugins/Unity/InputInfo/plugin.cpp 1970-01-01 00:00:00 +0000
570+++ src/app/unity8/plugins/Unity/InputInfo/plugin.cpp 2016-01-29 09:32:29 +0000
571@@ -0,0 +1,32 @@
572+/*
573+ * Copyright 2015 Canonical Ltd.
574+ *
575+ * This program is free software; you can redistribute it and/or modify
576+ * it under the terms of the GNU Lesser General Public License as published by
577+ * the Free Software Foundation; version 3.
578+ *
579+ * This program is distributed in the hope that it will be useful,
580+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
581+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
582+ * GNU Lesser General Public License for more details.
583+ *
584+ * You should have received a copy of the GNU Lesser General Public License
585+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
586+ */
587+
588+// Qt
589+#include <QtQml/qqml.h>
590+
591+// self
592+#include "plugin.h"
593+
594+// local
595+#include "qdeclarativeinputdevicemodel_p.h"
596+
597+void InputInfoPlugin::registerTypes(const char *uri)
598+{
599+ int major = 0;
600+ int minor = 1;
601+ qmlRegisterType<QDeclarativeInputDeviceModel>(uri, major, minor, "InputDeviceModel");
602+ qmlRegisterType<QInputDevice>(uri, major, minor, "InputInfo");
603+}
604
605=== added file 'src/app/unity8/plugins/Unity/InputInfo/plugin.h'
606--- src/app/unity8/plugins/Unity/InputInfo/plugin.h 1970-01-01 00:00:00 +0000
607+++ src/app/unity8/plugins/Unity/InputInfo/plugin.h 2016-01-29 09:32:29 +0000
608@@ -0,0 +1,30 @@
609+/*
610+ * Copyright 2015 Canonical Ltd.
611+ *
612+ * This program is free software; you can redistribute it and/or modify
613+ * it under the terms of the GNU Lesser General Public License as published by
614+ * the Free Software Foundation; version 3.
615+ *
616+ * This program is distributed in the hope that it will be useful,
617+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
618+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
619+ * GNU Lesser General Public License for more details.
620+ *
621+ * You should have received a copy of the GNU Lesser General Public License
622+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
623+ */
624+
625+#ifndef INPUTINFO_PLUGIN_H
626+#define INPUTINFO_PLUGIN_H
627+
628+#include <QtQml/QQmlExtensionPlugin>
629+
630+class InputInfoPlugin : public QQmlExtensionPlugin
631+{
632+ Q_OBJECT
633+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
634+public:
635+ void registerTypes(const char *uri);
636+};
637+
638+#endif // INPUTINFO_PLUGIN_H
639
640=== added file 'src/app/unity8/plugins/Unity/InputInfo/qdeclarativeinputdevicemodel.cpp'
641--- src/app/unity8/plugins/Unity/InputInfo/qdeclarativeinputdevicemodel.cpp 1970-01-01 00:00:00 +0000
642+++ src/app/unity8/plugins/Unity/InputInfo/qdeclarativeinputdevicemodel.cpp 2016-01-29 09:32:29 +0000
643@@ -0,0 +1,196 @@
644+/****************************************************************************
645+**
646+** Copyright (C) 2015 Jolla.
647+** Contact: http://www.qt-project.org/legal
648+**
649+** This file is part of the QtSystems module of the Qt Toolkit.
650+**
651+** $QT_BEGIN_LICENSE:LGPL$
652+** Commercial License Usage
653+** Licensees holding valid commercial Qt licenses may use this file in
654+** accordance with the commercial license agreement provided with the
655+** Software or, alternatively, in accordance with the terms contained in
656+** a written agreement between you and Digia. For licensing terms and
657+** conditions see http://qt.digia.com/licensing. For further information
658+** use the contact form at http://qt.digia.com/contact-us.
659+**
660+** GNU Lesser General Public License Usage
661+** Alternatively, this file may be used under the terms of the GNU Lesser
662+** General Public License version 2.1 as published by the Free Software
663+** Foundation and appearing in the file LICENSE.LGPL included in the
664+** packaging of this file. Please review the following information to
665+** ensure the GNU Lesser General Public License version 2.1 requirements
666+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
667+**
668+** In addition, as a special exception, Digia gives you certain additional
669+** rights. These rights are described in the Digia Qt LGPL Exception
670+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
671+**
672+** GNU General Public License Usage
673+** Alternatively, this file may be used under the terms of the GNU
674+** General Public License version 3.0 as published by the Free Software
675+** Foundation and appearing in the file LICENSE.GPL included in the
676+** packaging of this file. Please review the following information to
677+** ensure the GNU General Public License version 3.0 requirements will be
678+** met: http://www.gnu.org/copyleft/gpl.html.
679+**
680+**
681+** $QT_END_LICENSE$
682+**
683+****************************************************************************/
684+#include "qdeclarativeinputdevicemodel_p.h"
685+#include "qinputinfo.h"
686+
687+QDeclarativeInputDeviceModel::QDeclarativeInputDeviceModel(QObject *parent) :
688+ QAbstractListModel(parent),
689+ deviceInfo(new QInputDeviceManager),
690+ currentFilter(QInputDevice::Unknown)
691+{
692+ connect(deviceInfo,SIGNAL(ready()),this,SLOT(updateDeviceList()));
693+ connect(deviceInfo, &QInputDeviceManager::deviceAdded,this,&QDeclarativeInputDeviceModel::addedDevice);
694+ connect(deviceInfo, &QInputDeviceManager::deviceRemoved,this,&QDeclarativeInputDeviceModel::removedDevice);
695+}
696+
697+QDeclarativeInputDeviceModel::~QDeclarativeInputDeviceModel()
698+{
699+ delete deviceInfo;
700+}
701+
702+QVariant QDeclarativeInputDeviceModel::data(const QModelIndex &index, int role) const
703+{
704+ switch (role) {
705+ case ServiceRole:
706+ return QVariant::fromValue(static_cast<QObject *>(inputDevices.value(index.row())));
707+ break;
708+ case NameRole:
709+ return QVariant::fromValue(static_cast<QString>(inputDevices.value(index.row())->name()));
710+ break;
711+ case DevicePathRole:
712+ return QVariant::fromValue(static_cast<QString>(inputDevices.value(index.row())->devicePath()));
713+ break;
714+ case ButtonsRole:
715+ return QVariant::fromValue(static_cast<QList <int> >(inputDevices.value(index.row())->buttons()));
716+ break;
717+ case SwitchesRole:
718+ return QVariant::fromValue(static_cast<QList <int> >(inputDevices.value(index.row())->switches()));
719+ break;
720+ case RelativeAxisRole:
721+ return QVariant::fromValue(static_cast<QList <int> >(inputDevices.value(index.row())->relativeAxis()));
722+ break;
723+ case AbsoluteAxisRole:
724+ return QVariant::fromValue(static_cast<QList <int> >(inputDevices.value(index.row())->absoluteAxis()));
725+ break;
726+ case TypesRole:
727+ return QVariant::fromValue(static_cast<int>(inputDevices.value(index.row())->type()));
728+ break;
729+ };
730+
731+ return QVariant();
732+}
733+
734+int QDeclarativeInputDeviceModel::rowCount(const QModelIndex &parent) const
735+{
736+ Q_UNUSED(parent);
737+
738+ return inputDevices.count();
739+}
740+
741+int QDeclarativeInputDeviceModel::indexOf(const QString &devicePath) const
742+{
743+ int idx(-1);
744+ Q_FOREACH (QInputDevice *device, inputDevices) {
745+ idx++;
746+ if (device->devicePath() == devicePath) return idx;
747+ }
748+
749+ return -1;
750+}
751+
752+QInputDevice *QDeclarativeInputDeviceModel::get(int index) const
753+{
754+ if (index < 0 || index > inputDevices.count())
755+ return 0;
756+ return inputDevices.value(index);
757+}
758+
759+void QDeclarativeInputDeviceModel::updateDeviceList()
760+{
761+ QVector <QInputDevice *> newDevices = deviceInfo->deviceListOfType(currentFilter);
762+
763+ int numNew = newDevices.count();
764+
765+ for (int i = 0; i < numNew; i++) {
766+ int j = inputDevices.indexOf(newDevices.value(i));
767+
768+ if (j == -1) {
769+ beginInsertRows(QModelIndex(), i, i);
770+ inputDevices.insert(i, newDevices.value(i));
771+ endInsertRows();
772+ Q_EMIT countChanged();
773+ } else if (i != j) {
774+ // changed its position -> move it
775+ QInputDevice* device = inputDevices.value(j);
776+ beginMoveRows(QModelIndex(), j, j, QModelIndex(), i);
777+ inputDevices.remove(j);
778+ inputDevices.insert(i, device);
779+ endMoveRows();
780+ Q_EMIT countChanged();
781+ } //else {
782+ QModelIndex changedIndex(this->index(j, 0, QModelIndex()));
783+ Q_EMIT dataChanged(changedIndex, changedIndex);
784+ }
785+
786+ int numOld = inputDevices.count();
787+ if (numOld > numNew) {
788+ beginRemoveRows(QModelIndex(), numNew, numOld - 1);
789+ inputDevices.remove(numNew, numOld - numNew);
790+ endRemoveRows();
791+ Q_EMIT countChanged();
792+ }
793+}
794+
795+void QDeclarativeInputDeviceModel::addedDevice(const QString &devicePath)
796+{
797+ updateDeviceList();
798+ Q_EMIT deviceAdded(devicePath);
799+}
800+
801+void QDeclarativeInputDeviceModel::removedDevice(const QString &devicePath)
802+{
803+ updateDeviceList();
804+ Q_EMIT deviceRemoved(devicePath);
805+}
806+
807+QHash<int,QByteArray> QDeclarativeInputDeviceModel::roleNames() const
808+{
809+ QHash<int, QByteArray> roles;
810+ roles[NameRole] = "name";
811+ roles[DevicePathRole] = "devicePath";
812+ roles[ButtonsRole] = "buttons";
813+ roles[SwitchesRole] = "switches";
814+ roles[RelativeAxisRole] = "rAxis";
815+ roles[AbsoluteAxisRole] = "aAxis";
816+ roles[TypesRole] = "types";
817+ return roles;
818+}
819+
820+/*
821+ * Returns the currently set device filter.
822+ * */
823+QInputDevice::InputType QDeclarativeInputDeviceModel::deviceFilter()
824+{
825+ return currentFilter;
826+}
827+
828+/*
829+ * Sets the current input device filter to filter.
830+ * */
831+void QDeclarativeInputDeviceModel::setDeviceFilter(QInputDevice::InputType filter)
832+{
833+ if (filter != currentFilter) {
834+ deviceInfo->setDeviceFilter(filter);
835+ currentFilter = filter;
836+ updateDeviceList();
837+ Q_EMIT deviceFilterChanged(filter);
838+ }
839+}
840
841=== added file 'src/app/unity8/plugins/Unity/InputInfo/qdeclarativeinputdevicemodel_p.h'
842--- src/app/unity8/plugins/Unity/InputInfo/qdeclarativeinputdevicemodel_p.h 1970-01-01 00:00:00 +0000
843+++ src/app/unity8/plugins/Unity/InputInfo/qdeclarativeinputdevicemodel_p.h 2016-01-29 09:32:29 +0000
844@@ -0,0 +1,102 @@
845+/****************************************************************************
846+**
847+** Copyright (C) 2015 Jolla.
848+** Contact: http://www.qt-project.org/legal
849+**
850+** This file is part of the QtSystems module of the Qt Toolkit.
851+**
852+** $QT_BEGIN_LICENSE:LGPL$
853+** Commercial License Usage
854+** Licensees holding valid commercial Qt licenses may use this file in
855+** accordance with the commercial license agreement provided with the
856+** Software or, alternatively, in accordance with the terms contained in
857+** a written agreement between you and Digia. For licensing terms and
858+** conditions see http://qt.digia.com/licensing. For further information
859+** use the contact form at http://qt.digia.com/contact-us.
860+**
861+** GNU Lesser General Public License Usage
862+** Alternatively, this file may be used under the terms of the GNU Lesser
863+** General Public License version 2.1 as published by the Free Software
864+** Foundation and appearing in the file LICENSE.LGPL included in the
865+** packaging of this file. Please review the following information to
866+** ensure the GNU Lesser General Public License version 2.1 requirements
867+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
868+**
869+** In addition, as a special exception, Digia gives you certain additional
870+** rights. These rights are described in the Digia Qt LGPL Exception
871+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
872+**
873+** GNU General Public License Usage
874+** Alternatively, this file may be used under the terms of the GNU
875+** General Public License version 3.0 as published by the Free Software
876+** Foundation and appearing in the file LICENSE.GPL included in the
877+** packaging of this file. Please review the following information to
878+** ensure the GNU General Public License version 3.0 requirements will be
879+** met: http://www.gnu.org/copyleft/gpl.html.
880+**
881+**
882+** $QT_END_LICENSE$
883+**
884+****************************************************************************/
885+
886+#ifndef QDECLARATIVEINPUTDEVICEMODEL_H
887+#define QDECLARATIVEINPUTDEVICEMODEL_H
888+
889+#include <QObject>
890+#include <QAbstractListModel>
891+#include "qinputinfo.h"
892+
893+class QDeclarativeInputDeviceModel : public QAbstractListModel
894+{
895+ Q_OBJECT
896+ Q_DISABLE_COPY(QDeclarativeInputDeviceModel)
897+ Q_PROPERTY(QInputDevice::InputType deviceFilter READ deviceFilter WRITE setDeviceFilter NOTIFY deviceFilterChanged)
898+
899+ Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
900+
901+public:
902+ enum ItemRoles {
903+ ServiceRole = Qt::UserRole + 1,
904+ NameRole,
905+ DevicePathRole,
906+ ButtonsRole,
907+ SwitchesRole,
908+ RelativeAxisRole,
909+ AbsoluteAxisRole,
910+ TypesRole
911+ };
912+
913+ explicit QDeclarativeInputDeviceModel(QObject *parent = 0);
914+ virtual ~QDeclarativeInputDeviceModel();
915+
916+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
917+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
918+
919+ void setDeviceFilter(QInputDevice::InputType filter);
920+ QInputDevice::InputType deviceFilter();
921+
922+ Q_INVOKABLE int indexOf(const QString &devicePath) const;
923+
924+ Q_INVOKABLE QInputDevice *get(int index) const;
925+ QHash<int, QByteArray> roleNames() const;
926+
927+Q_SIGNALS:
928+ void deviceAdded(const QString &devicePath);
929+ void deviceRemoved(const QString &devicePath);
930+ void deviceFilterChanged(const QInputDevice::InputType filter);
931+ void countChanged();
932+
933+public Q_SLOTS:
934+ void updateDeviceList();
935+private:
936+ QInputDeviceManager *deviceInfo;
937+ QVector<QInputDevice *> inputDevices;
938+ QInputDevice::InputType currentFilter;
939+
940+private Q_SLOTS:
941+ void addedDevice(const QString &);
942+ void removedDevice(const QString &path);
943+
944+};
945+
946+#endif // QDECLARATIVEINPUTDEVICEMODEL_H
947
948=== added file 'src/app/unity8/plugins/Unity/InputInfo/qinputinfo.cpp'
949--- src/app/unity8/plugins/Unity/InputInfo/qinputinfo.cpp 1970-01-01 00:00:00 +0000
950+++ src/app/unity8/plugins/Unity/InputInfo/qinputinfo.cpp 2016-01-29 09:32:29 +0000
951@@ -0,0 +1,270 @@
952+/****************************************************************************
953+**
954+** Copyright (C) 2014 Canonical, Ltd. and/or its subsidiary(-ies).
955+** Contact: http://www.qt-project.org/legal
956+**
957+** This file is part of the QtSystems module of the Qt Toolkit.
958+**
959+** $QT_BEGIN_LICENSE:LGPL$
960+** Commercial License Usage
961+** Licensees holding valid commercial Qt licenses may use this file in
962+** accordance with the commercial license agreement provided with the
963+** Software or, alternatively, in accordance with the terms contained in
964+** a written agreement between you and Digia. For licensing terms and
965+** conditions see http://qt.digia.com/licensing. For further information
966+** use the contact form at http://qt.digia.com/contact-us.
967+**
968+** GNU Lesser General Public License Usage
969+** Alternatively, this file may be used under the terms of the GNU Lesser
970+** General Public License version 2.1 as published by the Free Software
971+** Foundation and appearing in the file LICENSE.LGPL included in the
972+** packaging of this file. Please review the following information to
973+** ensure the GNU Lesser General Public License version 2.1 requirements
974+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
975+**
976+** In addition, as a special exception, Digia gives you certain additional
977+** rights. These rights are described in the Digia Qt LGPL Exception
978+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
979+**
980+** GNU General Public License Usage
981+** Alternatively, this file may be used under the terms of the GNU
982+** General Public License version 3.0 as published by the Free Software
983+** Foundation and appearing in the file LICENSE.GPL included in the
984+** packaging of this file. Please review the following information to
985+** ensure the GNU General Public License version 3.0 requirements will be
986+** met: http://www.gnu.org/copyleft/gpl.html.
987+**
988+**
989+** $QT_END_LICENSE$
990+**
991+****************************************************************************/
992+
993+#include "qinputinfo.h"
994+
995+#if defined(UNITY_MOCKS)
996+#include "qinputdeviceinfo_mock_p.h"
997+#elif defined(Q_OS_LINUX)
998+#include "linux/qinputdeviceinfo_linux_p.h"
999+#endif
1000+
1001+Q_GLOBAL_STATIC(QInputDeviceManagerPrivate, inputDeviceManagerPrivate)
1002+
1003+QT_BEGIN_NAMESPACE
1004+
1005+QInputDeviceManagerPrivate * QInputDeviceManagerPrivate::instance()
1006+{
1007+ QInputDeviceManagerPrivate *priv = inputDeviceManagerPrivate();
1008+ return priv;
1009+}
1010+
1011+QInputDevicePrivate::QInputDevicePrivate(QObject *parent) :
1012+ QObject(parent),
1013+ type(QInputDevice::Unknown)
1014+{
1015+}
1016+
1017+QInputDevice::QInputDevice(QObject *parent) :
1018+ QObject(parent),
1019+ d_ptr(new QInputDevicePrivate(this))
1020+{
1021+}
1022+
1023+/*
1024+ * Returns the name of this input device.
1025+ */
1026+QString QInputDevice::name() const
1027+{
1028+ return d_ptr->name;
1029+}
1030+
1031+/*
1032+ * Sets the name of this input device to \b name.
1033+ */
1034+void QInputDevice::setName(const QString &name)
1035+{
1036+ d_ptr->name = name;
1037+}
1038+
1039+/*
1040+ * Returns the device path of this device.
1041+ */
1042+QString QInputDevice::devicePath() const
1043+{
1044+ return d_ptr->devicePath;
1045+}
1046+
1047+/*
1048+ * Sets the device ppath of this device to /b path.
1049+ */
1050+void QInputDevice::setDevicePath(const QString &path)
1051+{
1052+ d_ptr->devicePath = path;
1053+}
1054+
1055+/*
1056+ * Returns the number of buttons this device has.
1057+ */
1058+QList <int> QInputDevice::buttons() const
1059+{
1060+ return d_ptr->buttons;
1061+}
1062+
1063+/*
1064+ * Adds a button
1065+ */
1066+void QInputDevice::addButton(int buttonCode)
1067+{
1068+ d_ptr->buttons.append(buttonCode);
1069+}
1070+
1071+/*
1072+ * Returns the number of switch of this device.
1073+ */
1074+QList <int> QInputDevice::switches() const
1075+{
1076+ return d_ptr->switches;
1077+}
1078+
1079+/*
1080+ * Adds a switch
1081+ */
1082+void QInputDevice::addSwitch(int switchCode)
1083+{
1084+ d_ptr->switches.append(switchCode);
1085+}
1086+
1087+/*
1088+ * Returns a list of the relative axis of this device
1089+ */
1090+QList <int> QInputDevice::relativeAxis() const
1091+{
1092+ return d_ptr->relativeAxis;
1093+}
1094+
1095+/*
1096+ */
1097+void QInputDevice::addRelativeAxis(int axisCode)
1098+{
1099+ d_ptr->relativeAxis.append(axisCode);
1100+}
1101+
1102+/*
1103+ * Returns a list of the absolute axis of this device
1104+ */
1105+QList <int> QInputDevice::absoluteAxis() const
1106+{
1107+ return d_ptr->absoluteAxis;
1108+}
1109+
1110+/*
1111+ */
1112+void QInputDevice::addAbsoluteAxis(int axisCode)
1113+{
1114+ d_ptr->absoluteAxis.append(axisCode);
1115+}
1116+
1117+/*
1118+ * Returns a QInputDevice::InputTypeFlags of all the types of types.
1119+ */
1120+QInputDevice::InputTypeFlags QInputDevice::type() const
1121+{
1122+ return d_ptr->type;
1123+}
1124+
1125+/*
1126+ */
1127+void QInputDevice::setType(QInputDevice::InputTypeFlags type) //? setTypes?
1128+{
1129+ d_ptr->type = type;
1130+}
1131+
1132+QInputDeviceManager::QInputDeviceManager(QObject *parent) :
1133+ QObject(parent),
1134+ d_ptr(inputDeviceManagerPrivate)
1135+{
1136+ connect(d_ptr, &QInputDeviceManagerPrivate::deviceAdded,this,&QInputDeviceManager::addedDevice);
1137+ connect(d_ptr, &QInputDeviceManagerPrivate::deviceRemoved,this,&QInputDeviceManager::deviceRemoved);
1138+
1139+ connect(d_ptr,SIGNAL(ready()),this,SIGNAL(ready()));
1140+}
1141+
1142+/*
1143+ * Returns a QMap of known input devices.
1144+ */
1145+QMap <QString, QInputDevice *> QInputDeviceManager::deviceMap()
1146+{
1147+ return d_ptr->deviceMap;
1148+}
1149+
1150+/*
1151+ */
1152+void QInputDeviceManager::addedDevice(const QString & devicePath)
1153+{
1154+ Q_EMIT deviceAdded(devicePath);
1155+}
1156+
1157+/*
1158+ * Returns a QVector of InputDevices of type filter
1159+ * */
1160+QVector <QInputDevice *> QInputDeviceManager::deviceListOfType(QInputDevice::InputType filter)
1161+{
1162+ QVector <QInputDevice *> dList;
1163+ QMapIterator<QString, QInputDevice *> i(d_ptr->deviceMap);
1164+ while (i.hasNext()) {
1165+ i.next();
1166+ if (i.value()->type().testFlag(filter) || filter == QInputDevice::Unknown) {
1167+ dList.append(i.value());
1168+ }
1169+ }
1170+ return dList;
1171+}
1172+
1173+/*
1174+ * Returns the number of input devices with the currently set QInputDevice::InputType filter.
1175+ * If no device filter has been set, returns number of all available input devices.
1176+ * If filter has not been set, returns all available input devices
1177+ */
1178+int QInputDeviceManager::deviceCount() const
1179+{
1180+ return deviceCount(static_cast< QInputDevice::InputType >(d_ptr->currentFilter));
1181+}
1182+
1183+/*
1184+ * Returns the number of input devices of the type filter.
1185+ */
1186+int QInputDeviceManager::deviceCount(const QInputDevice::InputType filter) const
1187+{
1188+ int dList = 0;
1189+ QMapIterator<QString, QInputDevice *> i(d_ptr->deviceMap);
1190+ while (i.hasNext()) {
1191+ i.next();
1192+// qDebug() << i.value()->name() << i.value()->devicePath();
1193+// qDebug() << i.value()->type() << i.value()->type().testFlag(filter);
1194+
1195+ if (i.value()->type().testFlag(filter)) {
1196+ dList++;
1197+ }
1198+ }
1199+ return dList;
1200+}
1201+
1202+/*
1203+ * Returns the currently set device filter.
1204+ * */
1205+QInputDevice::InputType QInputDeviceManager::deviceFilter()
1206+{
1207+ return d_ptr->currentFilter;
1208+}
1209+
1210+/*
1211+ * Sets the current input device filter to filter.
1212+ * */
1213+void QInputDeviceManager::setDeviceFilter(QInputDevice::InputType filter)
1214+{
1215+ if (filter != d_ptr->currentFilter) {
1216+ d_ptr->currentFilter = filter;
1217+ Q_EMIT deviceFilterChanged(filter);
1218+ }
1219+}
1220+
1221+QT_END_NAMESPACE
1222
1223=== added file 'src/app/unity8/plugins/Unity/InputInfo/qinputinfo.h'
1224--- src/app/unity8/plugins/Unity/InputInfo/qinputinfo.h 1970-01-01 00:00:00 +0000
1225+++ src/app/unity8/plugins/Unity/InputInfo/qinputinfo.h 2016-01-29 09:32:29 +0000
1226@@ -0,0 +1,143 @@
1227+/****************************************************************************
1228+**
1229+** Copyright (C) 2014 Canonical, Ltd. and/or its subsidiary(-ies).
1230+** Contact: http://www.qt-project.org/legal
1231+**
1232+** This file is part of the QtSystems module of the Qt Toolkit.
1233+**
1234+** $QT_BEGIN_LICENSE:LGPL$
1235+** Commercial License Usage
1236+** Licensees holding valid commercial Qt licenses may use this file in
1237+** accordance with the commercial license agreement provided with the
1238+** Software or, alternatively, in accordance with the terms contained in
1239+** a written agreement between you and Digia. For licensing terms and
1240+** conditions see http://qt.digia.com/licensing. For further information
1241+** use the contact form at http://qt.digia.com/contact-us.
1242+**
1243+** GNU Lesser General Public License Usage
1244+** Alternatively, this file may be used under the terms of the GNU Lesser
1245+** General Public License version 2.1 as published by the Free Software
1246+** Foundation and appearing in the file LICENSE.LGPL included in the
1247+** packaging of this file. Please review the following information to
1248+** ensure the GNU Lesser General Public License version 2.1 requirements
1249+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
1250+**
1251+** In addition, as a special exception, Digia gives you certain additional
1252+** rights. These rights are described in the Digia Qt LGPL Exception
1253+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
1254+**
1255+** GNU General Public License Usage
1256+** Alternatively, this file may be used under the terms of the GNU
1257+** General Public License version 3.0 as published by the Free Software
1258+** Foundation and appearing in the file LICENSE.GPL included in the
1259+** packaging of this file. Please review the following information to
1260+** ensure the GNU General Public License version 3.0 requirements will be
1261+** met: http://www.gnu.org/copyleft/gpl.html.
1262+**
1263+**
1264+** $QT_END_LICENSE$
1265+**
1266+****************************************************************************/
1267+
1268+#ifndef QINPUTINFO_H
1269+#define QINPUTINFO_H
1270+
1271+#include <QObject>
1272+#include <QVector>
1273+#include <QMap>
1274+#include <QSocketNotifier>
1275+#include <QDebug>
1276+
1277+class QInputDeviceManagerPrivate;
1278+class QInputDevicePrivate;
1279+class QInputDevice;
1280+
1281+class QInputDeviceManager;
1282+
1283+class QInputDevice : public QObject
1284+{
1285+ Q_OBJECT
1286+ Q_ENUMS(InputType)
1287+ Q_FLAGS(InputType InputTypeFlags)
1288+ friend class QInputDeviceManagerPrivate;
1289+
1290+public:
1291+
1292+ enum InputType {
1293+ Unknown = 0,
1294+ Button = 1,
1295+ Mouse = 2,
1296+ TouchPad = 4,
1297+ TouchScreen = 8,
1298+ Keyboard = 16,
1299+ Switch = 32
1300+ };
1301+ Q_ENUMS(InputType)
1302+ Q_DECLARE_FLAGS(InputTypeFlags, InputType)
1303+
1304+ explicit QInputDevice(QObject *parent = 0);
1305+ QString name() const;
1306+ QString devicePath() const;
1307+ QList <int> buttons() const; //keys event code
1308+ QList <int> switches() const;
1309+ QList <int> relativeAxis() const;
1310+ QList <int> absoluteAxis() const;
1311+ QInputDevice::InputTypeFlags type() const;
1312+
1313+private:
1314+
1315+ QInputDevicePrivate *d_ptr;
1316+ void setName(const QString &);
1317+ void setDevicePath(const QString &);
1318+ void addButton(int);
1319+ void addSwitch(int);
1320+ void addRelativeAxis(int);
1321+ void addAbsoluteAxis(int);
1322+ void setType(QInputDevice::InputTypeFlags flags);
1323+
1324+};
1325+
1326+Q_DECLARE_METATYPE(QInputDevice::InputType)
1327+Q_DECLARE_METATYPE(QInputDevice::InputTypeFlags)
1328+
1329+class QInputDeviceManagerPrivate;
1330+
1331+class QInputDeviceManager : public QObject
1332+{
1333+ Q_OBJECT
1334+ Q_PROPERTY(int deviceCount READ deviceCount NOTIFY deviceCountChanged)
1335+ Q_PROPERTY(QInputDevice::InputType deviceFilter READ deviceFilter WRITE setDeviceFilter NOTIFY deviceFilterChanged)
1336+public:
1337+
1338+ explicit QInputDeviceManager(QObject *parent = 0);
1339+
1340+ int deviceCount() const;
1341+ int deviceCount(const QInputDevice::InputType filter) const;
1342+
1343+ void setDeviceFilter(QInputDevice::InputType filter);
1344+ QInputDevice::InputType deviceFilter();
1345+
1346+ QMap <QString, QInputDevice *> deviceMap();
1347+ Q_INVOKABLE QVector <QInputDevice *> deviceListOfType(QInputDevice::InputType filter);
1348+
1349+Q_SIGNALS:
1350+
1351+ void deviceAdded(const QString & devicePath);
1352+ void deviceRemoved(const QString & devicePath);
1353+
1354+ void ready();
1355+ void deviceCountChanged(int count);
1356+ void deviceFilterChanged(const QInputDevice::InputType filter);
1357+
1358+public Q_SLOTS:
1359+ void addedDevice(const QString & devicePath);
1360+
1361+private:
1362+ Q_DISABLE_COPY(QInputDeviceManager)
1363+#if !defined(QT_SIMULATOR)
1364+ QInputDeviceManagerPrivate *const d_ptr;
1365+ Q_DECLARE_PRIVATE(QInputDeviceManager)
1366+#endif
1367+};
1368+
1369+#endif // QINPUTINFO_H
1370
1371=== added file 'src/app/unity8/plugins/Unity/InputInfo/qmldir'
1372--- src/app/unity8/plugins/Unity/InputInfo/qmldir 1970-01-01 00:00:00 +0000
1373+++ src/app/unity8/plugins/Unity/InputInfo/qmldir 2016-01-29 09:32:29 +0000
1374@@ -0,0 +1,3 @@
1375+module Unity.InputInfo
1376+plugin InputInfo
1377+typeinfo InputInfo.qmltypes
1378
1379=== modified file 'src/app/webbrowser/Browser.qml'
1380--- src/app/webbrowser/Browser.qml 2016-01-22 10:23:17 +0000
1381+++ src/app/webbrowser/Browser.qml 2016-01-29 09:32:29 +0000
1382@@ -22,6 +22,7 @@
1383 import com.canonical.Oxide 1.8 as Oxide
1384 import Ubuntu.Components 1.3
1385 import Ubuntu.Components.Popups 1.3
1386+import Unity.InputInfo 0.1
1387 import webbrowserapp.private 0.1
1388 import webbrowsercommon.private 0.1
1389 import "../actions" as Actions
1390@@ -95,6 +96,16 @@
1391 onMediaAccessPermissionRequested: PopupUtils.open(mediaAccessDialogComponent, null, { request: request })
1392 }
1393
1394+ InputDeviceModel {
1395+ id: miceModel
1396+ deviceFilter: InputInfo.Mouse
1397+ }
1398+
1399+ InputDeviceModel {
1400+ id: touchPadModel
1401+ deviceFilter: InputInfo.TouchPad
1402+ }
1403+
1404 Component {
1405 id: mediaAccessDialogComponent
1406 MediaAccessDialog { }
1407@@ -181,7 +192,7 @@
1408 right: parent.right
1409 top: parent.top
1410 }
1411- height: parent.height - osk.height
1412+ height: parent.height - osk.height - bottomEdgeBar.height
1413
1414 focus: !errorSheetLoader.focus &&
1415 !invalidCertificateErrorSheetLoader.focus &&
1416@@ -531,23 +542,6 @@
1417 onTriggered: historyViewLoader.active = true
1418 },
1419 Action {
1420- objectName: "tabs"
1421- text: i18n.tr("Open tabs")
1422- iconName: "browser-tabs"
1423- enabled: (formFactor != "mobile") && !browser.wide
1424- onTriggered: {
1425- recentView.state = "shown"
1426- recentToolbar.state = "shown"
1427- }
1428- },
1429- Action {
1430- objectName: "newtab"
1431- text: i18n.tr("New tab")
1432- iconName: browser.incognito ? "private-tab-new" : "tab-new"
1433- enabled: (formFactor != "mobile") && !browser.wide
1434- onTriggered: browser.openUrlInNewTab("", true)
1435- },
1436- Action {
1437 objectName: "findinpage"
1438 text: i18n.tr("Find in page")
1439 iconName: "search"
1440@@ -697,8 +691,8 @@
1441 }
1442 height: units.gu(2)
1443
1444- enabled: (formFactor == "mobile") && !browser.wide &&
1445- (recentView.state == "") && browser.currentWebview &&
1446+ enabled: !browser.wide && (recentView.state == "") &&
1447+ browser.currentWebview &&
1448 (Screen.orientation == Screen.primaryOrientation)
1449
1450 onDraggingChanged: {
1451@@ -728,7 +722,7 @@
1452 Image {
1453 id: bottomEdgeHint
1454 objectName: "bottomEdgeHint"
1455- source: (formFactor == "mobile") ? "assets/bottom_edge_hint.png" : ""
1456+ source: "assets/bottom_edge_hint.png"
1457 property bool forceShow: false
1458 anchors {
1459 horizontalCenter: parent.horizontalCenter
1460@@ -738,7 +732,7 @@
1461 UbuntuNumberAnimation {}
1462 }
1463 }
1464- visible: bottomEdgeHandle.enabled
1465+ visible: bottomEdgeHandle.enabled && !internal.hasMouse
1466 opacity: recentView.visible ? 0 : 1
1467 Behavior on opacity {
1468 UbuntuNumberAnimation {}
1469@@ -757,6 +751,40 @@
1470 }
1471 }
1472
1473+ MouseArea {
1474+ id: bottomEdgeBar
1475+ anchors {
1476+ left: parent.left
1477+ right: parent.right
1478+ bottom: parent.bottom
1479+ }
1480+ enabled: !browser.wide && internal.hasMouse &&
1481+ (osk.state == "hidden") && (recentView.state == "")
1482+ visible: enabled
1483+ height: visible ? units.gu(4) : 0
1484+
1485+ onClicked: {
1486+ recentView.state = "shown"
1487+ recentToolbar.state = "shown"
1488+ }
1489+
1490+ Rectangle {
1491+ anchors.fill: parent
1492+ color: "#f7f7f7"
1493+ border {
1494+ width: units.dp(1)
1495+ color: "#cdcdcd"
1496+ }
1497+ }
1498+
1499+ Label {
1500+ anchors.centerIn: parent
1501+ color: "#5d5d5d"
1502+ // TRANSLATORS: %1 refers to the current number of tabs opened
1503+ text: i18n.tr("(%1)").arg(tabsModel ? tabsModel.count : 0)
1504+ }
1505+ }
1506+
1507 Loader {
1508 id: bookmarksViewLoader
1509
1510@@ -1403,6 +1431,8 @@
1511 }
1512 }
1513
1514+ readonly property bool hasMouse: (miceModel.count + touchPadModel.count) > 0
1515+
1516 function getOpenPages() {
1517 var urls = []
1518 for (var i = 0; i < tabsModel.count; i++) {

Subscribers

People subscribed via source and target branches

to status/vote changes: