summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/wayland/CMakeLists.txt4
-rw-r--r--src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp17
-rw-r--r--src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h6
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp9
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay_p.h7
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp7
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration_p.h2
-rw-r--r--src/plugins/platforms/wayland/qwaylandsessionmanager.cpp91
-rw-r--r--src/plugins/platforms/wayland/qwaylandsessionmanager_p.h71
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp11
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow_p.h3
11 files changed, 228 insertions, 0 deletions
diff --git a/src/plugins/platforms/wayland/CMakeLists.txt b/src/plugins/platforms/wayland/CMakeLists.txt
index 32a4ae34228..254a43c0dc6 100644
--- a/src/plugins/platforms/wayland/CMakeLists.txt
+++ b/src/plugins/platforms/wayland/CMakeLists.txt
@@ -77,6 +77,7 @@ qt_internal_add_module(WaylandClient
qwaylandplatformservices.cpp qwaylandplatformservices_p.h
qwaylandpointergestures.cpp qwaylandpointergestures_p.h
qwaylandscreen.cpp qwaylandscreen_p.h
+ qwaylandsessionmanager.cpp qwaylandsessionmanager_p.h
qwaylandshellsurface.cpp qwaylandshellsurface_p.h
qwaylandshm.cpp qwaylandshm_p.h
qwaylandshmbackingstore.cpp qwaylandshmbackingstore_p.h
@@ -124,6 +125,8 @@ qt_internal_add_module(WaylandClient
../../../3rdparty/wayland/protocols/viewporter
../../../3rdparty/wayland/protocols/xdg-shell
../../../3rdparty/wayland/protocols/wlr-data-control
+ ../../../3rdparty/wayland/protocols/session-management
+
)
qt_internal_add_plugin(QWaylandIntegrationPlugin
@@ -164,6 +167,7 @@ qt6_generate_wayland_protocol_client_sources(WaylandClient
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/extensions/server-buffer-extension.xml
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/protocols/color-management/xx-color-management-v4.xml
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/protocols/pointer-warp/pointer-warp-v1.xml
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/protocols/session-management/xx-session-management-v1.xml
)
#### Keys ignored in scope 1:.:.:client.pro:<TRUE>:
diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
index 1356d93abab..9c40103d1e5 100644
--- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
@@ -8,6 +8,7 @@
#include "qwaylandxdgexporterv2_p.h"
#include "qwaylandxdgdialogv1_p.h"
#include "qwaylandxdgtopleveliconv1_p.h"
+#include "qwaylandsessionmanager_p.h"
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
#include <QtWaylandClient/private/qwaylandwindow_p.h>
@@ -23,6 +24,16 @@ QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
+template <typename T, auto f>
+struct WithDestructor : public T
+{
+ using T::T;
+ ~WithDestructor()
+ {
+ f(this->object());
+ }
+};
+
QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
: QtWayland::xdg_toplevel(xdgSurface->get_toplevel())
, m_xdgSurface(xdgSurface)
@@ -45,6 +56,12 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
m_xdgDialog.reset(m_xdgSurface->m_shell->m_xdgDialogWm->getDialog(object()));
m_xdgDialog->set_modal();
}
+
+#ifndef QT_NO_SESSIONMANAGER
+ const QString sessionRestoreId = xdgSurface->window()->sessionRestoreId();
+ if (!sessionRestoreId.isEmpty() && QWaylandSessionManager::instance()->session())
+ m_session.reset(new WithDestructor<QtWayland::xx_toplevel_session_v1, xx_toplevel_session_v1_destroy>(QWaylandSessionManager::instance()->session()->restore_toplevel(object(), sessionRestoreId)));
+#endif
}
QWaylandXdgSurface::Toplevel::~Toplevel()
diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
index 236d34c351c..4595940508c 100644
--- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
+++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
@@ -30,6 +30,10 @@
QT_BEGIN_NAMESPACE
+namespace QtWayland {
+ class xx_toplevel_session_v1;
+}
+
namespace QtWaylandClient {
class QWaylandDisplay;
@@ -41,6 +45,7 @@ class QWaylandXdgExporterV2;
class QWaylandXdgDialogWmV1;
class QWaylandXdgDialogV1;
class QWaylandXdgToplevelIconManagerV1;
+class QWaylandTopLevelSession;
class Q_WAYLANDCLIENT_EXPORT QWaylandXdgSurface : public QWaylandShellSurface, public QtWayland::xdg_surface
{
@@ -114,6 +119,7 @@ private:
QWaylandXdgToplevelDecorationV1 *m_decoration = nullptr;
QScopedPointer<QWaylandXdgExportedV2> m_exported;
QScopedPointer<QWaylandXdgDialogV1> m_xdgDialog;
+ QScopedPointer<QtWayland::xx_toplevel_session_v1> m_session;
};
class Positioner : public QtWayland::xdg_positioner {
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index 071ad78f91c..d853fc673e5 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -53,6 +53,7 @@
#include <QtWaylandClient/private/qwayland-fractional-scale-v1.h>
#include <QtWaylandClient/private/qwayland-viewporter.h>
#include <QtWaylandClient/private/qwayland-cursor-shape-v1.h>
+#include <QtWaylandClient/private/qwayland-xx-session-management-v1.h>
#include <QtWaylandClient/private/qwayland-xdg-system-bell-v1.h>
#include <QtWaylandClient/private/qwayland-xdg-toplevel-drag-v1.h>
#include <QtWaylandClient/private/qwayland-wlr-data-control-unstable-v1.h>
@@ -803,6 +804,14 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
mGlobals.pointerWarp.reset(new WithDestructor<QtWayland::wp_pointer_warp_v1, wp_pointer_warp_v1_destroy>(
registry, id, 1));
}
+#ifndef QT_NO_SESSIONMANAGER
+ else if (interface == QLatin1String(QtWayland::xx_session_manager_v1::interface()->name)
+ && qEnvironmentVariableIntValue("QT_WAYLAND_ENABLE_XX_SESSION_MANAGER") > 0) {
+ mGlobals.xxSessionManager.reset(
+ new WithDestructor<QtWayland::xx_session_manager_v1, xx_session_manager_v1_destroy>(
+ registry, id, 1));
+ }
+#endif
mRegistryGlobals.append(RegistryGlobal(id, interface, version, registry));
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay_p.h b/src/plugins/platforms/wayland/qwaylanddisplay_p.h
index 29952886421..91d3497fe51 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay_p.h
+++ b/src/plugins/platforms/wayland/qwaylanddisplay_p.h
@@ -56,6 +56,7 @@ namespace QtWayland {
class wp_cursor_shape_manager_v1;
class wp_fractional_scale_manager_v1;
class wp_viewporter;
+ class xx_session_manager_v1;
class xdg_system_bell_v1;
class xdg_toplevel_drag_manager_v1;
class wp_pointer_warp_v1;
@@ -86,6 +87,7 @@ class QWaylandPointerGestures;
class QWaylandWindow;
class QWaylandIntegration;
class QWaylandHardwareIntegration;
+class QWaylandSessionManager;
class QWaylandSurface;
class QWaylandShellIntegration;
class QWaylandCursor;
@@ -214,6 +216,10 @@ public:
{
return mGlobals.xdgToplevelDragManager.get();
}
+ QtWayland::xx_session_manager_v1 *xxSessionManager() const
+ {
+ return mGlobals.xxSessionManager.get();
+ }
QtWayland::xdg_system_bell_v1 *systemBell() const
{
return mGlobals.systemBell.get();
@@ -360,6 +366,7 @@ private:
std::unique_ptr<QtWayland::wp_viewporter> viewporter;
std::unique_ptr<QtWayland::wp_fractional_scale_manager_v1> fractionalScaleManager;
std::unique_ptr<QtWayland::wp_cursor_shape_manager_v1> cursorShapeManager;
+ std::unique_ptr<QtWayland::xx_session_manager_v1> xxSessionManager;
std::unique_ptr<QtWayland::xdg_system_bell_v1> systemBell;
std::unique_ptr<QtWayland::xdg_toplevel_drag_manager_v1> xdgToplevelDragManager;
std::unique_ptr<QWaylandWindowManagerIntegration> windowManagerIntegration;
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index 9158013fe78..d66710f4e55 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -56,6 +56,7 @@
#include "qwaylandinputdeviceintegration_p.h"
#include "qwaylandinputdeviceintegrationfactory_p.h"
#include "qwaylandwindow_p.h"
+#include "qwaylandsessionmanager_p.h"
#include <QtWaylandClient/private/qwayland-xdg-system-bell-v1.h>
@@ -529,6 +530,12 @@ QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QStr
}
}
+QPlatformSessionManager *QWaylandIntegration::createPlatformSessionManager(const QString &id, const QString &key) const
+{
+ Q_UNUSED(key);
+ return new QWaylandSessionManager(mDisplay.data(), id);
+}
+
void QWaylandIntegration::reset()
{
mServerBufferIntegration.reset();
diff --git a/src/plugins/platforms/wayland/qwaylandintegration_p.h b/src/plugins/platforms/wayland/qwaylandintegration_p.h
index d799555570d..04a0787d1ef 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration_p.h
+++ b/src/plugins/platforms/wayland/qwaylandintegration_p.h
@@ -36,6 +36,7 @@ class QWaylandInputDevice;
class QWaylandScreen;
class QWaylandCursor;
class QWaylandPlatformServices;
+class QWaylandSessionManager;
class Q_WAYLANDCLIENT_EXPORT QWaylandIntegration : public QPlatformIntegration
#if QT_CONFIG(opengl)
@@ -131,6 +132,7 @@ private:
void initializeShellIntegration();
void initializeInputDeviceIntegration();
QWaylandShellIntegration *createShellIntegration(const QString& interfaceName);
+ QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const override;
const QString mPlatformName;
QScopedPointer<QPlatformFontDatabase> mFontDb;
diff --git a/src/plugins/platforms/wayland/qwaylandsessionmanager.cpp b/src/plugins/platforms/wayland/qwaylandsessionmanager.cpp
new file mode 100644
index 00000000000..9539bb15221
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandsessionmanager.cpp
@@ -0,0 +1,91 @@
+// Copyright (C) 2024 David Edmundson <davidedmundson@kde.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qwaylandsessionmanager_p.h"
+
+#ifndef QT_NO_SESSIONMANAGER
+
+#include "qwaylanddisplay_p.h"
+#include "qwaylandwindow_p.h"
+
+#include <private/qsessionmanager_p.h>
+#include <private/qguiapplication_p.h>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWaylandClient {
+
+QWaylandSessionManager::QWaylandSessionManager(QWaylandDisplay *display, const QString &id)
+ : QObject(nullptr)
+ , QPlatformSessionManager(id, QString())
+ , mDisplay(display)
+{
+ if (!display->xxSessionManager())
+ return;
+
+ // The protocol also exposes a way of supporting crash handling to expose later
+ startSession();
+}
+
+QWaylandSession *QWaylandSessionManager::session() const
+{
+ return mSession.data();
+}
+
+QWaylandSessionManager *QWaylandSessionManager::instance()
+{
+ auto *qGuiAppPriv = QGuiApplicationPrivate::instance();
+ auto *managerPrivate = static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(qGuiAppPriv->session_manager));
+ return static_cast<QWaylandSessionManager *>(managerPrivate->platformSessionManager);
+}
+
+void QWaylandSessionManager::setSessionId(const QString &id)
+{
+ m_sessionId = id;
+}
+
+void QWaylandSessionManager::startSession()
+{
+ QtWayland::xx_session_manager_v1::reason restoreReason = QtWayland::xx_session_manager_v1::reason_launch;
+ if (!sessionId().isEmpty()) {
+ restoreReason = QtWayland::xx_session_manager_v1::reason_session_restore;
+ }
+ mSession.reset(new QWaylandSession(this));
+ mSession->init(mDisplay->xxSessionManager()->get_session(restoreReason, sessionId()));
+ mDisplay->forceRoundTrip();
+}
+
+QWaylandSession::QWaylandSession(QWaylandSessionManager *sessionManager)
+ : mSessionManager(sessionManager)
+{
+}
+
+QWaylandSession::~QWaylandSession() {
+ // There's also remove which is another dtor
+ // depending on whether we're meant to clean up server side or not
+ // we might need to expose that later
+ destroy();
+}
+
+void QWaylandSession::xx_session_v1_created(const QString &id) {
+ qCDebug(lcQpaWayland) << "Session created" << id;
+ mSessionManager->setSessionId(id);
+}
+
+void QWaylandSession::xx_session_v1_restored() {
+ qCDebug(lcQpaWayland) << "Session restored";
+ // session Id won't have change, do nothing
+}
+
+void QWaylandSession::xx_session_v1_replaced() {
+ qCDebug(lcQpaWayland) << "Session replaced";
+ mSessionManager->setSessionId(QString());
+}
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/wayland/qwaylandsessionmanager_p.h b/src/plugins/platforms/wayland/qwaylandsessionmanager_p.h
new file mode 100644
index 00000000000..aa9e0eec001
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandsessionmanager_p.h
@@ -0,0 +1,71 @@
+// Copyright (C) 2024 David Edmundson <davidedmundson@kde.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWAYLANDSESSIONMANAGER_H
+#define QWAYLANDSESSIONMANAGER_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.
+//
+
+#ifndef QT_NO_SESSIONMANAGER
+
+#include <QtGui/qpa/qplatformsessionmanager.h>
+#include <QtWaylandClient/qtwaylandclientglobal.h>
+#include <QtWaylandClient/private/qwayland-xx-session-management-v1.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWaylandClient {
+
+class QWaylandDisplay;
+class QWaylandWindow;
+class QWaylandSession;
+class QWaylandSessionManager;
+
+
+class Q_WAYLANDCLIENT_EXPORT QWaylandSession : public QObject, public QtWayland::xx_session_v1
+{
+ Q_OBJECT
+public:
+ QWaylandSession(QWaylandSessionManager *sessionManager);
+ ~QWaylandSession();
+
+protected:
+ void xx_session_v1_created(const QString &id) override;
+ void xx_session_v1_restored() override;
+ void xx_session_v1_replaced() override;
+private:
+ QWaylandSessionManager *mSessionManager;
+};
+
+class Q_WAYLANDCLIENT_EXPORT QWaylandSessionManager : public QObject, public QPlatformSessionManager
+{
+ Q_OBJECT
+public:
+ static QWaylandSessionManager *instance();
+ QWaylandSessionManager(QWaylandDisplay *display, const QString &id);
+
+ QWaylandSession* session() const;
+private:
+ void setSessionId(const QString &id);
+ void startSession();
+
+ QWaylandDisplay *mDisplay = nullptr;
+ QScopedPointer<QWaylandSession> mSession;
+ friend class QWaylandSession;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif
+#endif
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index 73d90b6c321..cfbc392c319 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "qwaylandsessionmanager_p.h"
#include "qwaylandwindow_p.h"
#include "qwaylandbuffer_p.h"
@@ -1934,6 +1935,16 @@ QSurfaceFormat QWaylandWindow::format() const
return mSurfaceFormat;
}
+void QWaylandWindow::setSessionRestoreId(const QString &role)
+{
+ mSessionRestoreId = role;
+}
+
+QString QWaylandWindow::sessionRestoreId() const
+{
+ return mSessionRestoreId;
+}
+
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h
index 5ad826018bb..23c5ed04b8f 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow_p.h
+++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h
@@ -252,6 +252,8 @@ public:
bool windowEvent(QEvent *event) override;
QSurfaceFormat format() const override;
+ void setSessionRestoreId(const QString &role) override;
+ QString sessionRestoreId() const;
public Q_SLOTS:
void applyConfigure();
@@ -346,6 +348,7 @@ protected:
QWaylandShmBackingStore *mBackingStore = nullptr;
QMargins mCustomMargins;
+ QString mSessionRestoreId;
QPointer<QWaylandWindow> mTransientParent;
QList<QPointer<QWaylandWindow>> mChildPopups;