From 2ed43741ab4106c6a1e9eb3a5cb9a6c5ff34f450 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <samuel.rodal@nokia.com>
Date: Mon, 13 Feb 2012 20:39:22 +0100
Subject: [PATCH] Added convenience properties in WaylandSurface for window
 orientation.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The new windowRotation property is especially useful for the compositor
to know how much the surface needs to be rotated in order to be
displayed correctly.

Change-Id: I81ee17880ceafd465c39b4439dee978f2cb80924
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
---
 examples/qml-compositor/main.cpp              |  5 +++++
 .../qml/QmlCompositor/WindowContainer.qml     |  5 ++++-
 .../compositor_api/waylandcompositor.cpp      |  5 +++++
 .../compositor_api/waylandcompositor.h        |  2 ++
 .../compositor_api/waylandsurface.cpp         | 22 ++++++++++++++++++-
 .../compositor_api/waylandsurface.h           |  7 ++++++
 .../compositor_api/waylandsurfaceitem.cpp     |  6 +++++
 .../compositor_api/waylandsurfaceitem.h       |  3 ++-
 .../wayland_wrapper/wlcompositor.cpp          |  5 +++++
 src/compositor/wayland_wrapper/wlcompositor.h |  1 +
 .../wayland_wrapper/wlextendedsurface.cpp     |  8 +++++++
 src/compositor/wayland_wrapper/wloutput.h     |  1 +
 12 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/examples/qml-compositor/main.cpp b/examples/qml-compositor/main.cpp
index 530fee8b..8a016f39 100644
--- a/examples/qml-compositor/main.cpp
+++ b/examples/qml-compositor/main.cpp
@@ -101,6 +101,11 @@ private slots:
     }
 
 protected:
+    void resizeEvent(QResizeEvent *)
+    {
+        WaylandCompositor::setOutputGeometry(QRect(0, 0, width(), height()));
+    }
+
     void surfaceCreated(WaylandSurface *surface) {
         WaylandSurfaceItem *item = new WaylandSurfaceItem(surface, rootObject());
         item->setTouchEventsEnabled(true);
diff --git a/examples/qml-compositor/qml/QmlCompositor/WindowContainer.qml b/examples/qml-compositor/qml/QmlCompositor/WindowContainer.qml
index ed1dad54..ae70e3b8 100644
--- a/examples/qml-compositor/qml/QmlCompositor/WindowContainer.qml
+++ b/examples/qml-compositor/qml/QmlCompositor/WindowContainer.qml
@@ -86,7 +86,10 @@ Item {
         }
     }
 
-    transform: Scale { id: scaleTransform; origin.x: container.width / 2; origin.y: container.height / 2; xScale: 1; yScale: 1 }
+    transform: [
+        Rotation { origin.x: container.width / 2; origin.y: container.height / 2; angle: (child && child.surface ? child.surface.windowRotation : 0) },
+        Scale { id: scaleTransform; origin.x: container.width / 2; origin.y: container.height / 2; xScale: 1; yScale: 1 }
+    ]
 
     SequentialAnimation {
         id: destroyAnimation
diff --git a/src/compositor/compositor_api/waylandcompositor.cpp b/src/compositor/compositor_api/waylandcompositor.cpp
index b1388cbe..9196a574 100644
--- a/src/compositor/compositor_api/waylandcompositor.cpp
+++ b/src/compositor/compositor_api/waylandcompositor.cpp
@@ -157,6 +157,11 @@ void WaylandCompositor::setOutputGeometry(const QRect &geometry)
     m_compositor->setOutputGeometry(geometry);
 }
 
+QRect WaylandCompositor::outputGeometry() const
+{
+    return m_compositor->outputGeometry();
+}
+
 WaylandInputDevice *WaylandCompositor::defaultInputDevice() const
 {
     return m_compositor->defaultInputDevice()->handle();
diff --git a/src/compositor/compositor_api/waylandcompositor.h b/src/compositor/compositor_api/waylandcompositor.h
index 3cc255a8..22072659 100644
--- a/src/compositor/compositor_api/waylandcompositor.h
+++ b/src/compositor/compositor_api/waylandcompositor.h
@@ -82,7 +82,9 @@ public:
     const char *socketName() const;
 
     void setScreenOrientation(Qt::ScreenOrientation orientation);
+
     void setOutputGeometry(const QRect &outputGeometry);
+    QRect outputGeometry() const;
 
     WaylandInputDevice *defaultInputDevice() const;
 
diff --git a/src/compositor/compositor_api/waylandsurface.cpp b/src/compositor/compositor_api/waylandsurface.cpp
index e9be748c..7effff05 100644
--- a/src/compositor/compositor_api/waylandsurface.cpp
+++ b/src/compositor/compositor_api/waylandsurface.cpp
@@ -47,8 +47,12 @@
 #include "wayland_wrapper/wlsubsurface.h"
 #include "wayland_wrapper/wlcompositor.h"
 
+#include "waylandcompositor.h"
 #include "waylandwindowmanagerintegration.h"
 
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+
 #ifdef QT_COMPOSITOR_QUICK
 #include "waylandsurfaceitem.h"
 #endif
@@ -80,7 +84,7 @@ public:
 WaylandSurface::WaylandSurface(Wayland::Surface *surface)
     : QObject(*new WaylandSurfacePrivate(surface))
 {
-
+    connect(this, SIGNAL(windowOrientationChanged()), this, SIGNAL(windowRotationChanged()));
 }
 
 WaylandSurface *WaylandSurface::parentSurface() const
@@ -159,7 +163,23 @@ Qt::ScreenOrientation WaylandSurface::windowOrientation() const
     return d->surface->extendedSurface()->windowOrientation();
 }
 
