Merge lp:~gerboland/miral/qt-bump-to-qtmir-529 into lp:miral

Proposed by Gerry Boland
Status: Merged
Approved by: Alan Griffiths
Approved revision: 239
Merged at revision: 237
Proposed branch: lp:~gerboland/miral/qt-bump-to-qtmir-529
Merge into: lp:miral
Diff against target: 1275 lines (+453/-333)
29 files modified
miral-qt/CMakeLists.txt (+2/-3)
miral-qt/debian/control (+3/-2)
miral-qt/debian/gles-patches/convert-to-gles.patch (+1/-1)
miral-qt/src/modules/Unity/Application/CMakeLists.txt (+3/-1)
miral-qt/src/modules/Unity/Application/application.cpp (+1/-0)
miral-qt/src/modules/Unity/Application/application_manager.cpp (+3/-0)
miral-qt/src/modules/Unity/Application/application_manager.h (+2/-0)
miral-qt/src/modules/Unity/Application/cgmanager.cpp (+117/-0)
miral-qt/src/modules/Unity/Application/cgmanager.h (+42/-0)
miral-qt/src/modules/Unity/Application/dbusfocusinfo.cpp (+89/-0)
miral-qt/src/modules/Unity/Application/dbusfocusinfo.h (+54/-0)
miral-qt/src/modules/Unity/Application/mirsurface.cpp (+41/-0)
miral-qt/src/modules/Unity/Application/mirsurface.h (+8/-0)
miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h (+6/-0)
miral-qt/src/modules/Unity/Application/mirsurfaceitem.cpp (+11/-49)
miral-qt/src/modules/Unity/Application/mirsurfaceitem.h (+1/-2)
miral-qt/src/modules/Unity/Application/plugin.cpp (+0/-10)
miral-qt/src/modules/Unity/Application/session.cpp (+17/-0)
miral-qt/src/modules/Unity/Application/session.h (+4/-0)
miral-qt/src/modules/Unity/Application/session_interface.h (+6/-0)
miral-qt/src/modules/Unity/Application/ubuntukeyboardinfo.cpp (+0/-173)
miral-qt/src/modules/Unity/Application/ubuntukeyboardinfo.h (+0/-87)
miral-qt/src/platforms/mirserver/logging.cpp (+1/-0)
miral-qt/src/platforms/mirserver/logging.h (+1/-0)
miral-qt/src/platforms/mirserver/mirwindowmanager.cpp (+9/-4)
miral-qt/src/platforms/mirserver/surfaceobserver.cpp (+20/-0)
miral-qt/src/platforms/mirserver/surfaceobserver.h (+3/-1)
miral-qt/tests/framework/fake_mirsurface.h (+4/-0)
miral-qt/tests/framework/fake_session.h (+4/-0)
To merge this branch: bzr merge lp:~gerboland/miral/qt-bump-to-qtmir-529
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Review via email: mp+301168@code.launchpad.net

Commit message

[miral-qt] Bump to rev 529 of qtmir

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I wonder why "DBusFocusInfo *m_dbusFocusInfo;" isn't "DBusFocusInfo m_dbusFocusInfo;" (avoiding explicit memory management) but I guess this is the wrong project in which to ask that.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

+ QRect inputBounds() const override { return QRect(0,0,10,10); }

Is this really an override? It seems to be missing in the MirSurfaceInterface base class.

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

+ void inputBoundsChanged(const QRect &rect);

Neither the linker nor I can find the implementation.

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Hmm. A clean rebuild fixed those. (Is there a depends missing somewhere in CMakeLists.txt?)

review: Approve
Revision history for this message
Gerry Boland (gerboland) wrote :

> DBusFocusInfo *m_dbusFocusInfo
good point, I didn't see it as it landed while I was on hols!

