summaryrefslogtreecommitdiffstats
path: root/src/plugins/shellintegration
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2018-05-09 22:57:53 +0200
committerJohan Helsing <johan.helsing@qt.io>2018-05-18 09:37:07 +0000
commit42f71e680c6146526fb18116b1b98995543443c0 (patch)
tree465f50e000788cd699f7cbf3425c9404abea4712 /src/plugins/shellintegration
parent9ac2cdf96d36db9612effdbdb9669bd413b66b84 (diff)
Move wl-shell to a plugin
[ChangeLog][QPA plugin] The wl-shell shell integration has been moved to a plugin. This also adds API so shell integrations can return native resources for windows, as it was needed in order to continue to supporting wl_shell_surface. Change-Id: Ibc68ffcc5b0c6993d8f4e078f663e4d67340e1a5 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/plugins/shellintegration')
-rw-r--r--src/plugins/shellintegration/shellintegration.pro4
-rw-r--r--src/plugins/shellintegration/wl-shell/main.cpp69
-rw-r--r--src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp87
-rw-r--r--src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h79
-rw-r--r--src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp284
-rw-r--r--src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h131
-rw-r--r--src/plugins/shellintegration/wl-shell/wl-shell.json3
-rw-r--r--src/plugins/shellintegration/wl-shell/wl-shell.pro23
8 files changed, 679 insertions, 1 deletions
diff --git a/src/plugins/shellintegration/shellintegration.pro b/src/plugins/shellintegration/shellintegration.pro
index 7f465d61b..12a900db2 100644
--- a/src/plugins/shellintegration/shellintegration.pro
+++ b/src/plugins/shellintegration/shellintegration.pro
@@ -2,4 +2,6 @@ TEMPLATE = subdirs
SUBDIRS += \
ivi-shell \
- xdg-shell-v5
+ xdg-shell-v5 \
+ wl-shell \
+
diff --git a/src/plugins/shellintegration/wl-shell/main.cpp b/src/plugins/shellintegration/wl-shell/main.cpp
new file mode 100644
index 000000000..9b033b5f3
--- /dev/null
+++ b/src/plugins/shellintegration/wl-shell/main.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2017 ITAGE Corporation, author: <yusuke.binsaki@itage.co.jp>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandwlshellintegration_p.h"
+
+#include <QtWaylandClient/private/qwaylandshellintegrationplugin_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWaylandClient {
+
+class QWaylandWlShellIntegrationPlugin : public QWaylandShellIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QWaylandShellIntegrationFactoryInterface_iid FILE "wl-shell.json")
+
+public:
+ QWaylandShellIntegration *create(const QString &key, const QStringList &paramList) override;
+};
+
+QWaylandShellIntegration *QWaylandWlShellIntegrationPlugin::create(const QString &key, const QStringList &paramList)
+{
+ Q_UNUSED(key);
+ Q_UNUSED(paramList);
+ return new QWaylandWlShellIntegration();
+}
+
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp b/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp
new file mode 100644
index 000000000..be156dad2
--- /dev/null
+++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandwlshellintegration_p.h"
+#include "qwaylandwlshellsurface_p.h"
+
+#include <QtWaylandClient/private/qwaylandwindow_p.h>
+#include <QtWaylandClient/private/qwaylanddisplay_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWaylandClient {
+
+bool QWaylandWlShellIntegration::initialize(QWaylandDisplay *display)
+{
+ Q_FOREACH (QWaylandDisplay::RegistryGlobal global, display->globals()) {
+ if (global.interface == QLatin1String("wl_shell")) {
+ m_wlShell = new QtWayland::wl_shell(display->wl_registry(), global.id, 1);
+ break;
+ }
+ }
+
+ if (!m_wlShell) {
+ qCDebug(lcQpaWayland) << "Couldn't find global wl_shell";
+ return false;
+ }
+
+ return QWaylandShellIntegration::initialize(display);
+}
+
+QWaylandShellSurface *QWaylandWlShellIntegration::createShellSurface(QWaylandWindow *window)
+{
+ return new QWaylandWlShellSurface(m_wlShell->get_shell_surface(window->object()), window);
+}
+
+void *QWaylandWlShellIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
+{
+ QByteArray lowerCaseResource = resource.toLower();
+ if (lowerCaseResource == "wl_shell_surface") {
+ if (auto waylandWindow = static_cast<QWaylandWindow *>(window->handle())) {
+ if (auto shellSurface = qobject_cast<QWaylandWlShellSurface *>(waylandWindow->shellSurface())) {
+ return shellSurface->object();
+ }
+ }
+ }
+ return nullptr;
+}
+
+} // namespace QtWaylandClient
+
+QT_END_NAMESPACE
diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h b/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h
new file mode 100644
index 000000000..80a7507d4
--- /dev/null
+++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDWLSHELLINTEGRATION_P_H
+#define QWAYLANDWLSHELLINTEGRATION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <wayland-client.h>
+#include <private/qwayland-wayland.h>
+
+#include <QtWaylandClient/private/qwaylandshellintegration_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWaylandClient {
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandWlShellIntegration : public QWaylandShellIntegration
+{
+public:
+ QWaylandWlShellIntegration() {}
+ bool initialize(QWaylandDisplay *) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+ void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override;
+
+private:
+ QtWayland::wl_shell *m_wlShell = nullptr;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDWLSHELLINTEGRATION_P_H
diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp
new file mode 100644
index 000000000..9f2bcc00c
--- /dev/null
+++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp
@@ -0,0 +1,284 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandwlshellsurface_p.h"
+
+#include <QtWaylandClient/private/qwaylanddisplay_p.h>
+#include <QtWaylandClient/private/qwaylandwindow_p.h>
+#include <QtWaylandClient/private/qwaylandinputdevice_p.h>
+#include <QtWaylandClient/private/qwaylandabstractdecoration_p.h>
+#include <QtWaylandClient/private/qwaylandscreen_p.h>
+#include <QtWaylandClient/private/qwaylandextendedsurface_p.h>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWaylandClient {
+
+QWaylandWlShellSurface::QWaylandWlShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window)
+ : QWaylandShellSurface(window)
+ , QtWayland::wl_shell_surface(shell_surface)
+ , m_window(window)
+{
+ if (window->display()->windowExtension())
+ m_extendedWindow = new QWaylandExtendedSurface(window);
+}
+
+QWaylandWlShellSurface::~QWaylandWlShellSurface()
+{
+ wl_shell_surface_destroy(object());
+ delete m_extendedWindow;
+}
+
+void QWaylandWlShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges)
+{
+ resize(inputDevice->wl_seat(),
+ inputDevice->serial(),
+ edges);
+}
+
+bool QWaylandWlShellSurface::move(QWaylandInputDevice *inputDevice)
+{
+ move(inputDevice->wl_seat(),
+ inputDevice->serial());
+ return true;
+}
+
+void QWaylandWlShellSurface::setTitle(const QString & title)
+{
+ return QtWayland::wl_shell_surface::set_title(title);
+}
+
+void QWaylandWlShellSurface::setAppId(const QString & appId)
+{
+ return QtWayland::wl_shell_surface::set_class(appId);
+}
+
+void QWaylandWlShellSurface::raise()
+{
+ if (m_extendedWindow)
+ m_extendedWindow->raise();
+}
+
+void QWaylandWlShellSurface::lower()
+{
+ if (m_extendedWindow)
+ m_extendedWindow->lower();
+}
+
+void QWaylandWlShellSurface::setContentOrientationMask(Qt::ScreenOrientations orientation)
+{
+ if (m_extendedWindow)
+ m_extendedWindow->setContentOrientationMask(orientation);
+}
+
+void QWaylandWlShellSurface::setWindowFlags(Qt::WindowFlags flags)
+{
+ if (m_extendedWindow)
+ m_extendedWindow->setWindowFlags(flags);
+}
+
+void QWaylandWlShellSurface::sendProperty(const QString &name, const QVariant &value)
+{
+ if (m_extendedWindow)
+ m_extendedWindow->updateGenericProperty(name, value);
+}
+
+void QWaylandWlShellSurface::applyConfigure()
+{
+ if ((m_pending.states & (Qt::WindowMaximized|Qt::WindowFullScreen))
+ && !(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen))) {
+ m_normalSize = m_window->window()->frameGeometry().size();
+ }
+
+ if (m_pending.states != m_applied.states)
+ m_window->handleWindowStatesChanged(m_pending.states);
+
+ if (!m_pending.size.isEmpty()) {
+ int x = 0;
+ int y = 0;
+ if (m_pending.edges & resize_left)
+ x = m_applied.size.width() - m_pending.size.width();
+ if (m_pending.edges & resize_top)
+ y = m_applied.size.height() - m_pending.size.height();
+ QPoint offset(x, y);
+ m_window->resizeFromApplyConfigure(m_pending.size, offset);
+ } else if (m_pending.size.isValid() && !m_normalSize.isEmpty()) {
+ m_window->resizeFromApplyConfigure(m_normalSize);
+ }
+
+ m_applied = m_pending;
+}
+
+bool QWaylandWlShellSurface::wantsDecorations() const
+{
+ return !(m_pending.states & Qt::WindowFullScreen);
+}
+
+void QWaylandWlShellSurface::requestWindowStates(Qt::WindowStates states)
+{
+ // On wl-shell the client is in charge of states, so diff from the pending state
+ Qt::WindowStates changedStates = m_pending.states ^ states;
+ Qt::WindowStates addedStates = changedStates & states;
+
+ if (addedStates & Qt::WindowMinimized)
+ qCWarning(lcQpaWayland) << "Minimizing is not supported on wl-shell. Consider using xdg-shell instead.";
+
+ if (addedStates & Qt::WindowMaximized) {
+ set_maximized(nullptr);
+ m_window->applyConfigureWhenPossible();
+ }
+
+ if (addedStates & Qt::WindowFullScreen) {
+ set_fullscreen(WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, nullptr);
+ m_window->applyConfigureWhenPossible();
+ }
+
+ bool isNormal = ~states & (Qt::WindowMaximized | Qt::WindowFullScreen);
+ if (isNormal && (changedStates & (Qt::WindowMaximized | Qt::WindowFullScreen))) {
+ setTopLevel(); // set normal window
+ // There's usually no configure event after this, so just clear the rest of the pending
+ // configure here and queue the applyConfigure call
+ m_pending.size = {0, 0};
+ m_pending.edges = resize_none;
+ m_window->applyConfigureWhenPossible();
+ }
+
+ m_pending.states = states & ~Qt::WindowMinimized;
+}
+
+
+void QWaylandWlShellSurface::setTopLevel()
+{
+ set_toplevel();
+}
+
+static inline bool testShowWithoutActivating(const QWindow *window)
+{
+ // QWidget-attribute Qt::WA_ShowWithoutActivating.
+ const QVariant showWithoutActivating = window->property("_q_showWithoutActivating");
+ return showWithoutActivating.isValid() && showWithoutActivating.toBool();
+}
+
+void QWaylandWlShellSurface::updateTransientParent(QWindow *parent)
+{
+ QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle());
+ if (!parent_wayland_window)
+ return;
+
+ // set_transient expects a position relative to the parent
+ QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
+ transientPos -= parent->geometry().topLeft();
+ if (parent_wayland_window->decoration()) {
+ transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
+ transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
+ }
+
+ uint32_t flags = 0;
+ Qt::WindowFlags wf = m_window->window()->flags();
+ if (wf.testFlag(Qt::ToolTip)
+ || wf.testFlag(Qt::WindowTransparentForInput)
+ || testShowWithoutActivating(m_window->window()))
+ flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE;
+
+ Q_ASSERT(parent_wayland_window->object());
+ set_transient(parent_wayland_window->object(),
+ transientPos.x(),
+ transientPos.y(),
+ flags);
+}
+
+void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, uint serial)
+{
+ QWaylandWindow *parent_wayland_window = parent;
+ if (!parent_wayland_window) {
+ qCWarning(lcQpaWayland) << "setPopup called without a parent window";
+ return;
+ }
+ if (!device) {
+ qCWarning(lcQpaWayland) << "setPopup called without an input device";
+ return;
+ }
+
+ // set_popup expects a position relative to the parent
+ QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
+ transientPos -= parent_wayland_window->geometry().topLeft();
+ if (parent_wayland_window->decoration()) {
+ transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
+ transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
+ }
+
+ Q_ASSERT(parent_wayland_window->object());
+ set_popup(device->wl_seat(), serial, parent_wayland_window->object(),
+ transientPos.x(), transientPos.y(), 0);
+}
+
+void QWaylandWlShellSurface::setType(Qt::WindowType type, QWaylandWindow *transientParent)
+{
+ if (type == Qt::Popup && transientParent && transientParent->object())
+ setPopup(transientParent, m_window->display()->lastInputDevice(), m_window->display()->lastInputSerial());
+ else if (transientParent && transientParent->object())
+ updateTransientParent(transientParent->window());
+ else
+ setTopLevel();
+}
+
+void QWaylandWlShellSurface::shell_surface_ping(uint32_t serial)
+{
+ pong(serial);
+}
+
+void QWaylandWlShellSurface::shell_surface_configure(uint32_t edges, int32_t width, int32_t height)
+{
+ m_pending.size = QSize(width, height);
+ m_pending.edges = static_cast<enum resize>(edges);
+ if (m_pending.edges && !m_pending.size.isEmpty())
+ m_normalSize = m_pending.size;
+ m_window->applyConfigureWhenPossible();
+}
+
+void QWaylandWlShellSurface::shell_surface_popup_done()
+{
+ QCoreApplication::postEvent(m_window->window(), new QCloseEvent());
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h
new file mode 100644
index 000000000..ca81dd685
--- /dev/null
+++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDWLSHELLSURFACE_H
+#define QWAYLANDWLSHELLSURFACE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QSize>
+
+#include <wayland-client.h>
+
+#include <QtWaylandClient/qtwaylandclientglobal.h>
+#include <QtWaylandClient/private/qwayland-wayland.h>
+#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+
+namespace QtWaylandClient {
+
+class QWaylandWindow;
+class QWaylandInputDevice;
+class QWaylandExtendedSurface;
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandWlShellSurface : public QWaylandShellSurface
+ , public QtWayland::wl_shell_surface
+{
+ Q_OBJECT
+public:
+ QWaylandWlShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window);
+ ~QWaylandWlShellSurface() override;
+
+ using QtWayland::wl_shell_surface::resize;
+ void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) override;
+
+ using QtWayland::wl_shell_surface::move;
+ bool move(QWaylandInputDevice *inputDevice) override;
+
+ void setTitle(const QString & title) override;
+ void setAppId(const QString &appId) override;
+
+ void raise() override;
+ void lower() override;
+ void setContentOrientationMask(Qt::ScreenOrientations orientation) override;
+ void setWindowFlags(Qt::WindowFlags flags) override;
+ void sendProperty(const QString &name, const QVariant &value) override;
+
+ void setType(Qt::WindowType type, QWaylandWindow *transientParent) override;
+ void applyConfigure() override;
+ bool wantsDecorations() const override;
+
+protected:
+ void requestWindowStates(Qt::WindowStates states) override;
+
+private:
+ void setTopLevel();
+ void updateTransientParent(QWindow *parent);
+ void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, uint serial);
+
+ QWaylandWindow *m_window = nullptr;
+ struct {
+ Qt::WindowStates states = Qt::WindowNoState;
+ QSize size;
+ enum resize edges = resize_none;
+ } m_applied, m_pending;
+ QSize m_normalSize;
+ // There's really no need to have pending and applied state on wl-shell, but we do it just to
+ // keep the different shell implementations more similar.
+ QWaylandExtendedSurface *m_extendedWindow = nullptr;
+
+ void shell_surface_ping(uint32_t serial) override;
+ void shell_surface_configure(uint32_t edges,
+ int32_t width,
+ int32_t height) override;
+ void shell_surface_popup_done() override;
+
+ friend class QWaylandWindow;
+};
+
+QT_END_NAMESPACE
+
+}
+
+#endif // QWAYLANDSHELLSURFACE_H
diff --git a/src/plugins/shellintegration/wl-shell/wl-shell.json b/src/plugins/shellintegration/wl-shell/wl-shell.json
new file mode 100644
index 000000000..1859bb58a
--- /dev/null
+++ b/src/plugins/shellintegration/wl-shell/wl-shell.json
@@ -0,0 +1,3 @@
+{
+ "Keys":[ "wl-shell" ]
+}
diff --git a/src/plugins/shellintegration/wl-shell/wl-shell.pro b/src/plugins/shellintegration/wl-shell/wl-shell.pro
new file mode 100644
index 000000000..211dc876f
--- /dev/null
+++ b/src/plugins/shellintegration/wl-shell/wl-shell.pro
@@ -0,0 +1,23 @@
+QT += gui-private waylandclient-private
+CONFIG += wayland-scanner
+
+QMAKE_USE += wayland-client
+
+WAYLANDCLIENTSOURCES += \
+ ../../../3rdparty/protocol/wayland.xml
+
+HEADERS += \
+ qwaylandwlshellintegration_p.h \
+ qwaylandwlshellsurface_p.h \
+
+SOURCES += \
+ main.cpp \
+ qwaylandwlshellintegration.cpp \
+ qwaylandwlshellsurface.cpp \
+
+OTHER_FILES += \
+ wl-shell.json
+
+PLUGIN_TYPE = wayland-shell-integration
+PLUGIN_CLASS_NAME = QWaylandWlShellIntegrationPlugin
+load(qt_plugin)