Merge lp:~mir-team/qtmir/port-to-msh-shell-and-mirevent2 into lp:qtmir

Proposed by kevin gunn
Status: Work in progress
Proposed branch: lp:~mir-team/qtmir/port-to-msh-shell-and-mirevent2
Merge into: lp:qtmir
Diff against target: 2466 lines (+813/-771)
38 files modified
CMakeLists.txt (+1/-0)
debian/changelog (+6/-0)
debian/control (+3/-3)
src/common/debughelpers.cpp (+7/-23)
src/modules/Unity/Application/application.cpp (+9/-7)
src/modules/Unity/Application/application.h (+4/-15)
src/modules/Unity/Application/application_manager.cpp (+3/-32)
src/modules/Unity/Application/desktopfilereader.cpp (+96/-0)
src/modules/Unity/Application/desktopfilereader.h (+5/-0)
src/modules/Unity/Application/mirsurfaceitem.cpp (+140/-211)
src/modules/Unity/Application/mirsurfaceitem.h (+25/-5)
src/modules/Unity/Application/mirsurfacemanager.cpp (+5/-5)
src/modules/Unity/Application/plugin.cpp (+1/-0)
src/modules/Unity/Application/sessionmanager.cpp (+1/-1)
src/platforms/mirserver/CMakeLists.txt (+1/-3)
src/platforms/mirserver/focussetter.cpp (+0/-24)
src/platforms/mirserver/focussetter.h (+0/-28)
src/platforms/mirserver/mirplacementstrategy.cpp (+0/-59)
src/platforms/mirserver/mirplacementstrategy.h (+0/-42)
src/platforms/mirserver/mirserver.cpp (+13/-20)
src/platforms/mirserver/mirserver.h (+4/-3)
src/platforms/mirserver/mirshell.cpp (+75/-0)
src/platforms/mirserver/mirshell.h (+56/-0)
src/platforms/mirserver/nativeinterface.cpp (+2/-2)
src/platforms/mirserver/qteventfeeder.cpp (+137/-113)
src/platforms/mirserver/qteventfeeder.h (+6/-4)
src/platforms/mirserver/surfaceconfigurator.cpp (+0/-34)
src/platforms/mirserver/surfaceconfigurator.h (+0/-41)
tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h (+1/-0)
tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp (+2/-31)
tests/modules/ApplicationManager/application_manager_test.cpp (+99/-0)
tests/modules/DesktopFileReader/desktopfilereader_test.cpp (+70/-0)
tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp (+38/-22)
tests/modules/common/mock_focus_controller.h (+0/-40)
tests/modules/common/mock_mir_session.h (+1/-0)
tests/modules/common/mock_renderable.h (+0/-2)
tests/modules/common/mock_surface.h (+2/-0)
tests/modules/common/qtmir_test.h (+0/-1)
To merge this branch: bzr merge lp:~mir-team/qtmir/port-to-msh-shell-and-mirevent2
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+248433@code.launchpad.net

Commit message

merge of qtmir port to shell and mirevent2

Description of the change

merge of qtmir port to shell and mirevent2

To post a comment you must log in.
320. By Andreas Pokorny

merged daniels branch into this one

321. By kevin gunn

fix typo

322. By Andreas Pokorny

duplicate mock entry oO

323. By Andreas Pokorny

fix test cases

324. By kevin gunn

added mirsurfaceattribute to the qtmir application

Unmerged revisions

324. By kevin gunn

added mirsurfaceattribute to the qtmir application

323. By Andreas Pokorny

fix test cases

322. By Andreas Pokorny

duplicate mock entry oO

321. By kevin gunn

fix typo

320. By Andreas Pokorny

merged daniels branch into this one

319. By kevin gunn

merge port to shell and mir event

318. By Robert Carr

Finish touch-event-support

317. By Robert Carr

Implement touch mods

316. By Robert Carr

Typo

315. By Robert Carr