Build fail - am surprised, I bumped the required unity-shell-application version to the correct one (19). It should have not tried to build unless you have libunity-api-dev version 7.116 already installed

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'miral-qt/CMakeLists.txt'
2--- miral-qt/CMakeLists.txt 2016-06-21 13:38:53 +0000
3+++ miral-qt/CMakeLists.txt 2016-07-26 12:46:18 +0000
4@@ -90,9 +90,8 @@
5 pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
6 pkg_check_modules(QTDBUSTEST libqtdbustest-1 REQUIRED)
7 pkg_check_modules(QTDBUSMOCK libqtdbusmock-1 REQUIRED)
8-pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=18)
9-
10-include_directories(${APPLICATION_API_INCLUDE_DIRS})
11+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=19)
12+pkg_check_modules(CGMANAGER libcgmanager REQUIRED)
13
14 add_definitions(-DMIR_REQUIRE_DEPRECATED_EVENT_OPT_IN=1)
15
16
17=== modified file 'miral-qt/debian/control'
18--- miral-qt/debian/control 2016-06-21 13:38:53 +0000
19+++ miral-qt/debian/control 2016-07-26 12:46:18 +0000
20@@ -6,6 +6,7 @@
21 cmake-extras (>= 0.3),
22 debhelper (>= 9),
23 google-mock (>= 1.6.0+svn437),
24+ libcgmanager-dev,
25 libfontconfig1-dev,
26 libgles2-mesa-dev,
27 libglib2.0-dev,
28@@ -22,7 +23,7 @@
29 libubuntu-app-launch2-dev (>= 0.9),
30 libubuntu-application-api-dev (>= 2.1.0),
31 libudev-dev,
32- libunity-api-dev (>= 7.114),
33+ libunity-api-dev (>= 7.116),
34 liburl-dispatcher1-dev,
35 libxkbcommon-dev,
36 libxrender-dev,
37@@ -93,7 +94,7 @@
38 Conflicts: libqtmir,
39 libunity-mir1,
40 Provides: unity-application-impl,
41- unity-application-impl-17,
42+ unity-application-impl-19,
43 Description: Qt plugin for Unity specific Mir APIs
44 QtMir provides Qt/QML bindings for Mir features that are exposed through the
45 qtmir-desktop or qtmir-android QPA plugin such as Application management
46
47=== modified file 'miral-qt/debian/gles-patches/convert-to-gles.patch'
48--- miral-qt/debian/gles-patches/convert-to-gles.patch 2016-06-07 20:32:04 +0000
49+++ miral-qt/debian/gles-patches/convert-to-gles.patch 2016-07-26 12:46:18 +0000
50@@ -84,7 +84,7 @@
51 -Conflicts: libqtmir,
52 - libunity-mir1,
53 -Provides: unity-application-impl,
54-- unity-application-impl-17,
55+- unity-application-impl-19,
56 -Description: Qt plugin for Unity specific Mir APIs
57 - QtMir provides Qt/QML bindings for Mir features that are exposed through the
58 - qtmir-desktop or qtmir-android QPA plugin such as Application management
59
60=== modified file 'miral-qt/src/modules/Unity/Application/CMakeLists.txt'
61--- miral-qt/src/modules/Unity/Application/CMakeLists.txt 2016-06-01 22:06:51 +0000
62+++ miral-qt/src/modules/Unity/Application/CMakeLists.txt 2016-07-26 12:46:18 +0000
63@@ -10,6 +10,7 @@
64 ${MIRAL_QT_SOURCE_DIR}/src/platforms/mirserver
65 ${MIRAL_QT_SOURCE_DIR}/src/common
66 ${GSETTINGS_QT_INCLUDE_DIRS}
67+ ${CGMANAGER_INCLUDE_DIRS}
68
69 ${LTTNG_INCLUDE_DIRS}
70 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
71@@ -25,12 +26,13 @@
72 set(QMLMIRPLUGIN_SRC
73 application_manager.cpp
74 application.cpp
75+ cgmanager.cpp
76 ../../../common/abstractdbusservicemonitor.cpp
77 ../../../common/debughelpers.cpp
78+ dbusfocusinfo.cpp
79 plugin.cpp
80 dbuswindowstack.cpp
81 mirsurfacemanager.cpp
82- ubuntukeyboardinfo.cpp
83 mirfocuscontroller.cpp
84 mirsurface.cpp
85 mirsurfaceinterface.h
86
87=== modified file 'miral-qt/src/modules/Unity/Application/application.cpp'
88--- miral-qt/src/modules/Unity/Application/application.cpp 2016-06-21 13:38:53 +0000
89+++ miral-qt/src/modules/Unity/Application/application.cpp 2016-07-26 12:46:18 +0000
90@@ -18,6 +18,7 @@
91 #include "application.h"
92 #include "applicationinfo.h"
93 #include "application_manager.h"
94+#include "mirsurfaceinterface.h"
95 #include "session.h"
96 #include "sharedwakelock.h"
97 #include "timer.h"
98
99=== modified file 'miral-qt/src/modules/Unity/Application/application_manager.cpp'
100--- miral-qt/src/modules/Unity/Application/application_manager.cpp 2016-06-01 22:06:51 +0000
101+++ miral-qt/src/modules/Unity/Application/application_manager.cpp 2016-07-26 12:46:18 +0000
102@@ -18,6 +18,7 @@
103 #include "application_manager.h"
104 #include "application.h"
105 #include "applicationinfo.h"
106+#include "dbusfocusinfo.h"
107 #include "dbuswindowstack.h"
108 #include "mirfocuscontroller.h"
109 #include "session.h"
110@@ -176,6 +177,7 @@
111 const QSharedPointer<SettingsInterface>& settings,
112 QObject *parent)
113 : ApplicationManagerInterface(parent)
114+ , m_dbusFocusInfo(new DBusFocusInfo(m_applications))
115 , m_dbusWindowStack(new DBusWindowStack(this))
116 , m_taskController(taskController)
117 , m_procInfo(procInfo)
118@@ -200,6 +202,7 @@
119 ApplicationManager::~ApplicationManager()
120 {
121 qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::~ApplicationManager";
122+ delete m_dbusFocusInfo;
123 }
124
125 int ApplicationManager::rowCount(const QModelIndex &parent) const
126
127=== modified file 'miral-qt/src/modules/Unity/Application/application_manager.h'
128--- miral-qt/src/modules/Unity/Application/application_manager.h 2016-06-01 22:06:51 +0000
129+++ miral-qt/src/modules/Unity/Application/application_manager.h 2016-07-26 12:46:18 +0000
130@@ -49,6 +49,7 @@
131
132 namespace qtmir {
133
134+class DBusFocusInfo;
135 class DBusWindowStack;
136 class MirSurfaceManager;
137 class ProcInfo;
138@@ -138,6 +139,7 @@
139 Application *findApplication(MirSurfaceInterface* surface);
140
141 QList<Application*> m_applications;
142+ DBusFocusInfo *m_dbusFocusInfo;
143 DBusWindowStack* m_dbusWindowStack;
144 QSharedPointer<TaskController> m_taskController;
145 QSharedPointer<ProcInfo> m_procInfo;
146
147=== added file 'miral-qt/src/modules/Unity/Application/cgmanager.cpp'
148--- miral-qt/src/modules/Unity/Application/cgmanager.cpp 1970-01-01 00:00:00 +0000
149+++ miral-qt/src/modules/Unity/Application/cgmanager.cpp 2016-07-26 12:46:18 +0000
150@@ -0,0 +1,117 @@
151+/*
152+ * Copyright (C) 2016 Canonical, Ltd.
153+ *
154+ * This program is free software: you can redistribute it and/or modify it under
155+ * the terms of the GNU Lesser General Public License version 3, as published by
156+ * the Free Software Foundation.
157+ *
158+ * This program is distributed in the hope that it will be useful, but WITHOUT
159+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
160+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
161+ * Lesser General Public License for more details.
162+ *
163+ * You should have received a copy of the GNU Lesser General Public License
164+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
165+ */
166+
167+#include "cgmanager.h"
168+
169+// QPA mirserver
170+#include <logging.h>
171+
172+#include <cgmanager/cgmanager.h>
173+
174+#include <QDBusArgument>
175+#include <QDBusMessage>
176+
177+using namespace qtmir;
178+
179+// According to D-Bus interface defined in:
180+// https://github.com/lxc/cgmanager/blob/master/org.linuxcontainers.cgmanager.xml
181+
182+CGManager::CGManager(QObject *parent)
183+ : QObject(parent)
184+{
185+}
186+
187+CGManager::~CGManager()
188+{
189+ QDBusConnection::disconnectFromPeer("cgmanager");
190+}
191+
192+QDBusConnection CGManager::getConnection()
193+{
194+ auto connection = QDBusConnection("cgmanager");
195+
196+ if (!connection.isConnected()) {
197+ connection = QDBusConnection::connectToPeer(CGMANAGER_DBUS_PATH, "cgmanager");
198+ if (!connection.isConnected()) {
199+ qCWarning(QTMIR_DBUS, "CGManager: Failed to connect to %s", CGMANAGER_DBUS_PATH);
200+ }
201+ }
202+
203+ return connection;
204+}
205+
206+QString CGManager::getCGroupOfPid(const QString &controller, pid_t pid)
207+{
208+ auto connection = getConnection();
209+ if (!connection.isConnected()) {
210+ return QString();
211+ }
212+
213+ auto message = QDBusMessage::createMethodCall(QString() /*service*/, m_path, m_interface, "GetPidCgroup");
214+
215+ QList<QVariant> arguments;
216+ arguments << QVariant(controller);
217+ arguments << QVariant((int)pid);
218+
219+ message.setArguments(arguments);
220+
221+ QDBusMessage reply = connection.call(message);
222+
223+ if (reply.type() == QDBusMessage::ReplyMessage) {
224+ return reply.arguments()[0].toString();
225+ } else {
226+ Q_ASSERT(reply.type() == QDBusMessage::ErrorMessage);
227+ qCWarning(QTMIR_DBUS) << "CGManager::getCGroupOfPid failed." << reply.errorMessage();
228+ return QString();
229+ }
230+}
231+
232+QSet<pid_t> CGManager::getTasks(const QString &controller, const QString &cgroup)
233+{
234+ auto connection = getConnection();
235+ if (!connection.isConnected()) {
236+ return QSet<pid_t>();
237+ }
238+
239+ auto message = QDBusMessage::createMethodCall(QString() /*service*/, m_path, m_interface, "GetTasks");
240+
241+ QList<QVariant> arguments;
242+ arguments << QVariant(controller);
243+ arguments << QVariant(cgroup);
244+
245+ message.setArguments(arguments);
246+
247+ QDBusMessage reply = connection.call(message);
248+
249+ if (reply.type() == QDBusMessage::ErrorMessage) {
250+ qCWarning(QTMIR_DBUS) << "CGManager::getCGroupOfPid failed." << reply.errorMessage();
251+ return QSet<pid_t>();
252+ }
253+
254+ Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
255+
256+ auto arg = reply.arguments()[0].value<QDBusArgument>();
257+ Q_ASSERT(arg.currentType() == QDBusArgument::ArrayType);
258+
259+ auto pidList = qdbus_cast<QList<int>>(arg);
260+ Q_ASSERT(pidList.count() > 0);
261+
262+ QSet<pid_t> pidSet;
263+ for (int i = 0; i < pidList.count(); ++i) {
264+ pidSet << (pid_t)pidList[i];
265+ }
266+ return pidSet;
267+}
268
269=== added file 'miral-qt/src/modules/Unity/Application/cgmanager.h'
270--- miral-qt/src/modules/Unity/Application/cgmanager.h 1970-01-01 00:00:00 +0000
271+++ miral-qt/src/modules/Unity/Application/cgmanager.h 2016-07-26 12:46:18 +0000
272@@ -0,0 +1,42 @@
273+/*
274+ * Copyright (C) 2016 Canonical, Ltd.
275+ *
276+ * This program is free software: you can redistribute it and/or modify it under
277+ * the terms of the GNU Lesser General Public License version 3, as published by
278+ * the Free Software Foundation.
279+ *
280+ * This program is distributed in the hope that it will be useful, but WITHOUT
281+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
282+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
283+ * Lesser General Public License for more details.
284+ *
285+ * You should have received a copy of the GNU Lesser General Public License
286+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
287+ */
288+
289+#ifndef QTMIR_CGMANAGER_H
290+#define QTMIR_CGMANAGER_H
291+
292+#include <QDBusConnection>
293+
294+namespace qtmir {
295+
296+class CGManager : public QObject {
297+ Q_OBJECT
298+public:
299+ CGManager(QObject *parent = nullptr);
300+ virtual ~CGManager();
301+
302+ QString getCGroupOfPid(const QString &controller, pid_t pid);
303+
304+ QSet<pid_t> getTasks(const QString &controller, const QString &cgroup);
305+
306+private:
307+ const QString m_interface{"org.linuxcontainers.cgmanager0_0"};
308+ const QString m_path{"/org/linuxcontainers/cgmanager"};
309+ QDBusConnection getConnection();
310+};
311+
312+} // namespace qtmir
313+
314+#endif // QTMIR_CGMANAGER_H
315
316=== added file 'miral-qt/src/modules/Unity/Application/dbusfocusinfo.cpp'
317--- miral-qt/src/modules/Unity/Application/dbusfocusinfo.cpp 1970-01-01 00:00:00 +0000
318+++ miral-qt/src/modules/Unity/Application/dbusfocusinfo.cpp 2016-07-26 12:46:18 +0000
319@@ -0,0 +1,89 @@
320+/*
321+ * Copyright (C) 2016 Canonical, Ltd.
322+ *
323+ * This program is free software: you can redistribute it and/or modify it under
324+ * the terms of the GNU Lesser General Public License version 3, as published by
325+ * the Free Software Foundation.
326+ *
327+ * This program is distributed in the hope that it will be useful, but WITHOUT
328+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
329+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
330+ * Lesser General Public License for more details.
331+ *
332+ * You should have received a copy of the GNU Lesser General Public License
333+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
334+ */
335+
336+#include "dbusfocusinfo.h"
337+
338+// local
339+#include "cgmanager.h"
340+
341+// QPA mirserver
342+#include <logging.h>
343+
344+#include <QDBusConnection>
345+
346+using namespace qtmir;
347+
348+DBusFocusInfo::DBusFocusInfo(const QList<Application*> &applications)
349+ : m_applications(applications)
350+{
351+ QDBusConnection::sessionBus().registerService("com.canonical.Unity.FocusInfo");
352+ QDBusConnection::sessionBus().registerObject("/com/canonical/Unity/FocusInfo", this, QDBusConnection::ExportScriptableSlots);
353+
354+ m_cgManager = new CGManager(this);
355+}
356+
357+bool DBusFocusInfo::isPidFocused(unsigned int pid)
358+{
359+ if (QCoreApplication::applicationPid() == (qint64)pid) {
360+ // Shell itself.
361+ // Don't bother checking if it has a QML with activeFocus() which is not a MirSurfaceItem.
362+ return true;
363+ } else {
364+ auto pidSet = fetchAssociatedPids((pid_t)pid);
365+ SessionInterface *session = findSessionWithPid(pidSet);
366+ return session ? session->activeFocus() : false;
367+ }
368+}
369+
370+QSet<pid_t> DBusFocusInfo::fetchAssociatedPids(pid_t pid)
371+{
372+ QString cgroup = m_cgManager->getCGroupOfPid("freezer", pid);
373+
374+ // If a cgroup has a format like this:
375+ // /user.slice/user-32011.slice/session-c3.scope/upstart/application-legacy-puritine_gedit_0.0-
376+ // All PIds in it are associated with a single application.
377+ if (cgroup.split("/").contains("upstart")) {
378+ QSet<pid_t> pidSet = m_cgManager->getTasks("freezer", cgroup);
379+ qCDebug(QTMIR_DBUS) << "DBusFocusInfo: pid" << pid << "is in cgroup" << cgroup << "along with:" << pidSet;
380+ if (pidSet.isEmpty()) {
381+ pidSet << pid;
382+ }
383+ return pidSet;
384+ } else {
385+ qCDebug(QTMIR_DBUS) << "DBusFocusInfo: pid" << pid << "is in cgroup" << cgroup << "which is not app-specific";
386+ return QSet<pid_t>({pid});
387+ }
388+}
389+
390+SessionInterface* DBusFocusInfo::findSessionWithPid(const QSet<pid_t> &pidSet)
391+{
392+ Q_FOREACH (Application* application, m_applications) {
393+ auto session = application->session();
394+ if (pidSet.contains(session->pid())) {
395+ return session;
396+ }
397+ SessionInterface *chosenChildSession = nullptr;
398+ session->foreachChildSession([&](SessionInterface* childSession) {
399+ if (pidSet.contains(childSession->pid())) {
400+ chosenChildSession = childSession;
401+ }
402+ });
403+ if (chosenChildSession) {
404+ return chosenChildSession;
405+ }
406+ }
407+ return nullptr;
408+}
409
410=== added file 'miral-qt/src/modules/Unity/Application/dbusfocusinfo.h'
411--- miral-qt/src/modules/Unity/Application/dbusfocusinfo.h 1970-01-01 00:00:00 +0000
412+++ miral-qt/src/modules/Unity/Application/dbusfocusinfo.h 2016-07-26 12:46:18 +0000
413@@ -0,0 +1,54 @@
414+/*
415+ * Copyright (C) 2016 Canonical, Ltd.
416+ *
417+ * This program is free software: you can redistribute it and/or modify it under
418+ * the terms of the GNU Lesser General Public License version 3, as published by
419+ * the Free Software Foundation.
420+ *
421+ * This program is distributed in the hope that it will be useful, but WITHOUT
422+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
423+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
424+ * Lesser General Public License for more details.
425+ *
426+ * You should have received a copy of the GNU Lesser General Public License
427+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
428+ */
429+
430+#include <QList>
431+#include <QSet>
432+
433+#include "application.h"
434+
435+namespace qtmir {
436+
437+class CGManager;
438+
439+/*
440+ FIXME: This is a hack to provide OSK with needed info for avoiding input snooping.
441+ Remove when possible
442+ */
443+class DBusFocusInfo : public QObject
444+{
445+ Q_OBJECT
446+ Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity.FocusInfo")
447+public:
448+ explicit DBusFocusInfo(const QList<Application*> &applications);
449+ virtual ~DBusFocusInfo() {}
450+
451+public Q_SLOTS:
452+
453+ /*
454+ Returns true if the application with the given PID has input focus
455+ */
456+ Q_SCRIPTABLE bool isPidFocused(unsigned int pid);
457+
458+private:
459+ QSet<pid_t> fetchAssociatedPids(pid_t pid);
460+ SessionInterface* findSessionWithPid(const QSet<pid_t> &pidSet);
461+
462+ const QList<Application*> &m_applications;
463+
464+ CGManager *m_cgManager;
465+};
466+
467+} // namespace qtmir
468
469=== modified file 'miral-qt/src/modules/Unity/Application/mirsurface.cpp'
470--- miral-qt/src/modules/Unity/Application/mirsurface.cpp 2016-07-25 13:48:41 +0000
471+++ miral-qt/src/modules/Unity/Application/mirsurface.cpp 2016-07-26 12:46:18 +0000
472@@ -219,6 +219,7 @@
473 connect(observer.get(), &SurfaceObserver::shellChromeChanged, this, [&](MirShellChrome shell_chrome) {
474 setShellChrome(static_cast<Mir::ShellChrome>(shell_chrome));
475 });
476+ connect(observer.get(), &SurfaceObserver::inputBoundsChanged, this, &MirSurface::setInputBounds);
477 observer->setListener(this);
478 }
479
480@@ -277,12 +278,15 @@
481 {
482 switch (attribute) {
483 case mir_surface_attrib_type:
484+ DEBUG_MSG << " type = " << mirSurfaceTypeToStr(state());
485 Q_EMIT typeChanged(type());
486 break;
487 case mir_surface_attrib_state:
488+ DEBUG_MSG << " state = " << mirSurfaceStateToStr(state());
489 Q_EMIT stateChanged(state());
490 break;
491 case mir_surface_attrib_visibility:
492+ DEBUG_MSG << " visible = " << visible();
493 Q_EMIT visibleChanged(visible());
494 break;
495 default:
496@@ -453,6 +457,11 @@
497 }
498 }
499
500+bool MirSurface::activeFocus() const
501+{
502+ return !m_activelyFocusedViews.empty();
503+}
504+
505 void MirSurface::updateActiveFocus()
506 {
507 if (!m_session) {
508@@ -871,6 +880,24 @@
509 }
510 }
511
512+bool MirSurface::inputAreaContains(const QPoint &point) const
513+{
514+ bool result;
515+
516+
517+ // Can't use it due to https://bugs.launchpad.net/mir/+bug/1598936
518+ // FIXME: Use the line below instead of m_inputBounds once this bug gets fixed.
519+ //result = m_surface->input_area_contains(mir::geometry::Point(point.x(), point.y()));
520+
521+ if (m_inputBounds.isNull()) {
522+ result = true;
523+ } else {
524+ result = m_inputBounds.contains(point);
525+ }
526+
527+ return result;
528+}
529+
530 void MirSurface::setCursor(const QCursor &cursor)
531 {
532 DEBUG_MSG << "(" << qtCursorShapeToStr(cursor.shape()) << ")";
533@@ -962,6 +989,11 @@
534 return m_focused;
535 }
536
537+QRect MirSurface::inputBounds() const
538+{
539+ return m_inputBounds;
540+}
541+
542 void MirSurface::requestFocus()
543 {
544 DEBUG_MSG << "()";
545@@ -1003,3 +1035,12 @@
546 m_closeTimer->start();
547 }
548 }
549+
550+void MirSurface::setInputBounds(const QRect &rect)
551+{
552+ if (m_inputBounds != rect) {
553+ DEBUG_MSG << "(" << rect << ")";
554+ m_inputBounds = rect;
555+ Q_EMIT inputBoundsChanged(m_inputBounds);
556+ }
557+}
558
559=== modified file 'miral-qt/src/modules/Unity/Application/mirsurface.h'
560--- miral-qt/src/modules/Unity/Application/mirsurface.h 2016-07-25 13:48:41 +0000
561+++ miral-qt/src/modules/Unity/Application/mirsurface.h 2016-07-26 12:46:18 +0000
562@@ -24,6 +24,7 @@
563 #include <QCursor>
564 #include <QMutex>
565 #include <QPointer>
566+#include <QRect>
567 #include <QSharedPointer>
568 #include <QWeakPointer>
569 #include <QSet>
570@@ -89,6 +90,7 @@
571 int heightIncrement() const override;
572
573 bool focused() const override;
574+ QRect inputBounds() const override;
575
576 Q_INVOKABLE void requestFocus() override;
577 Q_INVOKABLE void close() override;
578@@ -121,6 +123,7 @@
579 void setFocused(bool focus) override;
580
581 void setViewActiveFocus(qintptr viewId, bool value) override;
582+ bool activeFocus() const override;
583
584 void mousePressEvent(QMouseEvent *event) override;
585 void mouseMoveEvent(QMouseEvent *event) override;
586@@ -149,6 +152,8 @@
587
588 SessionInterface* session() override { return m_session.data(); }
589
590+ bool inputAreaContains(const QPoint &) const override;
591+
592 ////
593 // Own API
594
595@@ -174,6 +179,7 @@
596 void emitSizeChanged();
597 void setCursor(const QCursor &cursor);
598 void onCloseTimedOut();
599+ void setInputBounds(const QRect &rect);
600
601 private:
602 void syncSurfaceSizeWithItemSize();
603@@ -223,6 +229,8 @@
604 int m_widthIncrement{0};
605 int m_heightIncrement{0};
606
607+ QRect m_inputBounds;
608+
609 bool m_focused{false};
610
611 enum ClosingState {
612
613=== modified file 'miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h'
614--- miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h 2016-07-25 13:48:41 +0000
615+++ miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h 2016-07-26 12:46:18 +0000
616@@ -77,6 +77,10 @@
617 the name.
618 */
619 virtual void setViewActiveFocus(qintptr viewId, bool value) = 0;
620+ /*
621+ Whether any view of this surface currently has QML active focus
622+ */
623+ virtual bool activeFocus() const = 0;
624
625 virtual void mousePressEvent(QMouseEvent *event) = 0;
626 virtual void mouseMoveEvent(QMouseEvent *event) = 0;
627@@ -100,6 +104,8 @@
628
629 virtual SessionInterface* session() = 0;
630
631+ virtual bool inputAreaContains(const QPoint &) const = 0;
632+
633 public Q_SLOTS:
634 virtual void onCompositorSwappedBuffers() = 0;
635
636
637=== modified file 'miral-qt/src/modules/Unity/Application/mirsurfaceitem.cpp'
638--- miral-qt/src/modules/Unity/Application/mirsurfaceitem.cpp 2016-07-25 13:48:41 +0000
639+++ miral-qt/src/modules/Unity/Application/mirsurfaceitem.cpp 2016-07-26 12:46:18 +0000
640@@ -20,7 +20,6 @@
641 #include "mirsurfaceitem.h"
642 #include "mirfocuscontroller.h"
643 #include "logging.h"
644-#include "ubuntukeyboardinfo.h"
645 #include "tracepoints.h" // generated from tracepoints.tp
646 #include "timestamp.h"
647
648@@ -103,10 +102,6 @@
649 setSmooth(true);
650 setFlag(QQuickItem::ItemHasContents, true); //so scene graph will render this item
651
652- if (!UbuntuKeyboardInfo::instance()) {
653- new UbuntuKeyboardInfo;
654- }
655-
656 m_updateMirSurfaceSizeTimer.setSingleShot(true);
657 m_updateMirSurfaceSizeTimer.setInterval(1);
658 connect(&m_updateMirSurfaceSizeTimer, &QTimer::timeout, this, &MirSurfaceItem::updateMirSurfaceSize);
659@@ -290,17 +285,9 @@
660
661 void MirSurfaceItem::mousePressEvent(QMouseEvent *event)
662 {
663- if (m_consumesInput && m_surface && m_surface->live()) {
664- if (type() == Mir::InputMethodType) {
665- // FIXME: Hack to get the VKB use case working while we don't have the proper solution in place.
666- if (isMouseInsideUbuntuKeyboard(event)) {
667- m_surface->mousePressEvent(event);
668- } else {
669- event->ignore();
670- }
671- } else {
672- m_surface->mousePressEvent(event);
673- }
674+ auto mousePos = event->localPos().toPoint();
675+ if (m_consumesInput && m_surface && m_surface->live() && m_surface->inputAreaContains(mousePos)) {
676+ m_surface->mousePressEvent(event);
677 } else {
678 event->ignore();
679 }
680@@ -471,51 +458,26 @@
681 return false;
682 }
683
684- bool accepted = true;
685- if (type() == Mir::InputMethodType && eventType == QEvent::TouchBegin) {
686- // FIXME: Hack to get the VKB use case working while we don't have the proper solution in place.
687- if (hasTouchInsideUbuntuKeyboard(touchPoints)) {
688- validateAndDeliverTouchEvent(eventType, timestamp, mods, touchPoints, touchPointStates);
689- } else {
690- accepted = false;
691- }
692-
693- } else {
694- // NB: If we are getting QEvent::TouchUpdate or QEvent::TouchEnd it's because we've
695- // previously accepted the corresponding QEvent::TouchBegin
696- validateAndDeliverTouchEvent(eventType, timestamp, mods, touchPoints, touchPointStates);
697+ if (eventType == QEvent::TouchBegin && !hasTouchInsideInputRegion(touchPoints)) {
698+ return false;
699 }
700- return accepted;
701+
702+ validateAndDeliverTouchEvent(eventType, timestamp, mods, touchPoints, touchPointStates);
703+
704+ return true;
705 }
706
707-bool MirSurfaceItem::hasTouchInsideUbuntuKeyboard(const QList<QTouchEvent::TouchPoint> &touchPoints)
708+bool MirSurfaceItem::hasTouchInsideInputRegion(const QList<QTouchEvent::TouchPoint> &touchPoints)
709 {
710- UbuntuKeyboardInfo *ubuntuKeyboardInfo = UbuntuKeyboardInfo::instance();
711-
712 for (int i = 0; i < touchPoints.count(); ++i) {
713 QPoint pos = touchPoints.at(i).pos().toPoint();
714- if (pos.x() >= ubuntuKeyboardInfo->x()
715- && pos.x() <= (ubuntuKeyboardInfo->x() + ubuntuKeyboardInfo->width())
716- && pos.y() >= ubuntuKeyboardInfo->y()
717- && pos.y() <= (ubuntuKeyboardInfo->y() + ubuntuKeyboardInfo->height())) {
718+ if (m_surface->inputAreaContains(pos)) {
719 return true;
720 }
721 }
722 return false;
723 }
724
725-bool MirSurfaceItem::isMouseInsideUbuntuKeyboard(const QMouseEvent *event)
726-{
727- UbuntuKeyboardInfo *ubuntuKeyboardInfo = UbuntuKeyboardInfo::instance();
728-
729- const QPointF &pos = event->localPos();
730-
731- return pos.x() >= ubuntuKeyboardInfo->x()
732- && pos.x() <= (ubuntuKeyboardInfo->x() + ubuntuKeyboardInfo->width())
733- && pos.y() >= ubuntuKeyboardInfo->y()
734- && pos.y() <= (ubuntuKeyboardInfo->y() + ubuntuKeyboardInfo->height());
735-}
736-
737 Mir::State MirSurfaceItem::surfaceState() const
738 {
739 if (m_surface) {
740
741=== modified file 'miral-qt/src/modules/Unity/Application/mirsurfaceitem.h'
742--- miral-qt/src/modules/Unity/Application/mirsurfaceitem.h 2016-07-25 13:48:41 +0000
743+++ miral-qt/src/modules/Unity/Application/mirsurfaceitem.h 2016-07-26 12:46:18 +0000
744@@ -126,8 +126,7 @@
745 private:
746 void ensureTextureProvider();
747
748- bool hasTouchInsideUbuntuKeyboard(const QList<QTouchEvent::TouchPoint> &touchPoints);
749- bool isMouseInsideUbuntuKeyboard(const QMouseEvent *event);
750+ bool hasTouchInsideInputRegion(const QList<QTouchEvent::TouchPoint> &touchPoints);
751
752 QString appId() const;
753 void endCurrentTouchSequence(ulong timestamp);
754
755=== modified file 'miral-qt/src/modules/Unity/Application/plugin.cpp'
756--- miral-qt/src/modules/Unity/Application/plugin.cpp 2016-06-01 22:06:51 +0000
757+++ miral-qt/src/modules/Unity/Application/plugin.cpp 2016-07-26 12:46:18 +0000
758@@ -25,7 +25,6 @@
759 #include "mirsurfaceinterface.h"
760 #include "mirsurfaceitem.h"
761 #include "mirsurfacelistmodel.h"
762-#include "ubuntukeyboardinfo.h"
763
764 // platforms/mirserver
765 #include <mirsingleton.h>
766@@ -55,13 +54,6 @@
767 return qtmir::MirSurfaceManager::singleton();
768 }
769
770-QObject* ubuntuKeyboardInfoSingleton(QQmlEngine* /*engine*/, QJSEngine* /*scriptEngine*/) {
771- if (!UbuntuKeyboardInfo::instance()) {
772- new UbuntuKeyboardInfo;
773- }
774- return UbuntuKeyboardInfo::instance();
775-}
776-
777 QObject* mirSingleton(QQmlEngine* /*engine*/, QJSEngine* /*scriptEngine*/) {
778 return qtmir::Mir::instance();
779 }
780@@ -101,8 +93,6 @@
781 qmlRegisterUncreatableType<unity::shell::application::MirSurfaceInterface>(
782 uri, 0, 1, "MirSurface", "MirSurface can't be instantiated from QML");
783 qmlRegisterType<qtmir::MirSurfaceItem>(uri, 0, 1, "MirSurfaceItem");
784- qmlRegisterSingletonType<qtmir::UbuntuKeyboardInfo>(
785- uri, 0, 1, "UbuntuKeyboardInfo", ubuntuKeyboardInfoSingleton);
786 qmlRegisterSingletonType<qtmir::Mir>(uri, 0, 1, "Mir", mirSingleton);
787 }
788
789
790=== modified file 'miral-qt/src/modules/Unity/Application/session.cpp'
791--- miral-qt/src/modules/Unity/Application/session.cpp 2016-06-21 13:38:53 +0000
792+++ miral-qt/src/modules/Unity/Application/session.cpp 2016-07-26 12:46:18 +0000
793@@ -514,6 +514,23 @@
794 return m_hadSurface;
795 }
796
797+bool Session::activeFocus() const
798+{
799+ for (int i = 0; i < m_surfaceList.count(); ++i) {
800+ auto surface = static_cast<const MirSurfaceInterface*>(m_surfaceList.get(i));
801+ if (surface->activeFocus()) {
802+ return true;
803+ }
804+ }
805+
806+ return false;
807+}
808+
809+pid_t Session::pid() const
810+{
811+ return m_session->process_id();
812+}
813+
814 void Session::setSuspendTimer(AbstractTimer *timer)
815 {
816 bool timerWasRunning = false;
817
818=== modified file 'miral-qt/src/modules/Unity/Application/session.h'
819--- miral-qt/src/modules/Unity/Application/session.h 2016-06-01 22:06:51 +0000
820+++ miral-qt/src/modules/Unity/Application/session.h 2016-07-26 12:46:18 +0000
821@@ -67,6 +67,10 @@
822 bool hadSurface() const override;
823 bool hasClosingSurfaces() const override;
824
825+ bool activeFocus() const override;
826+
827+ pid_t pid() const override;
828+
829 void addChildSession(SessionInterface* session) override;
830 void insertChildSession(uint index, SessionInterface* session) override;
831 void removeChildSession(SessionInterface* session) override;
832
833=== modified file 'miral-qt/src/modules/Unity/Application/session_interface.h'
834--- miral-qt/src/modules/Unity/Application/session_interface.h 2016-06-01 22:06:51 +0000
835+++ miral-qt/src/modules/Unity/Application/session_interface.h 2016-07-26 12:46:18 +0000
836@@ -92,6 +92,12 @@
837 virtual bool hadSurface() const = 0; // whether this session ever had any surface (currently or in the past)
838 virtual bool hasClosingSurfaces() const = 0; // whether it has surfaces being forcibly closed
839
840+ // Whether any of its MirSurfaces has activeFocus()
841+ // See qtmir::MirSurfaceInterface::activeFocus
842+ virtual bool activeFocus() const = 0;
843+
844+ virtual pid_t pid() const = 0;
845+
846 // For SessionManager use
847
848 virtual void addChildSession(SessionInterface* session) = 0;
849
850=== removed file 'miral-qt/src/modules/Unity/Application/ubuntukeyboardinfo.cpp'
851--- miral-qt/src/modules/Unity/Application/ubuntukeyboardinfo.cpp 2016-06-21 13:38:53 +0000
852+++ miral-qt/src/modules/Unity/Application/ubuntukeyboardinfo.cpp 1970-01-01 00:00:00 +0000
853@@ -1,173 +0,0 @@
854-/*
855- * Copyright (C) 2013-2015 Canonical, Ltd.
856- *
857- * This program is free software: you can redistribute it and/or modify it under
858- * the terms of the GNU Lesser General Public License version 3, as published by
859- * the Free Software Foundation.
860- *
861- * This program is distributed in the hope that it will be useful, but WITHOUT
862- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
863- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
864- * Lesser General Public License for more details.
865- *
866- * You should have received a copy of the GNU Lesser General Public License
867- * along with this program. If not, see <http://www.gnu.org/licenses/>.
868- */
869-
870-#include "ubuntukeyboardinfo.h"
871-
872-#include <QDir>
873-
874-namespace qtmir {
875-
876-namespace {
877- const int gConnectionAttemptIntervalMs = 5000;
878- const int gMaxConsecutiveAttempts = 10;
879- const char gServerName[] = "ubuntu-keyboard-info";
880-}
881-
882-UbuntuKeyboardInfo* UbuntuKeyboardInfo::m_instance = nullptr;
883-
884-UbuntuKeyboardInfo* UbuntuKeyboardInfo::instance()
885-{
886- return m_instance;
887-}
888-
889-UbuntuKeyboardInfo::UbuntuKeyboardInfo(QObject *parent)
890- : QObject(parent),
891- m_consecutiveAttempts(0),
892- m_lastX(0),
893- m_lastY(0),
894- m_lastWidth(0),
895- m_lastHeight(0)
896-{
897- if (m_instance) {
898- qFatal("Cannot have more than one instance of UbuntuKeyboardInfo simultaneously.");
899- }
900- m_instance = this;
901-
902- connect(&m_socket, &QLocalSocket::stateChanged, this, &UbuntuKeyboardInfo::onSocketStateChanged);
903- connect(&m_socket, &QIODevice::readyRead,
904- this, &UbuntuKeyboardInfo::readAllBytesFromSocket);
905-
906- buildSocketFilePath();
907-
908- typedef void (QLocalSocket::*MemberFunctionType)(QLocalSocket::LocalSocketError);
909- MemberFunctionType funcPointer = &QLocalSocket::error;
910- connect(&m_socket, funcPointer,
911- this, &UbuntuKeyboardInfo::onSocketError);
912-
913- m_connectionRetryTimer.setInterval(gConnectionAttemptIntervalMs);
914- m_connectionRetryTimer.setSingleShot(true);
915- connect(&m_connectionRetryTimer, &QTimer::timeout,
916- this, &UbuntuKeyboardInfo::tryConnectingToServer);
917- tryConnectingToServer();
918-}
919-
920-UbuntuKeyboardInfo::~UbuntuKeyboardInfo()
921-{
922- // Make sure we don't get onSocketStateChanged() called during
923- // destruction.
924- m_socket.disconnect(this);
925-
926- Q_ASSERT(m_instance);
927- m_instance = nullptr;
928-}
929-
930-void UbuntuKeyboardInfo::tryConnectingToServer()
931-{
932- ++m_consecutiveAttempts;
933- Q_ASSERT(!m_socketFilePath.isEmpty());
934- m_socket.connectToServer(m_socketFilePath, QIODevice::ReadOnly);
935-}
936-
937-void UbuntuKeyboardInfo::onSocketStateChanged(QLocalSocket::LocalSocketState socketState)
938-{
939- switch (socketState) {
940- case QLocalSocket::UnconnectedState:
941- retryConnection();
942- break;
943- case QLocalSocket::ConnectedState:
944- m_consecutiveAttempts = 0;
945- break;
946- default:
947- break;
948- }
949-}
950-
951-void UbuntuKeyboardInfo::onSocketError(QLocalSocket::LocalSocketError socketError)
952-{
953- Q_UNUSED(socketError);
954- qWarning() << "UbuntuKeyboardInfo - socket error:" << m_socket.errorString();
955-}
956-
957-void UbuntuKeyboardInfo::retryConnection()
958-{
959- // Polling every gConnectionAttemptIntervalMs. Not the best approach but could be worse.
960- if (m_consecutiveAttempts < gMaxConsecutiveAttempts) {
961- if (!m_connectionRetryTimer.isActive()) {
962- m_connectionRetryTimer.start();
963- }
964- } else {
965- qCritical() << "Failed to connect to" << m_socketFilePath << "after"
966- << m_consecutiveAttempts << "failed attempts";
967-
968- // it shouldn't be running, but just to be sure.
969- m_connectionRetryTimer.stop();
970- }
971-}
972-
973-void UbuntuKeyboardInfo::readAllBytesFromSocket()
974-{
975- while (m_socket.bytesAvailable() > 0) {
976- readInfoFromSocket();
977- }
978-}
979-
980-void UbuntuKeyboardInfo::readInfoFromSocket()
981-{
982- const size_t sharedInfoSize = sizeof(struct SharedInfo);
983- QByteArray bytes = m_socket.read(sharedInfoSize);
984- if (bytes.size() != sharedInfoSize) {
985- qWarning() << "UbuntuKeyboardInfo: expected to receive" << sharedInfoSize
986- << "but got" << bytes.size();
987- return;
988- }
989-
990- {
991- struct SharedInfo *sharedInfo = reinterpret_cast<struct SharedInfo*>(bytes.data());
992-
993- if (m_lastX != sharedInfo->keyboardX) {
994- m_lastX = sharedInfo->keyboardX;
995- Q_EMIT xChanged(m_lastX);
996- }
997-
998- if (m_lastY != sharedInfo->keyboardY) {
999- m_lastY = sharedInfo->keyboardY;
1000- Q_EMIT yChanged(m_lastY);
1001- }
1002-
1003- if (m_lastWidth != sharedInfo->keyboardWidth) {
1004- m_lastWidth = sharedInfo->keyboardWidth;
1005- Q_EMIT widthChanged(m_lastWidth);
1006- }
1007-
1008- if (m_lastHeight != sharedInfo->keyboardHeight) {
1009- m_lastHeight = sharedInfo->keyboardHeight;
1010- Q_EMIT heightChanged(m_lastHeight);
1011- }
1012- }
1013-}
1014-
1015-void UbuntuKeyboardInfo::buildSocketFilePath()
1016-{
1017- char *xdgRuntimeDir = getenv("XDG_RUNTIME_DIR");
1018-
1019- if (xdgRuntimeDir) {
1020- m_socketFilePath = QDir(xdgRuntimeDir).filePath(gServerName);
1021- } else {
1022- m_socketFilePath = QDir("/tmp").filePath(gServerName);
1023- }
1024-}
1025-
1026-} // namespace qtmir
1027
1028=== removed file 'miral-qt/src/modules/Unity/Application/ubuntukeyboardinfo.h'
1029--- miral-qt/src/modules/Unity/Application/ubuntukeyboardinfo.h 2016-06-01 22:06:51 +0000
1030+++ miral-qt/src/modules/Unity/Application/ubuntukeyboardinfo.h 1970-01-01 00:00:00 +0000
1031@@ -1,87 +0,0 @@
1032-/*
1033- * Copyright (C) 2013-2015 Canonical, Ltd.
1034- *
1035- * This program is free software: you can redistribute it and/or modify it under
1036- * the terms of the GNU Lesser General Public License version 3, as published by
1037- * the Free Software Foundation.
1038- *
1039- * This program is distributed in the hope that it will be useful, but WITHOUT
1040- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1041- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1042- * Lesser General Public License for more details.
1043- *
1044- * You should have received a copy of the GNU Lesser General Public License
1045- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1046- */
1047-
1048-#ifndef UBUNTU_KEYBOARD_INFO_H
1049-#define UBUNTU_KEYBOARD_INFO_H
1050-
1051-#include <QLocalSocket>
1052-#include <QTimer>
1053-
1054-namespace qtmir {
1055-
1056-// Temporary solution to get information about the onscreen keyboard
1057-// This shouldn't be needed once the OSK is a properly sized surface
1058-// instead of a fullscreen one.
1059-class UbuntuKeyboardInfo : public QObject {
1060- Q_OBJECT
1061- Q_PROPERTY(qreal x READ x NOTIFY xChanged)
1062- Q_PROPERTY(qreal y READ y NOTIFY yChanged)
1063- Q_PROPERTY(qreal width READ width NOTIFY widthChanged)
1064- Q_PROPERTY(qreal height READ height NOTIFY heightChanged)
1065-public:
1066- UbuntuKeyboardInfo(QObject *parent = 0);
1067- virtual ~UbuntuKeyboardInfo();
1068-
1069- static UbuntuKeyboardInfo* instance();
1070-
1071- qreal x() const { return m_lastX; }
1072- qreal y() const { return m_lastY; }
1073- qreal width() const { return m_lastWidth; }
1074- qreal height() const { return m_lastHeight; }
1075-
1076-Q_SIGNALS:
1077- void xChanged(qreal x);
1078- void yChanged(qreal y);
1079- void widthChanged(qreal width);
1080- void heightChanged(qreal height);
1081-
1082-private Q_SLOTS:
1083- void tryConnectingToServer();
1084- void onSocketStateChanged(QLocalSocket::LocalSocketState socketState);
1085- void onSocketError(QLocalSocket::LocalSocketError socketError);
1086- void readAllBytesFromSocket();
1087-
1088-private:
1089- // NB! Must match the definition in ubuntu-keyboard. Not worth creating a shared header
1090- // just for that.
1091- struct SharedInfo {
1092- qint32 keyboardX;
1093- qint32 keyboardY;
1094- qint32 keyboardWidth;
1095- qint32 keyboardHeight;
1096- };
1097- void readInfoFromSocket();
1098- void retryConnection();
1099- void buildSocketFilePath();
1100-
1101- int m_consecutiveAttempts;
1102-
1103- QLocalSocket m_socket;
1104- qint32 m_lastX;
1105- qint32 m_lastY;
1106- qint32 m_lastWidth;
1107- qint32 m_lastHeight;
1108- QTimer m_connectionRetryTimer;
1109-
1110- // Path to the socket file created by ubuntu-keyboard
1111- QString m_socketFilePath;
1112-
1113- static UbuntuKeyboardInfo* m_instance;
1114-};
1115-
1116-} // namespace qtmir
1117-
1118-#endif // UBUNTU_KEYBOARD_INFO_H
1119
1120=== modified file 'miral-qt/src/platforms/mirserver/logging.cpp'
1121--- miral-qt/src/platforms/mirserver/logging.cpp 2016-06-01 22:06:51 +0000
1122+++ miral-qt/src/platforms/mirserver/logging.cpp 2016-07-26 12:46:18 +0000
1123@@ -24,3 +24,4 @@
1124 Q_LOGGING_CATEGORY(QTMIR_CLIPBOARD, "qtmir.clipboard")
1125 Q_LOGGING_CATEGORY(QTMIR_SENSOR_MESSAGES, "qtmir.sensor")
1126 Q_LOGGING_CATEGORY(QTMIR_SCREENS, "qtmir.screens")
1127+Q_LOGGING_CATEGORY(QTMIR_DBUS, "qtmir.dbus", QtWarningMsg)
1128
1129=== modified file 'miral-qt/src/platforms/mirserver/logging.h'
1130--- miral-qt/src/platforms/mirserver/logging.h 2016-06-01 22:06:51 +0000
1131+++ miral-qt/src/platforms/mirserver/logging.h 2016-07-26 12:46:18 +0000
1132@@ -26,5 +26,6 @@
1133 Q_DECLARE_LOGGING_CATEGORY(QTMIR_MIR_INPUT)
1134 Q_DECLARE_LOGGING_CATEGORY(QTMIR_CLIPBOARD)
1135 Q_DECLARE_LOGGING_CATEGORY(QTMIR_SCREENS)
1136+Q_DECLARE_LOGGING_CATEGORY(QTMIR_DBUS)
1137
1138 #endif // UBUNTU_APPLICATION_PLUGIN_LOGGING_H
1139
1140=== modified file 'miral-qt/src/platforms/mirserver/mirwindowmanager.cpp'
1141--- miral-qt/src/platforms/mirserver/mirwindowmanager.cpp 2016-06-07 18:03:38 +0000
1142+++ miral-qt/src/platforms/mirserver/mirwindowmanager.cpp 2016-07-26 12:46:18 +0000
1143@@ -197,14 +197,19 @@
1144 const mir::shell::SurfaceSpecification& modifications)
1145 {
1146 QMutexLocker lock(&SurfaceObserver::mutex);
1147+
1148+ if (modifications.name.is_set()) {
1149+ surface->rename(modifications.name.value());
1150+ }
1151+
1152+ if (modifications.input_shape.is_set()) {
1153+ surface->set_input_region(modifications.input_shape.value());
1154+ }
1155+
1156 SurfaceObserver *observer = SurfaceObserver::observerForSurface(surface.get());
1157 if (observer) {
1158 observer->notifySurfaceModifications(modifications);
1159 }
1160-
1161- if (modifications.name.is_set()) {
1162- surface->rename(modifications.name.value());
1163- }
1164 }
1165
1166 std::shared_ptr<MirWindowManager> MirWindowManager::create(
1167
1168=== modified file 'miral-qt/src/platforms/mirserver/surfaceobserver.cpp'
1169--- miral-qt/src/platforms/mirserver/surfaceobserver.cpp 2016-06-01 22:06:51 +0000
1170+++ miral-qt/src/platforms/mirserver/surfaceobserver.cpp 2016-07-26 12:46:18 +0000
1171@@ -28,6 +28,22 @@
1172 #include <mir/geometry/size.h>
1173 #include <mir/shell/surface_specification.h>
1174
1175+namespace {
1176+
1177+QRect calculateBoundingRect(const std::vector<mir::geometry::Rectangle> &rectVector)
1178+{
1179+ QRect boundingRect;
1180+ for (auto mirRect : rectVector) {
1181+ boundingRect |= QRect(mirRect.top_left.x.as_int(),
1182+ mirRect.top_left.y.as_int(),
1183+ mirRect.size.width.as_int(),
1184+ mirRect.size.height.as_int());
1185+ }
1186+ return boundingRect;
1187+}
1188+
1189+} // anonymous namespace
1190+
1191 QMap<const mir::scene::Surface*, SurfaceObserver*> SurfaceObserver::m_surfaceToObserverMap;
1192 QMutex SurfaceObserver::mutex;
1193
1194@@ -154,6 +170,10 @@
1195 if (modifications.shell_chrome.is_set()) {
1196 Q_EMIT shellChromeChanged(modifications.shell_chrome.value());
1197 }
1198+ if (modifications.input_shape.is_set()) {
1199+ QRect qRect = calculateBoundingRect(modifications.input_shape.value());
1200+ Q_EMIT inputBoundsChanged(qRect);
1201+ }
1202 }
1203
1204 SurfaceObserver *SurfaceObserver::observerForSurface(const mir::scene::Surface *surface)
1205
1206=== modified file 'miral-qt/src/platforms/mirserver/surfaceobserver.h'
1207--- miral-qt/src/platforms/mirserver/surfaceobserver.h 2016-06-01 22:06:51 +0000
1208+++ miral-qt/src/platforms/mirserver/surfaceobserver.h 2016-07-26 12:46:18 +0000
1209@@ -1,5 +1,5 @@
1210 /*
1211- * Copyright (C) 2014-2015 Canonical, Ltd.
1212+ * Copyright (C) 2014-2016 Canonical, Ltd.
1213 *
1214 * This program is free software: you can redistribute it and/or modify it under
1215 * the terms of the GNU Lesser General Public License version 3, as published by
1216@@ -22,6 +22,7 @@
1217 #include <QObject>
1218 #include <QMap>
1219 #include <QMutex>
1220+#include <QRect>
1221 #include <QSize>
1222 #include <mir/scene/surface_observer.h>
1223
1224@@ -84,6 +85,7 @@
1225 void widthIncrementChanged(int);
1226 void heightIncrementChanged(int);
1227 void shellChromeChanged(MirShellChrome);
1228+ void inputBoundsChanged(const QRect &rect);
1229
1230 private:
1231 QCursor createQCursorFromMirCursorImage(const mir::graphics::CursorImage &cursorImage);
1232
1233=== modified file 'miral-qt/tests/framework/fake_mirsurface.h'
1234--- miral-qt/tests/framework/fake_mirsurface.h 2016-07-25 13:48:41 +0000
1235+++ miral-qt/tests/framework/fake_mirsurface.h 2016-07-26 12:46:18 +0000
1236@@ -76,6 +76,7 @@
1237 Mir::ShellChrome shellChrome() const override { return Mir::NormalChrome; }
1238
1239 bool focused() const override { return false; }
1240+ QRect inputBounds() const override { return QRect(0,0,10,10); }
1241
1242 void requestFocus() override {
1243 Q_EMIT focusRequested();
1244@@ -110,6 +111,7 @@
1245 void setFocused(bool focus) override;
1246
1247 void setViewActiveFocus(qintptr, bool) override {};
1248+ bool activeFocus() const override { return false; }
1249
1250 void mousePressEvent(QMouseEvent *) override;
1251 void mouseMoveEvent(QMouseEvent *) override;
1252@@ -132,6 +134,8 @@
1253
1254 SessionInterface* session() override { return m_session; }
1255
1256+ bool inputAreaContains(const QPoint &) const override { return true; }
1257+
1258 public Q_SLOTS:
1259 void onCompositorSwappedBuffers() override;
1260
1261
1262=== modified file 'miral-qt/tests/framework/fake_session.h'
1263--- miral-qt/tests/framework/fake_session.h 2016-06-07 20:32:04 +0000
1264+++ miral-qt/tests/framework/fake_session.h 2016-07-26 12:46:18 +0000
1265@@ -58,6 +58,10 @@
1266
1267 void close() override;
1268
1269+ bool activeFocus() const override { return false; }
1270+
1271+ pid_t pid() const override { return 0; }
1272+
1273 // For SessionManager use
1274
1275 void addChildSession(SessionInterface*) override;

Subscribers

People subscribed via source and target branches