Client: Add shell integration for xdg-shell stable

[ChangeLog][QPA plugin] Added support for xdg-shell stable.

Mostly a copy of xdg_shell unstable v6 with prefixes and suffixes
removed. Otherwise, this is what changed:

- The global is now named "xdg_wm_base", since "xdg_shell" was taken by
  xdg-shell <= v5.
- Anchors and gravities are not bitfields anymore.

Task-number: QTBUG-66783
Change-Id: I8ca881aae52cc07b22ff5e26df13a9a1566f58f4
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
Johan Klokkhammer Helsing 2018-05-24 11:46:11 +02:00 committed by Johan Helsing
parent 53749e2944
commit 6482bf5075
11 changed files with 1880 additions and 1 deletions

View File

@ -41,7 +41,7 @@ Copyright (c) 2013 BMW Car IT GmbH"
"Name": "Wayland XDG Shell Protocol",
"QDocModule": "qtwaylandcompositor",
"QtUsage": "Used in the Qt Wayland Compositor, and the Qt Wayland platform plugin.",
"Files": "xdg-shell-unstable-v5.xml xdg-shell-unstable-v6.xml",
"Files": "xdg-shell-unstable-v5.xml xdg-shell-unstable-v6.xml xdg-shell.xml",
"Description": "The XDG-Shell protocol is an extended way to manage surfaces under Wayland compositors.",
"Homepage": "https://wayland.freedesktop.org",

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@ TEMPLATE = subdirs
SUBDIRS += \
ivi-shell \
xdg-shell \
xdg-shell-v5 \
xdg-shell-v6 \
wl-shell \

View File

