Added transport of on-screen visibility to qt-compositor via wayland
authorMartin Zielinski <martin.zielinski@nokia.com>
Mon, 27 Jun 2011 06:56:41 +0000 (08:56 +0200)
committerMartin Zielinski <martin.zielinski@nokia.com>
Mon, 27 Jun 2011 06:58:28 +0000 (08:58 +0200)
qt-compositor now has the ability to inform a client of not being visible on-screen.
This is mainly used to stop rendering and processing on the client-app side if the
window is occluded by another fullscreen window.

src/qt-compositor/compositor_api/waylandsurface.cpp
src/qt-compositor/compositor_api/waylandsurface.h
src/qt-compositor/compositor_api/waylandsurfaceitem.cpp
src/qt-compositor/qt-compositor.pri
src/qt-compositor/wayland_wrapper/wlsurface.cpp
src/qt-compositor/wayland_wrapper/wlsurface.h
src/qt-compositor/windowmanagerprotocol/wayland-windowmanager-protocol.c
src/qt-compositor/windowmanagerprotocol/wayland-windowmanager-server-protocol.h
src/qt-compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp
src/qt-compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h
src/qt-compositor/windowmanagerprotocol/windowmanager.xml

index 90d9734..3f0e48f 100644 (file)
@@ -123,3 +123,8 @@ void WaylandSurface::setInputFocus()
     d->surface->setInputFocus();
 }
 
+void WaylandSurface::sendOnScreenVisibilityChange(bool visible)
+{
+    Q_D(WaylandSurface);
+    d->surface->sendOnScreenVisibilityChange(visible);
+}
index 7ce59af..26bd82f 100644 (file)
@@ -89,6 +89,8 @@ public:
     void sendKeyPressEvent(uint code);
     void sendKeyReleaseEvent(uint code);
 
+    void sendOnScreenVisibilityChange(bool visible);
+
     void frameFinished();
     void setInputFocus();
 
index 9ce0dc1..a84a604 100644 (file)
@@ -73,6 +73,7 @@ WaylandSurfaceItem::WaylandSurfaceItem(QSGItem *parent)
     , m_surface(0)
     , m_texture(0)
     , m_paintEnabled(true)
+
 {
 }
 
@@ -102,6 +103,7 @@ void WaylandSurfaceItem::init(WaylandSurface *surface)
     connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *)));
     connect(this, SIGNAL(textureChanged()), this, SLOT(update()));
     connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
+
 }
 
 WaylandSurfaceItem::~WaylandSurfaceItem()
@@ -229,7 +231,11 @@ void WaylandSurfaceItem::setClientRenderingEnabled(bool enabled)
 {
     if (m_clientRenderingEnabled != enabled) {
         m_clientRenderingEnabled = enabled;
-        //qDebug() << "CLIENT RENDERING ENABLED: " << enabled;
-        emit clientRenderingEnabledChanged();
+
+        if (m_surface) {
+            m_surface->sendOnScreenVisibilityChange(enabled);
+        }
+
+        emit clientRenderingEnabledChanged();       
     }
 }
index 7f5f5d4..ee143e3 100644 (file)
@@ -1,4 +1,6 @@
 INCLUDEPATH += $$PWD
+DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT
+
 use_pkgconfig {
     QMAKE_CXXFLAGS += $$system(pkg-config --cflags wayland-server)
     #for some reason this is not included in the cflags line
index 225b7ab..76862cc 100644 (file)
 #include <QtGui/QPlatformGLContext>
 #endif
 
+#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT
+#include "waylandwindowmanagerintegration.h"
+#endif
+
 namespace Wayland {
 
 class SurfacePrivate
@@ -69,6 +73,7 @@ public:
         , processId(0)
         , surfaceBuffer(0)
         , surfaceType(WaylandSurface::Invalid)
+
     {
 #ifdef QT_COMPOSITOR_WAYLAND_GL
         texture_id = 0;
@@ -353,3 +358,11 @@ void Surface::setInputFocus()
 }
 
 }
+
+void Wayland::Surface::sendOnScreenVisibilityChange(bool visible)
+{
+#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT
+    Q_D(Surface);
+    WindowManagerServerIntegration::instance()->changeScreenVisibility(d->client, visible ? 1 : 0);
+#endif
+}
index cc5dad7..3ee5c7f 100644 (file)
@@ -94,6 +94,8 @@ public:
     void frameFinished();
     void setInputFocus();
 
+    void sendOnScreenVisibilityChange(bool visible);
+
     WaylandSurface *handle() const;
     wl_client *clientHandle() const;
     qint64 processId() const;
index b753b16..e759b3a 100644 (file)
 #include "wayland-util.h"
 
 static const struct wl_message wl_windowmanager_requests[] = {
-        { "map_client_to_process", "u" },
-        { "authenticate_with_token", "s" },
+       { "map_client_to_process", "u", NULL },
+       { "authenticate_with_token", "s", NULL },
+};
+
+static const struct wl_message wl_windowmanager_events[] = {
+       { "client_onscreen_visibility", "i", NULL },
 };
 
 WL_EXPORT const struct wl_interface wl_windowmanager_interface = {
-        "wl_windowmanager", 1,
-        ARRAY_LENGTH(wl_windowmanager_requests), wl_windowmanager_requests,
-        0, NULL,
+       "wl_windowmanager", 1,
+       ARRAY_LENGTH(wl_windowmanager_requests), wl_windowmanager_requests,
+       ARRAY_LENGTH(wl_windowmanager_events), wl_windowmanager_events,
 };
 
index 8738146..a0f4e3a 100644 (file)
@@ -39,14 +39,16 @@ struct wl_windowmanager;
 extern const struct wl_interface wl_windowmanager_interface;
 
 struct wl_windowmanager_interface {
-        void (*map_client_to_process)(struct wl_client *client,
-                                      struct wl_windowmanager *windowmanager,
-                                      uint32_t processid);
-        void (*authenticate_with_token)(struct wl_client *client,
-                                        struct wl_windowmanager *windowmanager,
-                                        const char *wl_authentication_token);
+       void (*map_client_to_process)(struct wl_client *client,
+                                     struct wl_windowmanager *wl_windowmanager,
+                                     uint32_t processid);
+       void (*authenticate_with_token)(struct wl_client *client,
+                                       struct wl_windowmanager *wl_windowmanager,
+                                       const char *processid);
 };
 
+#define WL_WINDOWMANAGER_CLIENT_ONSCREEN_VISIBILITY    0
+
 #ifdef  __cplusplus
 }
 #endif
index 5783959..fa6d4b6 100644 (file)
@@ -71,6 +71,11 @@ public:
         WindowManagerServerIntegration::instance()->authenticateWithToken(client, authenticationToken);
     }
 
+    void changeScreenVisibility(wl_client *client, int visible)
+    {
+        WindowManagerServerIntegration::instance()->changeScreenVisibility(client, visible);
+    }
+
 };
 
 void map_client_to_process(wl_client *client, struct wl_windowmanager *windowMgr, uint32_t processId)
@@ -123,6 +128,16 @@ void WindowManagerServerIntegration::authenticateWithToken(wl_client *client, co
     m_managedClients.insert(client, managedClient);
 }
 
+void WindowManagerServerIntegration::changeScreenVisibility(wl_client *client, int visible)
+{
+    m_managedClients[client]->m_isVisibleOnScreen = visible != 0;
+
+    qDebug() << Q_FUNC_INFO << visible;
+    wl_client_post_event(client, m_windowManagerObject->base(),
+                         WL_WINDOWMANAGER_CLIENT_ONSCREEN_VISIBILITY, visible);
+}
+
+
 WaylandManagedClient *WindowManagerServerIntegration::managedClient(wl_client *client) const
 {
     return m_managedClients.value(client, 0);
index b3e90af..65eb3f3 100644 (file)
@@ -66,6 +66,7 @@ public:
 
     WaylandManagedClient *managedClient(wl_client *client) const;
 
+    void changeScreenVisibility(wl_client *client, int visible);
 private:
     void mapClientToProcess(wl_client *client, uint32_t processId);
     void authenticateWithToken(wl_client *client, const char *token);
@@ -85,10 +86,12 @@ public:
     WaylandManagedClient();
     qint64 processId() const;
     QByteArray authenticationToken() const;
+    bool isVisibleOnScreen() const { return m_isVisibleOnScreen; }
 
 private:
     qint64 m_processId;
     QByteArray m_authenticationToken;
+    bool m_isVisibleOnScreen;
 
     friend class WindowManagerServerIntegration;
 };
index f29c337..2d76ae0 100644 (file)
         <request name="map_client_to_process">
             <arg name="processid" type="uint" />
         </request>
-    </interface>
+        <request name="authenticate_with_token">
+            <arg name="processid" type="string" />
+        </request>
 
+       <!-- informs the client that it is visible/not visible on screen and can therfore stop / need to start rendering.
+            The client need to implement the handling of this by itself. This means, we cannot enforce the client to obey,
+            but we can encourage it to do so. -->
+        <event name="client_onscreen_visibility">
+           <arg name="visible" type="int"/>
+       </event>
+    </interface>
 </protocol>