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:
parent
53749e2944
commit
6482bf5075
@ -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",
|
||||
|
1120
src/3rdparty/wayland/protocols/xdg-shell.xml
vendored
Normal file
1120
src/3rdparty/wayland/protocols/xdg-shell.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@ TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += \
|
||||
ivi-shell \
|
||||
xdg-shell \
|
||||
xdg-shell-v5 \
|
||||
xdg-shell-v6 \
|
||||
wl-shell \
|
||||
|
@ -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 ¶mList) override;
|
||||
};
|
||||
|
||||
QWaylandShellIntegration *QWaylandXdgShellIntegrationPlugin::create(const QString &key, const QStringList ¶mList)
|
||||
{
|
||||
Q_UNUSED(key);
|
||||
Q_UNUSED(paramList);
|
||||
return new QWaylandXdgShellIntegration();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "main.moc"
|
@ -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 ®ion)
|
||||
{
|
||||
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
|
@ -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
|
@ -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
|
@ -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
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"Keys":[ "xdg-shell" ]
|
||||
}
|
@ -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)
|
@ -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")) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user