Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions panels/dock/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ file(
pluginmanagerintegration.cpp
dockpositioner.h
dockpositioner.cpp
xdgactivationmanager_p.h
xdgactivationmanager.cpp
)

set_source_files_properties(DockCompositor.qml PROPERTIES
Expand Down Expand Up @@ -148,6 +150,7 @@ qt_generate_wayland_protocol_server_sources(dock-plugin
FILES
${DDE_TRAY_LOADER_PROTOCOL}
${WaylandProtocols_DATADIR}/staging/fractional-scale/fractional-scale-v1.xml
${WaylandProtocols_DATADIR}/staging/xdg-activation/xdg-activation-v1.xml
)

target_link_libraries(dock-plugin PUBLIC
Expand Down
2 changes: 2 additions & 0 deletions panels/dock/DockCompositor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,7 @@ Item {
id: pluginScaleManager
pluginScale: dockCompositor.panelScale * 120
}

XdgActivationManager {}
}
}
3 changes: 3 additions & 0 deletions panels/dock/pluginmanagerextension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

#include "pluginmanagerextension_p.h"
#include "pluginmanagerintegration_p.h"
#include "xdgactivationmanager_p.h"
#include "constants.h"

#include <wayland/xdgactivation.h>

Check warning on line 10 in panels/dock/pluginmanagerextension.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <wayland/xdgactivation.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <DGuiApplicationHelper>

Check warning on line 12 in panels/dock/pluginmanagerextension.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <DGuiApplicationHelper> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <DPlatformTheme>

Check warning on line 13 in panels/dock/pluginmanagerextension.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <DPlatformTheme> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <cstdint>
#include <wayland-server-core.h>
Expand Down
135 changes: 135 additions & 0 deletions panels/dock/xdgactivationmanager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "xdgactivationmanager_p.h"

#include <wayland/xdgactivation.h>

Check warning on line 7 in panels/dock/xdgactivationmanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <wayland/xdgactivation.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <QGuiApplication>

Check warning on line 9 in panels/dock/xdgactivationmanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QGuiApplication> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QLoggingCategory>

Check warning on line 10 in panels/dock/xdgactivationmanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QLoggingCategory> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QWindow>

Check warning on line 11 in panels/dock/xdgactivationmanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QWindow> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <QtWaylandCompositor/QWaylandSeat>

Check warning on line 13 in panels/dock/xdgactivationmanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QtWaylandCompositor/QWaylandSeat> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Q_LOGGING_CATEGORY(xdgActivationMgr, "dde.shell.xdgactivation.manager")

// ---------------------------------------------------------------------------
// XdgActivationManager
// ---------------------------------------------------------------------------

XdgActivationManager::XdgActivationManager(QWaylandCompositor *compositor)
: QWaylandCompositorExtensionTemplate(compositor)
, m_compositor(compositor)
{
}

void XdgActivationManager::initialize()
{
QWaylandCompositorExtensionTemplate::initialize();
QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
Q_ASSERT(compositor);
m_compositor = compositor;
init(compositor->display(), 1);

// Create the client-side xdg_activation_v1 connection to the outer compositor
m_outerActivation = new ds::XdgActivation(this);
connect(m_outerActivation, &ds::XdgActivation::tokenReady,
this, &XdgActivationManager::onTokenReady);
}

void XdgActivationManager::xdg_activation_v1_destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}

void XdgActivationManager::xdg_activation_v1_get_activation_token(Resource *resource, uint32_t id)
{
QWaylandResource tokenResource(
wl_resource_create(resource->client(), &xdg_activation_token_v1_interface,
wl_resource_get_version(resource->handle), id));
new XdgActivationTokenV1(this, tokenResource);
}

void XdgActivationManager::setPendingToken(XdgActivationTokenV1 *token)
{
m_pendingToken = token;
}

void XdgActivationManager::requestOuterToken(const QString &appId)
{
QWindow *window = QGuiApplication::focusWindow();
m_outerActivation->requestToken(window, appId);
}

void XdgActivationManager::clearPendingTokenIf(XdgActivationTokenV1 *token)
{
if (m_pendingToken == token) {
m_pendingToken = nullptr;
}
}

void XdgActivationManager::onTokenReady(const QString &token)
{
if (m_pendingToken) {
qCDebug(xdgActivationMgr) << "Forwarding activation token to plugin client";
m_pendingToken->sendToken(token);
m_pendingToken = nullptr;
}
}

