Merge lp:~gerboland/qtmir/exposeOrientation into lp:qtmir

Proposed by Gerry Boland
Status: Merged
Approved by: Michael Zanetti
Approved revision: 244
Merged at revision: 255
Proposed branch: lp:~gerboland/qtmir/exposeOrientation
Merge into: lp:qtmir
Diff against target: 325 lines (+170/-2)
6 files modified
src/modules/Unity/Application/mirsurfaceitem.cpp (+48/-0)
src/modules/Unity/Application/mirsurfaceitem.h (+5/-0)
src/platforms/mirserver/logging.h (+1/-0)
src/platforms/mirserver/mirserverintegration.cpp (+11/-0)
src/platforms/mirserver/screen.cpp (+95/-2)
src/platforms/mirserver/screen.h (+10/-0)
To merge this branch: bzr merge lp:~gerboland/qtmir/exposeOrientation
Reviewer Review Type Date Requested Status
Michael Zanetti (community) Abstain
Daniel d'Andrada (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+232485@code.launchpad.net

Commit message

Expose Mir surface orientation property to QML

Description of the change

Expose Mir surface orientation property to QML

 * Are there any related MPs required for this MP to build/function as expected? Please list.
https://code.launchpad.net/~gerboland/unity8/orientationLock/+merge/232484
https://code.launchpad.net/~gerboland/qtubuntu/exposeOrientation/+merge/232252
https://code.launchpad.net/~gerboland/platform-api/exposeOrientation/+merge/232250

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Y

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Now that prompts-in-prompts has landed, there are merge conflicts in:
src/modules/Unity/Application/mirsurfaceitem.cpp
src/modules/Unity/Application/mirsurfaceitem.h

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

In src/modules/Unity/Application/mirsurfaceitem.cpp:

"""
    case Qt::PortraitOrientation:
        mirOrientation = mir_orientation_normal;
"""

Here you're assuming that the screen aspect-ratio is portrait, which is not always the case.

Qt::ScreenOrientation values do not map directly to MirOrientation ones. The two enums express orientation differently. Trying to shoehorn one into the other is no good.

Either do a proper translation between the two or make MirSurfaceItem::orientation use an enum that does match with MirOrientation.

------------------------

In src/platforms/mirserver/screen.cpp:

Who's calling Screen::toggleSensors()?
It was supposed to be called whenever the display goes on and off.

---------------------------

In src/platforms/mirserver/screen.cpp:

"""
    QCoreApplication::postEvent(this, new OrientationReadingEvent(
                                    OrientationReadingEvent::m_type, m_orientationSensor->reading()->orientation()));
"""

Weird indentation.

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

> In src/modules/Unity/Application/mirsurfaceitem.cpp:
>
> """
> case Qt::PortraitOrientation:
> mirOrientation = mir_orientation_normal;
> """
>
> Here you're assuming that the screen aspect-ratio is portrait, which is not
> always the case.

Why would we care here? This is just the shell telling an application: this is your orientation now.

> Qt::ScreenOrientation values do not map directly to MirOrientation ones. The
> two enums express orientation differently. Trying to shoehorn one into the
> other is no good.

I think it's a bad idea that there are 2 ways to express orientation, and we should just use one. You don't like that I ignore PrimaryOrientation?

> Either do a proper translation between the two or make
> MirSurfaceItem::orientation use an enum that does match with MirOrientation.

I prefer using a subset of an existing enum than creating a new enum. QML already knows about Qt::*Orientation - it would be a waste to duplicate it IMO.

> ------------------------
>
> In src/platforms/mirserver/screen.cpp:
>
> Who's calling Screen::toggleSensors()?
> It was supposed to be called whenever the display goes on and off.

Nobody yet. I had hoped to wire it up to the hide/show window event for display off/on, but that event doesn't happen. I'm not sure what signal to wire it up to still. Will be later MR.

