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

Proposed by kevin gunn on 2015-02-03
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 2015-02-03 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 on 2015-02-04

merged daniels branch into this one

321. By kevin gunn on 2015-02-04

fix typo

322. By Andreas Pokorny on 2015-02-04

duplicate mock entry oO

323. By Andreas Pokorny on 2015-02-04

fix test cases

324. By kevin gunn on 2015-02-05

added mirsurfaceattribute to the qtmir application

Unmerged revisions

324. By kevin gunn on 2015-02-05

added mirsurfaceattribute to the qtmir application

323. By Andreas Pokorny on 2015-02-04

fix test cases

322. By Andreas Pokorny on 2015-02-04

duplicate mock entry oO

321. By kevin gunn on 2015-02-04

fix typo

320. By Andreas Pokorny on 2015-02-04

merged daniels branch into this one

319. By kevin gunn on 2015-02-03

merge port to shell and mir event

318. By Robert Carr on 2015-01-30

Finish touch-event-support

317. By Robert Carr on 2015-01-29

Implement touch mods

316. By Robert Carr on 2015-01-29

Typo

315. By Robert Carr on 2015-01-29

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