@ -0,0 +1,68 @@
/****************************************************************************
**
** Copyright (C) 2018 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 "qwaylandxdgshellintegration_p.h"
#include <QtWaylandClient/private/qwaylandshellintegrationplugin_p.h>
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
class QWaylandXdgShellIntegrationPlugin : public QWaylandShellIntegrationPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QWaylandShellIntegrationFactoryInterface_iid FILE "xdg-shell.json")
public:
QWaylandShellIntegration *create(const QString &key, const QStringList &paramList) override;
};
QWaylandShellIntegration *QWaylandXdgShellIntegrationPlugin::create(const QString &key, const QStringList &paramList)
{
Q_UNUSED(key);
Q_UNUSED(paramList);
return new QWaylandXdgShellIntegration();
}
}
QT_END_NAMESPACE
#include "main.moc"

View File

@ -0,0 +1,337 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2017 Eurogiciel, author: <philippe.coval@eurogiciel.fr>
** 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 "qwaylandxdgshell_p.h"
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
#include <QtWaylandClient/private/qwaylandwindow_p.h>
#include <QtWaylandClient/private/qwaylandinputdevice_p.h>
#include <QtWaylandClient/private/qwaylandscreen_p.h>
#include <QtWaylandClient/private/qwaylandabstractdecoration_p.h>
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
: QtWayland::xdg_toplevel(xdgSurface->get_toplevel())
, m_xdgSurface(xdgSurface)
{
requestWindowStates(xdgSurface->window()->window()->windowStates());
}
QWaylandXdgSurface::Toplevel::~Toplevel()
{
if (m_applied.states & Qt::WindowActive) {
QWaylandWindow *window = m_xdgSurface->window();
window->display()->handleWindowDeactivated(window);
}
if (isInitialized())
destroy();
}
void QWaylandXdgSurface::Toplevel::applyConfigure()
{
if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
m_normalSize = m_xdgSurface->m_window->window()->frameGeometry().size();
if (m_pending.size.isEmpty() && !m_normalSize.isEmpty())
m_pending.size = m_normalSize;
if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive))
m_xdgSurface->m_window->display()->handleWindowActivated(m_xdgSurface->m_window);
if (!(m_pending.states & Qt::WindowActive) && (m_applied.states & Qt::WindowActive))
m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
// TODO: none of the other plugins send WindowActive either, but is it on purpose?
Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
m_xdgSurface->m_window->resizeFromApplyConfigure(m_pending.size);
m_applied = m_pending;
}
void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states)
{
m_pending.size = QSize(width, height);
auto *xdgStates = static_cast<uint32_t *>(states->data);
size_t numStates = states->size / sizeof(uint32_t);
m_pending.states = Qt::WindowNoState;
for (size_t i = 0; i < numStates; i++) {
switch (xdgStates[i]) {
case XDG_TOPLEVEL_STATE_ACTIVATED:
m_pending.states |= Qt::WindowActive;
break;
case XDG_TOPLEVEL_STATE_MAXIMIZED:
m_pending.states |= Qt::WindowMaximized;
break;
case XDG_TOPLEVEL_STATE_FULLSCREEN:
m_pending.states |= Qt::WindowFullScreen;
break;
default:
break;
}
}
}
void QWaylandXdgSurface::Toplevel::xdg_toplevel_close()
{
m_xdgSurface->m_window->window()->close();
}
void QWaylandXdgSurface::Toplevel::requestWindowStates(Qt::WindowStates states)
{
// Re-send what's different from the applied state
Qt::WindowStates changedStates = m_applied.states ^ states;
if (changedStates & Qt::WindowMaximized) {
if (states & Qt::WindowMaximized)
set_maximized();
else
unset_maximized();
}
if (changedStates & Qt::WindowFullScreen) {
if (states & Qt::WindowFullScreen)
set_fullscreen(nullptr);
else
unset_fullscreen();
}
// Minimized state is not reported by the protocol, so always send it
if (states & Qt::WindowMinimized) {
set_minimized();
m_xdgSurface->window()->handleWindowStatesChanged(states & ~Qt::WindowMinimized);
}
}
QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent,
QtWayland::xdg_positioner *positioner)
: xdg_popup(xdgSurface->get_popup(parent->object(), positioner->object()))
, m_xdgSurface(xdgSurface)
{
}
QWaylandXdgSurface::Popup::~Popup()
{
if (isInitialized())
destroy();
}
void QWaylandXdgSurface::Popup::applyConfigure()
{
}
void QWaylandXdgSurface::Popup::xdg_popup_popup_done()
{
m_xdgSurface->m_window->window()->close();
}
QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *surface, QWaylandWindow *window)
: QWaylandShellSurface(window)
, xdg_surface(surface)
, m_shell(shell)
, m_window(window)
{
}
QWaylandXdgSurface::~QWaylandXdgSurface()
{
if (m_toplevel)
xdg_toplevel_destroy(m_toplevel->object());
if (m_popup)
xdg_popup_destroy(m_popup->object());
destroy();
}
void QWaylandXdgSurface::resize(QWaylandInputDevice *inputDevice, xdg_toplevel_resize_edge edges)
{
Q_ASSERT(m_toplevel && m_toplevel->isInitialized());
m_toplevel->resize(inputDevice->wl_seat(), inputDevice->serial(), edges);
}
void QWaylandXdgSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges)
{
auto xdgEdges = reinterpret_cast<enum xdg_toplevel_resize_edge const * const>(&edges);
resize(inputDevice, *xdgEdges);
}
bool QWaylandXdgSurface::move(QWaylandInputDevice *inputDevice)
{
if (m_toplevel && m_toplevel->isInitialized()) {
m_toplevel->move(inputDevice->wl_seat(), inputDevice->serial());
return true;
}
return false;
}
void QWaylandXdgSurface::setTitle(const QString &title)
{
if (m_toplevel)
m_toplevel->set_title(title);
}
void QWaylandXdgSurface::setAppId(const QString &appId)
{
if (m_toplevel)
m_toplevel->set_app_id(appId);
}
void QWaylandXdgSurface::setType(Qt::WindowType type, QWaylandWindow *transientParent)
{
QWaylandDisplay *display = m_window->display();
if ((type == Qt::Popup || type == Qt::ToolTip) && transientParent && display->lastInputDevice()) {
setPopup(transientParent, display->lastInputDevice(), display->lastInputSerial(), type == Qt::Popup);
} else {
setToplevel();
if (transientParent) {
auto parentXdgSurface = static_cast<QWaylandXdgSurface *>(transientParent->shellSurface());
if (parentXdgSurface)
m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
}
}
}
bool QWaylandXdgSurface::handleExpose(const QRegion &region)
{
if (!m_configured && !region.isEmpty()) {
m_exposeRegion = region;
return true;
}
return false;
}
void QWaylandXdgSurface::applyConfigure()
{
Q_ASSERT(m_pendingConfigureSerial != 0);
if (m_toplevel)
m_toplevel->applyConfigure();
if (m_popup)
m_popup->applyConfigure();
m_configured = true;
ack_configure(m_pendingConfigureSerial);
m_pendingConfigureSerial = 0;
}
bool QWaylandXdgSurface::wantsDecorations() const
{
return m_toplevel && !(m_toplevel->m_pending.states & Qt::WindowFullScreen);
}
void QWaylandXdgSurface::requestWindowStates(Qt::WindowStates states)
{
if (m_toplevel)
m_toplevel->requestWindowStates(states);
else
qCWarning(lcQpaWayland) << "Non-toplevel surfaces can't request window states";
}
void QWaylandXdgSurface::setToplevel()
{
Q_ASSERT(!m_toplevel && !m_popup);
m_toplevel = new Toplevel(this);
}
void QWaylandXdgSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial, bool grab)
{
Q_ASSERT(!m_toplevel && !m_popup);
auto parentXdgSurface = static_cast<QWaylandXdgSurface *>(parent->shellSurface());
auto positioner = new QtWayland::xdg_positioner(m_shell->create_positioner());
// set_popup expects a position relative to the parent
QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
transientPos -= parent->geometry().topLeft();
if (parent->decoration()) {
transientPos.setX(transientPos.x() + parent->decoration()->margins().left());
transientPos.setY(transientPos.y() + parent->decoration()->margins().top());
}
positioner->set_anchor_rect(transientPos.x(), transientPos.y(), 1, 1);
positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left);
positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right);
positioner->set_size(m_window->geometry().width(), m_window->geometry().height());
m_popup = new Popup(this, parentXdgSurface, positioner);
positioner->destroy();
delete positioner;
if (grab) {
m_popup->grab(device->wl_seat(), serial);
}
}
void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
{
m_window->applyConfigureWhenPossible();
m_pendingConfigureSerial = serial;
if (!m_exposeRegion.isEmpty()) {
QWindowSystemInterface::handleExposeEvent(m_window->window(), m_exposeRegion);
m_exposeRegion = QRegion();
}
}
QWaylandXdgShell::QWaylandXdgShell(struct ::wl_registry *registry, uint32_t id, uint32_t availableVersion)
: QtWayland::xdg_wm_base(registry, id, qMin(availableVersion, 1u))
{
}
QWaylandXdgShell::~QWaylandXdgShell()
{
destroy();
}
QWaylandXdgSurface *QWaylandXdgShell::getXdgSurface(QWaylandWindow *window)
{
return new QWaylandXdgSurface(this, get_xdg_surface(window->object()), window);
}
void QWaylandXdgShell::xdg_wm_base_ping(uint32_t serial)
{
pong(serial);
}
}
QT_END_NAMESPACE

View File

@ -0,0 +1,161 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2017 Eurogiciel, author: <philippe.coval@eurogiciel.fr>
** 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 QWAYLANDXDGSHELL_H
#define QWAYLANDXDGSHELL_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 "qwayland-xdg-shell.h"
#include <QtWaylandClient/qtwaylandclientglobal.h>
#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
#include <QtCore/QSize>
#include <QtGui/QRegion>
#include <wayland-client.h>
QT_BEGIN_NAMESPACE
class QWindow;
namespace QtWaylandClient {
class QWaylandWindow;
class QWaylandInputDevice;
class QWaylandXdgShell;
class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgSurface : public QWaylandShellSurface, public QtWayland::xdg_surface
{
Q_OBJECT
public:
QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *surface, QWaylandWindow *window);
~QWaylandXdgSurface() override;
void resize(QWaylandInputDevice *inputDevice, enum xdg_toplevel_resize_edge edges);
void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) override;
bool move(QWaylandInputDevice *inputDevice) override;
void setTitle(const QString &title) override;
void setAppId(const QString &appId) override;
void setType(Qt::WindowType type, QWaylandWindow *transientParent) override;
bool isExposed() const override { return m_configured; }
bool handleExpose(const QRegion &) override;
bool handlesActiveState() const { return m_toplevel; }
void applyConfigure() override;
bool wantsDecorations() const override;
protected:
void requestWindowStates(Qt::WindowStates states) override;
void xdg_surface_configure(uint32_t serial) override;
private:
class Toplevel: public QtWayland::xdg_toplevel
{
public:
Toplevel(QWaylandXdgSurface *xdgSurface);
~Toplevel() override;
void applyConfigure();
void xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states) override;
void xdg_toplevel_close() override;
void requestWindowStates(Qt::WindowStates states);
struct {
QSize size = {0, 0};
Qt::WindowStates states = Qt::WindowNoState;
} m_pending, m_applied;
QSize m_normalSize;
QWaylandXdgSurface *m_xdgSurface = nullptr;
};
class Popup : public QtWayland::xdg_popup {
public:
Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent, QtWayland::xdg_positioner *positioner);
~Popup() override;
void applyConfigure();
void xdg_popup_popup_done() override;
QWaylandXdgSurface *m_xdgSurface = nullptr;
};
void setToplevel();
void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial, bool grab);
QWaylandXdgShell *m_shell = nullptr;
QWaylandWindow *m_window = nullptr;
Toplevel *m_toplevel = nullptr;
Popup *m_popup = nullptr;
bool m_configured = false;
QRegion m_exposeRegion;
uint m_pendingConfigureSerial = 0;
};
class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgShell : public QtWayland::xdg_wm_base
{
public:
QWaylandXdgShell(struct ::wl_registry *registry, uint32_t id, uint32_t availableVersion);
QWaylandXdgSurface *getXdgSurface(QWaylandWindow *window);
~QWaylandXdgShell() override;
private:
void xdg_wm_base_ping(uint32_t serial) override;
};
QT_END_NAMESPACE
}
#endif // QWAYLANDXDGSHELL_H

View File

@ -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 "qwaylandxdgshellintegration_p.h"
#include <QtWaylandClient/private/qwaylandwindow_p.h>
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
bool QWaylandXdgShellIntegration::initialize(QWaylandDisplay *display)
{
for (QWaylandDisplay::RegistryGlobal global : display->globals()) {
if (global.interface == QLatin1String("xdg_wm_base")) {
m_xdgShell.reset(new QWaylandXdgShell(display->wl_registry(), global.id, global.version));
break;
}
}
if (!m_xdgShell) {
qCDebug(lcQpaWayland) << "Couldn't find global xdg_wm_base for xdg-shell stable";
return false;
}
return QWaylandShellIntegration::initialize(display);
}
QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWindow *window)
{
return m_xdgShell->getXdgSurface(window);
}
void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
{
if (newFocus) {
auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(newFocus->shellSurface());
if (xdgSurface && !xdgSurface->handlesActiveState())
m_display->handleWindowActivated(newFocus);
}
if (oldFocus && qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface())) {
auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface());
if (xdgSurface && !xdgSurface->handlesActiveState())
m_display->handleWindowDeactivated(oldFocus);
}
}
}
QT_END_NAMESPACE

View File

@ -0,0 +1,78 @@
/****************************************************************************
**
** 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 QWAYLANDXDGSHELLINTEGRATION_P_H
#define QWAYLANDXDGSHELLINTEGRATION_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 "qwaylandxdgshell_p.h"
#include <QtWaylandClient/private/qwaylandshellintegration_p.h>
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgShellIntegration : public QWaylandShellIntegration
{
public:
QWaylandXdgShellIntegration() {}
bool initialize(QWaylandDisplay *display) override;
QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
private:
QScopedPointer<QWaylandXdgShell> m_xdgShell;
};
}
QT_END_NAMESPACE
#endif // QWAYLANDXDGSHELLINTEGRATION_P_H

View File

@ -0,0 +1,3 @@
{
"Keys":[ "xdg-shell" ]
}

View File

@ -0,0 +1,23 @@
QT += gui-private waylandclient-private
CONFIG += wayland-scanner
QMAKE_USE += wayland-client
WAYLANDCLIENTSOURCES += \
../../../3rdparty/protocol/xdg-shell.xml
HEADERS += \
qwaylandxdgshell_p.h \
qwaylandxdgshellintegration_p.h \
SOURCES += \
main.cpp \
qwaylandxdgshell.cpp \
qwaylandxdgshellintegration.cpp \
OTHER_FILES += \
xdg-shell.json
PLUGIN_TYPE = wayland-shell-integration
PLUGIN_CLASS_NAME = QWaylandXdgShellIntegrationPlugin
load(qt_plugin)

View File

@ -388,6 +388,7 @@ void QWaylandIntegration::initializeShellIntegration()
if (!targetKey.isEmpty()) {
preferredShells << targetKey;
} else {
preferredShells << QLatin1String("xdg-shell");
preferredShells << QLatin1String("xdg-shell-v6");
QString useXdgShell = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_USE_XDG_SHELL"));
if (!useXdgShell.isEmpty() && useXdgShell != QLatin1String("0")) {