> ---------------------------
>
> In src/platforms/mirserver/screen.cpp:
>
> """
> QCoreApplication::postEvent(this, new OrientationReadingEvent(
> OrientationReadingEvent::m_type,
> m_orientationSensor->reading()->orientation()));
> """
>
> Weird indentation.
done

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> > In src/modules/Unity/Application/mirsurfaceitem.cpp:
> >
> > """
> > case Qt::PortraitOrientation:
> > mirOrientation = mir_orientation_normal;
> > """
> >
> > Here you're assuming that the screen aspect-ratio is portrait, which is not
> > always the case.
>
> Why would we care here? This is just the shell telling an application: this is
> your orientation now.

Because the code is wrong. If it's a main stage tablet app and shell says "surface.orientation = Landscape" it means mir_orientation_normal, not mir_orientation_left.

>
> > Qt::ScreenOrientation values do not map directly to MirOrientation ones. The
> > two enums express orientation differently. Trying to shoehorn one into the
> > other is no good.
>
> I think it's a bad idea that there are 2 ways to express orientation, and we
> should just use one.

But that's what we have in your patch. There's Qt::ScreenOrientation and MirOrientation. Ignoring it will not make it go away. :)

So I will more explicitly: I see two ways of fixing it:
1 - Doing the proper translation from Qt::ScreenOrientation to MirOrientation in MirSurfaceItem::setOrientation
2 - Using an enum semantically equivalent to MirOrientation in MirSurfaceItem.orientation.

> You don't like that I ignore PrimaryOrientation?

It's not about that. But now that you mentioned it, there should be at least a warning if unity8 uses it if it's explicitly not supported. Otherwise we would be hiding an implementation bug in unity8.

>
> > Either do a proper translation between the two or make
> > MirSurfaceItem::orientation use an enum that does match with MirOrientation.
>
> I prefer using a subset of an existing enum than creating a new enum. QML
> already knows about Qt::*Orientation - it would be a waste to duplicate it
> IMO.

I suppose you're talking about going for the option 2 above. We wouldn't be duplicating Qt::ScreenOrientation as it would be a semantically different enum.

>
>
>
> > ------------------------
> >
> > In src/platforms/mirserver/screen.cpp:
> >
> > Who's calling Screen::toggleSensors()?
> > It was supposed to be called whenever the display goes on and off.
>
> Nobody yet. I had hoped to wire it up to the hide/show window event for
> display off/on, but that event doesn't happen. I'm not sure what signal to
> wire it up to still. Will be later MR.

If not body uses it then it's dead code. I think it would be better to only add it once we have use for it.

Btw, I think we should have a big FIXME somewhere saying that we must turn off the orientation sensor when the display is off.

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

> > I think it's a bad idea that there are 2 ways to express orientation, and we
> > should just use one.
>
> But that's what we have in your patch. There's Qt::ScreenOrientation and
> MirOrientation. Ignoring it will not make it go away. :)
>
> So I will more explicitly: I see two ways of fixing it:
> 1 - Doing the proper translation from Qt::ScreenOrientation to MirOrientation
> in MirSurfaceItem::setOrientation

I finally saw what you mean. I'm not such a big fan of it, and it relies other toolkits to deal with orientation in the same way Qt does (i.e. compare supplied orientation with a deduced native orientation), but anyway: it's done.

> > You don't like that I ignore PrimaryOrientation?
>
> It's not about that. But now that you mentioned it, there should be at least a
> warning if unity8 uses it if it's explicitly not supported. Otherwise we would
> be hiding an implementation bug in unity8.

I implemented it properly, PrimaryOrientation = native orientation.

> > > ------------------------
> > >
> > > In src/platforms/mirserver/screen.cpp:
> > >
> > > Who's calling Screen::toggleSensors()?
> > > It was supposed to be called whenever the display goes on and off.
> >
> > Nobody yet. I had hoped to wire it up to the hide/show window event for
> > display off/on, but that event doesn't happen. I'm not sure what signal to
> > wire it up to still. Will be later MR.
>
> If not body uses it then it's dead code. I think it would be better to only
> add it once we have use for it.
>
> Btw, I think we should have a big FIXME somewhere saying that we must turn off
> the orientation sensor when the display is off.

