diff options
author | Paul Olav Tvete <paul.tvete@qt.io> | 2021-10-18 16:41:12 +0200 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2021-12-02 09:08:40 +0100 |
commit | d89c8920f3b82dd2098971b5a66c4b9c75da5af0 (patch) | |
tree | b7f35e03485f1aa8725e30870f3066b34d24ea94 /src/plugins | |
parent | 0204df32ee7417db3156ef3c70bcf762d7e9fb0a (diff) | |
download | qtwayland-d89c8920f3b82dd2098971b5a66c4b9c75da5af0.tar.gz |
Introduce new qt-shell and an API for custom shells
Adds a new API for writing custom shell extensions. This API is supported,
but semi-public. Binary compatibility is not guaranteed.
Also adds qt-shell, a new shell that maps directly to the QWindow API, and
provides functionality that Qt provides on other window systems, such as
absolute window positions and window activation. This shell is not intended
for use on the desktop.
This is a squashed commit of a development branch consisting of approximately
60 changes. Contributors:
Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Paul Olav Tvete <paul.tvete@qt.io>
Task-number: QTBUG-94330
Task-number: QTBUG-91542
Change-Id: I419b6bd8179fe03e4da47d328c7ff4b4795b8a91
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Reviewed-by: David Edmundson <davidedmundson@kde.org>
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/plugins')
16 files changed, 678 insertions, 42 deletions
diff --git a/src/plugins/shellintegration/CMakeLists.txt b/src/plugins/shellintegration/CMakeLists.txt index fef15fe7..eefa0227 100644 --- a/src/plugins/shellintegration/CMakeLists.txt +++ b/src/plugins/shellintegration/CMakeLists.txt @@ -12,3 +12,7 @@ endif() if(QT_FEATURE_wayland_client_xdg_shell) add_subdirectory(xdg-shell) endif() + +if(QT_FEATURE_wayland_client_qt_shell) + add_subdirectory(qt-shell) +endif() diff --git a/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.cpp b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.cpp index 0cd2cb1e..033cbf6e 100644 --- a/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.cpp +++ b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.cpp @@ -44,23 +44,22 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { -bool QWaylandFullScreenShellV1Integration::initialize(QWaylandDisplay *display) +bool QWaylandFullScreenShellV1Integration::initialize() { - for (const QWaylandDisplay::RegistryGlobal &global : display->globals()) { - if (global.interface == QLatin1String("zwp_fullscreen_shell_v1") && !m_shell) { - m_shell.reset(new QtWayland::zwp_fullscreen_shell_v1(display->wl_registry(), global.id, global.version)); - break; - } - } - + if (m_shell) + return true; + wl_registry *registry; + uint32_t id; + uint32_t version; + bool found = findGlobal(QLatin1String("zwp_fullscreen_shell_v1"), ®istry, &id, &version); + if (found) + m_shell.reset(new QtWayland::zwp_fullscreen_shell_v1(registry, id, version)); if (!m_shell) { qCDebug(lcQpaWayland) << "Couldn't find global zwp_fullscreen_shell_v1 for fullscreen-shell"; return false; } - - return QWaylandShellIntegration::initialize(display); + return true; } - QWaylandShellSurface *QWaylandFullScreenShellV1Integration::createShellSurface(QWaylandWindow *window) { return new QWaylandFullScreenShellV1Surface(m_shell.data(), window); diff --git a/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.h b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.h index 131f9e72..da99f6c4 100644 --- a/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.h +++ b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.h @@ -43,6 +43,7 @@ #include <wayland-client.h> #include <QtWaylandClient/private/qwayland-wayland.h> #include <QtWaylandClient/private/qwaylandshellintegration_p.h> +#include <QScopedPointer> #include "qwayland-fullscreen-shell-unstable-v1.h" @@ -53,7 +54,7 @@ namespace QtWaylandClient { class Q_WAYLAND_CLIENT_EXPORT QWaylandFullScreenShellV1Integration : public QWaylandShellIntegration { public: - bool initialize(QWaylandDisplay *display) override; + bool initialize() override; QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override; private: diff --git a/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp b/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp index 5571682b..aab5c573 100644 --- a/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp +++ b/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp @@ -60,21 +60,30 @@ QWaylandIviShellIntegration::QWaylandIviShellIntegration() { } -bool QWaylandIviShellIntegration::initialize(QWaylandDisplay *display) +bool QWaylandIviShellIntegration::initialize() { - for (QWaylandDisplay::RegistryGlobal global : display->globals()) { - if (global.interface == QLatin1String("ivi_application") && !m_iviApplication) - m_iviApplication.reset(new QtWayland::ivi_application(display->wl_registry(), global.id, global.version)); - if (global.interface == QLatin1String("ivi_controller") && !m_iviController) - m_iviController.reset(new QtWayland::ivi_controller(display->wl_registry(), global.id, global.version)); + if (!m_iviApplication) { + wl_registry *registry; + uint32_t id; + uint32_t version; + bool found = findGlobal(QLatin1String("ivi_application"), ®istry, &id, &version); + if (found) + m_iviApplication.reset(new QtWayland::ivi_application(registry, id, version)); + } + if (!m_iviController) { + wl_registry *registry; + uint32_t id; + uint32_t version; + bool found = findGlobal(QLatin1String("ivi_controller"), ®istry, &id, &version); + if (found) + m_iviController.reset(new QtWayland::ivi_controller(registry, id, version)); } if (!m_iviApplication) { qCDebug(lcQpaWayland) << "Couldn't find global ivi_application for ivi-shell"; return false; } - - return QWaylandShellIntegration::initialize(display); + return true; } /* get unique id diff --git a/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.h b/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.h index bf8c9877..40ec378c 100644 --- a/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.h +++ b/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.h @@ -45,6 +45,7 @@ #include <QtWaylandClient/private/qwaylandshellintegration_p.h> #include "qwayland-ivi-application.h" #include "qwayland-ivi-controller.h" +#include <QScopedPointer> QT_BEGIN_NAMESPACE @@ -58,7 +59,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandIviShellIntegration : public QWaylandShell public: QWaylandIviShellIntegration(); - bool initialize(QWaylandDisplay *display) override; + bool initialize() override; QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override; private: diff --git a/src/plugins/shellintegration/qt-shell/CMakeLists.txt b/src/plugins/shellintegration/qt-shell/CMakeLists.txt new file mode 100644 index 00000000..99fbfda3 --- /dev/null +++ b/src/plugins/shellintegration/qt-shell/CMakeLists.txt @@ -0,0 +1,31 @@ +##################################################################### +## QWaylandQtShellIntegrationPlugin Plugin: +##################################################################### + +qt_internal_add_plugin(QWaylandQtShellIntegrationPlugin + OUTPUT_NAME qt-shell + TYPE wayland-shell-integration + SOURCES + main.cpp + qwaylandqtshellintegration.cpp qwaylandqtshellintegration.h + qwaylandqtsurface.cpp qwaylandqtsurface_p.h + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui + Qt::GuiPrivate + Qt::WaylandClientPrivate + Wayland::Client +) + +qt6_generate_wayland_protocol_client_sources(QWaylandQtShellIntegrationPlugin + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/../../../extensions/qt-shell-unstable-v1.xml +) + +## Scopes: +##################################################################### + +qt_internal_extend_target(QWaylandQtShellIntegrationPlugin CONDITION QT_FEATURE_xkbcommon + PUBLIC_LIBRARIES + XKB::XKB +) diff --git a/src/plugins/shellintegration/qt-shell/main.cpp b/src/plugins/shellintegration/qt-shell/main.cpp new file mode 100644 index 00000000..7628040f --- /dev/null +++ b/src/plugins/shellintegration/qt-shell/main.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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 <QtWaylandClient/private/qwaylandshellintegrationplugin_p.h> +#include "qwaylandqtshellintegration.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +class QWaylandQtShellIntegrationPlugin : public QWaylandShellIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QWaylandShellIntegrationFactoryInterface_iid FILE "qt-shell.json") + +public: + QWaylandShellIntegration *create(const QString &key, const QStringList ¶mList) override; +}; + +QWaylandShellIntegration *QWaylandQtShellIntegrationPlugin::create(const QString &key, const QStringList ¶mList) +{ + Q_UNUSED(key); + Q_UNUSED(paramList); + return new QWaylandQtShellIntegration(); +} + +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/shellintegration/qt-shell/qt-shell.json b/src/plugins/shellintegration/qt-shell/qt-shell.json new file mode 100644 index 00000000..aa6df623 --- /dev/null +++ b/src/plugins/shellintegration/qt-shell/qt-shell.json @@ -0,0 +1,3 @@ +{ + "Keys":[ "qt-shell" ] +} diff --git a/src/plugins/shellintegration/qt-shell/qwaylandqtshellintegration.cpp b/src/plugins/shellintegration/qt-shell/qwaylandqtshellintegration.cpp new file mode 100644 index 00000000..225ee61f --- /dev/null +++ b/src/plugins/shellintegration/qt-shell/qwaylandqtshellintegration.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt-project.org/legal +** +** 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 "qwaylandqtshellintegration.h" + +#include <QtCore/qsize.h> +#include <QtCore/qdebug.h> + +#include <QtWaylandClient/private/qwaylanddisplay_p.h> +#include <QtWaylandClient/private/qwaylandwindow_p.h> + +#include "qwaylandqtsurface_p.h" + +#include <mutex> + +#include <unistd.h> + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +QWaylandQtShellIntegration::QWaylandQtShellIntegration() +{ +} + +bool QWaylandQtShellIntegration::initialize() +{ + if (m_qtShell) + return true; + wl_registry *registry; + uint32_t id; + uint32_t version; + bool found = findGlobal(QLatin1String("zqt_shell_v1"), ®istry, &id, &version); + if (!found) { + qCDebug(lcQpaWayland) << "Couldn't find global zqt_shell_v1 for qt-shell"; + return false; + } + m_qtShell.reset(new QtWayland::zqt_shell_v1(registry, id, version)); + return true; +} + +QWaylandShellSurface *QWaylandQtShellIntegration::createShellSurface(QWaylandWindow *window) +{ + if (!m_qtShell) + return nullptr; + + auto *surface = m_qtShell->surface_create(wlSurfaceForWindow(window)); + return new QWaylandQtSurface(surface, window); +} + +} + +QT_END_NAMESPACE diff --git a/src/plugins/shellintegration/qt-shell/qwaylandqtshellintegration.h b/src/plugins/shellintegration/qt-shell/qwaylandqtshellintegration.h new file mode 100644 index 00000000..4feb216a --- /dev/null +++ b/src/plugins/shellintegration/qt-shell/qwaylandqtshellintegration.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt-project.org/legal +** +** 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 QWAYLANDQTINTEGRATION_H +#define QWAYLANDQTINTEGRATION_H + +#include <QtCore/qmutex.h> + +#include <QtWaylandClient/private/qwaylandshellintegration_p.h> +#include <QScopedPointer> +#include "qwayland-qt-shell-unstable-v1.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +class QWaylandWindow; +class QWaylandDisplay; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandQtShellIntegration : public QWaylandShellIntegration +{ +public: + QWaylandQtShellIntegration(); + + bool initialize() override; + QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override; + +private: + QScopedPointer<QtWayland::zqt_shell_v1> m_qtShell; +}; + +} + +QT_END_NAMESPACE + +#endif // QWAYLANDQTINTEGRATION_H diff --git a/src/plugins/shellintegration/qt-shell/qwaylandqtsurface.cpp b/src/plugins/shellintegration/qt-shell/qwaylandqtsurface.cpp new file mode 100644 index 00000000..dcd62768 --- /dev/null +++ b/src/plugins/shellintegration/qt-shell/qwaylandqtsurface.cpp @@ -0,0 +1,252 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt-project.org/legal +** +** 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 "qwaylandqtsurface_p.h" +#include <qpa/qwindowsysteminterface.h> +#include <qpa/qplatformwindow.h> + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +QWaylandQtSurface::QWaylandQtSurface(struct ::zqt_shell_surface_v1 *shell_surface, QWaylandWindow *window) + : QWaylandShellSurface(window) + , QtWayland::zqt_shell_surface_v1(shell_surface) +{ + sendSizeHints(); +} + +QWaylandQtSurface::~QWaylandQtSurface() +{ + zqt_shell_surface_v1::destroy(); +} + +void QWaylandQtSurface::resetConfiguration() +{ + m_pendingPosition = QPoint(-1, -1); + m_pendingSize = QSize(); + m_pendingPositionValid = false; + m_pendingStates = m_currentStates; +} + +void QWaylandQtSurface::applyConfigure() +{ + if (m_pendingSize.isValid() && m_pendingPositionValid) + setGeometryFromApplyConfigure(m_pendingPosition, m_pendingSize); + else if (m_pendingSize.isValid()) + resizeFromApplyConfigure(m_pendingSize); + else if (m_pendingPositionValid) + repositionFromApplyConfigure(m_pendingPosition); + + if (m_pendingStates != m_currentStates) { + QWindowSystemInterface::handleWindowStateChanged(platformWindow()->window(), m_pendingStates); + m_currentStates = m_pendingStates; + } + + ack_configure(m_currentConfigureSerial); + + resetConfiguration(); + m_currentConfigureSerial = UINT32_MAX; +} + +void QWaylandQtSurface::setTitle(const QString &title) +{ + set_window_title(title); +} + +void QWaylandQtSurface::zqt_shell_surface_v1_set_capabilities(uint32_t capabilities) +{ + m_capabilities = capabilities; +} + +void QWaylandQtSurface::zqt_shell_surface_v1_set_position(uint32_t serial, int32_t x, int32_t y) +{ + if (serial < m_currentConfigureSerial && m_currentConfigureSerial != UINT32_MAX) + return; + + if (serial != m_currentConfigureSerial) { + m_currentConfigureSerial = serial; + resetConfiguration(); + } + + m_pendingPosition = QPoint(x, y); + m_pendingPositionValid = true; +} + +void QWaylandQtSurface::zqt_shell_surface_v1_resize(uint32_t serial, int32_t width, int32_t height) +{ + if (serial < m_currentConfigureSerial && m_currentConfigureSerial != UINT32_MAX) + return; + + if (serial != m_currentConfigureSerial) { + m_currentConfigureSerial = serial; + resetConfiguration(); + } + + m_pendingSize = QSize(width, height); +} + +void QWaylandQtSurface::zqt_shell_surface_v1_configure(uint32_t serial) +{ + if (serial < m_currentConfigureSerial) + return; + + if (serial > m_currentConfigureSerial) { + m_currentConfigureSerial = serial; + resetConfiguration(); + } + + applyConfigureWhenPossible(); +} + +void QWaylandQtSurface::zqt_shell_surface_v1_close() +{ + platformWindow()->window()->close(); +} + +void QWaylandQtSurface::zqt_shell_surface_v1_set_frame_margins(uint32_t left, uint32_t right, + uint32_t top, uint32_t bottom) +{ + QPlatformWindow *win = platformWindow(); + m_frameMargins = QMargins(left, top, right, bottom); + m_pendingPosition = win->geometry().topLeft(); + m_pendingPositionValid = true; + m_pendingSize = win->geometry().size(); + applyConfigureWhenPossible(); +} + +bool QWaylandQtSurface::requestActivate() +{ + request_activate(); + return true; +} + +void QWaylandQtSurface::propagateSizeHints() +{ + sendSizeHints(); +} + +void QWaylandQtSurface::sendSizeHints() +{ + QPlatformWindow *win = platformWindow(); + if (win) { + const int minWidth = qMax(0, win->windowMinimumSize().width()); + const int minHeight = qMax(0, win->windowMinimumSize().height()); + set_minimum_size(minWidth, minHeight); + + int maxWidth = qMax(0, win->windowMaximumSize().width()); + if (maxWidth == QWINDOWSIZE_MAX) + maxWidth = -1; + int maxHeight = qMax(0, win->windowMaximumSize().height()); + if (maxHeight == QWINDOWSIZE_MAX) + maxHeight = -1; + set_maximum_size(maxWidth, maxHeight); + } +} + +void QWaylandQtSurface::zqt_shell_surface_v1_set_window_state(uint32_t serial, uint32_t state) +{ + if (serial < m_currentConfigureSerial && m_currentConfigureSerial != UINT32_MAX) + return; + + if (serial != m_currentConfigureSerial) { + m_currentConfigureSerial = serial; + resetConfiguration(); + } + m_pendingStates = Qt::WindowStates(state); +} + +void QWaylandQtSurface::setWindowGeometry(const QRect &rect) +{ + set_size(rect.width(), rect.height()); +} + +void QWaylandQtSurface::setWindowPosition(const QPoint &position) +{ + reposition(position.x(), position.y()); +} + +void QWaylandQtSurface::setWindowFlags(Qt::WindowFlags flags) +{ + set_window_flags(flags); +} + +void QWaylandQtSurface::requestWindowStates(Qt::WindowStates states) +{ + change_window_state(states & ~Qt::WindowActive); +} + +bool QWaylandQtSurface::resize(QWaylandInputDevice *inputDevice, Qt::Edges edge) +{ + if (m_capabilities & ZQT_SHELL_SURFACE_V1_CAPABILITIES_INTERACTIVE_RESIZE) { + start_system_resize(getSerial(inputDevice), uint(edge)); + return true; + } + + return false; +} + +bool QWaylandQtSurface::move(QWaylandInputDevice *inputDevice) +{ + if (m_capabilities & ZQT_SHELL_SURFACE_V1_CAPABILITIES_INTERACTIVE_RESIZE) { + start_system_move(getSerial(inputDevice)); + return true; + } + + return false; +} + +QMargins QWaylandQtSurface::serverSideFrameMargins() const +{ + return m_frameMargins; +} + +void QWaylandQtSurface::raise() +{ + QtWayland::zqt_shell_surface_v1::raise(); +} + +void QWaylandQtSurface::lower() +{ + QtWayland::zqt_shell_surface_v1::lower(); +} + +} + +QT_END_NAMESPACE diff --git a/src/plugins/shellintegration/qt-shell/qwaylandqtsurface_p.h b/src/plugins/shellintegration/qt-shell/qwaylandqtsurface_p.h new file mode 100644 index 00000000..9b64b1d1 --- /dev/null +++ b/src/plugins/shellintegration/qt-shell/qwaylandqtsurface_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt-project.org/legal +** +** 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 QWAYLANDQTSURFACE_H +#define QWAYLANDQTSURFACE_H + +#include <QtCore/qpoint.h> +#include <QtWaylandClient/private/qwaylandshellsurface_p.h> +#include "qwayland-qt-shell-unstable-v1.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +class QWaylandWindow; +class QWaylandInputDevice; +class QWindow; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandQtSurface : public QWaylandShellSurface + , public QtWayland::zqt_shell_surface_v1 +{ +public: + QWaylandQtSurface(struct ::zqt_shell_surface_v1 *shell_surface, QWaylandWindow *window); + ~QWaylandQtSurface() override; + + void applyConfigure() override; + void setWindowGeometry(const QRect &rect) override; + void setWindowPosition(const QPoint &position) override; + + void setWindowFlags(Qt::WindowFlags flags) override; + void requestWindowStates(Qt::WindowStates states) override; + void setTitle(const QString &title) override; + + bool resize(QWaylandInputDevice *, Qt::Edges) override; + bool move(QWaylandInputDevice *) override; + bool requestActivate() override; + + void propagateSizeHints() override; + + QMargins serverSideFrameMargins() const override; + + void raise() override; + void lower() override; + +private: + void resetConfiguration(); + void sendSizeHints(); + void zqt_shell_surface_v1_close() override; + void zqt_shell_surface_v1_resize(uint32_t serial, int32_t width, int32_t height) override; + void zqt_shell_surface_v1_set_position(uint32_t serial, int32_t x, int32_t y) override; + void zqt_shell_surface_v1_configure(uint32_t serial) override; + void zqt_shell_surface_v1_set_window_state(uint32_t serial, uint32_t state) override; + void zqt_shell_surface_v1_set_frame_margins(uint32_t left, uint32_t right, + uint32_t top, uint32_t bottom) override; + void zqt_shell_surface_v1_set_capabilities(uint32_t capabilities) override; + + QSize m_pendingSize; + QPoint m_pendingPosition = { -1, -1 }; + bool m_pendingPositionValid = false; + Qt::WindowStates m_pendingStates = Qt::WindowNoState; + Qt::WindowStates m_currentStates = Qt::WindowNoState; + QMargins m_frameMargins; + uint32_t m_currentConfigureSerial = UINT32_MAX; + uint32_t m_capabilities = 0; +}; + +} + +QT_END_NAMESPACE + +#endif // QWAYLANDQTSURFACE_H diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp b/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp index 354ee19b..7353cb1f 100644 --- a/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp +++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp @@ -47,15 +47,16 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { -bool QWaylandWlShellIntegration::initialize(QWaylandDisplay *display) +bool QWaylandWlShellIntegration::initialize() { - const auto globals = display->globals(); - for (QWaylandDisplay::RegistryGlobal global : globals) { - if (global.interface == QLatin1String("wl_shell")) { - m_wlShell = new QtWayland::wl_shell(display->wl_registry(), global.id, 1); - break; - } - } + if (m_wlShell) + return true; + wl_registry *registry; + uint32_t id; + uint32_t version; + bool found = findGlobal(QLatin1String("wl_shell"), ®istry, &id, &version); + if (found) + m_wlShell = new QtWayland::wl_shell(registry, id, 1); if (!m_wlShell) { qCDebug(lcQpaWayland) << "Couldn't find global wl_shell"; @@ -66,7 +67,7 @@ bool QWaylandWlShellIntegration::initialize(QWaylandDisplay *display) << "\"xdg-shell\" if supported by the compositor" << "by setting the environment variable QT_WAYLAND_SHELL_INTEGRATION"; - return QWaylandShellIntegration::initialize(display); + return true; } QWaylandShellSurface *QWaylandWlShellIntegration::createShellSurface(QWaylandWindow *window) diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h b/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h index 3d76cc31..47815d54 100644 --- a/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h +++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h @@ -63,7 +63,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandWlShellIntegration : public QWaylandShellI { public: QWaylandWlShellIntegration() {} - bool initialize(QWaylandDisplay *) override; + bool initialize() override; QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override; void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override; diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp index fcdd435c..8390d76f 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp @@ -47,21 +47,21 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { -bool QWaylandXdgShellIntegration::initialize(QWaylandDisplay *display) +bool QWaylandXdgShellIntegration::initialize() { - for (QWaylandDisplay::RegistryGlobal global : display->globals()) { - if (global.interface == QLatin1String("xdg_wm_base")) { - m_xdgShell.reset(new QWaylandXdgShell(display, global.id, global.version)); - break; - } - } - + if (m_xdgShell) + return true; + wl_registry *registry; + uint32_t id; + uint32_t version; + bool found = findGlobal(QLatin1String("xdg_wm_base"), ®istry, &id, &version); + if (found) + m_xdgShell.reset(new QWaylandXdgShell(m_display, id, version)); if (!m_xdgShell) { qCDebug(lcQpaWayland) << "Couldn't find global xdg_wm_base for xdg-shell stable"; return false; } - - return QWaylandShellIntegration::initialize(display); + return true; } QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWindow *window) diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h index fced9eb0..cd54dd48 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h @@ -63,7 +63,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgShellIntegration : public QWaylandShell { public: QWaylandXdgShellIntegration() {} - bool initialize(QWaylandDisplay *display) override; + bool initialize() override; QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override; void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override; |