Update to use chrono

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-12-09 14:12:57 +0000
3+++ CMakeLists.txt 2015-02-05 10:26:37 +0000
4@@ -78,6 +78,7 @@
5 pkg_check_modules(GIO_UNIX gio-unix-2.0)
6 pkg_check_modules(LTTNG lttng-ust)
7
8+add_definitions(-DMIR_REQUIRE_DEPRECATED_EVENT_OPT_IN=1)
9
10 # We expect this to be set via debian/rules for GLES builds
11 if ("${USE_OPENGLES}" STREQUAL 1)
12
13=== modified file 'debian/changelog'
14--- debian/changelog 2015-01-15 15:19:46 +0000
15+++ debian/changelog 2015-02-05 10:26:37 +0000
16@@ -1,3 +1,9 @@
17+qtmir (0.4.5) UNRELEASED; urgency=medium
18+
19+ * Add X-Ubuntu-Supported-Orientations desktop file entry
20+
21+ -- Daniel d'Andrada <daniel.dandrada@canonical.com> Fri, 31 Oct 2014 10:17:42 -0200
22+
23 qtmir (0.4.4+15.04.20150115-0ubuntu1) vivid; urgency=low
24
25 [ Gerry Boland ]
26
27=== modified file 'debian/control'
28--- debian/control 2015-01-14 09:07:31 +0000
29+++ debian/control 2015-02-05 10:26:37 +0000
30@@ -10,7 +10,7 @@
31 # version. To allow cross-compiling to work, we also must
32 # append :native to g++-4.9 so we don't try to run armhf g++
33 # on an x86 CPU for example, when cross-compiling.
34- g++-4.9:native,
35+ g++-4.9,
36 google-mock (>= 1.6.0+svn437),
37 libboost-system-dev,
38 libfontconfig1-dev,
39@@ -26,7 +26,7 @@
40 libubuntu-app-launch2-dev,
41 libubuntu-application-api-dev (>= 2.1.0),
42 libudev-dev,
43- libunity-api-dev (>= 7.92),
44+ libunity-api-dev (>= 7.94),
45 liburl-dispatcher1-dev,
46 libxkbcommon-dev,
47 libxrender-dev,
48@@ -96,7 +96,7 @@
49 Conflicts: libqtmir,
50 libunity-mir1,
51 Provides: unity-application-impl,
52- unity-application-impl-4,
53+ unity-application-impl-5,
54 Description: Qt plugin for Unity specific Mir APIs
55 QtMir provides Qt/QML bindings for Mir features that are exposed through the
56 qtmir-desktop or qtmir-android QPA plugin such as Application management
57
58=== modified file 'src/common/debughelpers.cpp'
59--- src/common/debughelpers.cpp 2014-08-27 11:51:28 +0000
60+++ src/common/debughelpers.cpp 2015-02-05 10:26:37 +0000
61@@ -176,31 +176,15 @@
62 }
63 }
64
65-const char *mirMotionActionToStr(int value)
66+const char *mirTouchActionToStr(MirTouchInputEventTouchAction action)
67 {
68- switch (value) {
69- case mir_motion_action_move:
70- return "move";
71- case mir_motion_action_down:
72+ switch (action) {
73+ case mir_touch_input_event_action_up:
74+ return "up";
75+ case mir_touch_input_event_action_down:
76 return "down";
77- case mir_motion_action_up:
78- return "up";
79- case mir_motion_action_pointer_down:
80- return "pointer_down";
81- case mir_motion_action_cancel:
82- return "cancel";
83- case mir_motion_action_pointer_up:
84- return "pointer_up";
85- case mir_motion_action_outside:
86- return "outside";
87- case mir_motion_action_hover_move:
88- return "hover_move";
89- case mir_motion_action_scroll:
90- return "scroll";
91- case mir_motion_action_hover_enter:
92- return "hover_enter";
93- case mir_motion_action_hover_exit:
94- return "hover_exit";
95+ case mir_touch_input_event_action_change:
96+ return "change";
97 default:
98 return "???";
99 }
100
101=== modified file 'src/modules/Unity/Application/application.cpp'
102--- src/modules/Unity/Application/application.cpp 2015-01-08 12:35:41 +0000
103+++ src/modules/Unity/Application/application.cpp 2015-02-05 10:26:37 +0000
104@@ -60,12 +60,9 @@
105 // FIXME(greyback) need to save long appId internally until ubuntu-app-launch can hide it from us
106 m_longAppId = desktopFileReader->file().remove(QRegExp(".desktop$")).split('/').last();
107
108- // FIXME: This is a hack. Remove once we have a real implementation for knowing the supported
109- // orientations of an app
110- m_supportedOrientations = PortraitOrientation
111- | LandscapeOrientation
112- | InvertedPortraitOrientation
113- | InvertedLandscapeOrientation;
114+ m_supportedOrientations = m_desktopData->supportedOrientations();
115+
116+ m_rotatesWindowContents = m_desktopData->rotatesWindowContents();
117 }
118
119 Application::~Application()
120@@ -353,11 +350,16 @@
121 return m_longAppId;
122 }
123
124-Application::SupportedOrientations Application::supportedOrientations() const
125+Qt::ScreenOrientations Application::supportedOrientations() const
126 {
127 return m_supportedOrientations;
128 }
129
130+bool Application::rotatesWindowContents() const
131+{
132+ return m_rotatesWindowContents;
133+}
134+
135 Session* Application::session() const
136 {
137 return m_session;
138
139=== modified file 'src/modules/Unity/Application/application.h'
140--- src/modules/Unity/Application/application.h 2015-01-08 12:35:41 +0000
141+++ src/modules/Unity/Application/application.h 2015-02-05 10:26:37 +0000
142@@ -47,27 +47,15 @@
143 {
144 Q_OBJECT
145
146- Q_FLAGS(Orientation SupportedOrientations)
147-
148 Q_PROPERTY(QString desktopFile READ desktopFile CONSTANT)
149 Q_PROPERTY(QString exec READ exec CONSTANT)
150 Q_PROPERTY(bool fullscreen READ fullscreen NOTIFY fullscreenChanged)
151 Q_PROPERTY(Stage stage READ stage WRITE setStage NOTIFY stageChanged)
152- Q_PROPERTY(SupportedOrientations supportedOrientations READ supportedOrientations CONSTANT)
153 Q_PROPERTY(Session* session READ session NOTIFY sessionChanged DESIGNABLE false)
154
155 public:
156 Q_DECLARE_FLAGS(Stages, Stage)
157
158- // Matching Qt::ScreenOrientation values for convenience
159- enum Orientation {
160- PortraitOrientation = 0x1,
161- LandscapeOrientation = 0x2,
162- InvertedPortraitOrientation = 0x4,
163- InvertedLandscapeOrientation = 0x8
164- };
165- Q_DECLARE_FLAGS(SupportedOrientations, Orientation)
166-
167 Application(const QSharedPointer<TaskController>& taskController,
168 const QSharedPointer<SharedWakelock>& sharedWakelock,
169 DesktopFileReader *desktopFileReader,
170@@ -90,6 +78,8 @@
171 QColor splashColor() const override;
172 QColor splashColorHeader() const override;
173 QColor splashColorFooter() const override;
174+ Qt::ScreenOrientations supportedOrientations() const override;
175+ bool rotatesWindowContents() const override;
176
177 void setStage(Stage stage);
178 void setState(State state);
179@@ -105,7 +95,6 @@
180 bool fullscreen() const;
181
182 Stages supportedStages() const;
183- SupportedOrientations supportedOrientations() const;
184
185 pid_t pid() const;
186
187@@ -140,7 +129,8 @@
188 bool m_focused;
189 bool m_canBeResumed;
190 QStringList m_arguments;
191- SupportedOrientations m_supportedOrientations;
192+ Qt::ScreenOrientations m_supportedOrientations;
193+ bool m_rotatesWindowContents;
194 Session *m_session;
195
196 friend class ApplicationManager;
197@@ -151,6 +141,5 @@
198 } // namespace qtmir
199
200 Q_DECLARE_METATYPE(qtmir::Application*)
201-Q_DECLARE_OPERATORS_FOR_FLAGS(qtmir::Application::SupportedOrientations)
202
203 #endif // APPLICATION_H
204
205=== modified file 'src/modules/Unity/Application/application_manager.cpp'
206--- src/modules/Unity/Application/application_manager.cpp 2015-01-07 17:56:07 +0000
207+++ src/modules/Unity/Application/application_manager.cpp 2015-02-05 10:26:37 +0000
208@@ -61,33 +61,6 @@
209
210 namespace {
211
212-// FIXME: AppManager should not implement policy based on display geometry, shell should do that
213-bool forceAllAppsIntoMainStage(const QSharedPointer<MirServer> &mirServer)
214-{
215- const int tabletModeMinimimWithGU = 100;
216-
217- // Obtain display size
218- mir::geometry::Rectangles view_area;
219- mirServer->the_display()->for_each_display_buffer(
220- [&view_area](const mir::graphics::DisplayBuffer & db)
221- {
222- view_area.add(db.view_area());
223- });
224-
225- // Get current Grid Unit value
226- int gridUnitPx = 8;
227- QByteArray gridUnitString = qgetenv("GRID_UNIT_PX");
228- if (!gridUnitString.isEmpty()) {
229- bool ok;
230- int value = gridUnitString.toInt(&ok);
231- if (ok) {
232- gridUnitPx = value;
233- }
234- }
235-
236- return (view_area.bounding_rectangle().size.width.as_int() < tabletModeMinimimWithGU * gridUnitPx);
237-}
238-
239 // FIXME: To be removed once shell has fully adopted short appIds!!
240 QString toShortAppIdIfPossible(const QString &appId) {
241 QRegExp longAppIdMask("[a-z0-9][a-z0-9+.-]+_[a-zA-Z0-9+.-]+_[0-9][a-zA-Z0-9.+:~-]*");
242@@ -413,7 +386,9 @@
243 if (m_focusedApplication) {
244 m_focusedApplication->setFocused(false);
245 Application *lastApplication = applicationForStage(application->stage());
246- suspendApplication(lastApplication);
247+ if (lastApplication != application) {
248+ suspendApplication(lastApplication);
249+ }
250 }
251
252 if (application->stage() == Application::MainStage) {
253@@ -539,10 +514,6 @@
254 return;
255 }
256
257- // override stage if necessary (i.e. side stage invalid on phone)
258- if (application->stage() == Application::SideStage && forceAllAppsIntoMainStage(m_mirServer))
259- application->setStage(Application::MainStage);
260-
261 add(application);
262 Q_EMIT focusRequested(appId);
263 }
264
265=== modified file 'src/modules/Unity/Application/desktopfilereader.cpp'
266--- src/modules/Unity/Application/desktopfilereader.cpp 2014-10-07 13:43:17 +0000
267+++ src/modules/Unity/Application/desktopfilereader.cpp 2015-02-05 10:26:37 +0000
268@@ -68,6 +68,8 @@
269 : d_ptr(new DesktopFileReaderPrivate(this))
270 {
271 Q_D(DesktopFileReader);
272+ qCDebug(QTMIR_APPLICATIONS) << "Loading desktop file" << desktopFile.absoluteFilePath()
273+ << "for appId" << appId;
274
275 d->appId = appId;
276 d->file = desktopFile.absoluteFilePath();
277@@ -202,6 +204,100 @@
278 return d->getKey("X-Ubuntu-Splash-Color-Footer");
279 }
280
281+Qt::ScreenOrientations DesktopFileReader::supportedOrientations() const
282+{
283+ Q_D(const DesktopFileReader);
284+ Qt::ScreenOrientations result;
285+
286+ if (!parseOrientations(d->getKey("X-Ubuntu-Supported-Orientations"), result)) {
287+ qCWarning(QTMIR_APPLICATIONS) << d->file << "has an invalid X-Ubuntu-Supported-Orientations entry.";
288+ }
289+
290+ return result;
291+}
292+
293+bool DesktopFileReader::rotatesWindowContents() const
294+{
295+ Q_D(const DesktopFileReader);
296+ bool result;
297+
298+ if (!parseBoolean(d->getKey("X-Ubuntu-Rotates-Window-Contents"), result)) {
299+ qCWarning(QTMIR_APPLICATIONS) << d->file << "has an invalid X-Ubuntu-Rotates-Window-Contents entry.";
300+ }
301+
302+ return result;
303+}
304+
305+bool DesktopFileReader::parseOrientations(const QString &rawString, Qt::ScreenOrientations &result)
306+{
307+ // Default to all orientations
308+ result = Qt::PortraitOrientation | Qt::LandscapeOrientation
309+ | Qt::InvertedPortraitOrientation | Qt::InvertedLandscapeOrientation;
310+
311+ if (rawString.isEmpty()) {
312+ return true;
313+ }
314+
315+ Qt::ScreenOrientations parsedOrientations = 0;
316+ bool ok = true;
317+
318+ QStringList orientationsList = rawString
319+ .simplified()
320+ .replace(QChar(','), ";")
321+ .remove(QChar(' '))
322+ .remove(QChar('-'))
323+ .remove(QChar('_'))
324+ .toLower()
325+ .split(";");
326+
327+ for (int i = 0; i < orientationsList.count() && ok; ++i) {
328+ const QString &orientationString = orientationsList.at(i);
329+ if (orientationString.isEmpty()) {
330+ // skip it
331+ continue;
332+ }
333+
334+ if (orientationString == "portrait") {
335+ parsedOrientations |= Qt::PortraitOrientation;
336+ } else if (orientationString == "landscape") {
337+ parsedOrientations |= Qt::LandscapeOrientation;
338+ } else if (orientationString == "invertedportrait") {
339+ parsedOrientations |= Qt::InvertedPortraitOrientation;
340+ } else if (orientationString == "invertedlandscape") {
341+ parsedOrientations |= Qt::InvertedLandscapeOrientation;
342+ } else if (orientationsList.count() == 1 && orientationString == "primary") {
343+ // Special case: primary orientation must be alone
344+ // There's no sense in supporting primary orientation + other orientations
345+ // like "primary,landscape"
346+ parsedOrientations = Qt::PrimaryOrientation;
347+ } else {
348+ ok = false;
349+ }
350+ }
351+
352+ if (ok) {
353+ result = parsedOrientations;
354+ }
355+
356+ return ok;
357+}
358+
359+bool DesktopFileReader::parseBoolean(const QString &rawString, bool &result)
360+{
361+ QString cookedString = rawString.trimmed().toLower();
362+
363+ result = cookedString == "y"
364+ || cookedString == "1"
365+ || cookedString == "yes"
366+ || cookedString == "true";
367+
368+ return result || rawString.isEmpty()
369+ || cookedString == "n"
370+ || cookedString == "0"
371+ || cookedString == "no"
372+ || cookedString == "false";
373+}
374+
375 bool DesktopFileReader::loaded() const
376 {
377 Q_D(const DesktopFileReader);
378
379=== modified file 'src/modules/Unity/Application/desktopfilereader.h'
380--- src/modules/Unity/Application/desktopfilereader.h 2014-10-14 19:39:43 +0000
381+++ src/modules/Unity/Application/desktopfilereader.h 2015-02-05 10:26:37 +0000
382@@ -55,8 +55,13 @@
383 virtual QString splashColor() const;
384 virtual QString splashColorHeader() const;
385 virtual QString splashColorFooter() const;
386+ virtual Qt::ScreenOrientations supportedOrientations() const;
387+ virtual bool rotatesWindowContents() const;
388 virtual bool loaded() const;
389
390+ static bool parseOrientations(const QString &rawString, Qt::ScreenOrientations &result);
391+ static bool parseBoolean(const QString &rawString, bool &result);
392+
393 protected:
394 DesktopFileReader(const QString &appId, const QFileInfo &desktopFile);
395
396
397=== modified file 'src/modules/Unity/Application/mirsurfaceitem.cpp'
398--- src/modules/Unity/Application/mirsurfaceitem.cpp 2015-01-14 09:07:41 +0000
399+++ src/modules/Unity/Application/mirsurfaceitem.cpp 2015-02-05 10:26:37 +0000
400@@ -44,6 +44,7 @@
401
402 // Mir
403 #include <mir/geometry/rectangle.h>
404+#include <mir/events/event_builders.h>
405 #include <mir_toolkit/event.h>
406
407 namespace mg = mir::graphics;
408@@ -52,160 +53,99 @@
409
410 namespace {
411
412-bool fillInMirEvent(MirEvent &mirEvent, QKeyEvent *qtEvent)
413-{
414- mirEvent.type = mir_event_type_key;
415-
416- // don't care
417- mirEvent.key.device_id = 0;
418- mirEvent.key.source_id = 0;
419-
420- switch (qtEvent->type()) {
421- case QEvent::KeyPress:
422- mirEvent.key.action = mir_key_action_down;
423- break;
424- case QEvent::KeyRelease:
425- mirEvent.key.action = mir_key_action_up;
426- break;
427- default:
428- return false;
429- }
430-
431- // don't care
432- mirEvent.key.flags = (MirKeyFlag)0;
433-
434- mirEvent.key.modifiers = qtEvent->nativeModifiers();
435- mirEvent.key.key_code = qtEvent->nativeVirtualKey();
436- mirEvent.key.scan_code = qtEvent->nativeScanCode();
437-
438- // TODO: It's not the best that we lose the actual repeat count from
439- // the original mir event (pre QtEventFeeder)...of course it will
440- // not matter for Qt clients...so this is an improvement for now.
441- mirEvent.key.repeat_count = qtEvent->isAutoRepeat() ? 1 : 0;
442-
443- // Don't care
444- mirEvent.key.down_time = 0;
445-
446- mirEvent.key.event_time = qtEvent->timestamp() * 1000000;
447-
448- // Don't care
449- mirEvent.key.is_system_key = 0;
450-
451- return true;
452-}
453-
454-bool fillInMirEvent(MirEvent &mirEvent,
455- const QList<QTouchEvent::TouchPoint> &qtTouchPoints,
456- Qt::TouchPointStates qtTouchPointStates,
457- ulong qtTimestamp)
458-{
459- mirEvent.type = mir_event_type_motion;
460-
461- // Hardcoding it for now
462- // TODO: Gather this info from a QTouchDevice-derived class created by QtEventFeeder
463- mirEvent.motion.device_id = 0;
464- mirEvent.motion.source_id = 0x00001002; // AINPUT_SOURCE_TOUCHSCREEN; https://bugs.launchpad.net/bugs/1311687
465-
466- // NB: it's assumed that touch points are pressed and released
467- // one at a time.
468-
469- if (qtTouchPointStates.testFlag(Qt::TouchPointPressed)) {
470- if (qtTouchPoints.count() > 1) {
471- mirEvent.motion.action = mir_motion_action_pointer_down;
472- } else {
473- mirEvent.motion.action = mir_motion_action_down;
474- }
475- } else if (qtTouchPointStates.testFlag(Qt::TouchPointReleased)) {
476- if (qtTouchPoints.count() > 1) {
477- mirEvent.motion.action = mir_motion_action_pointer_up;
478- } else {
479- mirEvent.motion.action = mir_motion_action_up;
480- }
481- } else {
482- mirEvent.motion.action = mir_motion_action_move;
483- }
484-
485- // not used
486- mirEvent.motion.flags = (MirMotionFlag) 0;
487-
488- // TODO: map QInputEvent::modifiers()
489- mirEvent.motion.modifiers = 0;
490-
491- // not used
492- mirEvent.motion.edge_flags = 0;
493-
494- // TODO
495- mirEvent.motion.button_state = (MirMotionButton) 0;
496-
497- // Does it matter?
498- mirEvent.motion.x_offset = 0.;
499- mirEvent.motion.y_offset = 0.;
500- mirEvent.motion.x_precision = 0.1;
501- mirEvent.motion.y_precision = 0.1;
502-
503- // TODO. Not useful to Qt at least...
504- mirEvent.motion.down_time = 0;
505-
506- // Note: QtEventFeeder scales the event time down, scale it back up - precision is
507- // lost but the time difference should still be accurate to milliseconds
508- mirEvent.motion.event_time = static_cast<nsecs_t>(qtTimestamp) * 1000000;
509-
510- mirEvent.motion.pointer_count = qtTouchPoints.count();
511-
512+// Would be better if QMouseEvent had nativeModifiers
513+MirInputEventModifiers
514+mir_modifiers_from_qt(Qt::KeyboardModifiers mods)
515+{
516+ MirInputEventModifiers m_mods = mir_input_event_modifier_none;
517+ if (mods & Qt::ShiftModifier)
518+ m_mods |= mir_input_event_modifier_shift;
519+ if (mods & Qt::ControlModifier)
520+ m_mods |= mir_input_event_modifier_ctrl;
521+ if (mods & Qt::AltModifier)
522+ m_mods |= mir_input_event_modifier_alt;
523+ if (mods & Qt::MetaModifier)
524+ m_mods |= mir_input_event_modifier_meta;
525+
526+ return m_mods;
527+}
528+
529+mir::EventUPtr makeMirEvent(QMouseEvent *qtEvent, MirPointerInputEventAction action)
530+{
531+ auto timestamp = qtEvent->timestamp() * 1000000;
532+ auto modifiers = mir_modifiers_from_qt(qtEvent->modifiers());
533+
534+ std::vector<MirPointerInputEventButton> buttons;
535+ if (qtEvent->buttons() & Qt::LeftButton)
536+ buttons.push_back(mir_pointer_input_button_primary);
537+ if (qtEvent->buttons() & Qt::RightButton)
538+ buttons.push_back(mir_pointer_input_button_secondary);
539+ if (qtEvent->buttons() & Qt::MidButton)
540+ buttons.push_back(mir_pointer_input_button_tertiary);
541+
542+ return mir::events::make_event(0 /*DeviceID */, timestamp, modifiers, action,
543+ buttons, qtEvent->x(), qtEvent->y(), 0, 0);
544+}
545+
546+mir::EventUPtr makeMirEvent(QKeyEvent *qtEvent)
547+{
548+ MirKeyInputEventAction action = mir_key_input_event_action_down;
549+ switch (qtEvent->type())
550+ {
551+ case QEvent::KeyPress:
552+ action = mir_key_input_event_action_down;
553+ break;
554+ case QEvent::KeyRelease:
555+ action = mir_key_input_event_action_up;
556+ break;
557+ default:
558+ break;
559+ }
560+ if (qtEvent->isAutoRepeat())
561+ action = mir_key_input_event_action_repeat;
562+
563+ return mir::events::make_event(0 /* DeviceID */, qtEvent->timestamp() * 1000000,
564+ action, qtEvent->nativeVirtualKey(),
565+ qtEvent->nativeScanCode(),
566+ qtEvent->nativeModifiers());
567+}
568+
569+mir::EventUPtr makeMirEvent(Qt::KeyboardModifiers qmods,
570+ const QList<QTouchEvent::TouchPoint> &qtTouchPoints,
571+ Qt::TouchPointStates /* qtTouchPointStates */,
572+ ulong qtTimestamp)
573+{
574+ auto modifiers = mir_modifiers_from_qt(qmods);
575+ auto ev = mir::events::make_event(0, static_cast<int64_t>(qtTimestamp) * 1000000,
576+ modifiers);
577+
578 for (int i = 0; i < qtTouchPoints.count(); ++i) {
579 auto touchPoint = qtTouchPoints.at(i);
580- auto &pointer = mirEvent.motion.pointer_coordinates[i];
581-
582- // FIXME: https://bugs.launchpad.net/mir/+bug/1311699
583- // When multiple touch points are transmitted with a MirEvent
584- // and one of them (only one is allowed) indicates a presse
585- // state change the index is encoded in the second byte of the
586- // action value.
587- const int mir_motion_event_pointer_index_shift = 8;
588- if (mirEvent.motion.action == mir_motion_action_pointer_up &&
589- touchPoint.state() == Qt::TouchPointReleased)
590- {
591- mirEvent.motion.action |= i << mir_motion_event_pointer_index_shift;
592- }
593- if (mirEvent.motion.action == mir_motion_action_pointer_down &&
594- touchPoint.state() == Qt::TouchPointPressed)
595- {
596- mirEvent.motion.action |= i << mir_motion_event_pointer_index_shift;
597- }
598-
599-
600- pointer.id = touchPoint.id();
601- pointer.x = touchPoint.pos().x();
602- pointer.y = touchPoint.pos().y();
603-
604- // FIXME: https://bugs.launchpad.net/mir/+bug/1311809
605-
606- if (touchPoint.rawScreenPositions().isEmpty()) {
607- pointer.raw_x = 0.;
608- pointer.raw_y = 0.;
609- } else {
610- pointer.raw_x = touchPoint.rawScreenPositions().at(0).x();
611- pointer.raw_y = touchPoint.rawScreenPositions().at(0).y();
612- }
613-
614- pointer.touch_major = touchPoint.rect().width();
615- pointer.touch_minor = touchPoint.rect().height();
616- pointer.size = 0.;
617- pointer.pressure = touchPoint.pressure();
618- pointer.orientation = 0.;
619- pointer.vscroll = 0.;
620- pointer.hscroll = 0.;
621-
622- // TODO: Mir supports a wider set of tool types (finger, stylus, mouse, eraser, unknown).
623- // so just because we are not TouchPoint::Pen does not mean we are motion_tool_type_finger...
624- // however this is the best we can do with the QtEventFeeder approach.
625+ auto id = touchPoint.id();
626+
627+ MirTouchInputEventTouchAction action = mir_touch_input_event_action_change;
628+ if (touchPoint.state() == Qt::TouchPointReleased)
629+ {
630+ action = mir_touch_input_event_action_up;
631+ }
632+ if (touchPoint.state() == Qt::TouchPointPressed)
633+ {
634+ action = mir_touch_input_event_action_down;
635+ }
636+
637+ MirTouchInputEventTouchTooltype tooltype = mir_touch_input_tool_type_finger;
638 if (touchPoint.flags() & QTouchEvent::TouchPoint::Pen)
639- pointer.tool_type = mir_motion_tool_type_stylus;
640- else
641- pointer.tool_type = mir_motion_tool_type_finger;
642+ tooltype = mir_touch_input_tool_type_stylus;
643+
644+ mir::events::add_touch(*ev, id, action, tooltype,
645+ touchPoint.pos().x(), touchPoint.pos().y(),
646+ touchPoint.pressure(),
647+ touchPoint.rect().width(),
648+ touchPoint.rect().height(),
649+ 0 /* size */);
650 }
651
652- return true;
653+ return ev;
654 }
655
656 } // namespace {
657@@ -243,7 +183,7 @@
658 , m_session(session)
659 , m_firstFrameDrawn(false)
660 , m_live(true)
661- , m_orientation(Qt::PortraitOrientation)
662+ , m_orientationAngle(Angle0)
663 , m_textureProvider(nullptr)
664 , m_lastTouchEvent(nullptr)
665 {
666@@ -352,49 +292,42 @@
667 return static_cast<MirSurfaceItem::State>(m_surface->state());
668 }
669
670-Qt::ScreenOrientation MirSurfaceItem::orientation() const
671+MirSurfaceItem::OrientationAngle MirSurfaceItem::orientationAngle() const
672 {
673- return m_orientation;
674+ return m_orientationAngle;
675 }
676
677-void MirSurfaceItem::setOrientation(const Qt::ScreenOrientation orientation)
678+void MirSurfaceItem::setOrientationAngle(MirSurfaceItem::OrientationAngle angle)
679 {
680- qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::setOrientation - orientation=" << orientation;
681+ qCDebug(QTMIR_SURFACES, "MirSurfaceItem::setOrientationAngle(%d)", angle);
682
683- if (m_orientation == orientation)
684+ if (m_orientationAngle == angle)
685 return;
686
687 MirOrientation mirOrientation;
688- Qt::ScreenOrientation nativeOrientation = QGuiApplication::primaryScreen()->nativeOrientation();
689- const bool landscapeNativeOrientation = (nativeOrientation == Qt::LandscapeOrientation);
690-
691- Qt::ScreenOrientation requestedOrientation = orientation;
692- if (orientation == Qt::PrimaryOrientation) { // means orientation equals native orientation, set it as such
693- requestedOrientation = nativeOrientation;
694- }
695-
696- switch(requestedOrientation) {
697- case Qt::PortraitOrientation:
698- mirOrientation = (landscapeNativeOrientation) ? mir_orientation_right : mir_orientation_normal;
699- break;
700- case Qt::LandscapeOrientation:
701- mirOrientation = (landscapeNativeOrientation) ? mir_orientation_normal : mir_orientation_left;
702- break;
703- case Qt::InvertedPortraitOrientation:
704- mirOrientation = (landscapeNativeOrientation) ? mir_orientation_left : mir_orientation_inverted;
705- break;
706- case Qt::InvertedLandscapeOrientation:
707- mirOrientation = (landscapeNativeOrientation) ? mir_orientation_inverted : mir_orientation_right;
708+
709+ switch (angle) {
710+ case Angle0:
711+ mirOrientation = mir_orientation_normal;
712+ break;
713+ case Angle90:
714+ mirOrientation = mir_orientation_right;
715+ break;
716+ case Angle180:
717+ mirOrientation = mir_orientation_inverted;
718+ break;
719+ case Angle270:
720+ mirOrientation = mir_orientation_left;
721 break;
722 default:
723- qWarning("Unrecognized Qt::ScreenOrientation!");
724+ qCWarning(QTMIR_SURFACES, "Unsupported orientation angle: %d", angle);
725 return;
726 }
727
728 m_surface->set_orientation(mirOrientation);
729
730- m_orientation = orientation;
731- Q_EMIT orientationChanged();
732+ m_orientationAngle = angle;
733+ Q_EMIT orientationAngleChanged(angle);
734 }
735
736 QString MirSurfaceItem::name() const
737@@ -440,10 +373,11 @@
738 ensureProvider();
739 bool textureUpdated = false;
740
741+ const void* const user_id = (void*)123;
742 std::unique_ptr<mg::Renderable> renderable =
743- m_surface->compositor_snapshot((void*)123/*user_id*/);
744+ m_surface->compositor_snapshot(user_id);
745
746- if (renderable->buffers_ready_for_compositor() > 0) {
747+ if (m_surface->buffers_ready_for_compositor(user_id) > 0) {
748 if (!m_textureProvider->t) {
749 m_textureProvider->t = new MirBufferSGTexture(renderable->buffer());
750 } else {
751@@ -455,7 +389,7 @@
752 textureUpdated = true;
753 }
754
755- if (renderable->buffers_ready_for_compositor() > 0) {
756+ if (m_surface->buffers_ready_for_compositor(user_id) > 0) {
757 QTimer::singleShot(0, this, SLOT(update()));
758 // restart the frame dropper so that we have enough time to render the next frame.
759 m_frameDropperTimer.start();
760@@ -507,18 +441,20 @@
761
762 void MirSurfaceItem::mousePressEvent(QMouseEvent *event)
763 {
764- // TODO: Implement for desktop support
765- event->ignore();
766+ auto ev = makeMirEvent(event, mir_pointer_input_event_action_button_down);
767+ m_surface->consume(*ev);
768 }
769
770 void MirSurfaceItem::mouseMoveEvent(QMouseEvent *event)
771 {
772- Q_UNUSED(event);
773+ auto ev = makeMirEvent(event, mir_pointer_input_event_action_motion);
774+ m_surface->consume(*ev);
775 }
776
777 void MirSurfaceItem::mouseReleaseEvent(QMouseEvent *event)
778 {
779- Q_UNUSED(event);
780+ auto ev = makeMirEvent(event, mir_pointer_input_event_action_button_up);
781+ m_surface->consume(*ev);
782 }
783
784 void MirSurfaceItem::wheelEvent(QWheelEvent *event)
785@@ -528,18 +464,14 @@
786
787 void MirSurfaceItem::keyPressEvent(QKeyEvent *qtEvent)
788 {
789- MirEvent mirEvent;
790- if (fillInMirEvent(mirEvent, qtEvent)) {
791- m_surface->consume(mirEvent);
792- }
793+ auto ev = makeMirEvent(qtEvent);
794+ m_surface->consume(*ev);
795 }
796
797 void MirSurfaceItem::keyReleaseEvent(QKeyEvent *qtEvent)
798 {
799- MirEvent mirEvent;
800- if (fillInMirEvent(mirEvent, qtEvent)) {
801- m_surface->consume(mirEvent);
802- }
803+ auto ev = makeMirEvent(qtEvent);
804+ m_surface->consume(*ev);
805 }
806
807 QString MirSurfaceItem::appId() const
808@@ -555,8 +487,6 @@
809
810 void MirSurfaceItem::endCurrentTouchSequence(ulong timestamp)
811 {
812- MirEvent mirEvent;
813-
814 Q_ASSERT(m_lastTouchEvent);
815 Q_ASSERT(m_lastTouchEvent->type != QEvent::TouchEnd);
816 Q_ASSERT(m_lastTouchEvent->touchPoints.count() > 0);
817@@ -580,10 +510,10 @@
818
819 touchEvent.updateTouchPointStatesAndType();
820
821- if (fillInMirEvent(mirEvent, touchEvent.touchPoints,
822- touchEvent.touchPointStates, touchEvent.timestamp)) {
823- m_surface->consume(mirEvent);
824- }
825+ auto ev = makeMirEvent(touchEvent.modifiers, touchEvent.touchPoints,
826+ touchEvent.touchPointStates, touchEvent.timestamp);
827+ m_surface->consume(*ev);
828+
829 *m_lastTouchEvent = touchEvent;
830
831 touchEvent.touchPoints.removeAt(0);
832@@ -592,11 +522,10 @@
833
834 void MirSurfaceItem::validateAndDeliverTouchEvent(int eventType,
835 ulong timestamp,
836+ Qt::KeyboardModifiers mods,
837 const QList<QTouchEvent::TouchPoint> &touchPoints,
838 Qt::TouchPointStates touchPointStates)
839 {
840- MirEvent mirEvent;
841-
842 if (eventType == QEvent::TouchBegin && m_lastTouchEvent && m_lastTouchEvent->type != QEvent::TouchEnd) {
843 qCWarning(QTMIR_SURFACES) << qPrintable(QString("MirSurfaceItem(%1) - Got a QEvent::TouchBegin while "
844 "there's still an active/unfinished touch sequence.").arg(appId()));
845@@ -604,9 +533,8 @@
846 endCurrentTouchSequence(timestamp);
847 }
848
849- if (fillInMirEvent(mirEvent, touchPoints, touchPointStates, timestamp)) {
850- m_surface->consume(mirEvent);
851- }
852+ auto ev = makeMirEvent(mods, touchPoints, touchPointStates, timestamp);
853+ m_surface->consume(*ev);
854
855 if (!m_lastTouchEvent) {
856 m_lastTouchEvent = new TouchEvent;
857@@ -621,6 +549,7 @@
858 {
859 bool accepted = processTouchEvent(event->type(),
860 event->timestamp(),
861+ event->modifiers(),
862 event->touchPoints(),
863 event->touchPointStates());
864 event->setAccepted(accepted);
865@@ -629,6 +558,7 @@
866 bool MirSurfaceItem::processTouchEvent(
867 int eventType,
868 ulong timestamp,
869+ Qt::KeyboardModifiers mods,
870 const QList<QTouchEvent::TouchPoint> &touchPoints,
871 Qt::TouchPointStates touchPointStates)
872 {
873@@ -636,7 +566,7 @@
874 if (type() == InputMethod && eventType == QEvent::TouchBegin) {
875 // FIXME: Hack to get the VKB use case working while we don't have the proper solution in place.
876 if (hasTouchInsideUbuntuKeyboard(touchPoints)) {
877- validateAndDeliverTouchEvent(eventType, timestamp, touchPoints, touchPointStates);
878+ validateAndDeliverTouchEvent(eventType, timestamp, mods, touchPoints, touchPointStates);
879 } else {
880 accepted = false;
881 }
882@@ -644,7 +574,7 @@
883 } else {
884 // NB: If we are getting QEvent::TouchUpdate or QEvent::TouchEnd it's because we've
885 // previously accepted the corresponding QEvent::TouchBegin
886- validateAndDeliverTouchEvent(eventType, timestamp, touchPoints, touchPointStates);
887+ validateAndDeliverTouchEvent(eventType, timestamp, mods, touchPoints, touchPointStates);
888 }
889 return accepted;
890 }
891@@ -747,18 +677,17 @@
892 {
893 QMutexLocker locker(&m_mutex);
894
895- std::unique_ptr<mg::Renderable> renderable =
896- m_surface->compositor_snapshot((void*)123/*user_id*/);
897+ const void* const user_id = (void*)123; // TODO: Multimonitor support
898
899- while (renderable->buffers_ready_for_compositor() > 0) {
900+ while (m_surface->buffers_ready_for_compositor(user_id) > 0) {
901 // The line below looks like an innocent, effect-less, getter. But as this
902 // method returns a unique_pointer, not holding its reference causes the
903 // buffer to be destroyed/released straight away.
904- m_surface->compositor_snapshot((void*)123/*user_id*/)->buffer();
905+ m_surface->compositor_snapshot(user_id)->buffer();
906 qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::dropPendingBuffers()"
907 << "surface =" << this
908 << "buffer dropped."
909- << renderable->buffers_ready_for_compositor()
910+ << m_surface->buffers_ready_for_compositor(user_id)
911 << "left.";
912 }
913 }
914
915=== modified file 'src/modules/Unity/Application/mirsurfaceitem.h'
916--- src/modules/Unity/Application/mirsurfaceitem.h 2015-01-14 08:24:29 +0000
917+++ src/modules/Unity/Application/mirsurfaceitem.h 2015-02-05 10:26:37 +0000
918@@ -47,12 +47,17 @@
919 Q_OBJECT
920 Q_ENUMS(Type)
921 Q_ENUMS(State)
922+ Q_ENUMS(OrientationAngle)
923
924 Q_PROPERTY(Type type READ type NOTIFY typeChanged)
925 Q_PROPERTY(State state READ state NOTIFY stateChanged)
926 Q_PROPERTY(QString name READ name NOTIFY nameChanged)
927 Q_PROPERTY(bool live READ live NOTIFY liveChanged)
928- Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged DESIGNABLE false)
929+
930+ // How many degrees, clockwise, the UI in the surface has to rotate to match with the
931+ // shell UI orientation
932+ Q_PROPERTY(OrientationAngle orientationAngle READ orientationAngle WRITE setOrientationAngle
933+ NOTIFY orientationAngleChanged DESIGNABLE false)
934
935 public:
936 explicit MirSurfaceItem(std::shared_ptr<mir::scene::Surface> surface,
937@@ -81,12 +86,18 @@
938 Fullscreen = mir_surface_state_fullscreen,
939 };
940
941+ enum OrientationAngle {
942+ Angle0 = 0,
943+ Angle90 = 90,
944+ Angle180 = 180,
945+ Angle270 = 270
946+ };
947+
948 //getters
949 Type type() const;
950 State state() const;
951 QString name() const;
952 bool live() const;
953- Qt::ScreenOrientation orientation() const;
954 SessionInterface *session() const;
955
956 Q_INVOKABLE void release();
957@@ -100,12 +111,15 @@
958
959 bool isFirstFrameDrawn() const { return m_firstFrameDrawn; }
960
961- void setOrientation(const Qt::ScreenOrientation orientation);
962+ OrientationAngle orientationAngle() const;
963+ void setOrientationAngle(OrientationAngle angle);
964+
965 void setSession(SessionInterface *app);
966
967 // to allow easy touch event injection from tests
968 bool processTouchEvent(int eventType,
969 ulong timestamp,
970+ Qt::KeyboardModifiers modifiers,
971 const QList<QTouchEvent::TouchPoint> &touchPoints,
972 Qt::TouchPointStates touchPointStates);
973
974@@ -113,7 +127,7 @@
975 void typeChanged();
976 void stateChanged();
977 void nameChanged();
978- void orientationChanged();
979+ void orientationAngleChanged(OrientationAngle angle);
980 void liveChanged(bool live);
981 void firstFrameDrawn(MirSurfaceItem *item);
982
983@@ -164,6 +178,7 @@
984 void endCurrentTouchSequence(ulong timestamp);
985 void validateAndDeliverTouchEvent(int eventType,
986 ulong timestamp,
987+ Qt::KeyboardModifiers modifiers,
988 const QList<QTouchEvent::TouchPoint> &touchPoints,
989 Qt::TouchPointStates touchPointStates);
990
991@@ -173,7 +188,9 @@
992 QPointer<SessionInterface> m_session;
993 bool m_firstFrameDrawn;
994 bool m_live;
995- Qt::ScreenOrientation m_orientation; //FIXME - have to save the state as Mir has no getter for it (bug:1357429)
996+
997+ //FIXME - have to save the state as Mir has no getter for it (bug:1357429)
998+ OrientationAngle m_orientationAngle;
999
1000 QMirSurfaceTextureProvider *m_textureProvider;
1001
1002@@ -188,6 +205,7 @@
1003 TouchEvent &operator= (const QTouchEvent &qtEvent) {
1004 type = qtEvent.type();
1005 timestamp = qtEvent.timestamp();
1006+ modifiers = qtEvent.modifiers();
1007 touchPoints = qtEvent.touchPoints();
1008 touchPointStates = qtEvent.touchPointStates();
1009 return *this;
1010@@ -197,6 +215,7 @@
1011
1012 int type;
1013 ulong timestamp;
1014+ Qt::KeyboardModifiers modifiers;
1015 QList<QTouchEvent::TouchPoint> touchPoints;
1016 Qt::TouchPointStates touchPointStates;
1017 } *m_lastTouchEvent;
1018@@ -207,5 +226,6 @@
1019 } // namespace qtmir
1020
1021 Q_DECLARE_METATYPE(qtmir::MirSurfaceItem*)
1022+Q_DECLARE_METATYPE(qtmir::MirSurfaceItem::OrientationAngle)
1023
1024 #endif // MIRSURFACEITEM_H
1025
1026=== modified file 'src/modules/Unity/Application/mirsurfacemanager.cpp'
1027--- src/modules/Unity/Application/mirsurfacemanager.cpp 2014-12-16 15:55:29 +0000
1028+++ src/modules/Unity/Application/mirsurfacemanager.cpp 2015-02-05 10:26:37 +0000
1029@@ -31,7 +31,7 @@
1030 #include "nativeinterface.h"
1031 #include "mirserver.h"
1032 #include "sessionlistener.h"
1033-#include "surfaceconfigurator.h"
1034+#include "mirshell.h"
1035 #include "logging.h"
1036
1037 Q_LOGGING_CATEGORY(QTMIR_SURFACES, "qtmir.surfaces")
1038@@ -51,9 +51,9 @@
1039 manager, &MirSurfaceManager::onSessionDestroyingSurface);
1040 }
1041
1042-void connectToSurfaceConfigurator(MirSurfaceManager *manager, SurfaceConfigurator *surfaceConfigurator)
1043+void connectToShell(MirSurfaceManager *manager, MirShell *shell)
1044 {
1045- QObject::connect(surfaceConfigurator, &SurfaceConfigurator::surfaceAttributeChanged,
1046+ QObject::connect(shell, &MirShell::surfaceAttributeChanged,
1047 manager, &MirSurfaceManager::onSurfaceAttributeChanged);
1048 }
1049
1050@@ -70,12 +70,12 @@
1051 }
1052
1053 SessionListener *sessionListener = static_cast<SessionListener*>(nativeInterface->nativeResourceForIntegration("SessionListener"));
1054- SurfaceConfigurator *surfaceConfigurator = static_cast<SurfaceConfigurator*>(nativeInterface->nativeResourceForIntegration("SessionConfigurator"));
1055+ MirShell *shell = static_cast<MirShell*>(nativeInterface->nativeResourceForIntegration("Shell"));
1056
1057 the_surface_manager = new MirSurfaceManager(nativeInterface->m_mirServer, SessionManager::singleton());
1058
1059 connectToSessionListener(the_surface_manager, sessionListener);
1060- connectToSurfaceConfigurator(the_surface_manager, surfaceConfigurator);
1061+ connectToShell(the_surface_manager, shell);
1062 }
1063 return the_surface_manager;
1064 }
1065
1066=== modified file 'src/modules/Unity/Application/plugin.cpp'
1067--- src/modules/Unity/Application/plugin.cpp 2014-10-06 11:37:56 +0000
1068+++ src/modules/Unity/Application/plugin.cpp 2015-02-05 10:26:37 +0000
1069@@ -78,6 +78,7 @@
1070 qRegisterMetaType<qtmir::Session*>("Session*");
1071 qRegisterMetaType<qtmir::SessionInterface*>("SessionInterface*");
1072 qRegisterMetaType<qtmir::SessionModel*>("SessionModel*");
1073+ qRegisterMetaType<MirSurfaceAttrib>("MirSurfaceAttrib");
1074
1075 qmlRegisterUncreatableType<unity::shell::application::ApplicationManagerInterface>(
1076 uri, 0, 1, "ApplicationManagerInterface", "Abstract interface. Cannot be created in QML");
1077
1078=== modified file 'src/modules/Unity/Application/sessionmanager.cpp'
1079--- src/modules/Unity/Application/sessionmanager.cpp 2014-12-01 11:05:01 +0000
1080+++ src/modules/Unity/Application/sessionmanager.cpp 2015-02-05 10:26:37 +0000
1081@@ -26,7 +26,7 @@
1082 #include "nativeinterface.h"
1083 #include "mirserver.h"
1084 #include "sessionlistener.h"
1085-#include "surfaceconfigurator.h"
1086+#include "mirshell.h"
1087 #include "logging.h"
1088 #include "promptsessionlistener.h"
1089
1090
1091=== modified file 'src/platforms/mirserver/CMakeLists.txt'
1092--- src/platforms/mirserver/CMakeLists.txt 2014-12-12 15:15:06 +0000
1093+++ src/platforms/mirserver/CMakeLists.txt 2015-02-05 10:26:37 +0000
1094@@ -38,16 +38,14 @@
1095
1096 set(MIRSERVER_QPA_PLUGIN_SRC
1097 ../../common/debughelpers.cpp
1098- focussetter.cpp
1099+ mirshell.cpp
1100 qteventfeeder.cpp
1101 plugin.cpp
1102 qmirserver.cpp
1103 sessionauthorizer.cpp
1104 sessionlistener.cpp
1105- surfaceconfigurator.cpp
1106 surfaceobserver.cpp
1107 promptsessionlistener.cpp
1108- mirplacementstrategy.cpp
1109 mirserver.cpp
1110 mirserverstatuslistener.cpp
1111 display.cpp
1112
1113=== removed file 'src/platforms/mirserver/focussetter.cpp'
1114--- src/platforms/mirserver/focussetter.cpp 2014-07-02 11:06:22 +0000
1115+++ src/platforms/mirserver/focussetter.cpp 1970-01-01 00:00:00 +0000
1116@@ -1,24 +0,0 @@
1117-/*
1118- * Copyright (C) 2014 Canonical, Ltd.
1119- *
1120- * This program is free software: you can redistribute it and/or modify it under
1121- * the terms of the GNU Lesser General Public License version 3, as published by
1122- * the Free Software Foundation.
1123- *
1124- * This program is distributed in the hope that it will be useful, but WITHOUT
1125- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1126- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1127- * Lesser General Public License for more details.
1128- *
1129- * You should have received a copy of the GNU Lesser General Public License
1130- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1131- */
1132-
1133-#include "focussetter.h"
1134-
1135-void FocusSetter::set_focus_to(std::shared_ptr<mir::scene::Session> const&)
1136-{
1137- // no-op
1138- // The focus concept live entirely inside the shell qml scene. Therefore
1139- // we don't want anything in mir to intervene with it
1140-}
1141
1142=== removed file 'src/platforms/mirserver/focussetter.h'
1143--- src/platforms/mirserver/focussetter.h 2014-07-02 11:06:22 +0000
1144+++ src/platforms/mirserver/focussetter.h 1970-01-01 00:00:00 +0000
1145@@ -1,28 +0,0 @@
1146-/*
1147- * Copyright (C) 2014 Canonical, Ltd.
1148- *
1149- * This program is free software: you can redistribute it and/or modify it under
1150- * the terms of the GNU Lesser General Public License version 3, as published by
1151- * the Free Software Foundation.
1152- *
1153- * This program is distributed in the hope that it will be useful, but WITHOUT
1154- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1155- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1156- * Lesser General Public License for more details.
1157- *
1158- * You should have received a copy of the GNU Lesser General Public License
1159- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1160- */
1161-
1162-#ifndef QPAMIRSERVER_FOCUS_SETTER_H
1163-#define QPAMIRSERVER_FOCUS_SETTER_H
1164-
1165-#include <mir/shell/focus_setter.h>
1166-
1167-class FocusSetter : public mir::shell::FocusSetter
1168-{
1169-public:
1170- void set_focus_to(std::shared_ptr<mir::scene::Session> const& new_focus) override;
1171-};
1172-
1173-#endif // QPAMIRSERVER_FOCUS_SETTER_H
1174
1175=== removed file 'src/platforms/mirserver/mirplacementstrategy.cpp'
1176--- src/platforms/mirserver/mirplacementstrategy.cpp 2014-09-22 18:06:58 +0000
1177+++ src/platforms/mirserver/mirplacementstrategy.cpp 1970-01-01 00:00:00 +0000
1178@@ -1,59 +0,0 @@
1179-/*
1180- * Copyright (C) 2014 Canonical, Ltd.
1181- *
1182- * This program is free software: you can redistribute it and/or modify it under
1183- * the terms of the GNU Lesser General Public License version 3, as published by
1184- * the Free Software Foundation.
1185- *
1186- * This program is distributed in the hope that it will be useful, but WITHOUT
1187- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1188- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1189- * Lesser General Public License for more details.
1190- *
1191- * You should have received a copy of the GNU Lesser General Public License
1192- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1193- */
1194-
1195-#include "mirplacementstrategy.h"
1196-#include "logging.h"
1197-#include "tracepoints.h" // generated from tracepoints.tp
1198-
1199-#include <mir/geometry/rectangle.h>
1200-#include <mir/shell/display_layout.h>
1201-#include <mir/scene/surface_creation_parameters.h>
1202-
1203-namespace ms = mir::scene;
1204-namespace msh = mir::shell;
1205-
1206-MirPlacementStrategy::MirPlacementStrategy(
1207- std::shared_ptr<msh::DisplayLayout> const& display_layout)
1208- : m_displayLayout(display_layout)
1209-{
1210- qCDebug(QTMIR_MIR_MESSAGES) << "MirPlacementStrategy::MirPlacementStrategy";
1211-}
1212-
1213-ms::SurfaceCreationParameters
1214-MirPlacementStrategy::place(ms::Session const& /*session*/,
1215- ms::SurfaceCreationParameters const& requestParameters)
1216-{
1217- tracepoint(qtmirserver, surfacePlacementStart);
1218-
1219- // TODO: Callback unity8 so that it can make a decision on that.
1220- // unity8 must bear in mind that the called function will be on a Mir thread though.
1221- // The QPA shouldn't be deciding for itself on such things.
1222-
1223- ms::SurfaceCreationParameters placedParameters = requestParameters;
1224-
1225- // Just make it fullscreen for now
1226- mir::geometry::Rectangle rect{requestParameters.top_left, requestParameters.size};
1227- m_displayLayout->size_to_output(rect);
1228- placedParameters.size = rect.size;
1229-
1230- qCDebug(QTMIR_MIR_MESSAGES) << "MirPlacementStrategy: requested ("
1231- << requestParameters.size.width.as_int() << "," << requestParameters.size.height.as_int() << ") and returned ("
1232- << placedParameters.size.width.as_int() << "," << placedParameters.size.height.as_int() << ")";
1233-
1234- tracepoint(qtmirserver, surfacePlacementEnd);
1235-
1236- return placedParameters;
1237-}
1238
1239=== removed file 'src/platforms/mirserver/mirplacementstrategy.h'
1240--- src/platforms/mirserver/mirplacementstrategy.h 2014-04-17 22:25:39 +0000
1241+++ src/platforms/mirserver/mirplacementstrategy.h 1970-01-01 00:00:00 +0000
1242@@ -1,42 +0,0 @@
1243-/*
1244- * Copyright (C) 2014 Canonical, Ltd.
1245- *
1246- * This program is free software: you can redistribute it and/or modify it under
1247- * the terms of the GNU Lesser General Public License version 3, as published by
1248- * the Free Software Foundation.
1249- *
1250- * This program is distributed in the hope that it will be useful, but WITHOUT
1251- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1252- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1253- * Lesser General Public License for more details.
1254- *
1255- * You should have received a copy of the GNU Lesser General Public License
1256- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1257- */
1258-
1259-#ifndef MIRSERVERQPA_MIR_PLACEMENT_STRATEGY_H
1260-#define MIRSERVERQPA_MIR_PLACEMENT_STRATEGY_H
1261-
1262-#include <mir/scene/placement_strategy.h>
1263-
1264-#include <memory>
1265-
1266-namespace mir {
1267- namespace shell {
1268- class DisplayLayout;
1269- }
1270-}
1271-
1272-class MirPlacementStrategy : public mir::scene::PlacementStrategy
1273-{
1274-public:
1275- MirPlacementStrategy(std::shared_ptr<mir::shell::DisplayLayout> const& display_layout);
1276-
1277- mir::scene::SurfaceCreationParameters place(mir::scene::Session const& session,
1278- mir::scene::SurfaceCreationParameters const& request_parameters) override;
1279-
1280-private:
1281- std::shared_ptr<mir::shell::DisplayLayout> const m_displayLayout;
1282-};
1283-
1284-#endif // MIRSERVERQPA_MIR_PLACEMENT_STRATEGY_H
1285
1286=== modified file 'src/platforms/mirserver/mirserver.cpp'
1287--- src/platforms/mirserver/mirserver.cpp 2014-12-03 12:06:30 +0000
1288+++ src/platforms/mirserver/mirserver.cpp 2015-02-05 10:26:37 +0000
1289@@ -19,13 +19,11 @@
1290 #include "mirserver.h"
1291
1292 // local
1293-#include "focussetter.h"
1294+#include "mirshell.h"
1295 #include "mirglconfig.h"
1296-#include "mirplacementstrategy.h"
1297 #include "mirserverstatuslistener.h"
1298 #include "promptsessionlistener.h"
1299 #include "sessionlistener.h"
1300-#include "surfaceconfigurator.h"
1301 #include "sessionauthorizer.h"
1302 #include "qtcompositor.h"
1303 #include "qteventfeeder.h"
1304@@ -53,11 +51,6 @@
1305 set_command_line_handler(&ignore_unparsed_arguments);
1306 set_command_line(argc, argv);
1307
1308- override_the_placement_strategy([this]
1309- {
1310- return std::make_shared<MirPlacementStrategy>(the_shell_display_layout());
1311- });
1312-
1313 override_the_session_listener([]
1314 {
1315 return std::make_shared<SessionListener>();
1316@@ -68,11 +61,6 @@
1317 return std::make_shared<PromptSessionListener>();
1318 });
1319
1320- override_the_surface_configurator([]
1321- {
1322- return std::make_shared<SurfaceConfigurator>();
1323- });
1324-
1325 override_the_session_authorizer([]
1326 {
1327 return std::make_shared<SessionAuthorizer>();
1328@@ -102,9 +90,17 @@
1329 return std::make_shared<MirServerStatusListener>();
1330 });
1331
1332- override_the_shell_focus_setter([]
1333+ override_the_shell([this]
1334 {
1335- return std::make_shared<FocusSetter>();
1336+ auto const shell = std::make_shared<MirShell>(
1337+ the_input_targeter(),
1338+ the_surface_coordinator(),
1339+ the_session_coordinator(),
1340+ the_prompt_session_manager(),
1341+ the_shell_display_layout());
1342+
1343+ m_shell = shell;
1344+ return shell;
1345 });
1346
1347 set_terminator([&](int)
1348@@ -157,10 +153,7 @@
1349 return static_cast<PromptSessionListener*>(sharedPtr.get());
1350 }
1351
1352-SurfaceConfigurator *MirServer::surfaceConfigurator()
1353+MirShell *MirServer::shell()
1354 {
1355- auto sharedPtr = the_surface_configurator();
1356- if (sharedPtr.unique()) return 0;
1357-
1358- return static_cast<SurfaceConfigurator*>(sharedPtr.get());
1359+ return m_shell.lock().get();
1360 }
1361
1362=== modified file 'src/platforms/mirserver/mirserver.h'
1363--- src/platforms/mirserver/mirserver.h 2014-12-02 14:55:17 +0000
1364+++ src/platforms/mirserver/mirserver.h 2015-02-05 10:26:37 +0000
1365@@ -23,7 +23,7 @@
1366 class QtEventFeeder;
1367 class SessionListener;
1368 class SessionAuthorizer;
1369-class SurfaceConfigurator;
1370+class MirShell;
1371 class PromptSessionListener;
1372
1373 // We use virtual inheritance of mir::Server to facilitate derived classes (e.g. testing)
1374@@ -34,7 +34,7 @@
1375
1376 Q_PROPERTY(SessionAuthorizer* sessionAuthorizer READ sessionAuthorizer CONSTANT)
1377 Q_PROPERTY(SessionListener* sessionListener READ sessionListener CONSTANT)
1378- Q_PROPERTY(SurfaceConfigurator* surfaceConfigurator READ surfaceConfigurator CONSTANT)
1379+ Q_PROPERTY(MirShell* shell READ shell CONSTANT)
1380 Q_PROPERTY(PromptSessionListener* promptSessionListener READ promptSessionListener CONSTANT)
1381
1382 public:
1383@@ -58,10 +58,11 @@
1384 SessionAuthorizer *sessionAuthorizer();
1385 SessionListener *sessionListener();
1386 PromptSessionListener *promptSessionListener();
1387- SurfaceConfigurator *surfaceConfigurator();
1388+ MirShell *shell();
1389
1390 private:
1391 std::shared_ptr<QtEventFeeder> m_qtEventFeeder;
1392+ std::weak_ptr<MirShell> m_shell;
1393 };
1394
1395 #endif // MIRSERVER_H
1396
1397=== added file 'src/platforms/mirserver/mirshell.cpp'
1398--- src/platforms/mirserver/mirshell.cpp 1970-01-01 00:00:00 +0000
1399+++ src/platforms/mirserver/mirshell.cpp 2015-02-05 10:26:37 +0000
1400@@ -0,0 +1,75 @@
1401+/*
1402+ * Copyright © 2015 Canonical Ltd.
1403+ *
1404+ * This program is free software: you can redistribute it and/or modify it under
1405+ * the terms of the GNU Lesser General Public License version 3, as published by
1406+ * the Free Software Foundation.
1407+ *
1408+ * This program is distributed in the hope that it will be useful, but WITHOUT
1409+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1410+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1411+ * Lesser General Public License for more details.
1412+ *
1413+ * You should have received a copy of the GNU Lesser General Public License
1414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1415+ */
1416+
1417+#include "mirshell.h"
1418+#include "logging.h"
1419+#include "tracepoints.h" // generated from tracepoints.tp
1420+
1421+#include <mir/geometry/rectangle.h>
1422+#include <mir/scene/session.h>
1423+#include <mir/scene/surface_creation_parameters.h>
1424+#include <mir/shell/display_layout.h>
1425+
1426+namespace ms = mir::scene;
1427+using mir::shell::AbstractShell;
1428+
1429+MirShell::MirShell(
1430+ std::shared_ptr<mir::shell::InputTargeter> const& input_targeter,
1431+ std::shared_ptr<mir::scene::SurfaceCoordinator> const& surface_coordinator,
1432+ std::shared_ptr<mir::scene::SessionCoordinator> const& session_coordinator,
1433+ std::shared_ptr<mir::scene::PromptSessionManager> const& prompt_session_manager,
1434+ std::shared_ptr<mir::shell::DisplayLayout> const& display_layout) :
1435+ AbstractShell(input_targeter, surface_coordinator, session_coordinator, prompt_session_manager),
1436+ m_displayLayout{display_layout}
1437+{
1438+ qCDebug(QTMIR_MIR_MESSAGES) << "MirShell::MirShell";
1439+}
1440+
1441+mir::frontend::SurfaceId MirShell::create_surface(std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& requestParameters)
1442+{
1443+ tracepoint(qtmirserver, surfacePlacementStart);
1444+
1445+ // TODO: Callback unity8 so that it can make a decision on that.
1446+ // unity8 must bear in mind that the called function will be on a Mir thread though.
1447+ // The QPA shouldn't be deciding for itself on such things.
1448+
1449+ ms::SurfaceCreationParameters placedParameters = requestParameters;
1450+
1451+ // Just make it fullscreen for now
1452+ mir::geometry::Rectangle rect{requestParameters.top_left, requestParameters.size};
1453+ m_displayLayout->size_to_output(rect);
1454+ placedParameters.size = rect.size;
1455+
1456+ qCDebug(QTMIR_MIR_MESSAGES) << "MirShell::create_surface(): size requested ("
1457+ << requestParameters.size.width.as_int() << "," << requestParameters.size.height.as_int() << ") and placed ("
1458+ << placedParameters.size.width.as_int() << "," << placedParameters.size.height.as_int() << ")";
1459+
1460+ tracepoint(qtmirserver, surfacePlacementEnd);
1461+
1462+ return AbstractShell::create_surface(session, placedParameters);
1463+}
1464+
1465+int MirShell::set_surface_attribute(
1466+ std::shared_ptr<mir::scene::Session> const& session,
1467+ std::shared_ptr<mir::scene::Surface> const& surface,
1468+ MirSurfaceAttrib attrib,
1469+ int value)
1470+{
1471+ auto const result = AbstractShell::set_surface_attribute(session, surface, attrib, value);
1472+ Q_EMIT surfaceAttributeChanged(surface.get(), attrib, result);
1473+
1474+ return result;
1475+}
1476
1477=== added file 'src/platforms/mirserver/mirshell.h'
1478--- src/platforms/mirserver/mirshell.h 1970-01-01 00:00:00 +0000
1479+++ src/platforms/mirserver/mirshell.h 2015-02-05 10:26:37 +0000
1480@@ -0,0 +1,56 @@
1481+/*
1482+ * Copyright © 2015 Canonical Ltd.
1483+ *
1484+ * This program is free software: you can redistribute it and/or modify it under
1485+ * the terms of the GNU Lesser General Public License version 3, as published by
1486+ * the Free Software Foundation.
1487+ *
1488+ * This program is distributed in the hope that it will be useful, but WITHOUT
1489+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1490+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1491+ * Lesser General Public License for more details.
1492+ *
1493+ * You should have received a copy of the GNU Lesser General Public License
1494+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1495+ */
1496+
1497+#ifndef QPAMIRSERVER_SHELL_H
1498+#define QPAMIRSERVER_SHELL_H
1499+
1500+#include <mir/shell/abstract_shell.h>
1501+#include <QObject>
1502+
1503+namespace mir {
1504+ namespace shell {
1505+ class DisplayLayout;
1506+ }
1507+}
1508+
1509+class MirShell : public QObject, public mir::shell::AbstractShell
1510+{
1511+ Q_OBJECT
1512+
1513+public:
1514+ MirShell(
1515+ std::shared_ptr<mir::shell::InputTargeter> const& input_targeter,
1516+ std::shared_ptr<mir::scene::SurfaceCoordinator> const& surface_coordinator,
1517+ std::shared_ptr<mir::scene::SessionCoordinator> const& session_coordinator,
1518+ std::shared_ptr<mir::scene::PromptSessionManager> const& prompt_session_manager,
1519+ std::shared_ptr<mir::shell::DisplayLayout> const& display_layout);
1520+
1521+ virtual mir::frontend::SurfaceId create_surface(std::shared_ptr<mir::scene::Session> const& session, mir::scene::SurfaceCreationParameters const& params);
1522+
1523+ int set_surface_attribute(
1524+ std::shared_ptr<mir::scene::Session> const& session,
1525+ std::shared_ptr<mir::scene::Surface> const& surface,
1526+ MirSurfaceAttrib attrib,
1527+ int value) override;
1528+
1529+Q_SIGNALS:
1530+ void surfaceAttributeChanged(mir::scene::Surface const*, const MirSurfaceAttrib, const int);
1531+
1532+private:
1533+ std::shared_ptr<mir::shell::DisplayLayout> const m_displayLayout;
1534+};
1535+
1536+#endif /* QPAMIRSERVER_SHELL_H */
1537
1538=== modified file 'src/platforms/mirserver/nativeinterface.cpp'
1539--- src/platforms/mirserver/nativeinterface.cpp 2014-12-01 11:05:01 +0000
1540+++ src/platforms/mirserver/nativeinterface.cpp 2015-02-05 10:26:37 +0000
1541@@ -29,8 +29,8 @@
1542
1543 if (resource == "SessionAuthorizer")
1544 result = m_mirServer->sessionAuthorizer();
1545- else if (resource == "SessionConfigurator")
1546- result = m_mirServer->surfaceConfigurator();
1547+ else if (resource == "Shell")
1548+ result = m_mirServer->shell();
1549 else if (resource == "SessionListener")
1550 result = m_mirServer->sessionListener();
1551 else if (resource == "PromptSessionListener")
1552
1553=== modified file 'src/platforms/mirserver/qteventfeeder.cpp'
1554--- src/platforms/mirserver/qteventfeeder.cpp 2015-01-05 21:42:31 +0000
1555+++ src/platforms/mirserver/qteventfeeder.cpp 2015-02-05 10:26:37 +0000
1556@@ -33,11 +33,6 @@
1557 Q_LOGGING_CATEGORY(QTMIR_MIR_INPUT, "qtmir.mir.input")
1558
1559 // from android-input AMOTION_EVENT_ACTION_*, hidden inside mir bowels
1560-// mir headers should define them
1561-const int QtEventFeeder::MirEventActionMask = 0xff;
1562-const int QtEventFeeder::MirEventActionPointerIndexMask = 0xff00;
1563-const int QtEventFeeder::MirEventActionPointerIndexShift = 8;
1564-
1565
1566 // XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)
1567 static const uint32_t KeyTable[] = {
1568@@ -182,6 +177,15 @@
1569 Q_ASSERT(!mTopLevelWindow.isNull());
1570 QWindowSystemInterface::handleTouchEvent(mTopLevelWindow.data(), timestamp, device, points, mods);
1571 }
1572+
1573+ void handleMouseEvent(ulong timestamp, QPointF point, Qt::MouseButton buttons, Qt::KeyboardModifiers modifiers) override
1574+ {
1575+ Q_ASSERT(!mTopLevelWindow.isNull());
1576+ QWindowSystemInterface::handleMouseEvent(mTopLevelWindow.data(), timestamp, point, point, // local and global point are the same
1577+ buttons, modifiers);
1578+ }
1579+
1580+
1581 private:
1582 QPointer<QWindow> mTopLevelWindow;
1583 };
1584@@ -216,55 +220,109 @@
1585
1586 void QtEventFeeder::dispatch(MirEvent const& event)
1587 {
1588- switch (event.type) {
1589- case mir_event_type_key:
1590- dispatchKey(event.key);
1591- break;
1592- case mir_event_type_motion:
1593- dispatchMotion(event.motion);
1594- break;
1595- case mir_event_type_surface:
1596- // Just ignore these events: it doesn't make sense to pass them on.
1597- break;
1598+ auto type = mir_event_get_type(&event);
1599+ if (type != mir_event_type_input)
1600+ return;
1601+ auto iev = mir_event_get_input_event(&event);
1602+
1603+ switch (mir_input_event_get_type(iev)) {
1604+ case mir_input_event_type_key:
1605+ dispatchKey(iev);
1606+ break;
1607+ case mir_input_event_type_touch:
1608+ dispatchTouch(iev);
1609+ break;
1610+ case mir_input_event_type_pointer:
1611+ dispatchPointer(iev);
1612 default:
1613- // mir_event_type_surface and mir_event_type_resize events go through
1614- // mir's own protobuf channel instead of the android_input one. The latter
1615- // being the one we're dealing with here.
1616- qFatal("QtEventFeeder got unsupported event type from mir");
1617 break;
1618 }
1619 }
1620
1621-void QtEventFeeder::dispatchKey(MirKeyEvent const& event)
1622-{
1623- if (!mQtWindowSystem->hasTargetWindow())
1624- return;
1625-
1626- ulong timestamp = event.event_time / 1000000;
1627- xkb_keysym_t xk_sym = static_cast<xkb_keysym_t>(event.key_code);
1628+namespace
1629+{
1630+
1631+Qt::KeyboardModifiers qt_modifiers_from_mir(MirInputEventModifiers modifiers)
1632+{
1633+ int q_modifiers = Qt::NoModifier;
1634+ if (modifiers & mir_input_event_modifier_shift) {
1635+ q_modifiers |= Qt::ShiftModifier;
1636+ }
1637+ if (modifiers & mir_input_event_modifier_ctrl) {
1638+ q_modifiers |= Qt::ControlModifier;
1639+ }
1640+ if (modifiers & mir_input_event_modifier_alt) {
1641+ q_modifiers |= Qt::AltModifier;
1642+ }
1643+ if (modifiers & mir_input_event_modifier_meta) {
1644+ q_modifiers |= Qt::MetaModifier;
1645+ }
1646+ return static_cast<Qt::KeyboardModifiers>(q_modifiers);
1647+}
1648+
1649+Qt::MouseButton extract_buttons(MirPointerInputEvent const* pev)
1650+{
1651+ int buttons = Qt::NoButton;
1652+ if (mir_pointer_input_event_get_button_state(pev, mir_pointer_input_button_primary))
1653+ buttons |= Qt::LeftButton;
1654+ if (mir_pointer_input_event_get_button_state(pev, mir_pointer_input_button_secondary))
1655+ buttons |= Qt::RightButton;
1656+ if (mir_pointer_input_event_get_button_state(pev, mir_pointer_input_button_tertiary))
1657+ buttons |= Qt::MidButton;
1658+
1659+ // TODO: Should mir back and forward buttons exist?
1660+ // should they be Qt::X button 1 and 2?
1661+ return static_cast<Qt::MouseButton>(buttons);
1662+}
1663+}
1664+
1665+void QtEventFeeder::dispatchPointer(MirInputEvent const* ev)
1666+{
1667+ if (!mQtWindowSystem->hasTargetWindow())
1668+ return;
1669+
1670+ auto timestamp = mir_input_event_get_event_time(ev) / 1000000;
1671+
1672+ auto pev = mir_input_event_get_pointer_input_event(ev);
1673+ auto modifiers = qt_modifiers_from_mir(mir_pointer_input_event_get_modifiers(pev));
1674+ auto buttons = extract_buttons(pev);
1675+
1676+ auto local_point = QPointF(mir_pointer_input_event_get_axis_value(pev, mir_pointer_input_axis_x),
1677+ mir_pointer_input_event_get_axis_value(pev, mir_pointer_input_axis_y));
1678+
1679+ mQtWindowSystem->handleMouseEvent(timestamp, local_point,
1680+ buttons, modifiers);
1681+}
1682+
1683+void QtEventFeeder::dispatchKey(MirInputEvent const* event)
1684+{
1685+ if (!mQtWindowSystem->hasTargetWindow())
1686+ return;
1687+
1688+ ulong timestamp = mir_input_event_get_event_time(event) / 1000000;
1689+
1690+ auto kev = mir_input_event_get_key_input_event(event);
1691+ xkb_keysym_t xk_sym = mir_key_input_event_get_key_code(kev);
1692
1693 // Key modifier and unicode index mapping.
1694- const int kEventModifiers = event.modifiers;
1695- Qt::KeyboardModifiers modifiers = Qt::NoModifier;
1696- if (kEventModifiers & mir_key_modifier_shift) {
1697- modifiers |= Qt::ShiftModifier;
1698- }
1699- if (kEventModifiers & mir_key_modifier_ctrl) {
1700- modifiers |= Qt::ControlModifier;
1701- }
1702- if (kEventModifiers & mir_key_modifier_alt) {
1703- modifiers |= Qt::AltModifier;
1704- }
1705- if (kEventModifiers & mir_key_modifier_meta) {
1706- modifiers |= Qt::MetaModifier;
1707- }
1708+ auto modifiers = qt_modifiers_from_mir(mir_key_input_event_get_modifiers(kev));
1709
1710 // Key action
1711- QEvent::Type keyType;
1712- if (event.action == mir_key_action_down) {
1713+ QEvent::Type keyType = QEvent::KeyRelease;
1714+ bool is_auto_rep = false;
1715+
1716+ switch (mir_key_input_event_get_action(kev))
1717+ {
1718+ case mir_key_input_event_action_repeat:
1719+ is_auto_rep = true; // fall-through
1720+ case mir_key_input_event_action_down:
1721 keyType = QEvent::KeyPress;
1722- } else {
1723+ break;
1724+ case mir_key_input_event_action_up:
1725 keyType = QEvent::KeyRelease;
1726+ break;
1727+ default:
1728+ break;
1729 }
1730
1731 // Key event propagation.
1732@@ -272,13 +330,13 @@
1733 int keyCode = translateKeysym(xk_sym, s, sizeof(s));
1734 QString text = QString::fromLatin1(s);
1735
1736- bool is_auto_rep = event.repeat_count > 0;
1737-
1738 QPlatformInputContext* context = QGuiApplicationPrivate::platformIntegration()->inputContext();
1739 if (context) {
1740 // TODO: consider event.repeat_count
1741 QKeyEvent qKeyEvent(keyType, keyCode, modifiers,
1742- event.scan_code, event.key_code, event.modifiers,
1743+ mir_key_input_event_get_scan_code(kev),
1744+ mir_key_input_event_get_key_code(kev),
1745+ mir_key_input_event_get_modifiers(kev),
1746 text, is_auto_rep);
1747 qKeyEvent.setTimestamp(timestamp);
1748 if (context->filterEvent(&qKeyEvent)) {
1749@@ -288,27 +346,17 @@
1750 }
1751
1752 mQtWindowSystem->handleExtendedKeyEvent(timestamp, keyType, keyCode, modifiers,
1753- event.scan_code, event.key_code, event.modifiers, text, is_auto_rep);
1754+ mir_key_input_event_get_scan_code(kev),
1755+ mir_key_input_event_get_key_code(kev),
1756+ mir_key_input_event_get_modifiers(kev), text, is_auto_rep);
1757 }
1758
1759-void QtEventFeeder::dispatchMotion(MirMotionEvent const& event)
1760+void QtEventFeeder::dispatchTouch(MirInputEvent const* event)
1761 {
1762 if (!mQtWindowSystem->hasTargetWindow())
1763 return;
1764
1765- const int mirMotionAction = event.action & MirEventActionMask;
1766-
1767- // Ignore the events that do not interest us (or that we currently don't support or know
1768- // how to translate into Qt events)
1769- if (mirMotionAction != mir_motion_action_move
1770- && mirMotionAction != mir_motion_action_down
1771- && mirMotionAction != mir_motion_action_up
1772- && mirMotionAction != mir_motion_action_pointer_down
1773- && mirMotionAction != mir_motion_action_pointer_up
1774- && mirMotionAction != mir_motion_action_cancel) {
1775- return;
1776- }
1777-
1778+ auto tev = mir_input_event_get_touch_input_event(event);
1779
1780 // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
1781 // needs to be fixed as soon as the compat input lib adds query support.
1782@@ -318,72 +366,48 @@
1783
1784 // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left
1785 // as Qt::TouchPointMoved
1786- const int kPointerCount = (int) event.pointer_count;
1787+ const int kPointerCount = mir_touch_input_event_get_touch_count(tev);
1788 for (int i = 0; i < kPointerCount; ++i) {
1789 QWindowSystemInterface::TouchPoint touchPoint;
1790
1791- const float kX = event.pointer_coordinates[i].x;
1792- const float kY = event.pointer_coordinates[i].y;
1793- const float kW = event.pointer_coordinates[i].touch_major;
1794- const float kH = event.pointer_coordinates[i].touch_minor;
1795- const float kP = event.pointer_coordinates[i].pressure;
1796- touchPoint.id = event.pointer_coordinates[i].id;
1797+ const float kX = mir_touch_input_event_get_touch_axis_value(tev, i, mir_touch_input_axis_x);
1798+ const float kY = mir_touch_input_event_get_touch_axis_value(tev, i, mir_touch_input_axis_y);
1799+ const float kW = mir_touch_input_event_get_touch_axis_value(tev, i, mir_touch_input_axis_touch_major);
1800+ const float kH = mir_touch_input_event_get_touch_axis_value(tev, i, mir_touch_input_axis_touch_minor);
1801+ const float kP = mir_touch_input_event_get_touch_axis_value(tev, i, mir_touch_input_axis_pressure);
1802+ touchPoint.id = mir_touch_input_event_get_touch_id(tev, i);
1803+
1804 touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height());
1805 touchPoint.area = QRectF(kX - (kW / 2.0), kY - (kH / 2.0), kW, kH);
1806 touchPoint.pressure = kP / kMaxPressure;
1807- touchPoint.state = Qt::TouchPointMoved;
1808+ switch (mir_touch_input_event_get_touch_action(tev, i))
1809+ {
1810+ case mir_touch_input_event_action_up:
1811+ touchPoint.state = Qt::TouchPointReleased;
1812+ break;
1813+ case mir_touch_input_event_action_down:
1814+ touchPoint.state = Qt::TouchPointPressed;
1815+ break;
1816+ case mir_touch_input_event_action_change:
1817+ touchPoint.state = Qt::TouchPointMoved;
1818+ break;
1819+ default:
1820+ break;
1821+ }
1822
1823 touchPoints.append(touchPoint);
1824 }
1825
1826- switch (mirMotionAction) {
1827- case mir_motion_action_move:
1828- // No extra work needed.
1829- break;
1830-
1831- case mir_motion_action_down:
1832- // NB: hardcoded index 0 because there's only a single touch point in this case
1833- touchPoints[0].state = Qt::TouchPointPressed;
1834- break;
1835-
1836- case mir_motion_action_up:
1837- touchPoints[0].state = Qt::TouchPointReleased;
1838- break;
1839-
1840- case mir_motion_action_pointer_down: {
1841- const int index = (event.action & MirEventActionPointerIndexMask) >>
1842- MirEventActionPointerIndexShift;
1843- touchPoints[index].state = Qt::TouchPointPressed;
1844- break;
1845- }
1846-
1847- case mir_motion_action_cancel:
1848- case mir_motion_action_pointer_up: {
1849- const int index = (event.action & MirEventActionPointerIndexMask) >>
1850- MirEventActionPointerIndexShift;
1851- touchPoints[index].state = Qt::TouchPointReleased;
1852- break;
1853- }
1854-
1855- case mir_motion_action_outside:
1856- case mir_motion_action_hover_move:
1857- case mir_motion_action_scroll:
1858- case mir_motion_action_hover_enter:
1859- case mir_motion_action_hover_exit:
1860- default:
1861- // Should never reach this point. If so, it's a programming error.
1862- qFatal("Trying to handle unsupported motion event action");
1863- }
1864-
1865 // Qt needs a happy, sane stream of touch events. So let's make sure we're not forwarding
1866 // any insanity.
1867 validateTouches(touchPoints);
1868
1869 // Touch event propagation.
1870 mQtWindowSystem->handleTouchEvent(
1871- event.event_time / 1000000, //scales down the nsec_t (int64) to fit a ulong, precision lost but time difference suitable
1872- mTouchDevice,
1873- touchPoints);
1874+ //scales down the nsec_t (int64) to fit a ulong, precision lost but time difference suitable
1875+ mir_input_event_get_event_time(event) / 1000000,
1876+ mTouchDevice,
1877+ touchPoints);
1878 }
1879
1880 void QtEventFeeder::start()
1881@@ -396,12 +420,12 @@
1882 // not used
1883 }
1884
1885-void QtEventFeeder::configuration_changed(nsecs_t when)
1886+void QtEventFeeder::configuration_changed(std::chrono::nanoseconds when)
1887 {
1888 Q_UNUSED(when);
1889 }
1890
1891-void QtEventFeeder::device_reset(int32_t device_id, nsecs_t when)
1892+void QtEventFeeder::device_reset(int32_t device_id, std::chrono::nanoseconds when)
1893 {
1894 Q_UNUSED(device_id);
1895 Q_UNUSED(when);
1896
1897=== modified file 'src/platforms/mirserver/qteventfeeder.h'
1898--- src/platforms/mirserver/qteventfeeder.h 2014-08-28 12:22:55 +0000
1899+++ src/platforms/mirserver/qteventfeeder.h 2015-02-05 10:26:37 +0000
1900@@ -51,6 +51,7 @@
1901 virtual void handleTouchEvent(ulong timestamp, QTouchDevice *device,
1902 const QList<struct QWindowSystemInterface::TouchPoint> &points,
1903 Qt::KeyboardModifiers mods = Qt::NoModifier) = 0;
1904+ virtual void handleMouseEvent(ulong timestamp, QPointF point, Qt::MouseButton buttons, Qt::KeyboardModifiers modifiers) = 0;
1905 };
1906
1907 QtEventFeeder(QtWindowSystemInterface *windowSystem = nullptr);
1908@@ -60,15 +61,16 @@
1909 static const int MirEventActionPointerIndexMask;
1910 static const int MirEventActionPointerIndexShift;
1911
1912- void configuration_changed(nsecs_t when) override;
1913- void device_reset(int32_t device_id, nsecs_t when) override;
1914+ void configuration_changed(std::chrono::nanoseconds when) override;
1915+ void device_reset(int32_t device_id, std::chrono::nanoseconds when) override;
1916 void dispatch(MirEvent const& event) override;
1917 void start() override;
1918 void stop() override;
1919
1920 private:
1921- void dispatchKey(MirKeyEvent const& event);
1922- void dispatchMotion(MirMotionEvent const& event);
1923+ void dispatchKey(MirInputEvent const* event);
1924+ void dispatchTouch(MirInputEvent const* event);
1925+ void dispatchPointer(MirInputEvent const* event);
1926 void validateTouches(QList<QWindowSystemInterface::TouchPoint> &touchPoints);
1927 bool validateTouch(QWindowSystemInterface::TouchPoint &touchPoint);
1928
1929
1930=== removed file 'src/platforms/mirserver/surfaceconfigurator.cpp'
1931--- src/platforms/mirserver/surfaceconfigurator.cpp 2014-04-02 16:10:34 +0000
1932+++ src/platforms/mirserver/surfaceconfigurator.cpp 1970-01-01 00:00:00 +0000
1933@@ -1,34 +0,0 @@
1934-/*
1935- * Copyright (C) 2013,2014 Canonical, Ltd.
1936- *
1937- * This program is free software: you can redistribute it and/or modify it under
1938- * the terms of the GNU Lesser General Public License version 3, as published by
1939- * the Free Software Foundation.
1940- *
1941- * This program is distributed in the hope that it will be useful, but WITHOUT
1942- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1943- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1944- * Lesser General Public License for more details.
1945- *
1946- * You should have received a copy of the GNU Lesser General Public License
1947- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1948- */
1949-
1950-#include "surfaceconfigurator.h"
1951-
1952-namespace ms = mir::scene;
1953-
1954-SurfaceConfigurator::SurfaceConfigurator()
1955-{
1956- qRegisterMetaType<MirSurfaceAttrib>("MirSurfaceAttrib");
1957-}
1958-
1959-int SurfaceConfigurator::select_attribute_value(ms::Surface const&, MirSurfaceAttrib, int requested_value)
1960-{
1961- return requested_value;
1962-}
1963-
1964-void SurfaceConfigurator::attribute_set(ms::Surface const& surface, MirSurfaceAttrib attrib, int value)
1965-{
1966- Q_EMIT surfaceAttributeChanged(&surface, attrib, value);
1967-}
1968
1969=== removed file 'src/platforms/mirserver/surfaceconfigurator.h'
1970--- src/platforms/mirserver/surfaceconfigurator.h 2014-04-02 16:10:34 +0000
1971+++ src/platforms/mirserver/surfaceconfigurator.h 1970-01-01 00:00:00 +0000
1972@@ -1,41 +0,0 @@
1973-/*
1974- * Copyright (C) 2013,2014 Canonical, Ltd.
1975- *
1976- * This program is free software: you can redistribute it and/or modify it under
1977- * the terms of the GNU Lesser General Public License version 3, as published by
1978- * the Free Software Foundation.
1979- *
1980- * This program is distributed in the hope that it will be useful, but WITHOUT
1981- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1982- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1983- * Lesser General Public License for more details.
1984- *
1985- * You should have received a copy of the GNU Lesser General Public License
1986- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1987- */
1988-
1989-#ifndef SURFACECONFIGURATOR_H
1990-#define SURFACECONFIGURATOR_H
1991-
1992-#include <QObject>
1993-
1994-#include <mir/scene/surface_configurator.h>
1995-#include <mir_toolkit/common.h>
1996-
1997-namespace mir { namespace scene { class Surface; }}
1998-
1999-class SurfaceConfigurator : public QObject, public mir::scene::SurfaceConfigurator
2000-{
2001- Q_OBJECT
2002-
2003-public:
2004- SurfaceConfigurator();
2005-
2006- int select_attribute_value(mir::scene::Surface const&, MirSurfaceAttrib, int) override;
2007- void attribute_set(mir::scene::Surface const&, MirSurfaceAttrib, int) override;
2008-
2009-Q_SIGNALS:
2010- void surfaceAttributeChanged(mir::scene::Surface const*, const MirSurfaceAttrib, const int);
2011-};
2012-
2013-#endif // SURFACECONFIGURATOR_H
2014
2015=== modified file 'tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h'
2016--- tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h 2014-08-28 12:20:13 +0000
2017+++ tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h 2015-02-05 10:26:37 +0000
2018@@ -34,6 +34,7 @@
2019 MOCK_METHOD4(handleTouchEvent, void(ulong timestamp, QTouchDevice *device,
2020 const QList<struct QWindowSystemInterface::TouchPoint> &points,
2021 Qt::KeyboardModifiers mods));
2022+ MOCK_METHOD4(handleMouseEvent, void(ulong, QPointF, Qt::MouseButton, Qt::KeyboardModifiers));
2023 };
2024
2025 namespace testing
2026
2027=== modified file 'tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp'
2028--- tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp 2014-08-28 13:12:30 +0000
2029+++ tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp 2015-02-05 10:26:37 +0000
2030@@ -15,6 +15,8 @@
2031 *
2032 */
2033
2034+#define MIR_INCLUDE_DEPRECATED_EVENT_HEADER
2035+
2036 #include <gmock/gmock.h>
2037 #include <gtest/gtest.h>
2038
2039@@ -191,34 +193,3 @@
2040 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
2041 }
2042
2043-TEST_F(QtEventFeederTest, IgnoreHovering)
2044-{
2045- setIrrelevantMockWindowSystemExpectations();
2046- EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,_,_,_)).Times(0);
2047-
2048- MirEvent mirEvent;
2049- mirEvent.type = mir_event_type_motion;
2050- mirEvent.motion.pointer_count = 1;
2051- mirEvent.motion.pointer_coordinates[0].id = 0;
2052- mirEvent.motion.pointer_coordinates[0].x = 10;
2053- mirEvent.motion.pointer_coordinates[0].y = 10;
2054- mirEvent.motion.pointer_coordinates[0].touch_major = 1;
2055- mirEvent.motion.pointer_coordinates[0].touch_minor = 1;
2056- mirEvent.motion.pointer_coordinates[0].pressure = 10;
2057- mirEvent.motion.action = mir_motion_action_hover_enter;
2058- mirEvent.motion.event_time = 123 * 1000000;
2059-
2060- qtEventFeeder->dispatch(mirEvent);
2061-
2062- mirEvent.motion.pointer_coordinates[0].x = 20;
2063- mirEvent.motion.pointer_coordinates[0].y = 20;
2064- mirEvent.motion.action = mir_motion_action_hover_move;
2065- mirEvent.motion.event_time = 125 * 1000000;
2066-
2067- qtEventFeeder->dispatch(mirEvent);
2068-
2069- mirEvent.motion.action = mir_motion_action_hover_exit;
2070- mirEvent.motion.event_time = 127 * 1000000;
2071-
2072- qtEventFeeder->dispatch(mirEvent);
2073-}
2074
2075=== modified file 'tests/modules/ApplicationManager/application_manager_test.cpp'
2076--- tests/modules/ApplicationManager/application_manager_test.cpp 2014-11-13 16:26:03 +0000
2077+++ tests/modules/ApplicationManager/application_manager_test.cpp 2015-02-05 10:26:37 +0000
2078@@ -15,6 +15,8 @@
2079 *
2080 */
2081
2082+#define MIR_INCLUDE_DEPRECATED_EVENT_HEADER
2083+
2084 #include <thread>
2085 #include <condition_variable>
2086 #include <QSignalSpy>
2087@@ -2135,3 +2137,100 @@
2088 cv.wait(lk, [&] { return done; } );
2089 }
2090 }
2091+
2092+/*
2093+ 1 - launch and focus a main stage app
2094+ * main stage app is running and focused
2095+ 2 - launch and focus a side stage app
2096+ * main stage app is running but is not focused
2097+ * side stage app is running and has focus
2098+ 3 - focus the main stage app
2099+ * main stage app is running and has focus
2100+ * side stage app is running but is not focused
2101+
2102+ This is a regression test for the bug where on step 3, the main stage app was momentarily
2103+ suspended and then resumed again.
2104+ */
2105+TEST_F(ApplicationManagerTests, focusMainStageAfterSideStage)
2106+{
2107+ using namespace testing;
2108+
2109+ QString webbrowserAppId("webbrowser-app");
2110+ quint64 webbrowserPID = 123;
2111+ std::shared_ptr<mir::scene::Surface> webbrowserSurface(nullptr);
2112+
2113+ QString dialerAppId("dialer-app");
2114+ quint64 dialerPID = 456;
2115+ std::shared_ptr<mir::scene::Surface> dialerSurface(nullptr);
2116+
2117+ /*** Start webbrowser-app (main stage) ***/
2118+
2119+ ON_CALL(appController,appIdHasProcessId(webbrowserPID, webbrowserAppId)).WillByDefault(Return(true));
2120+
2121+ {
2122+ auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(webbrowserAppId, QFileInfo());
2123+ ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
2124+ ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(webbrowserAppId));
2125+ ON_CALL(*mockDesktopFileReader, stageHint()).WillByDefault(Return("MainStage"));
2126+
2127+ ON_CALL(desktopFileReaderFactory, createInstance(webbrowserAppId, _))
2128+ .WillByDefault(Return(mockDesktopFileReader));
2129+ }
2130+
2131+ EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(webbrowserAppId, _))
2132+ .Times(1)
2133+ .WillOnce(Return(true));
2134+
2135+ /*auto application =*/ applicationManager.startApplication(webbrowserAppId, ApplicationManager::NoFlag);
2136+ applicationManager.onProcessStarting(webbrowserAppId);
2137+
2138+ {
2139+ bool authed = false;
2140+ applicationManager.authorizeSession(webbrowserPID, authed);
2141+ EXPECT_EQ(authed, true);
2142+ }
2143+
2144+ auto webbrowserSession = std::make_shared<mir::scene::MockSession>(webbrowserAppId.toStdString(), webbrowserPID);
2145+ sessionManager.onSessionStarting(webbrowserSession);
2146+ applicationManager.focusApplication(webbrowserAppId);
2147+ applicationManager.onSessionCreatedSurface(webbrowserSession.get(), webbrowserSurface);
2148+
2149+ /*** Start dialer-app (side stage) ***/
2150+
2151+ ON_CALL(appController, appIdHasProcessId(dialerPID, dialerAppId)).WillByDefault(Return(true));
2152+
2153+ {
2154+ auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(dialerAppId, QFileInfo());
2155+ ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
2156+ ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(dialerAppId));
2157+ ON_CALL(*mockDesktopFileReader, stageHint()).WillByDefault(Return("SideStage"));
2158+
2159+ ON_CALL(desktopFileReaderFactory, createInstance(dialerAppId, _))
2160+ .WillByDefault(Return(mockDesktopFileReader));
2161+ }
2162+
2163+ EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(dialerAppId, _))
2164+ .Times(1)
2165+ .WillOnce(Return(true));
2166+
2167+ /*auto application =*/ applicationManager.startApplication(dialerAppId, ApplicationManager::NoFlag);
2168+ applicationManager.onProcessStarting(dialerAppId);
2169+
2170+ {
2171+ bool authed = false;
2172+ applicationManager.authorizeSession(dialerPID, authed);
2173+ EXPECT_EQ(authed, true);
2174+ }
2175+
2176+ auto dialerSession = std::make_shared<mir::scene::MockSession>(dialerAppId.toStdString(), dialerPID);
2177+ sessionManager.onSessionStarting(dialerSession);
2178+ applicationManager.focusApplication(dialerAppId);
2179+ applicationManager.onSessionCreatedSurface(dialerSession.get(), dialerSurface);
2180+
2181+ /*** Focus webbrowser ***/
2182+
2183+ // Nothing should happen as it's already the running main stage app
2184+ EXPECT_CALL(*webbrowserSession.get(), set_lifecycle_state(_))
2185+ .Times(0);
2186+ applicationManager.focusApplication(webbrowserAppId);
2187+}
2188
2189=== modified file 'tests/modules/DesktopFileReader/desktopfilereader_test.cpp'
2190--- tests/modules/DesktopFileReader/desktopfilereader_test.cpp 2014-10-14 23:15:46 +0000
2191+++ tests/modules/DesktopFileReader/desktopfilereader_test.cpp 2015-02-05 10:26:37 +0000
2192@@ -126,3 +126,73 @@
2193 EXPECT_EQ(reader->comment(), "Ubuntu 简易计算器");
2194 EXPECT_EQ(reader->splashTitle(), "计算器 2.0");
2195 }
2196+
2197+TEST(DesktopFileReader, parseOrientations)
2198+{
2199+ using namespace ::testing;
2200+
2201+ const Qt::ScreenOrientations defaultOrientations = Qt::PortraitOrientation | Qt::LandscapeOrientation
2202+ | Qt::InvertedPortraitOrientation | Qt::InvertedLandscapeOrientation;
2203+ bool ok;
2204+ Qt::ScreenOrientations orientations;
2205+
2206+ ok = DesktopFileReader::parseOrientations(QString(), orientations);
2207+ ASSERT_TRUE(ok);
2208+ EXPECT_EQ(defaultOrientations, orientations);
2209+
2210+ ok = DesktopFileReader::parseOrientations("An invalid string!", orientations);
2211+ ASSERT_FALSE(ok);
2212+ EXPECT_EQ(defaultOrientations, orientations);
2213+
2214+ ok = DesktopFileReader::parseOrientations("landscape", orientations);
2215+ ASSERT_TRUE(ok);
2216+ EXPECT_EQ(Qt::LandscapeOrientation, orientations);
2217+
2218+ ok = DesktopFileReader::parseOrientations(" InvertedPortrait , Portrait ", orientations);
2219+ ASSERT_TRUE(ok);
2220+ EXPECT_EQ(Qt::InvertedPortraitOrientation | Qt::PortraitOrientation, orientations);
2221+
2222+ ok = DesktopFileReader::parseOrientations(",inverted-landscape, inverted_portrait, ", orientations);
2223+ ASSERT_TRUE(ok);
2224+ EXPECT_EQ(Qt::InvertedPortraitOrientation | Qt::InvertedLandscapeOrientation, orientations);
2225+
2226+ ok = DesktopFileReader::parseOrientations(",inverted-landscape, some-invalid-text, ", orientations);
2227+ ASSERT_FALSE(ok);
2228+ EXPECT_EQ(defaultOrientations, orientations);
2229+
2230+ ok = DesktopFileReader::parseOrientations("landscape;portrait", orientations);
2231+ ASSERT_TRUE(ok);
2232+ EXPECT_EQ(Qt::PortraitOrientation | Qt::LandscapeOrientation, orientations);
2233+
2234+ ok = DesktopFileReader::parseOrientations("primary", orientations);
2235+ ASSERT_TRUE(ok);
2236+ EXPECT_EQ(Qt::PrimaryOrientation, orientations);
2237+
2238+ ok = DesktopFileReader::parseOrientations("landscpe,primary", orientations);
2239+ ASSERT_FALSE(ok);
2240+ EXPECT_EQ(defaultOrientations, orientations);
2241+}
2242+
2243+TEST(DesktopFileReader, parseBoolean)
2244+{
2245+ using namespace ::testing;
2246+
2247+ bool ok;
2248+ bool boolean;
2249+
2250+ ok = DesktopFileReader::parseBoolean(QString(), boolean);
2251+ ASSERT_TRUE(ok);
2252+ EXPECT_EQ(false, boolean);
2253+
2254+ ok = DesktopFileReader::parseBoolean(" Yes ", boolean);
2255+ ASSERT_TRUE(ok);
2256+ EXPECT_EQ(true, boolean);
2257+
2258+ ok = DesktopFileReader::parseBoolean("False", boolean);
2259+ ASSERT_TRUE(ok);
2260+ EXPECT_EQ(false, boolean);
2261+
2262+ ok = DesktopFileReader::parseBoolean("Hello World!", boolean);
2263+ ASSERT_FALSE(ok);
2264+ EXPECT_EQ(false, boolean);
2265+}
2266
2267=== modified file 'tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp'
2268--- tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp 2014-12-12 15:15:06 +0000
2269+++ tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp 2015-02-05 10:26:37 +0000
2270@@ -15,6 +15,8 @@
2271 *
2272 */
2273
2274+#define MIR_INCLUDE_DEPRECATED_EVENT_HEADER
2275+
2276 #include <gtest/gtest.h>
2277
2278 #include <QLoggingCategory>
2279@@ -60,29 +62,43 @@
2280 EXPECT_CALL(*mockSurface, type()).Times(AnyNumber()).WillRepeatedly(Return(mir_surface_type_normal));
2281 EXPECT_CALL(*mockSession, setSurface(_)).Times(AnyNumber());
2282
2283+ auto get_touch_event = [](MirEvent const& event) -> MirTouchInputEvent const*
2284+ {
2285+ if (mir_event_get_type(&event) != mir_event_type_input)
2286+ return nullptr;
2287+ auto const* input_event = mir_event_get_input_event(&event);
2288+ if (mir_input_event_get_type(input_event) != mir_input_event_type_touch)
2289+ return nullptr;
2290+ return mir_input_event_get_touch_input_event(input_event);
2291+ };
2292+
2293+ auto event_matches = [&](MirEvent const& event,
2294+ int touch_count,
2295+ MirTouchInputEventTouchAction action,
2296+ MirTouchInputEventTouchId touch_id) ->void
2297+ {
2298+ auto const* touch_event = get_touch_event(event);
2299+ ASSERT_NE(touch_event, nullptr);
2300+ ASSERT_EQ(touch_count, mir_touch_input_event_get_touch_count(touch_event));
2301+ ASSERT_EQ(action, mir_touch_input_event_get_touch_action(touch_event,0));
2302+ ASSERT_EQ(touch_id, mir_touch_input_event_get_touch_id(touch_event,0));
2303+ };
2304+
2305 // The touch event sequence we expect mir::input::surface to receive from MirSurfaceItem.
2306 // It should properly finish the sequence for touch 0 ('down', 'move' and 'up') before starting
2307 // the sequence for touch 1.
2308 EXPECT_CALL(*mockSurface, consume(_))
2309- .WillOnce(Invoke([] (MirEvent const& mirEvent) {
2310- ASSERT_EQ(mir_motion_action_down, mirEvent.motion.action);
2311- ASSERT_EQ(1, mirEvent.motion.pointer_count);
2312- ASSERT_EQ(0, mirEvent.motion.pointer_coordinates[0].id);
2313- }))
2314- .WillOnce(Invoke([] (MirEvent const& mirEvent) {
2315- ASSERT_EQ(mir_motion_action_move, mirEvent.motion.action);
2316- ASSERT_EQ(1, mirEvent.motion.pointer_count);
2317- ASSERT_EQ(0, mirEvent.motion.pointer_coordinates[0].id);
2318- }))
2319- .WillOnce(Invoke([] (MirEvent const& mirEvent) {
2320- ASSERT_EQ(mir_motion_action_up, mirEvent.motion.action);
2321- ASSERT_EQ(1, mirEvent.motion.pointer_count);
2322- ASSERT_EQ(0, mirEvent.motion.pointer_coordinates[0].id);
2323- }))
2324- .WillOnce(Invoke([] (MirEvent const& mirEvent) {
2325- ASSERT_EQ(mir_motion_action_down, mirEvent.motion.action);
2326- ASSERT_EQ(1, mirEvent.motion.pointer_count);
2327- ASSERT_EQ(1, mirEvent.motion.pointer_coordinates[0].id);
2328+ .WillOnce(Invoke([&] (MirEvent const& mirEvent) {
2329+ event_matches(mirEvent, 1, mir_touch_input_event_action_down, 0);
2330+ }))
2331+ .WillOnce(Invoke([&] (MirEvent const& mirEvent) {
2332+ event_matches(mirEvent, 1, mir_touch_input_event_action_change, 0);
2333+ }))
2334+ .WillOnce(Invoke([&] (MirEvent const& mirEvent) {
2335+ event_matches(mirEvent, 1, mir_touch_input_event_action_up, 0);
2336+ }))
2337+ .WillOnce(Invoke([&] (MirEvent const& mirEvent) {
2338+ event_matches(mirEvent, 1, mir_touch_input_event_action_down, 1);
2339 }));
2340
2341
2342@@ -95,18 +111,18 @@
2343 touchPoints[0].setId(0);
2344 touchPoints[0].setState(Qt::TouchPointPressed);
2345 surfaceItem->processTouchEvent(QEvent::TouchBegin,
2346- timestamp, touchPoints, touchPoints[0].state());
2347+ timestamp, Qt::NoModifier, touchPoints, touchPoints[0].state());
2348
2349 touchPoints[0].setState(Qt::TouchPointMoved);
2350 surfaceItem->processTouchEvent(QEvent::TouchUpdate,
2351- timestamp + 10, touchPoints, touchPoints[0].state());
2352+ timestamp + 10, Qt::NoModifier, touchPoints, touchPoints[0].state());
2353
2354 // Starting a new touch sequence (with touch 1) without ending the current one
2355 // (wich has touch 0).
2356 touchPoints[0].setId(1);
2357 touchPoints[0].setState(Qt::TouchPointPressed);
2358 surfaceItem->processTouchEvent(QEvent::TouchBegin,
2359- timestamp + 20, touchPoints, touchPoints[0].state());
2360+ timestamp + 20, Qt::NoModifier, touchPoints, touchPoints[0].state());
2361
2362 delete surfaceItem;
2363 delete mockSession;
2364
2365=== removed file 'tests/modules/common/mock_focus_controller.h'
2366--- tests/modules/common/mock_focus_controller.h 2014-09-11 16:18:40 +0000
2367+++ tests/modules/common/mock_focus_controller.h 1970-01-01 00:00:00 +0000
2368@@ -1,40 +0,0 @@
2369-/*
2370- * Copyright (C) 2014 Canonical, Ltd.
2371- *
2372- * This program is free software: you can redistribute it and/or modify it under
2373- * the terms of the GNU Lesser General Public License version 3, as published by
2374- * the Free Software Foundation.
2375- *
2376- * This program is distributed in the hope that it will be useful, but WITHOUT
2377- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2378- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2379- * Lesser General Public License for more details.
2380- *
2381- * You should have received a copy of the GNU Lesser General Public License
2382- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2383- *
2384- */
2385-
2386-#ifndef MOCK_MIR_SHELL_FOCUS_CONTROLLER_H
2387-#define MOCK_MIR_SHELL_FOCUS_CONTROLLER_H
2388-
2389-#include <mir/shell/focus_controller.h>
2390-#include <gmock/gmock.h>
2391-
2392-#include <string>
2393-
2394-namespace mir {
2395-namespace shell {
2396-
2397-class MockFocusController : public FocusController
2398-{
2399-public:
2400- MOCK_METHOD0(focus_next, void());
2401- MOCK_CONST_METHOD0(focussed_application, std::weak_ptr<scene::Session>());
2402- MOCK_METHOD1(set_focus_to, void(std::shared_ptr<scene::Session>const&));
2403-};
2404-
2405-} // namespace shell
2406-} // namespace mir
2407-
2408-#endif // MOCK_MIR_SHELL_FOCUS_CONTROLLER_H_
2409
2410=== modified file 'tests/modules/common/mock_mir_session.h'
2411--- tests/modules/common/mock_mir_session.h 2015-01-07 15:35:29 +0000
2412+++ tests/modules/common/mock_mir_session.h 2015-02-05 10:26:37 +0000
2413@@ -49,6 +49,7 @@
2414
2415 MOCK_CONST_METHOD0(default_surface, std::shared_ptr<Surface>());
2416 MOCK_CONST_METHOD1(get_surface, std::shared_ptr<frontend::Surface>(frontend::SurfaceId));
2417+ MOCK_CONST_METHOD1(surface, std::shared_ptr<scene::Surface>(frontend::SurfaceId));
2418
2419 MOCK_METHOD1(take_snapshot, void(SnapshotCallback const&));
2420 MOCK_METHOD1(set_lifecycle_state, void(MirLifecycleState));
2421
2422=== modified file 'tests/modules/common/mock_renderable.h'
2423--- tests/modules/common/mock_renderable.h 2014-09-11 16:18:40 +0000
2424+++ tests/modules/common/mock_renderable.h 2015-02-05 10:26:37 +0000
2425@@ -34,9 +34,7 @@
2426 MOCK_CONST_METHOD0(screen_position, geometry::Rectangle());
2427 MOCK_CONST_METHOD0(alpha, float() );
2428 MOCK_CONST_METHOD0(transformation, glm::mat4());
2429- MOCK_CONST_METHOD0(visible, bool());
2430 MOCK_CONST_METHOD0(shaped, bool());
2431- MOCK_CONST_METHOD0(buffers_ready_for_compositor, int());
2432 };
2433
2434 } // namespace graphics
2435
2436=== modified file 'tests/modules/common/mock_surface.h'
2437--- tests/modules/common/mock_surface.h 2015-01-06 17:28:52 +0000
2438+++ tests/modules/common/mock_surface.h 2015-02-05 10:26:37 +0000
2439@@ -36,6 +36,7 @@
2440 MOCK_CONST_METHOD0(input_bounds, geometry::Rectangle());
2441 MOCK_CONST_METHOD0(top_left, geometry::Point());
2442 MOCK_CONST_METHOD0(size, geometry::Size());
2443+ MOCK_CONST_METHOD0(parent, std::shared_ptr<Surface>());
2444
2445 std::unique_ptr<graphics::Renderable> compositor_snapshot(void const* /*compositor_id*/) const
2446 {
2447@@ -64,6 +65,7 @@
2448 MOCK_CONST_METHOD0(input_channel, std::shared_ptr<input::InputChannel>());
2449 MOCK_METHOD1(set_reception_mode, void(input::InputReceptionMode mode));
2450 MOCK_METHOD0(request_client_surface_close, void());
2451+ MOCK_CONST_METHOD1(buffers_ready_for_compositor, int(void const*));
2452
2453 // from mir::input::surface
2454 MOCK_CONST_METHOD1(input_area_contains, bool(geometry::Point const& point));
2455
2456=== modified file 'tests/modules/common/qtmir_test.h'
2457--- tests/modules/common/qtmir_test.h 2015-01-09 11:24:44 +0000
2458+++ tests/modules/common/qtmir_test.h 2015-02-05 10:26:37 +0000
2459@@ -33,7 +33,6 @@
2460 #include "mock_desktop_file_reader.h"
2461 #include "mock_proc_info.h"
2462 #include "mock_mir_session.h"
2463-#include "mock_focus_controller.h"
2464 #include "mock_prompt_session_manager.h"
2465 #include "mock_prompt_session.h"
2466 #include "mock_shared_wakelock.h"

Subscribers

People subscribed via source and target branches