It's not dead if we'll use it soon :) I added a FIXME on top of the method. Will that do?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> [...]
>
> I finally saw what you mean. I'm not such a big fan of it, and it relies other
> toolkits to deal with orientation in the same way Qt does (i.e. compare
> supplied orientation with a deduced native orientation), but anyway: it's
> done.

Didn't get your comment. It relies on other toolkits dealing with MirOrientation the way it's defined. e.g. "rotate UI left by 90 if mir_orientation_left", "right by 90 if mir_orientation_right" and so on. Regardless of the aspect ratio.

But anyway, glad you did the change so I'm happy with it now. :)

--------------------------------

In src/modules/Unity/Application/mirsurfaceitem.cpp:

"""
    default:
        qWarning("Unrecognized Qt::ScreenOrientation!");
        return;
"""

It should use qCWarning(QTMIR_SURFACES), but I won't block this MP because of that as this review has been going on for too long now.

review: Approve
Revision history for this message
Michael Zanetti (mzanetti) wrote :

Text conflict in src/modules/Unity/Application/mirsurfaceitem.h
1 conflicts encountered.

review: Needs Fixing
244. By Gerry Boland

Merge trunk and resolve conflict

Revision history for this message
Michael Zanetti (mzanetti) wrote :

conflicts fixed.

review: Abstain
245. By Gerry Boland