+/*!
+   \property windowRotation
+
+   Convenience property to get the rotation required to map the surface to the screen
+   based on its windowOrientation.
+ */
+int WaylandSurface::windowRotation() const
+{
+    QRect geometry = compositor()->outputGeometry();
+    Qt::ScreenOrientation compositorOrientation = geometry.width() >= geometry.height() ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
+    Qt::ScreenOrientation wOrientation = windowOrientation();
 
+    if (wOrientation == Qt::PrimaryOrientation)
+        return 0;
+
+    return QGuiApplication::primaryScreen()->angleBetween(wOrientation, compositorOrientation);
+}
 
 WaylandSurface::WindowFlags WaylandSurface::windowFlags() const
 {
diff --git a/src/compositor/compositor_api/waylandsurface.h b/src/compositor/compositor_api/waylandsurface.h
index 83490661..40b87017 100644
--- a/src/compositor/compositor_api/waylandsurface.h
+++ b/src/compositor/compositor_api/waylandsurface.h
@@ -73,6 +73,9 @@ class Q_COMPOSITOR_EXPORT WaylandSurface : public QObject
     Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged)
     Q_PROPERTY(QPointF pos READ pos WRITE setPos NOTIFY posChanged)
     Q_PROPERTY(WaylandSurface::WindowFlags windowFlags READ windowFlags NOTIFY windowFlagsChanged)
+    Q_PROPERTY(Qt::ScreenOrientation windowOrientation READ windowOrientation NOTIFY windowOrientationChanged)
+    Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation NOTIFY contentOrientationChanged)
+    Q_PROPERTY(int windowRotation READ windowRotation NOTIFY windowRotationChanged)
 
     Q_ENUMS(WindowFlag)
     Q_FLAGS(WindowFlag WindowFlags)
@@ -107,6 +110,7 @@ public:
 
     Qt::ScreenOrientation contentOrientation() const;
     Qt::ScreenOrientation windowOrientation() const;
+    int windowRotation() const;
 
     WindowFlags windowFlags() const;
 
@@ -147,6 +151,9 @@ signals:
     void posChanged();
     void windowPropertyChanged(const QString &name, const QVariant &value);
     void windowFlagsChanged(WindowFlags flags);
+    void windowOrientationChanged();
+    void contentOrientationChanged();
+    void windowRotationChanged();
 
     friend class Wayland::Surface;
     friend class Wayland::SurfacePrivate;
diff --git a/src/compositor/compositor_api/waylandsurfaceitem.cpp b/src/compositor/compositor_api/waylandsurfaceitem.cpp
index a080f836..9418b429 100644
--- a/src/compositor/compositor_api/waylandsurfaceitem.cpp
+++ b/src/compositor/compositor_api/waylandsurfaceitem.cpp
@@ -47,6 +47,8 @@
 #include "wlextendedsurface.h"
 
 #include <QtGui/QKeyEvent>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
 
 #include <QtQuick/QSGSimpleTextureNode>
 #include <QtQuick/QSGSimpleRectNode>
@@ -130,7 +132,11 @@ WaylandSurfaceItem::~WaylandSurfaceItem()
 
 void WaylandSurfaceItem::setSurface(WaylandSurface *surface)
 {
+    if (surface == m_surface)
+        return;
+
     init(surface);
+    emit surfaceChanged();
 }
 
 bool WaylandSurfaceItem::isYInverted() const
