summaryrefslogtreecommitdiffstats
path: root/src/compositor/extensions/qwaylandwlshell.cpp
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@theqtcompany.com>2016-03-29 15:04:42 +0200
committerJohan Helsing <johan.helsing@theqtcompany.com>2016-04-05 14:05:28 +0000
commit465e6f559fccf04203997cdf5182693567a9e697 (patch)
treeca1c50eb8fd3a26e02d8a2b205d1775febb0859e /src/compositor/extensions/qwaylandwlshell.cpp
parentac670666395882c60b512ff493b66d58a1ad6541 (diff)
Rename compositor Shell to WlShell
* QWaylandShell -> QWaylandWlShell * QWaylandShellSurface -> QWaylandWlShellSurface * QWaylandQuickShellSurfaceItem -> QWaylandQuickWlShellSurfaceItem * Shell -> WlShell (QML) * ShellSurface -> WlShellSurface (QML) * ShellSurfaceItem -> WlShellSurfaceItem (QML) This is done to avoid confusion with XdgShell and will hopefully help clarify that some of the examples only support wl_shell and not xdg_shell. Additionally, this makes "Shell" an available name in the compositor API, which may in turn enable the creation of a more general abstraction hiding the details of the shell backends (i.e. xdg_shell, wl_shell, and eventually ivi_shell). Change-Id: Iebac1f36505084bfaaea68838005d54db6c55e21 Reviewed-by: Giulio Camuffo <giulio.camuffo@kdab.com>
Diffstat (limited to 'src/compositor/extensions/qwaylandwlshell.cpp')
-rw-r--r--src/compositor/extensions/qwaylandwlshell.cpp592
1 files changed, 592 insertions, 0 deletions
diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp
new file mode 100644
index 000000000..c6d13b392
--- /dev/null
+++ b/src/compositor/extensions/qwaylandwlshell.cpp
@@ -0,0 +1,592 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandwlshell.h"
+#include "qwaylandwlshell_p.h"
+
+#include <QtWaylandCompositor/QWaylandCompositor>
+#include <QtWaylandCompositor/QWaylandView>
+#include <QtWaylandCompositor/QWaylandOutput>
+#include <QtWaylandCompositor/QWaylandClient>
+
+#include <QtCore/QObject>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+QWaylandSurfaceRole QWaylandWlShellSurfacePrivate::s_role("wl_shell_surface");
+
+QWaylandWlShellPrivate::QWaylandWlShellPrivate()
+ : QWaylandExtensionTemplatePrivate()
+ , wl_shell()
+{
+}
+
+void QWaylandWlShellPrivate::shell_get_shell_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface_res)
+{
+ Q_Q(QWaylandWlShell);
+ QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res);
+
+ wl_resource *res = wl_resource_create(resource->client(), &wl_shell_surface_interface,
+ wl_resource_get_version(resource->handle), id);
+ // XXX FIXME
+ // The role concept was formalized in wayland 1.7, so that release adds one error
+ // code for each interface that implements a role, and we are supposed to pass here
+ // the newly constructed resource and the correct error code so that if setting the
+ // role fails, a proper error can be sent to the client.
+ // However we're still using wayland 1.4, which doesn't have interface specific role
+ // errors, so the best we can do is to use wl_display's object_id error.
+ wl_resource *displayRes = wl_client_get_object(resource->client(), 1);
+ if (surface->setRole(QWaylandWlShellSurface::role(), displayRes, WL_DISPLAY_ERROR_INVALID_OBJECT))
+ emit q->createShellSurface(surface, QWaylandResource(res));
+}
+
+QWaylandWlShellSurfacePrivate::QWaylandWlShellSurfacePrivate()
+ : QWaylandExtensionTemplatePrivate()
+ , wl_shell_surface()
+ , m_shell(Q_NULLPTR)
+ , m_surface(Q_NULLPTR)
+ , m_focusPolicy(QWaylandWlShellSurface::DefaultFocus)
+{
+}
+
+QWaylandWlShellSurfacePrivate::~QWaylandWlShellSurfacePrivate()
+{
+}
+
+void QWaylandWlShellSurfacePrivate::ping(uint32_t serial)
+{
+ m_pings.insert(serial);
+ send_ping(serial);
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_destroy_resource(Resource *)
+{
+ Q_Q(QWaylandWlShellSurface);
+
+ delete q;
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_move(Resource *resource,
+ struct wl_resource *input_device_super,
+ uint32_t serial)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(serial);
+
+ Q_Q(QWaylandWlShellSurface);
+ QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(input_device_super);
+ emit q->startMove(input_device);
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_resize(Resource *resource,
+ struct wl_resource *input_device_super,
+ uint32_t serial,
+ uint32_t edges)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(serial);
+ Q_Q(QWaylandWlShellSurface);
+
+ QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(input_device_super);
+ emit q->startResize(input_device, QWaylandWlShellSurface::ResizeEdge(edges));
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_set_toplevel(Resource *resource)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandWlShellSurface);
+ setFocusPolicy(QWaylandWlShellSurface::DefaultFocus);
+ emit q->setDefaultToplevel();
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_set_transient(Resource *resource,
+ struct wl_resource *parent_surface_resource,
+ int x,
+ int y,
+ uint32_t flags)
+{
+
+ Q_UNUSED(resource);
+ Q_Q(QWaylandWlShellSurface);
+ QWaylandSurface *parent_surface = QWaylandSurface::fromResource(parent_surface_resource);
+ QWaylandWlShellSurface::FocusPolicy focusPolicy =
+ flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE ? QWaylandWlShellSurface::NoKeyboardFocus
+ : QWaylandWlShellSurface::DefaultFocus;
+ setFocusPolicy(focusPolicy);
+ emit q->setTransient(parent_surface, QPoint(x,y), focusPolicy);
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_set_fullscreen(Resource *resource,
+ uint32_t method,
+ uint32_t framerate,
+ struct wl_resource *output_resource)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(method);
+ Q_UNUSED(framerate);
+ Q_Q(QWaylandWlShellSurface);
+ setFocusPolicy(QWaylandWlShellSurface::DefaultFocus);
+ QWaylandOutput *output = output_resource
+ ? QWaylandOutput::fromResource(output_resource)
+ : Q_NULLPTR;
+ emit q->setFullScreen(QWaylandWlShellSurface::FullScreenMethod(method), framerate, output);
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_set_popup(Resource *resource, wl_resource *input_device, uint32_t serial, wl_resource *parent, int32_t x, int32_t y, uint32_t flags)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(serial);
+ Q_UNUSED(flags);
+ Q_Q(QWaylandWlShellSurface);
+ setFocusPolicy(QWaylandWlShellSurface::DefaultFocus);
+ QWaylandInputDevice *input = QWaylandInputDevice::fromSeatResource(input_device);
+ QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent);
+ emit q->setPopup(input, parentSurface, QPoint(x,y));
+
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_set_maximized(Resource *resource,
+ struct wl_resource *output_resource)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandWlShellSurface);
+ setFocusPolicy(QWaylandWlShellSurface::DefaultFocus);
+ QWaylandOutput *output = output_resource
+ ? QWaylandOutput::fromResource(output_resource)
+ : Q_NULLPTR;
+ emit q->setMaximized(output);
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_pong(Resource *resource,
+ uint32_t serial)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandWlShellSurface);
+ if (m_pings.remove(serial))
+ emit q->pong();
+ else
+ qWarning("Received an unexpected pong!");
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_set_title(Resource *resource,
+ const QString &title)
+{
+ Q_UNUSED(resource);
+ if (title == m_title)
+ return;
+ Q_Q(QWaylandWlShellSurface);
+ m_title = title;
+ emit q->titleChanged();
+}
+
+void QWaylandWlShellSurfacePrivate::shell_surface_set_class(Resource *resource,
+ const QString &className)
+{
+ Q_UNUSED(resource);
+ if (className == m_className)
+ return;
+ Q_Q(QWaylandWlShellSurface);
+ m_className = className;
+ emit q->classNameChanged();
+}
+
+/*!
+ * \qmltype WlShell
+ * \inqmlmodule QtWayland.Compositor
+ * \brief Extension for desktop-style user interfaces.
+ *
+ * The WlShell extension provides a way to assiociate a \l{ShellSurface}
+ * with a regular Wayland surface. Using the shell surface interface, the client
+ * can request that the surface is resized, moved, and so on.
+ *
+ * WlShell corresponds to the Wayland interface wl_shell.
+ *
+ * To provide the functionality of the shell extension in a compositor, create
+ * an instance of the WlShell component and add it to the list of extensions
+ * supported by the compositor:
+ * \code
+ * import QtWayland.Compositor 1.0
+ *
+ * WaylandCompositor {
+ * extensions: WlShell {
+ * // ...
+ * }
+ * }
+ * \endcode
+ */
+
+/*!
+ * \class QWaylandWlShell
+ * \inmodule QtWaylandCompositor
+ * \brief Extension for desktop-style user interfaces.
+ *
+ * The QWaylandWlShell extension provides a way to assiociate a QWaylandWlShellSurface with
+ * a regular Wayland surface. Using the shell surface interface, the client
+ * can request that the surface is resized, moved, and so on.
+ *
+ * WlShell corresponds to the Wayland interface wl_shell.
+ */
+
+/*!
+ * Constructs a QWaylandWlShell object.
+ */
+QWaylandWlShell::QWaylandWlShell()
+ : QWaylandExtensionTemplate<QWaylandWlShell>(*new QWaylandWlShellPrivate())
+{ }
+
+/*!
+ * Constructs a QWaylandWlShell object for the provided \a compositor.
+ */
+QWaylandWlShell::QWaylandWlShell(QWaylandCompositor *compositor)
+ : QWaylandExtensionTemplate<QWaylandWlShell>(compositor, *new QWaylandWlShellPrivate())
+{ }
+
+
+/*!
+ * Initializes the WlShell extension.
+ */
+void QWaylandWlShell::initialize()
+{
+ Q_D(QWaylandWlShell);
+ QWaylandExtensionTemplate::initialize();
+ QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
+ if (!compositor) {
+ qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandWlShell";
+ return;
+ }
+ d->init(compositor->display(), 1);
+}
+
+/*!
+ * Returns the Wayland interface for the QWaylandWlShell.
+ */
+const struct wl_interface *QWaylandWlShell::interface()
+{
+ return QWaylandWlShellPrivate::interface();
+}
+
+/*!
+ * \qmlsignal void QtWaylandCompositor::WlShell::createShellSurface(object surface, object client, int id)
+ *
+ * This signal is emitted when the \a client has requested a wl_shell_surface to be associated
+ * with \a surface and be assigned the given \a id. The handler for this signal is
+ * expected to create the shell surface and initialize it within the scope of the
+ * signal emission.
+ */
+
+/*!
+ * \fn void QWaylandWlShell::createShellSurface(QWaylandSurface *surface, QWaylandClient *client, uint id)
+ *
+ * This signal is emitted when the \a client has requested a shell surface to be associated
+ * with \a surface and be assigned the given \a id. The handler for this signal is
+ * expected to create the shell surface and initialize it within the scope of the
+ * signal emission.
+ */
+
+/*!
+ * \internal
+ */
+QByteArray QWaylandWlShell::interfaceName()
+{
+ return QWaylandWlShellPrivate::interfaceName();
+}
+
+/*!
+ * \qmltype WlShellSurface
+ * \inqmlmodule QtWayland.Compositor
+ * \brief A wl_shell_surface providing desktop-style compositor-specific features to a surface.
+ *
+ * This type is part of the \l{WlShell} extension and provides a way to extend
+ * the functionality of an existing WaylandSurface with features specific to desktop-style
+ * compositors, such as resizing and moving the surface.
+ *
+ * It corresponds to the Wayland interface wl_shell_surface.
+ */
+
+/*!
+ * \class QWaylandWlShellSurface
+ * \inmodule QtWaylandCompositor
+ * \brief A shell surface providing desktop-style compositor-specific features to a surface.
+ *
+ * This class is part of the QWaylandWlShell extension and provides a way to extend
+ * the functionality of an existing QWaylandSurface with features specific to desktop-style
+ * compositors, such as resizing and moving the surface.
+ *
+ * It corresponds to the Wayland interface wl_shell_surface.
+ */
+
+/*!
+ * Constructs a QWaylandWlShellSurface.
+ */
+QWaylandWlShellSurface::QWaylandWlShellSurface()
+ : QWaylandExtensionTemplate<QWaylandWlShellSurface>(*new QWaylandWlShellSurfacePrivate)
+{
+}
+
+/*!
+ * Constructs a QWaylandWlShellSurface for \a surface and initializes it with the given \a shell and \a resource.
+ */
+QWaylandWlShellSurface::QWaylandWlShellSurface(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &res)
+ : QWaylandExtensionTemplate<QWaylandWlShellSurface>(*new QWaylandWlShellSurfacePrivate)
+{
+ initialize(shell, surface, res);
+}
+
+/*!
+ * \qmlmethod void QtWaylandCompositor::WlShellSurface::initialize(object shell, object surface, object client, int id)
+ *
+ * Initializes the WlShellSurface, associating it with the given \a shell, \a surface, \a client, and \a id.
+ */
+
+/*!
+ * Initializes the QWaylandWlShellSurface, associating it with the given \a shell, \a surface and \a resource.
+ */
+void QWaylandWlShellSurface::initialize(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &resource)
+{
+ Q_D(QWaylandWlShellSurface);
+ d->m_shell = shell;
+ d->m_surface = surface;
+ d->init(resource.resource());
+ setExtensionContainer(surface);
+ emit surfaceChanged();
+ QWaylandExtension::initialize();
+}
+
+/*!
+ * \internal
+ */
+void QWaylandWlShellSurface::initialize()
+{
+ QWaylandExtensionTemplate::initialize();
+}
+
+const struct wl_interface *QWaylandWlShellSurface::interface()
+{
+ return QWaylandWlShellSurfacePrivate::interface();
+}
+
+/*!
+ * \internal
+ */
+QByteArray QWaylandWlShellSurface::interfaceName()
+{
+ return QWaylandWlShellSurfacePrivate::interfaceName();
+}
+
+QSize QWaylandWlShellSurface::sizeForResize(const QSizeF &size, const QPointF &delta, QWaylandWlShellSurface::ResizeEdge edge)
+{
+ qreal width = size.width();
+ qreal height = size.height();
+ if (edge & LeftEdge)
+ width -= delta.x();
+ else if (edge & RightEdge)
+ width += delta.x();
+
+ if (edge & TopEdge)
+ height -= delta.y();
+ else if (edge & BottomEdge)
+ height += delta.y();
+
+ return QSizeF(width, height).toSize();
+}
+
+/*!
+ * \enum QWaylandWlShellSurface::ResizeEdge
+ *
+ * This enum type provides a way to specify a specific edge or corner of
+ * the surface.
+ *
+ * \value None No edge.
+ * \value TopEdge The top edge.
+ * \value BottomEdge The bottom edge.
+ * \value LeftEdge The left edge.
+ * \value TopLeftEdge The top left corner.
+ * \value BottomLeftEdge The bottom left corner.
+ * \value RightEdge The right edge.
+ * \value TopRightEdge The top right corner.
+ * \value BottomRightEdge The bottom right corner.
+ */
+
+/*!
+ * \qmlmethod void QtWaylandCompositor::WlShellSurface::sendConfigure(size size, enum edges)
+ *
+ * Sends a configure event to the client, suggesting that it resize its surface to
+ * the provided \a size. The \a edges provide a hint about how the surface
+ * was resized.
+ */
+
+/*!
+ * Sends a configure event to the client, suggesting that it resize its surface to
+ * the provided \a size. The \a edges provide a hint about how the surface
+ * was resized.
+ */
+void QWaylandWlShellSurface::sendConfigure(const QSize &size, ResizeEdge edges)
+{
+ Q_D(QWaylandWlShellSurface);
+ d->send_configure(edges, size.width(), size.height());
+}
+
+/*!
+ * \qmlmethod void QtWaylandCompositor::WlShellSurface::sendPopupDone()
+ *
+ * Sends a popup_done event to the client to indicate that the user has clicked
+ * somewhere outside the client's surfaces.
+ */
+
+/*!
+ * Sends a popup_done event to the client to indicate that the user has clicked
+ * somewhere outside the client's surfaces.
+ */
+void QWaylandWlShellSurface::sendPopupDone()
+{
+ Q_D(QWaylandWlShellSurface);
+ d->send_popup_done();
+}
+
+/*!
+ * \qmlproperty object QtWaylandCompositor::WlShellSurface::surface
+ *
+ * This property holds the wl_surface associated with this WlShellSurface.
+ */
+
+/*!
+ * \property QWaylandWlShellSurface::surface
+ *
+ * This property holds the surface associated with this QWaylandWlShellSurface.
+ */
+QWaylandSurface *QWaylandWlShellSurface::surface() const
+{
+ Q_D(const QWaylandWlShellSurface);
+ return d->m_surface;
+}
+
+/*!
+ * \enum QWaylandWlShellSurface::FocusPolicy
+ *
+ * This enum type is used to specify the focus policy of a shell surface.
+ *
+ * \value DefaultFocus The default focus policy should be used.
+ * \value NoKeyboardFocus The shell surface should not get keyboard focus.
+ */
+
+/*!
+ * \qmlproperty enum QtWaylandCompositor::WlShellSurface::focusPolicy
+ *
+ * This property holds the focus policy of the WlShellSurface.
+ */
+
+/*!
+ * \property QWaylandWlShellSurface::focusPolicy
+ *
+ * This property holds the focus policy of the QWaylandWlShellSurface.
+ */
+QWaylandWlShellSurface::FocusPolicy QWaylandWlShellSurface::focusPolicy() const
+{
+ Q_D(const QWaylandWlShellSurface);
+ return d->m_focusPolicy;
+}
+
+/*!
+ * \qmlproperty string QtWaylandCompositor::WlShellSurface::title
+ *
+ * This property holds the title of the WlShellSurface.
+ */
+
+/*!
+ * \property QWaylandWlShellSurface::title
+ *
+ * This property holds the title of the QWaylandWlShellSurface.
+ */
+QString QWaylandWlShellSurface::title() const
+{
+ Q_D(const QWaylandWlShellSurface);
+ return d->m_title;
+}
+
+/*!
+ * \qmlproperty string QtWaylandCompositor::WlShellSurface::className
+ *
+ * This property holds the class name of the WlShellSurface.
+ */
+
+/*!
+ * \property QWaylandWlShellSurface::className
+ *
+ * This property holds the class name of the QWaylandWlShellSurface.
+ */
+QString QWaylandWlShellSurface::className() const
+{
+ Q_D(const QWaylandWlShellSurface);
+ return d->m_className;
+}
+
+QWaylandSurfaceRole *QWaylandWlShellSurface::role()
+{
+ return &QWaylandWlShellSurfacePrivate::s_role;
+}
+
+/*!
+ * \qmlmethod void QtWaylandCompositor::WlShellSurface::ping()
+ *
+ * Sends a ping event to the client. If the client replies to the event the \a pong
+ * signal will be emitted.
+ */
+
+/*!
+ * Sends a ping event to the client. If the client replies to the event the \a pong
+ * signal will be emitted.
+ */
+void QWaylandWlShellSurface::ping()
+{
+ Q_D(QWaylandWlShellSurface);
+ uint32_t serial = d->m_surface->compositor()->nextSerial();
+ d->ping(serial);
+}
+
+/*!
+ * Returns the QWaylandWlShellSurface object associated with the given \a resource, or null if no such object exists.
+ */
+QWaylandWlShellSurface *QWaylandWlShellSurface::fromResource(wl_resource *resource)
+{
+ QWaylandWlShellSurfacePrivate::Resource *res = QWaylandWlShellSurfacePrivate::Resource::fromResource(resource);
+ if (res)
+ return static_cast<QWaylandWlShellSurfacePrivate *>(res->shell_surface_object)->q_func();
+ return 0;
+}
+
+QT_END_NAMESPACE