summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiulio Camuffo <giulio.camuffo@jollamobile.com>2015-02-17 14:59:46 +0200
committerGiulio Camuffo <giulio.camuffo@jollamobile.com>2015-04-23 16:01:46 +0000
commitf889660e400afae140a9d4c0560e0a22d5f20059 (patch)
treea651e220df0302e361705e5319820e917ce49fc9
parentb58d9c68d1730b061df16b191bc90f4496b3451e (diff)
downloadqtwayland-f889660e400afae140a9d4c0560e0a22d5f20059.tar.gz
qtwayland-f889660e400afae140a9d4c0560e0a22d5f20059.tar.bz2
qtwayland-f889660e400afae140a9d4c0560e0a22d5f20059.zip
Introduce the surface role concept
This is a concept originating initially from an implementation detail in Weston which was later formalized in Wayland 1.7. A wl_surface by itself will not be shown on screen, it must have a 'role' attched for that to happen. A role can be a shell surface, a pointer surface, ... Once a role is set on a wl_surface it cannot be changed, attempting to do so should send a protocol error. It is however allowed to destroy and recreate a new i.e. wl_shell_surface for the same wl_surface. This patch introduces the role and role handler concepts. A class such as a shell surface implementation should inherit from SurfaceRoleHandler, and have a 'static SurfaceRole *role()' function, which will be used to check against the role the surface has when the role handler is set to it. This changes introduces the new plumbing code but does not port existing code to it. Eventually this new API should become public. Change-Id: I43dc809b86051b7528ae6c39f796b9a96719ffd0 Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp15
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface_p.h62
2 files changed, 77 insertions, 0 deletions
diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp
index e26eec8b..2c30872a 100644
--- a/src/compositor/wayland_wrapper/qwlsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurface.cpp
@@ -129,6 +129,8 @@ Surface::Surface(struct wl_client *client, uint32_t id, int version, QWaylandCom
, m_destroyed(false)
, m_contentOrientation(Qt::PrimaryOrientation)
, m_visibility(QWindow::Hidden)
+ , m_role(0)
+ , m_roleHandler(0)
{
m_pending.buffer = 0;
m_pending.newlyAttached = false;
@@ -150,6 +152,17 @@ Surface::~Surface()
c->destroy();
}
+bool Surface::setRole(const SurfaceRole *role, wl_resource *errorResource, uint32_t errorCode)
+{
+ if (m_role && m_role != role) {
+ wl_resource_post_error(errorResource, errorCode, "Cannot assign role %s to wl_surface@%d, already has role %s\n", role->name,
+ wl_resource_get_id(resource()->handle), m_role->name);
+ return false;
+ }
+ m_role = role;
+ return true;
+}
+
void Surface::setTransientOffset(qreal x, qreal y)
{
m_transientOffset.setX(x);
@@ -406,6 +419,8 @@ void Surface::surface_commit(Resource *)
if (m_attacher)
m_attacher->attach(m_bufferRef);
emit m_waylandSurface->configure(m_bufferRef);
+ if (m_roleHandler)
+ m_roleHandler->configure(m_pending.offset.x(), m_pending.offset.y());
}
m_pending.buffer = 0;
diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h
index 4e8f6aa9..422c147e 100644
--- a/src/compositor/wayland_wrapper/qwlsurface_p.h
+++ b/src/compositor/wayland_wrapper/qwlsurface_p.h
@@ -74,12 +74,20 @@ class InputPanelSurface;
class SubSurface;
class FrameCallback;
+class SurfaceRole;
+class RoleBase;
+
class Q_COMPOSITOR_EXPORT Surface : public QtWaylandServer::wl_surface
{
public:
Surface(struct wl_client *client, uint32_t id, int version, QWaylandCompositor *compositor, QWaylandSurface *surface);
~Surface();
+ bool setRole(const SurfaceRole *role, wl_resource *errorResource, uint32_t errorCode);
+ const SurfaceRole *role() const { return m_role; }
+ template<class T>
+ bool setRoleHandler(T *handler);
+
static Surface *fromResource(struct ::wl_resource *resource);
QWaylandSurface::Type type() const;
@@ -205,12 +213,66 @@ protected:
Qt::ScreenOrientation m_contentOrientation;
QWindow::Visibility m_visibility;
+ const SurfaceRole *m_role;
+ RoleBase *m_roleHandler;
+
void setBackBuffer(SurfaceBuffer *buffer);
SurfaceBuffer *createSurfaceBuffer(struct ::wl_resource *buffer);
friend class QWaylandSurface;
+ friend class RoleBase;
+};
+
+class SurfaceRole
+{
+public:
+ const char *name;
+};
+
+class RoleBase
+{
+public:
+ virtual ~RoleBase() {
+ if (m_surface) {
+ m_surface->m_roleHandler = 0; m_surface = 0;
+ }
+ }
+
+protected:
+ RoleBase() : m_surface(0) {}
+ static inline RoleBase *roleOf(Surface *s) { return s->m_roleHandler; }
+
+ virtual void configure(int dx, int dy) = 0;
+
+private:
+ Surface *m_surface;
+ friend class Surface;
};
+template<class T>
+class SurfaceRoleHandler : public RoleBase
+{
+public:
+ static T *get(Surface *surface) {
+ if (surface->role() == T::role()) {
+ return static_cast<T *>(roleOf(surface));
+ }
+ return 0;
+ }
+};
+
+template<class T>
+bool Surface::setRoleHandler(T *handler)
+{
+ RoleBase *base = handler;
+ if (m_role == T::role()) {
+ m_roleHandler = base;
+ base->m_surface = this;
+ return true;
+ }
+ return false;
+}
+
}
QT_END_NAMESPACE