Skip to content
Merged
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
2 changes: 1 addition & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Depends:
qml6-module-qtquick-layouts,
qml6-module-qtquick-window,
qt6-wayland (>= 6.8),
dde-application-manager (>> 1.2.54),
dde-application-manager (>> 1.2.55),
${misc:Depends},
${shlibs:Depends},
Breaks:
Expand Down
8 changes: 7 additions & 1 deletion frame/wayland/xdgactivation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

#include "xdgactivation_p.h"

#include <DSGApplication>
#include <DGuiApplicationHelper>

Check warning on line 7 in frame/wayland/xdgactivation.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 <DSGApplication>

Check warning on line 8 in frame/wayland/xdgactivation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

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

Check warning on line 9 in frame/wayland/xdgactivation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

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

Check warning on line 10 in frame/wayland/xdgactivation.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 11 in frame/wayland/xdgactivation.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 <QMetaObject>

Check warning on line 12 in frame/wayland/xdgactivation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

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

Expand Down Expand Up @@ -150,6 +151,11 @@
qCWarning(dsXdgActivation) << "XDG activation request has empty app id";

auto effectiveWindow = window ? window : QGuiApplication::focusWindow();
if (!effectiveWindow) {
// fallback to top-level window at cursor position if the focused window is not a Wayland window
qCDebug(dsXdgActivation) << "No focused window, falling back to top-level window at cursor position";
effectiveWindow = QGuiApplication::topLevelAt(QCursor::pos());
}
if (!effectiveWindow) {
qCWarning(dsXdgActivation) << "XDG activation request has no target window";
Q_EMIT tokenReady({});
Expand Down
6 changes: 3 additions & 3 deletions panels/notification/server/dbusadaptor.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -32,7 +32,7 @@ public Q_SLOTS: // methods
Q_SIGNALS:
void ActionInvoked(uint id, const QString &actionKey);
void NotificationClosed(uint id, uint reason);
// todo void ActivationToken(uint id, const QString &activationToken)
void ActivationToken(uint id, const QString &token);
};

class DDENotificationDbusAdaptor : public QDBusAbstractAdaptor
Expand All @@ -54,7 +54,7 @@ public Q_SLOTS: // methods
Q_SIGNALS:
void ActionInvoked(uint id, const QString &actionKey);
void NotificationClosed(uint id, uint reason);
// todo void ActivationToken(uint id, const QString &activationToken)
void ActivationToken(uint id, const QString &token);

public Q_SLOTS: // methods
uint recordCount() const;
Expand Down
65 changes: 56 additions & 9 deletions panels/notification/server/notificationmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@
#include <QJsonObject>
#include <QGuiApplication>

#include <appletbridge.h>

Check warning on line 27 in panels/notification/server/notificationmanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

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

Check warning on line 28 in panels/notification/server/notificationmanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

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

Check warning on line 29 in panels/notification/server/notificationmanager.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.

DCORE_USE_NAMESPACE
DS_USE_NAMESPACE
Expand Down Expand Up @@ -134,8 +135,30 @@
qInfo(notifyLog) << "Action invoked, bubbleId:" << bubbleId << ", id:" << id << ", actionKey" << actionKey;
actionInvoked(id, actionKey);

Q_EMIT ActionInvoked(bubbleId, actionKey);
Q_EMIT NotificationClosed(bubbleId, NotifyEntity::Closed);
if (isExtendedAction(id, actionKey)) {
// Extended action (x-deepin-action-*) handles token request internally in doActionInvoked,
// so we skip the outer token request to avoid requesting twice.
Q_EMIT ActionInvoked(bubbleId, actionKey);
Q_EMIT NotificationClosed(bubbleId, NotifyEntity::Closed);
} else {
// For non-extended actions, emit ActivationToken first if available
auto *activation = new DS_NAMESPACE::XdgActivation(this);
connect(
activation,
&DS_NAMESPACE::XdgActivation::tokenReady,
this,
[this, bubbleId, actionKey, activation](const QString &token) {
if (!token.isEmpty()) {
Q_EMIT ActivationToken(bubbleId, token);
qDebug(notifyLog) << "Emitted ActivationToken for non-extended action:" << token;
}
Q_EMIT ActionInvoked(bubbleId, actionKey);
Q_EMIT NotificationClosed(bubbleId, NotifyEntity::Closed);
activation->deleteLater();
},
Qt::SingleShotConnection);
activation->requestToken();
}
}

void NotificationManager::notificationClosed(qint64 id, uint bubbleId, uint reason)
Expand Down Expand Up @@ -542,6 +565,16 @@
return QString();
}

bool NotificationManager::isExtendedAction(qint64 id, const QString &actionId) const
{
auto entity = m_persistence->fetchEntity(id);
if (!entity.isValid()) {
return false;
}
QMap<QString, QVariant> hints = entity.hints();
return hints.contains("x-deepin-action-" + actionId);
}

void NotificationManager::doActionInvoked(const NotifyEntity &entity, const QString &actionId)
{
qDebug(notifyLog) << "Invoke the notification:" << entity.id() << entity.appName() << actionId;
Expand All @@ -566,13 +599,27 @@
amArgs << "--" << args;
}

QProcess pro;
pro.setProgram("dde-am");
pro.setArguments(amArgs);
QProcessEnvironment proEnv = QProcessEnvironment::systemEnvironment();
proEnv.remove("DSG_APP_ID");
pro.setProcessEnvironment(proEnv);
pro.startDetached();
// Get activation token, then start process
auto *activation = new DS_NAMESPACE::XdgActivation(this);
auto amArgsCopy = amArgs;
connect(activation, &DS_NAMESPACE::XdgActivation::tokenReady, this,
[amArgsCopy, activation](const QString &token) {
QProcess pro;
pro.setProgram("dde-am");
pro.setArguments(amArgsCopy);
QProcessEnvironment proEnv = QProcessEnvironment::systemEnvironment();
proEnv.remove("DSG_APP_ID");

if (!token.isEmpty()) {
proEnv.insert("XDG_ACTIVATION_TOKEN", token);
qDebug(notifyLog) << "Set XDG_ACTIVATION_TOKEN for extended action:" << token;
}

pro.setProcessEnvironment(proEnv);
pro.startDetached();
activation->deleteLater();
}, Qt::SingleShotConnection);
activation->requestToken();
}
} else if (i.key() == "deepin-dde-shell-action-" + actionId) {
const QString data(i.value().toString());
Expand Down
4 changes: 4 additions & 0 deletions panels/notification/server/notificationmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@

void NotificationStateChanged(qint64 id, int processedType);

// Activation token signal for Wayland
void ActivationToken(uint id, const QString &token);

public Q_SLOTS:

Check warning on line 56 in panels/notification/server/notificationmanager.h

View workflow job for this annotation

GitHub Actions / cppcheck

There is an unknown macro here somewhere. Configuration is required. If Q_SLOTS is a macro then please configure it.
// Standard Notifications dbus implementation
QStringList GetCapabilities();
uint Notify(const QString &appName, uint replacesId, const QString &appIcon, const QString &summary, const QString &body, const QStringList &actions, const QVariantMap &hints, int expireTimeout);
Expand Down Expand Up @@ -78,6 +81,7 @@

QString appIdByAppName(const QString &appName) const;
void doActionInvoked(const NotifyEntity &entity, const QString &actionId);
bool isExtendedAction(qint64 id, const QString &actionId) const;
bool invokeShellAction(const QString &data);
void initScreenLockedState();

Expand Down
Loading