Client: Implement xdg-decoration-unstable-v1 for SSD support
[ChangeLog][QPA plugin] Added client-side support for the xdg-decoration-unstable-v1 Wayland extension. Qt clients will now let the compositor draw the window decorations if configured through this extension. Note: The env var QT_WAYLAND_DISABLE_WINDOWDECORATION is still supported, but works on a higher level, and for all shell integrations, while xdg-decoration only works with xdg-shell stable. Task-number: QTBUG-69746 Change-Id: I9dd0331bbd8d624c6be54ed23ee3b96446d5820d Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@liri.io>
This commit is contained in:
parent
87752e03d2
commit
c2f156e27b
@ -36,6 +36,23 @@
|
|||||||
Copyright (c) 2013 BMW Car IT GmbH"
|
Copyright (c) 2013 BMW Car IT GmbH"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Id": "wayland-xdg-decoration-protocol",
|
||||||
|
"Name": "Wayland xdg-decoration Protocol",
|
||||||
|
"QDocModule": "qtwaylandcompositor",
|
||||||
|
"QtUsage": "Used in the Qt Wayland platform plugin.",
|
||||||
|
"Files": "xdg-decoration-unstable-v1.xml",
|
||||||
|
|
||||||
|
"Description": "The xdg-decoration protocol allows a compositor to announce support for server-side decorations.",
|
||||||
|
"Homepage": "https://wayland.freedesktop.org",
|
||||||
|
"Version": "unstable v1, version 1",
|
||||||
|
"DownloadLocation": "https://cgit.freedesktop.org/wayland/wayland-protocols/plain/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml?h=1.16",
|
||||||
|
"LicenseId": "MIT",
|
||||||
|
"License": "MIT License",
|
||||||
|
"LicenseFile": "MIT_LICENSE.txt",
|
||||||
|
"Copyright": "Copyright © 2018 Simon Ser"
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"Id": "wayland-xdg-output-protocol",
|
"Id": "wayland-xdg-output-protocol",
|
||||||
"Name": "Wayland XDG Output Protocol",
|
"Name": "Wayland XDG Output Protocol",
|
||||||
|
156
src/3rdparty/wayland/protocols/xdg-decoration-unstable-v1.xml
vendored
Normal file
156
src/3rdparty/wayland/protocols/xdg-decoration-unstable-v1.xml
vendored
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="xdg_decoration_unstable_v1">
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2018 Simon Ser
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<interface name="zxdg_decoration_manager_v1" version="1">
|
||||||
|
<description summary="window decoration manager">
|
||||||
|
This interface allows a compositor to announce support for server-side
|
||||||
|
decorations.
|
||||||
|
|
||||||
|
A window decoration is a set of window controls as deemed appropriate by
|
||||||
|
the party managing them, such as user interface components used to move,
|
||||||
|
resize and change a window's state.
|
||||||
|
|
||||||
|
A client can use this protocol to request being decorated by a supporting
|
||||||
|
compositor.
|
||||||
|
|
||||||
|
If compositor and client do not negotiate the use of a server-side
|
||||||
|
decoration using this protocol, clients continue to self-decorate as they
|
||||||
|
see fit.
|
||||||
|
|
||||||
|
Warning! The protocol described in this file is experimental and
|
||||||
|
backward incompatible changes may be made. Backward compatible changes
|
||||||
|
may be added together with the corresponding interface version bump.
|
||||||
|
Backward incompatible changes are done by bumping the version number in
|
||||||
|
the protocol and interface names and resetting the interface version.
|
||||||
|
Once the protocol is to be declared stable, the 'z' prefix and the
|
||||||
|
version number in the protocol and interface names are removed and the
|
||||||
|
interface version number is reset.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the decoration manager object">
|
||||||
|
Destroy the decoration manager. This doesn't destroy objects created
|
||||||
|
with the manager.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="get_toplevel_decoration">
|
||||||
|
<description summary="create a new toplevel decoration object">
|
||||||
|
Create a new decoration object associated with the given toplevel.
|
||||||
|
|
||||||
|
Creating an xdg_toplevel_decoration from an xdg_toplevel which has a
|
||||||
|
buffer attached or committed is a client error, and any attempts by a
|
||||||
|
client to attach or manipulate a buffer prior to the first
|
||||||
|
xdg_toplevel_decoration.configure event must also be treated as
|
||||||
|
errors.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="zxdg_toplevel_decoration_v1"/>
|
||||||
|
<arg name="toplevel" type="object" interface="xdg_toplevel"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="zxdg_toplevel_decoration_v1" version="1">
|
||||||
|
<description summary="decoration object for a toplevel surface">
|
||||||
|
The decoration object allows the compositor to toggle server-side window
|
||||||
|
decorations for a toplevel surface. The client can request to switch to
|
||||||
|
another mode.
|
||||||
|
|
||||||
|
The xdg_toplevel_decoration object must be destroyed before its
|
||||||
|
xdg_toplevel.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="unconfigured_buffer" value="0"
|
||||||
|
summary="xdg_toplevel has a buffer attached before configure"/>
|
||||||
|
<entry name="already_constructed" value="1"
|
||||||
|
summary="xdg_toplevel already has a decoration object"/>
|
||||||
|
<entry name="orphaned" value="2"
|
||||||
|
summary="xdg_toplevel destroyed before the decoration object"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the decoration object">
|
||||||
|
Switch back to a mode without any server-side decorations at the next
|
||||||
|
commit.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="mode">
|
||||||
|
<description summary="window decoration modes">
|
||||||
|
These values describe window decoration modes.
|
||||||
|
</description>
|
||||||
|
<entry name="client_side" value="1"
|
||||||
|
summary="no server-side window decoration"/>
|
||||||
|
<entry name="server_side" value="2"
|
||||||
|
summary="server-side window decoration"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="set_mode">
|
||||||
|
<description summary="set the decoration mode">
|
||||||
|
Set the toplevel surface decoration mode. This informs the compositor
|
||||||
|
that the client prefers the provided decoration mode.
|
||||||
|
|
||||||
|
After requesting a decoration mode, the compositor will respond by
|
||||||
|
emitting a xdg_surface.configure event. The client should then update
|
||||||
|
its content, drawing it without decorations if the received mode is
|
||||||
|
server-side decorations. The client must also acknowledge the configure
|
||||||
|
when committing the new content (see xdg_surface.ack_configure).
|
||||||
|
|
||||||
|
The compositor can decide not to use the client's mode and enforce a
|
||||||
|
different mode instead.
|
||||||
|
|
||||||
|
Clients whose decoration mode depend on the xdg_toplevel state may send
|
||||||
|
a set_mode request in response to a xdg_surface.configure event and wait
|
||||||
|
for the next xdg_surface.configure event to prevent unwanted state.
|
||||||
|
Such clients are responsible for preventing configure loops and must
|
||||||
|
make sure not to send multiple successive set_mode requests with the
|
||||||
|
same decoration mode.
|
||||||
|
</description>
|
||||||
|
<arg name="mode" type="uint" enum="mode" summary="the decoration mode"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="unset_mode">
|
||||||
|
<description summary="unset the decoration mode">
|
||||||
|
Unset the toplevel surface decoration mode. This informs the compositor
|
||||||
|
that the client doesn't prefer a particular decoration mode.
|
||||||
|
|
||||||
|
This request has the same semantics as set_mode.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="configure">
|
||||||
|
<description summary="suggest a surface change">
|
||||||
|
The configure event asks the client to change its decoration mode. The
|
||||||
|
configured state should not be applied immediately. Clients must send an
|
||||||
|
ack_configure in response to this event. See xdg_surface.configure and
|
||||||
|
xdg_surface.ack_configure for details.
|
||||||
|
|
||||||
|
A configure event can be sent at any time. The specified mode must be
|
||||||
|
obeyed by the client.
|
||||||
|
</description>
|
||||||
|
<arg name="mode" type="uint" enum="mode" summary="the decoration mode"/>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
@ -0,0 +1,105 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2018 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 "qwaylandxdgdecorationv1_p.h"
|
||||||
|
#include "qwaylandxdgshell_p.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace QtWaylandClient {
|
||||||
|
|
||||||
|
QWaylandXdgDecorationManagerV1::QWaylandXdgDecorationManagerV1(wl_registry *registry, uint32_t id, uint32_t availableVersion)
|
||||||
|
: QtWayland::zxdg_decoration_manager_v1(registry, id, qMin(availableVersion, 1u))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandXdgDecorationManagerV1::~QWaylandXdgDecorationManagerV1()
|
||||||
|
{
|
||||||
|
Q_ASSERT(isInitialized());
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandXdgToplevelDecorationV1 *QWaylandXdgDecorationManagerV1::createToplevelDecoration(::xdg_toplevel *toplevel)
|
||||||
|
{
|
||||||
|
Q_ASSERT(toplevel);
|
||||||
|
return new QWaylandXdgToplevelDecorationV1(get_toplevel_decoration(toplevel));
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandXdgToplevelDecorationV1::QWaylandXdgToplevelDecorationV1(::zxdg_toplevel_decoration_v1 *decoration)
|
||||||
|
: QtWayland::zxdg_toplevel_decoration_v1(decoration)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandXdgToplevelDecorationV1::~QWaylandXdgToplevelDecorationV1()
|
||||||
|
{
|
||||||
|
Q_ASSERT(isInitialized());
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandXdgToplevelDecorationV1::requestMode(QtWayland::zxdg_toplevel_decoration_v1::mode mode)
|
||||||
|
{
|
||||||
|
// According to the spec the client is responsible for not requesting a mode repeatedly.
|
||||||
|
if (m_modeSet && m_requested == mode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
set_mode(mode);
|
||||||
|
m_requested = mode;
|
||||||
|
m_modeSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandXdgToplevelDecorationV1::unsetMode()
|
||||||
|
{
|
||||||
|
unset_mode();
|
||||||
|
m_modeSet = false;
|
||||||
|
m_requested = mode_client_side;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandXdgToplevelDecorationV1::mode QWaylandXdgToplevelDecorationV1::pending() const
|
||||||
|
{
|
||||||
|
return m_pending;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtWaylandClient::QWaylandXdgToplevelDecorationV1::zxdg_toplevel_decoration_v1_configure(uint32_t mode)
|
||||||
|
{
|
||||||
|
m_pending = zxdg_toplevel_decoration_v1::mode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
@ -0,0 +1,97 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2018 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 QWAYLANDXDGDECORATIONV1_P_H
|
||||||
|
#define QWAYLANDXDGDECORATIONV1_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 "qwayland-xdg-decoration-unstable-v1.h"
|
||||||
|
|
||||||
|
#include <QtWaylandClient/qtwaylandclientglobal.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QWindow;
|
||||||
|
|
||||||
|
namespace QtWaylandClient {
|
||||||
|
|
||||||
|
class QWaylandXdgToplevel;
|
||||||
|
class QWaylandXdgToplevelDecorationV1;
|
||||||
|
|
||||||
|
class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgDecorationManagerV1 : public QtWayland::zxdg_decoration_manager_v1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QWaylandXdgDecorationManagerV1(struct ::wl_registry *registry, uint32_t id, uint32_t availableVersion);
|
||||||
|
~QWaylandXdgDecorationManagerV1() override;
|
||||||
|
QWaylandXdgToplevelDecorationV1 *createToplevelDecoration(::xdg_toplevel *toplevel);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgToplevelDecorationV1 : public QtWayland::zxdg_toplevel_decoration_v1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QWaylandXdgToplevelDecorationV1(::zxdg_toplevel_decoration_v1 *decoration);
|
||||||
|
~QWaylandXdgToplevelDecorationV1() override;
|
||||||
|
void requestMode(mode mode);
|
||||||
|
void unsetMode();
|
||||||
|
mode pending() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void zxdg_toplevel_decoration_v1_configure(uint32_t mode) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mode m_pending = mode_client_side;
|
||||||
|
mode m_requested = mode_client_side;
|
||||||
|
bool m_modeSet = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QWAYLANDXDGDECORATIONV1_P_H
|
@ -54,7 +54,12 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
|
|||||||
: QtWayland::xdg_toplevel(xdgSurface->get_toplevel())
|
: QtWayland::xdg_toplevel(xdgSurface->get_toplevel())
|
||||||
, m_xdgSurface(xdgSurface)
|
, m_xdgSurface(xdgSurface)
|
||||||
{
|
{
|
||||||
requestWindowStates(xdgSurface->window()->window()->windowStates());
|
if (auto *decorationManager = m_xdgSurface->m_shell->decorationManager())
|
||||||
|
m_decoration = decorationManager->createToplevelDecoration(object());
|
||||||
|
|
||||||
|
QWindow *window = xdgSurface->window()->window();
|
||||||
|
requestWindowStates(window->windowStates());
|
||||||
|
requestWindowFlags(window->flags());
|
||||||
}
|
}
|
||||||
|
|
||||||
QWaylandXdgSurface::Toplevel::~Toplevel()
|
QWaylandXdgSurface::Toplevel::~Toplevel()
|
||||||
@ -63,6 +68,11 @@ QWaylandXdgSurface::Toplevel::~Toplevel()
|
|||||||
QWaylandWindow *window = m_xdgSurface->window();
|
QWaylandWindow *window = m_xdgSurface->window();
|
||||||
window->display()->handleWindowDeactivated(window);
|
window->display()->handleWindowDeactivated(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The protocol spec requires that the decoration object is deleted before xdg_toplevel.
|
||||||
|
delete m_decoration;
|
||||||
|
m_decoration = nullptr;
|
||||||
|
|
||||||
if (isInitialized())
|
if (isInitialized())
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
@ -91,6 +101,14 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
|
|||||||
m_applied = m_pending;
|
m_applied = m_pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QWaylandXdgSurface::Toplevel::wantsDecorations()
|
||||||
|
{
|
||||||
|
if (m_decoration && m_decoration->pending() == QWaylandXdgToplevelDecorationV1::mode_server_side)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !(m_pending.states & Qt::WindowFullScreen);
|
||||||
|
}
|
||||||
|
|
||||||
void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states)
|
void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states)
|
||||||
{
|
{
|
||||||
m_pending.size = QSize(width, height);
|
m_pending.size = QSize(width, height);
|
||||||
@ -124,6 +142,16 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_close()
|
|||||||
m_xdgSurface->m_window->window()->close();
|
m_xdgSurface->m_window->window()->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWaylandXdgSurface::Toplevel::requestWindowFlags(Qt::WindowFlags flags)
|
||||||
|
{
|
||||||
|
if (m_decoration) {
|
||||||
|
if (flags & Qt::FramelessWindowHint)
|
||||||
|
m_decoration->requestMode(QWaylandXdgToplevelDecorationV1::mode_client_side);
|
||||||
|
else
|
||||||
|
m_decoration->unsetMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QWaylandXdgSurface::Toplevel::requestWindowStates(Qt::WindowStates states)
|
void QWaylandXdgSurface::Toplevel::requestWindowStates(Qt::WindowStates states)
|
||||||
{
|
{
|
||||||
// Re-send what's different from the applied state
|
// Re-send what's different from the applied state
|
||||||
@ -237,6 +265,12 @@ void QWaylandXdgSurface::setAppId(const QString &appId)
|
|||||||
m_toplevel->set_app_id(appId);
|
m_toplevel->set_app_id(appId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWaylandXdgSurface::setWindowFlags(Qt::WindowFlags flags)
|
||||||
|
{
|
||||||
|
if (m_toplevel)
|
||||||
|
m_toplevel->requestWindowFlags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
bool QWaylandXdgSurface::handleExpose(const QRegion ®ion)
|
bool QWaylandXdgSurface::handleExpose(const QRegion ®ion)
|
||||||
{
|
{
|
||||||
if (!m_configured && !region.isEmpty()) {
|
if (!m_configured && !region.isEmpty()) {
|
||||||
@ -261,7 +295,7 @@ void QWaylandXdgSurface::applyConfigure()
|
|||||||
|
|
||||||
bool QWaylandXdgSurface::wantsDecorations() const
|
bool QWaylandXdgSurface::wantsDecorations() const
|
||||||
{
|
{
|
||||||
return m_toplevel && !(m_toplevel->m_pending.states & Qt::WindowFullScreen);
|
return m_toplevel && m_toplevel->wantsDecorations();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandXdgSurface::requestWindowStates(Qt::WindowStates states)
|
void QWaylandXdgSurface::requestWindowStates(Qt::WindowStates states)
|
||||||
@ -313,13 +347,16 @@ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QWaylandXdgShell::QWaylandXdgShell(struct ::wl_registry *registry, uint32_t id, uint32_t availableVersion)
|
QWaylandXdgShell::QWaylandXdgShell(QWaylandDisplay *display, uint32_t id, uint32_t availableVersion)
|
||||||
: QtWayland::xdg_wm_base(registry, id, qMin(availableVersion, 1u))
|
: QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 1u))
|
||||||
|
, m_display(display)
|
||||||
{
|
{
|
||||||
|
display->addRegistryListener(&QWaylandXdgShell::handleRegistryGlobal, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWaylandXdgShell::~QWaylandXdgShell()
|
QWaylandXdgShell::~QWaylandXdgShell()
|
||||||
{
|
{
|
||||||
|
m_display->removeListener(&QWaylandXdgShell::handleRegistryGlobal, this);
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,6 +370,14 @@ void QWaylandXdgShell::xdg_wm_base_ping(uint32_t serial)
|
|||||||
pong(serial);
|
pong(serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWaylandXdgShell::handleRegistryGlobal(void *data, wl_registry *registry, uint id,
|
||||||
|
const QString &interface, uint version)
|
||||||
|
{
|
||||||
|
QWaylandXdgShell *xdgShell = static_cast<QWaylandXdgShell *>(data);
|
||||||
|
if (interface == QLatin1String(QWaylandXdgDecorationManagerV1::interface()->name))
|
||||||
|
xdgShell->m_xdgDecorationManager.reset(new QWaylandXdgDecorationManagerV1(registry, id, version));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -54,6 +54,8 @@
|
|||||||
|
|
||||||
#include "qwayland-xdg-shell.h"
|
#include "qwayland-xdg-shell.h"
|
||||||
|
|
||||||
|
#include "qwaylandxdgdecorationv1_p.h"
|
||||||
|
|
||||||
#include <QtWaylandClient/qtwaylandclientglobal.h>
|
#include <QtWaylandClient/qtwaylandclientglobal.h>
|
||||||
#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
|
#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
|
||||||
|
|
||||||
@ -68,6 +70,7 @@ class QWindow;
|
|||||||
|
|
||||||
namespace QtWaylandClient {
|
namespace QtWaylandClient {
|
||||||
|
|
||||||
|
class QWaylandDisplay;
|
||||||
class QWaylandWindow;
|
class QWaylandWindow;
|
||||||
class QWaylandInputDevice;
|
class QWaylandInputDevice;
|
||||||
class QWaylandXdgShell;
|
class QWaylandXdgShell;
|
||||||
@ -84,6 +87,7 @@ public:
|
|||||||
bool move(QWaylandInputDevice *inputDevice) override;
|
bool move(QWaylandInputDevice *inputDevice) override;
|
||||||
void setTitle(const QString &title) override;
|
void setTitle(const QString &title) override;
|
||||||
void setAppId(const QString &appId) override;
|
void setAppId(const QString &appId) override;
|
||||||
|
void setWindowFlags(Qt::WindowFlags flags) override;
|
||||||
|
|
||||||
bool isExposed() const override { return m_configured; }
|
bool isExposed() const override { return m_configured; }
|
||||||
bool handleExpose(const QRegion &) override;
|
bool handleExpose(const QRegion &) override;
|
||||||
@ -103,10 +107,12 @@ private:
|
|||||||
~Toplevel() override;
|
~Toplevel() override;
|
||||||
|
|
||||||
void applyConfigure();
|
void applyConfigure();
|
||||||
|
bool wantsDecorations();
|
||||||
|
|
||||||
void xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states) override;
|
void xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states) override;
|
||||||
void xdg_toplevel_close() override;
|
void xdg_toplevel_close() override;
|
||||||
|
|
||||||
|
void requestWindowFlags(Qt::WindowFlags flags);
|
||||||
void requestWindowStates(Qt::WindowStates states);
|
void requestWindowStates(Qt::WindowStates states);
|
||||||
struct {
|
struct {
|
||||||
QSize size = {0, 0};
|
QSize size = {0, 0};
|
||||||
@ -115,6 +121,7 @@ private:
|
|||||||
QSize m_normalSize;
|
QSize m_normalSize;
|
||||||
|
|
||||||
QWaylandXdgSurface *m_xdgSurface = nullptr;
|
QWaylandXdgSurface *m_xdgSurface = nullptr;
|
||||||
|
QWaylandXdgToplevelDecorationV1 *m_decoration = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Popup : public QtWayland::xdg_popup {
|
class Popup : public QtWayland::xdg_popup {
|
||||||
@ -142,14 +149,21 @@ private:
|
|||||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgShell : public QtWayland::xdg_wm_base
|
class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgShell : public QtWayland::xdg_wm_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QWaylandXdgShell(struct ::wl_registry *registry, uint32_t id, uint32_t availableVersion);
|
QWaylandXdgShell(QWaylandDisplay *display, uint32_t id, uint32_t availableVersion);
|
||||||
|
|
||||||
QWaylandXdgSurface *getXdgSurface(QWaylandWindow *window);
|
|
||||||
|
|
||||||
~QWaylandXdgShell() override;
|
~QWaylandXdgShell() override;
|
||||||
|
|
||||||
private:
|
QWaylandXdgDecorationManagerV1 *decorationManager() { return m_xdgDecorationManager.data(); }
|
||||||
|
QWaylandXdgSurface *getXdgSurface(QWaylandWindow *window);
|
||||||
|
|
||||||
|
protected:
|
||||||
void xdg_wm_base_ping(uint32_t serial) override;
|
void xdg_wm_base_ping(uint32_t serial) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void handleRegistryGlobal(void *data, ::wl_registry *registry, uint id,
|
||||||
|
const QString &interface, uint version);
|
||||||
|
|
||||||
|
QWaylandDisplay *m_display = nullptr;
|
||||||
|
QScopedPointer<QWaylandXdgDecorationManagerV1> m_xdgDecorationManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qwaylandxdgshellintegration_p.h"
|
#include "qwaylandxdgshellintegration_p.h"
|
||||||
|
#include "qwaylandxdgdecorationv1_p.h"
|
||||||
|
|
||||||
#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
||||||
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
|
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
|
||||||
@ -50,7 +51,7 @@ bool QWaylandXdgShellIntegration::initialize(QWaylandDisplay *display)
|
|||||||
{
|
{
|
||||||
for (QWaylandDisplay::RegistryGlobal global : display->globals()) {
|
for (QWaylandDisplay::RegistryGlobal global : display->globals()) {
|
||||||
if (global.interface == QLatin1String("xdg_wm_base")) {
|
if (global.interface == QLatin1String("xdg_wm_base")) {
|
||||||
m_xdgShell.reset(new QWaylandXdgShell(display->wl_registry(), global.id, global.version));
|
m_xdgShell.reset(new QWaylandXdgShell(display, global.id, global.version));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,17 @@ qtConfig(xkbcommon-evdev): \
|
|||||||
QMAKE_USE_PRIVATE += xkbcommon_evdev
|
QMAKE_USE_PRIVATE += xkbcommon_evdev
|
||||||
|
|
||||||
WAYLANDCLIENTSOURCES += \
|
WAYLANDCLIENTSOURCES += \
|
||||||
|
../../../3rdparty/protocol/xdg-decoration-unstable-v1.xml \
|
||||||
../../../3rdparty/protocol/xdg-shell.xml
|
../../../3rdparty/protocol/xdg-shell.xml
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
qwaylandxdgdecorationv1_p.h \
|
||||||
qwaylandxdgshell_p.h \
|
qwaylandxdgshell_p.h \
|
||||||
qwaylandxdgshellintegration_p.h \
|
qwaylandxdgshellintegration_p.h \
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
|
qwaylandxdgdecorationv1.cpp \
|
||||||
qwaylandxdgshell.cpp \
|
qwaylandxdgshell.cpp \
|
||||||
qwaylandxdgshellintegration.cpp \
|
qwaylandxdgshellintegration.cpp \
|
||||||
|
|
||||||
|
@ -326,6 +326,13 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
|
|||||||
(*l.listener)(l.data, mGlobals[i].registry, mGlobals[i].id, mGlobals[i].interface, mGlobals[i].version);
|
(*l.listener)(l.data, mGlobals[i].registry, mGlobals[i].id, mGlobals[i].interface, mGlobals[i].version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWaylandDisplay::removeListener(RegistryListener listener, void *data)
|
||||||
|
{
|
||||||
|
std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
|
||||||
|
return (l.listener == listener && l.data == data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t QWaylandDisplay::currentTimeMillisec()
|
uint32_t QWaylandDisplay::currentTimeMillisec()
|
||||||
{
|
{
|
||||||
//### we throw away the time information
|
//### we throw away the time information
|
||||||
|
@ -161,6 +161,7 @@ public:
|
|||||||
/* wl_registry_add_listener does not add but rather sets a listener, so this function is used
|
/* wl_registry_add_listener does not add but rather sets a listener, so this function is used
|
||||||
* to enable many listeners at once. */
|
* to enable many listeners at once. */
|
||||||
void addRegistryListener(RegistryListener listener, void *data);
|
void addRegistryListener(RegistryListener listener, void *data);
|
||||||
|
void removeListener(RegistryListener listener, void *data);
|
||||||
|
|
||||||
QWaylandShm *shm() const { return mShm.data(); }
|
QWaylandShm *shm() const { return mShm.data(); }
|
||||||
|
|
||||||
|
@ -117,7 +117,8 @@ public:
|
|||||||
virtual QWaylandShellIntegration *shellIntegration() const;
|
virtual QWaylandShellIntegration *shellIntegration() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// NOTE: mDisplay *must* be destructed after mDrag and mClientBufferIntegration.
|
// NOTE: mDisplay *must* be destructed after mDrag and mClientBufferIntegration
|
||||||
|
// and mShellIntegration.
|
||||||
// Do not move this definition into the private section at the bottom.
|
// Do not move this definition into the private section at the bottom.
|
||||||
QScopedPointer<QWaylandDisplay> mDisplay;
|
QScopedPointer<QWaylandDisplay> mDisplay;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user