// ---------------------------------------------------------------------------
// XdgActivationTokenV1
// ---------------------------------------------------------------------------
// XdgActivationTokenV1
// ---------------------------------------------------------------------------

XdgActivationTokenV1::XdgActivationTokenV1(XdgActivationManager *manager, const QWaylandResource &resource)
: QObject(manager)
, m_manager(manager)
{
init(resource.resource());
}

XdgActivationTokenV1::~XdgActivationTokenV1() = default;

void XdgActivationTokenV1::sendToken(const QString &token)
{
send_done(token);
}

void XdgActivationTokenV1::xdg_activation_token_v1_set_serial(Resource *resource, uint32_t serial, struct ::wl_resource *seat)
{
Q_UNUSED(resource)
Q_UNUSED(seat)
m_serial = serial;
}

void XdgActivationTokenV1::xdg_activation_token_v1_set_app_id(Resource *resource, const QString &app_id)
{
Q_UNUSED(resource)
m_appId = app_id;
}

void XdgActivationTokenV1::xdg_activation_token_v1_set_surface(Resource *resource, struct ::wl_resource *surface)
{
Q_UNUSED(resource)
m_surface = QWaylandSurface::fromResource(surface);
}

void XdgActivationTokenV1::xdg_activation_token_v1_commit(Resource *resource)
{
Q_UNUSED(resource)
qCDebug(xdgActivationMgr) << "Token committed by plugin client, appId:" << m_appId;

// Store this token as pending and request from the outer compositor
m_manager->setPendingToken(this);
m_manager->requestOuterToken(m_appId);
}

void XdgActivationTokenV1::xdg_activation_token_v1_destroy(Resource *resource)
{
Q_UNUSED(resource)
m_manager->clearPendingTokenIf(this);
deleteLater();
}
67 changes: 67 additions & 0 deletions panels/dock/xdgactivationmanager_p.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QMap>

Check warning on line 7 in panels/dock/xdgactivationmanager_p.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QMap> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QPointer>

Check warning on line 8 in panels/dock/xdgactivationmanager_p.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QPointer> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtWaylandCompositor/QWaylandCompositorExtension>
#include <QtWaylandCompositor/QWaylandQuickExtension>
#include <QtWaylandCompositor/QWaylandResource>
#include <QtWaylandCompositor/QWaylandSurface>

#include "qwayland-server-xdg-activation-v1.h"

namespace ds { class XdgActivation; }

class XdgActivationTokenV1;
class XdgActivationManager : public QWaylandCompositorExtensionTemplate<XdgActivationManager>, public QtWaylandServer::xdg_activation_v1
{
Q_OBJECT
QML_ELEMENT
public:
XdgActivationManager(QWaylandCompositor *compositor = nullptr);
void initialize() override;

void setPendingToken(XdgActivationTokenV1 *token);
void requestOuterToken(const QString &appId);
void clearPendingTokenIf(XdgActivationTokenV1 *token);

protected:
void xdg_activation_v1_destroy(Resource *resource) override;
void xdg_activation_v1_get_activation_token(Resource *resource, uint32_t id) override;

private:
void onTokenReady(const QString &token);

QWaylandCompositor *m_compositor = nullptr;
ds::XdgActivation *m_outerActivation = nullptr;
QPointer<XdgActivationTokenV1> m_pendingToken;
};

class XdgActivationTokenV1 : public QObject, public QtWaylandServer::xdg_activation_token_v1
{
Q_OBJECT
public:
XdgActivationTokenV1(XdgActivationManager *manager, const QWaylandResource &resource);
~XdgActivationTokenV1() override;

void sendToken(const QString &token);

protected:
void xdg_activation_token_v1_set_serial(Resource *resource, uint32_t serial, struct ::wl_resource *seat) override;
void xdg_activation_token_v1_set_app_id(Resource *resource, const QString &app_id) override;
void xdg_activation_token_v1_set_surface(Resource *resource, struct ::wl_resource *surface) override;
void xdg_activation_token_v1_commit(Resource *resource) override;
void xdg_activation_token_v1_destroy(Resource *resource) override;

private:
XdgActivationManager *m_manager;
QPointer<QWaylandSurface> m_surface;
uint32_t m_serial = 0;
QString m_appId;
};

Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(XdgActivationManager)
Loading