diff options
author | Giulio Camuffo <giulio.camuffo@jollamobile.com> | 2015-02-17 14:59:46 +0200 |
---|---|---|
committer | Giulio Camuffo <giulio.camuffo@jollamobile.com> | 2015-04-23 16:01:46 +0000 |
commit | f889660e400afae140a9d4c0560e0a22d5f20059 (patch) | |
tree | a651e220df0302e361705e5319820e917ce49fc9 | |
parent | b58d9c68d1730b061df16b191bc90f4496b3451e (diff) | |
download | qtwayland-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.cpp | 15 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlsurface_p.h | 62 |
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 |