diff --git a/panels/notification/server/notificationmanager.cpp b/panels/notification/server/notificationmanager.cpp index ce01d302c..02820b638 100644 --- a/panels/notification/server/notificationmanager.cpp +++ b/panels/notification/server/notificationmanager.cpp @@ -144,8 +144,10 @@ void NotificationManager::actionInvoked(qint64 id, uint bubbleId, const QString 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); + // For non-extended actions, emit ActivationToken first if available. + // The activation must not be parented to the worker-thread manager; + // the tokenReady handler below deletes it when the token arrives. + auto *activation = new DS_NAMESPACE::XdgActivation(); connect( activation, &DS_NAMESPACE::XdgActivation::tokenReady, @@ -561,8 +563,10 @@ void NotificationManager::doActionInvoked(const NotifyEntity &entity, const QStr amArgs << "--" << args; } - // Get activation token, then start process - auto *activation = new DS_NAMESPACE::XdgActivation(this); + // Get activation token, then start process. It must not be + // parented to the worker-thread manager; the tokenReady + // handler below deletes it when the token arrives. + auto *activation = new DS_NAMESPACE::XdgActivation(); auto amArgsCopy = amArgs; connect(activation, &DS_NAMESPACE::XdgActivation::tokenReady, this, [amArgsCopy, activation](const QString &token) { diff --git a/panels/notification/server/notifyserverapplet.cpp b/panels/notification/server/notifyserverapplet.cpp index 1fd903568..c0dc588af 100644 --- a/panels/notification/server/notifyserverapplet.cpp +++ b/panels/notification/server/notifyserverapplet.cpp @@ -83,13 +83,18 @@ bool NotifyServerApplet::init() void NotifyServerApplet::actionInvoked(qint64 id, uint bubbleId, const QString &actionKey) { - QMetaObject::invokeMethod(m_manager, "actionInvoked", Qt::QueuedConnection, + // Keep the action synchronous with the notification center's remove() + // call. The center invokes the action and then deletes the notification, + // so the action has to reach the manager before that deletion. This was + // the behavior before the expire rework switched these calls to queued + // connections; the synchronous blocking is small and intentional. + QMetaObject::invokeMethod(m_manager, "actionInvoked", Qt::DirectConnection, Q_ARG(qint64, id), Q_ARG(uint, bubbleId), Q_ARG(QString, actionKey)); } void NotifyServerApplet::actionInvoked(qint64 id, const QString &actionKey) { - QMetaObject::invokeMethod(m_manager, "actionInvoked", Qt::QueuedConnection, + QMetaObject::invokeMethod(m_manager, "actionInvoked", Qt::DirectConnection, Q_ARG(qint64, id), Q_ARG(QString, actionKey)); }