diff --git a/src/compositor/compositor_api/waylandsurfaceitem.h b/src/compositor/compositor_api/waylandsurfaceitem.h
index 73697ae2..0114f127 100644
--- a/src/compositor/compositor_api/waylandsurfaceitem.h
+++ b/src/compositor/compositor_api/waylandsurfaceitem.h
@@ -56,7 +56,7 @@ Q_DECLARE_METATYPE(WaylandSurface*)
 class Q_COMPOSITOR_EXPORT WaylandSurfaceItem : public QQuickItem
 {
     Q_OBJECT
-    Q_PROPERTY(WaylandSurface* surface READ surface WRITE setSurface)
+    Q_PROPERTY(WaylandSurface* surface READ surface WRITE setSurface NOTIFY surfaceChanged)
     Q_PROPERTY(bool paintEnabled READ paintEnabled WRITE setPaintEnabled)
     Q_PROPERTY(bool useTextureAlpha READ useTextureAlpha WRITE setUseTextureAlpha NOTIFY useTextureAlphaChanged)
     Q_PROPERTY(bool clientRenderingEnabled READ clientRenderingEnabled WRITE setClientRenderingEnabled NOTIFY clientRenderingEnabledChanged)
@@ -114,6 +114,7 @@ signals:
     void clientRenderingEnabledChanged();
     void touchEventsEnabledChanged();
     void yInvertedChanged();
+    void surfaceChanged();
 
 protected:
     QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
diff --git a/src/compositor/wayland_wrapper/wlcompositor.cpp b/src/compositor/wayland_wrapper/wlcompositor.cpp
index 545d14e3..27378f19 100644
--- a/src/compositor/wayland_wrapper/wlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/wlcompositor.cpp
@@ -360,6 +360,11 @@ void Compositor::setOutputGeometry(const QRect &geometry)
     m_output_global.setGeometry(geometry);
 }
 
+QRect Compositor::outputGeometry() const
+{
+    return m_output_global.geometry();
+}
+
 InputDevice* Compositor::defaultInputDevice()
 {
     return m_default_input_device;
diff --git a/src/compositor/wayland_wrapper/wlcompositor.h b/src/compositor/wayland_wrapper/wlcompositor.h
index 03cd1db5..b2d4ef6e 100644
--- a/src/compositor/wayland_wrapper/wlcompositor.h
+++ b/src/compositor/wayland_wrapper/wlcompositor.h
@@ -117,6 +117,7 @@ public:
     void setScreenOrientation(Qt::ScreenOrientation orientation);
     Qt::ScreenOrientation screenOrientation() const;
     void setOutputGeometry(const QRect &geometry);
+    QRect outputGeometry() const;
 
     void enableTouchExtension();
     TouchExtensionGlobal *touchExtension() { return m_touchExtension; }
diff --git a/src/compositor/wayland_wrapper/wlextendedsurface.cpp b/src/compositor/wayland_wrapper/wlextendedsurface.cpp
index c5bde258..e4dd6bf4 100644
--- a/src/compositor/wayland_wrapper/wlextendedsurface.cpp
+++ b/src/compositor/wayland_wrapper/wlextendedsurface.cpp
@@ -154,7 +154,11 @@ void ExtendedSurface::set_window_orientation(struct wl_client *client,
 {
     Q_UNUSED(client);
     ExtendedSurface *extended_surface = static_cast<ExtendedSurface *>(extended_surface_resource->data);
+
+    Qt::ScreenOrientation oldOrientation = extended_surface->m_windowOrientation;
     extended_surface->m_windowOrientation = screenOrientationFromWaylandOrientation(orientation);
+    if (extended_surface->m_windowOrientation != oldOrientation)
+        emit extended_surface->m_surface->waylandSurface()->windowOrientationChanged();
 }
 
 void ExtendedSurface::set_content_orientation(struct wl_client *client,
@@ -163,7 +167,11 @@ void ExtendedSurface::set_content_orientation(struct wl_client *client,
 {
     Q_UNUSED(client);
     ExtendedSurface *extended_surface = static_cast<ExtendedSurface *>(extended_surface_resource->data);
+
+    Qt::ScreenOrientation oldOrientation = extended_surface->m_contentOrientation;
     extended_surface->m_contentOrientation = screenOrientationFromWaylandOrientation(orientation);
+    if (extended_surface->m_windowOrientation != oldOrientation)
+        emit extended_surface->m_surface->waylandSurface()->contentOrientationChanged();
 }
 
 void ExtendedSurface::setWindowFlags(WaylandSurface::WindowFlags flags)
diff --git a/src/compositor/wayland_wrapper/wloutput.h b/src/compositor/wayland_wrapper/wloutput.h
index f678547a..b637d2d3 100644
--- a/src/compositor/wayland_wrapper/wloutput.h
+++ b/src/compositor/wayland_wrapper/wloutput.h
@@ -57,6 +57,7 @@ public:
     OutputGlobal();
 
     void setGeometry(const QRect &geometry);
+    QRect geometry() const { return m_geometry; }
 
     int x() const { return m_geometry.x(); }
     int y() const { return m_geometry.y(); }
-- 
GitLab