2626
2727#include < appletbridge.h>
2828#include < pluginloader.h>
29+ #include < wayland/xdgactivation.h>
2930
3031DCORE_USE_NAMESPACE
3132DS_USE_NAMESPACE
@@ -134,8 +135,30 @@ void NotificationManager::actionInvoked(qint64 id, uint bubbleId, const QString
134135 qInfo (notifyLog) << " Action invoked, bubbleId:" << bubbleId << " , id:" << id << " , actionKey" << actionKey;
135136 actionInvoked (id, actionKey);
136137
137- Q_EMIT ActionInvoked (bubbleId, actionKey);
138- Q_EMIT NotificationClosed (bubbleId, NotifyEntity::Closed);
138+ if (isExtendedAction (id, actionKey)) {
139+ // Extended action (x-deepin-action-*) handles token request internally in doActionInvoked,
140+ // so we skip the outer token request to avoid requesting twice.
141+ Q_EMIT ActionInvoked (bubbleId, actionKey);
142+ Q_EMIT NotificationClosed (bubbleId, NotifyEntity::Closed);
143+ } else {
144+ // For non-extended actions, emit ActivationToken first if available
145+ auto *activation = new DS_NAMESPACE::XdgActivation (this );
146+ connect (
147+ activation,
148+ &DS_NAMESPACE ::XdgActivation::tokenReady,
149+ this ,
150+ [this , bubbleId, actionKey, activation](const QString &token) {
151+ if (!token.isEmpty ()) {
152+ Q_EMIT ActivationToken (bubbleId, token);
153+ qDebug (notifyLog) << " Emitted ActivationToken for non-extended action:" << token;
154+ }
155+ Q_EMIT ActionInvoked (bubbleId, actionKey);
156+ Q_EMIT NotificationClosed (bubbleId, NotifyEntity::Closed);
157+ activation->deleteLater ();
158+ },
159+ Qt::SingleShotConnection);
160+ activation->requestToken ();
161+ }
139162}
140163
141164void NotificationManager::notificationClosed (qint64 id, uint bubbleId, uint reason)
@@ -542,6 +565,16 @@ QString NotificationManager::appIdByAppName(const QString &appName) const
542565 return QString ();
543566}
544567
568+ bool NotificationManager::isExtendedAction (qint64 id, const QString &actionId) const
569+ {
570+ auto entity = m_persistence->fetchEntity (id);
571+ if (!entity.isValid ()) {
572+ return false ;
573+ }
574+ QMap<QString, QVariant> hints = entity.hints ();
575+ return hints.contains (" x-deepin-action-" + actionId);
576+ }
577+
545578void NotificationManager::doActionInvoked (const NotifyEntity &entity, const QString &actionId)
546579{
547580 qDebug (notifyLog) << " Invoke the notification:" << entity.id () << entity.appName () << actionId;
@@ -566,13 +599,27 @@ void NotificationManager::doActionInvoked(const NotifyEntity &entity, const QStr
566599 amArgs << " --" << args;
567600 }
568601
569- QProcess pro;
570- pro.setProgram (" dde-am" );
571- pro.setArguments (amArgs);
572- QProcessEnvironment proEnv = QProcessEnvironment::systemEnvironment ();
573- proEnv.remove (" DSG_APP_ID" );
574- pro.setProcessEnvironment (proEnv);
575- pro.startDetached ();
602+ // Get activation token, then start process
603+ auto *activation = new DS_NAMESPACE::XdgActivation (this );
604+ auto amArgsCopy = amArgs;
605+ connect (activation, &DS_NAMESPACE ::XdgActivation::tokenReady, this ,
606+ [amArgsCopy, activation](const QString &token) {
607+ QProcess pro;
608+ pro.setProgram (" dde-am" );
609+ pro.setArguments (amArgsCopy);
610+ QProcessEnvironment proEnv = QProcessEnvironment::systemEnvironment ();
611+ proEnv.remove (" DSG_APP_ID" );
612+
613+ if (!token.isEmpty ()) {
614+ proEnv.insert (" XDG_ACTIVATION_TOKEN" , token);
615+ qDebug (notifyLog) << " Set XDG_ACTIVATION_TOKEN for extended action:" << token;
616+ }
617+
618+ pro.setProcessEnvironment (proEnv);
619+ pro.startDetached ();
620+ activation->deleteLater ();
621+ }, Qt::SingleShotConnection);
622+ activation->requestToken ();
576623 }
577624 } else if (i.key () == " deepin-dde-shell-action-" + actionId) {
578625 const QString data (i.value ().toString ());
0 commit comments