Merge trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/modules/Unity/Application/mirsurfaceitem.cpp'
2--- src/modules/Unity/Application/mirsurfaceitem.cpp 2014-09-11 20:21:47 +0000
3+++ src/modules/Unity/Application/mirsurfaceitem.cpp 2014-09-19 12:20:29 +0000
4@@ -30,8 +30,10 @@
5
6 // Qt
7 #include <QDebug>
8+#include <QGuiApplication>
9 #include <QQmlEngine>
10 #include <QQuickWindow>
11+#include <QScreen>
12 #include <QSGSimpleTextureNode>
13 #include <QSGTextureProvider>
14 #include <QTimer>
15@@ -243,6 +245,7 @@
16 , m_session(session)
17 , m_firstFrameDrawn(false)
18 , m_live(true)
19+ , m_orientation(Qt::PortraitOrientation)
20 , m_textureProvider(nullptr)
21 , m_lastTouchEvent(nullptr)
22 {
23@@ -349,6 +352,51 @@
24 return static_cast<MirSurfaceItem::State>(m_surface->state());
25 }
26
27+Qt::ScreenOrientation MirSurfaceItem::orientation() const
28+{
29+ return m_orientation;
30+}
31+
32+void MirSurfaceItem::setOrientation(const Qt::ScreenOrientation orientation)
33+{
34+ qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::setOrientation - orientation=" << orientation;
35+
36+ if (m_orientation == orientation)
37+ return;
38+
39+ MirOrientation mirOrientation;
40+ Qt::ScreenOrientation nativeOrientation = QGuiApplication::primaryScreen()->nativeOrientation();
41+ const bool landscapeNativeOrientation = (nativeOrientation == Qt::LandscapeOrientation);
42+
43+ Qt::ScreenOrientation requestedOrientation = orientation;
44+ if (orientation == Qt::PrimaryOrientation) { // means orientation equals native orientation, set it as such
45+ requestedOrientation = nativeOrientation;
46+ }
47+
48+ switch(requestedOrientation) {
49+ case Qt::PortraitOrientation:
50+ mirOrientation = (landscapeNativeOrientation) ? mir_orientation_right : mir_orientation_normal;
51+ break;
52+ case Qt::LandscapeOrientation:
53+ mirOrientation = (landscapeNativeOrientation) ? mir_orientation_normal : mir_orientation_left;
54+ break;
55+ case Qt::InvertedPortraitOrientation:
56+ mirOrientation = (landscapeNativeOrientation) ? mir_orientation_left : mir_orientation_inverted;
57+ break;
58+ case Qt::InvertedLandscapeOrientation:
59+ mirOrientation = (landscapeNativeOrientation) ? mir_orientation_inverted : mir_orientation_right;
60+ break;
61+ default:
62+ qWarning("Unrecognized Qt::ScreenOrientation!");
63+ return;
64+ }
65+
66+ m_surface->set_orientation(mirOrientation);
67+
68+ m_orientation = orientation;
69+ Q_EMIT orientationChanged();
70+}
71+
72 QString MirSurfaceItem::name() const
73 {
74 //FIXME - how to listen to change in this property?
75
76=== modified file 'src/modules/Unity/Application/mirsurfaceitem.h'
77--- src/modules/Unity/Application/mirsurfaceitem.h 2014-09-11 20:21:47 +0000
78+++ src/modules/Unity/Application/mirsurfaceitem.h 2014-09-19 12:20:29 +0000
79@@ -75,6 +75,7 @@
80 Q_PROPERTY(State state READ state NOTIFY stateChanged)
81 Q_PROPERTY(QString name READ name NOTIFY nameChanged)
82 Q_PROPERTY(bool live READ live NOTIFY liveChanged)
83+ Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged DESIGNABLE false)
84
85 public:
86 explicit MirSurfaceItem(std::shared_ptr<mir::scene::Surface> surface,
87@@ -107,6 +108,7 @@
88 State state() const;
89 QString name() const;
90 bool live() const;
91+ Qt::ScreenOrientation orientation() const;
92 SessionInterface *session() const;
93
94 Q_INVOKABLE void release();
95@@ -120,6 +122,7 @@
96
97 bool isFirstFrameDrawn() const { return m_firstFrameDrawn; }
98
99+ void setOrientation(const Qt::ScreenOrientation orientation);
100 void setSession(SessionInterface *app);
101
102 // to allow easy touch event injection from tests
103@@ -132,6 +135,7 @@
104 void typeChanged();
105 void stateChanged();
106 void nameChanged();
107+ void orientationChanged();
108 void liveChanged(bool live);
109 void firstFrameDrawn(MirSurfaceItem *item);
110
111@@ -191,6 +195,7 @@
112 QPointer<SessionInterface> m_session;
113 bool m_firstFrameDrawn;
114 bool m_live;
115+ Qt::ScreenOrientation m_orientation; //FIXME - have to save the state as Mir has no getter for it (bug:1357429)
116
117 QMirSurfaceTextureProvider *m_textureProvider;
118
119
120=== modified file 'src/platforms/mirserver/logging.h'
121--- src/platforms/mirserver/logging.h 2014-09-07 19:42:14 +0000
122+++ src/platforms/mirserver/logging.h 2014-09-19 12:20:29 +0000
123@@ -22,6 +22,7 @@
124 Q_DECLARE_LOGGING_CATEGORY(QTMIR_SESSIONS)
125 Q_DECLARE_LOGGING_CATEGORY(QTMIR_SURFACES)
126 Q_DECLARE_LOGGING_CATEGORY(QTMIR_MIR_MESSAGES)
127+Q_DECLARE_LOGGING_CATEGORY(QTMIR_SENSOR_MESSAGES)
128 Q_DECLARE_LOGGING_CATEGORY(QTMIR_MIR_INPUT)
129
130 #endif // UBUNTU_APPLICATION_PLUGIN_LOGGING_H
131
132=== modified file 'src/platforms/mirserver/mirserverintegration.cpp'
133--- src/platforms/mirserver/mirserverintegration.cpp 2014-07-08 18:23:45 +0000
134+++ src/platforms/mirserver/mirserverintegration.cpp 2014-09-19 12:20:29 +0000
135@@ -80,6 +80,17 @@
136 }
137 argv[args.size()] = '\0';
138
139+ // For access to sensors, qtmir uses qtubuntu-sensors. qtubuntu-sensors reads the
140+ // UBUNTU_PLATFORM_API_BACKEND variable to decide if to load a valid sensor backend or not.
141+ // For it to function we need to ensure a valid backend has been specified
142+ if (qEnvironmentVariableIsEmpty("UBUNTU_PLATFORM_API_BACKEND")) {
143+ if (qgetenv("DESKTOP_SESSION").contains("mir")) {
144+ qputenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirserver");
145+ } else {
146+ qputenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirserver");
147+ }
148+ }
149+
150 m_mirConfig = QSharedPointer<MirServerConfiguration>(
151 new MirServerConfiguration(args.length(), const_cast<const char**>(argv)));
152
153
154=== modified file 'src/platforms/mirserver/screen.cpp'
155--- src/platforms/mirserver/screen.cpp 2014-07-08 18:31:50 +0000
156+++ src/platforms/mirserver/screen.cpp 2014-09-19 12:20:29 +0000
157@@ -18,8 +18,11 @@
158 * Gerry Boland <gerry.boland@canonical.com>
159 */
160
161+// local
162 #include "screen.h"
163+#include "logging.h"
164
165+// Mir
166 #include "mir/geometry/size.h"
167
168 // Qt
169@@ -29,8 +32,14 @@
170 #include <QtSensors/QOrientationReading>
171 #include <QThread>
172
173+// Qt sensors
174+#include <QtSensors/QOrientationReading>
175+#include <QtSensors/QOrientationSensor>
176+
177 namespace mg = mir::geometry;
178
179+Q_LOGGING_CATEGORY(QTMIR_SENSOR_MESSAGES, "qtmir.sensor")
180+
181 namespace {
182 bool isLittleEndian() {
183 unsigned int i = 1;
184@@ -80,16 +89,42 @@
185
186 } // namespace {
187
188+
189+class OrientationReadingEvent : public QEvent {
190+public:
191+ OrientationReadingEvent(QEvent::Type type, QOrientationReading::Orientation orientation)
192+ : QEvent(type)
193+ , m_orientation(orientation) {
194+ }
195+
196+ static const QEvent::Type m_type;
197+ QOrientationReading::Orientation m_orientation;
198+};
199+
200+const QEvent::Type OrientationReadingEvent::m_type =
201+ static_cast<QEvent::Type>(QEvent::registerEventType());
202+
203+
204+
205 Screen::Screen(mir::graphics::DisplayConfigurationOutput const &screen)
206 : QObject(nullptr)
207+ , m_orientationSensor(new QOrientationSensor(this))
208 {
209 readMirDisplayConfiguration(screen);
210
211 // Set the default orientation based on the initial screen dimmensions.
212 m_nativeOrientation = (m_geometry.width() >= m_geometry.height())
213 ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
214-
215- m_currentOrientation = m_nativeOrientation;
216+ qCDebug(QTMIR_SENSOR_MESSAGES) << "Screen - nativeOrientation is:" << m_nativeOrientation;
217+
218+ // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait
219+ m_currentOrientation = (m_nativeOrientation == Qt::LandscapeOrientation)
220+ ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
221+ qCDebug(QTMIR_SENSOR_MESSAGES) << "Screen - initial currentOrientation is:" << m_currentOrientation;
222+
223+ QObject::connect(m_orientationSensor, &QOrientationSensor::readingChanged,
224+ this, &Screen::onOrientationReadingChanged);
225+ m_orientationSensor->start();
226 }
227
228 void Screen::readMirDisplayConfiguration(mir::graphics::DisplayConfigurationOutput const &screen)
229@@ -111,3 +146,61 @@
230
231 m_refreshRate = mode.vrefresh_hz;
232 }
233+
234+// FIXME: nothing is using this method yet, but we should turn off sensors when display is off.
235+void Screen::toggleSensors(const bool enable) const
236+{
237+ qCDebug(QTMIR_SENSOR_MESSAGES) << "Screen::toggleSensors - enable=" << enable;
238+ if (enable) {
239+ m_orientationSensor->start();
240+ } else {
241+ m_orientationSensor->stop();
242+ }
243+}
244+
245+void Screen::customEvent(QEvent* event)
246+{
247+ OrientationReadingEvent* oReadingEvent = static_cast<OrientationReadingEvent*>(event);
248+ switch (oReadingEvent->m_orientation) {
249+ case QOrientationReading::LeftUp: {
250+ m_currentOrientation = (m_nativeOrientation == Qt::LandscapeOrientation) ?
251+ Qt::InvertedPortraitOrientation : Qt::LandscapeOrientation;
252+ break;
253+ }
254+ case QOrientationReading::TopUp: {
255+ m_currentOrientation = (m_nativeOrientation == Qt::LandscapeOrientation) ?
256+ Qt::LandscapeOrientation : Qt::PortraitOrientation;
257+ break;
258+ }
259+ case QOrientationReading::RightUp: {
260+ m_currentOrientation = (m_nativeOrientation == Qt::LandscapeOrientation) ?
261+ Qt::PortraitOrientation : Qt::InvertedLandscapeOrientation;
262+ break;
263+ }
264+ case QOrientationReading::TopDown: {
265+ m_currentOrientation = (m_nativeOrientation == Qt::LandscapeOrientation) ?
266+ Qt::InvertedLandscapeOrientation : Qt::InvertedPortraitOrientation;
267+ break;
268+ }
269+ default: {
270+ qWarning("Unknown orientation.");
271+ event->accept();
272+ return;
273+ }
274+ }
275+
276+ // Raise the event signal so that client apps know the orientation changed
277+ QWindowSystemInterface::handleScreenOrientationChange(screen(), m_currentOrientation);
278+ event->accept();
279+ qCDebug(QTMIR_SENSOR_MESSAGES) << "Screen::customEvent - new orientation" << m_currentOrientation << "handled";
280+}
281+
282+void Screen::onOrientationReadingChanged()
283+{
284+ qCDebug(QTMIR_SENSOR_MESSAGES) << "Screen::onOrientationReadingChanged";
285+
286+ // Make sure to switch to the main Qt thread context
287+ QCoreApplication::postEvent(this, new OrientationReadingEvent(
288+ OrientationReadingEvent::m_type,
289+ m_orientationSensor->reading()->orientation()));
290+}
291
292=== modified file 'src/platforms/mirserver/screen.h'
293--- src/platforms/mirserver/screen.h 2014-06-30 16:13:01 +0000
294+++ src/platforms/mirserver/screen.h 2014-09-19 12:20:29 +0000
295@@ -23,6 +23,7 @@
296 #include <QObject>
297 #include <QTimer>
298 #include <qpa/qplatformscreen.h>
299+
300 #include "mir/graphics/display_configuration.h"
301
302 class QOrientationSensor;
303@@ -42,6 +43,14 @@
304 Qt::ScreenOrientation nativeOrientation() const override { return m_nativeOrientation; }
305 Qt::ScreenOrientation orientation() const override { return m_currentOrientation; }
306
307+ void toggleSensors(const bool enable) const;
308+
309+ // QObject methods.
310+ void customEvent(QEvent* event) override;
311+
312+public Q_SLOTS:
313+ void onOrientationReadingChanged();
314+
315 private:
316 void readMirDisplayConfiguration(mir::graphics::DisplayConfigurationOutput const&);
317
318@@ -53,6 +62,7 @@
319
320 Qt::ScreenOrientation m_nativeOrientation;
321 Qt::ScreenOrientation m_currentOrientation;
322+ QOrientationSensor *m_orientationSensor;
323 };
324
325 #endif // SCREEN_H

Subscribers

People subscribed via source and target branches