Nemo notifications plugin allows to add remote actions to notifications using Notification::setRemoteActions. If the app is closed, it can be opened using the DBus service file, which is created automatically by Saijail from the .desktop file. When this is used, the app is also automatically brought to the front when a notification remote action is triggered. Is there a way to turn this behaviour off?
For example, my desktop file looks like this:
[Desktop Entry]
Type=Application
X-Nemo-Application-Type=silica-qt5
Icon=harbour-myapp
Exec=harbour-myapp
Name=My App
X-DBusActivatable=true
MimeType=x-scheme-handler/mycustomscheme
X-Maemo-Service=io.myorg.myapp
X-Maemo-Object-Path=/io/myorg/myapp
X-Maemo-Method=io.myorg.myapp.openUrl
[X-Sailjail]
OrganizationName=io.myorg
ApplicationName=myapp
ExecDBus=harbour-myapp -prestart
And I create a notification like this:
Notification *notification = new Notification();
notification->setAppName("My App");
notification->setSummary("Test notification");
notification->setBody("My test notification description.");
QVariantList actions;
actions << Notification::remoteAction("default", "", "io.myorg.myapp", "/io/myorg/myapp", "io.myorg.myapp", "openUrl");
actions << Notification::remoteAction("", "Do something", "io.myorg.myapp", "/io/myorg/myapp", "io.myorg.myapp", "triggerAction");
notification->setRemoteActions(actions);
notification->publish();
I want the âDo somethingâ button to trigger an action without activating the app. But I canât find a way to disable that behaviour. DBus handler for triggerAction method does not bring the app to front, and as I understood, lipstick does that on its own.
I havenât looked into it or tried, but couldnât you implement the âorg.freedesktop.Applicationâ interface, and override the âActivateâ method?
Assuming thatâs what Lipstick uses:
/* Adaptor to provide the SFOS/FDO DBus-Activation interface */
class BusAdaptor : public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Application")
public:
BusAdaptor(QGuiApplication *application, QQuickView *view)
: QDBusAbstractAdaptor(application), app(application), view(view)
{
}
public slots:
/* To test:
busctl --user call foo bar org.freedesktop.Application Activate a{sv} 0
*/
void Activate( const QVariantMap &platform_data ) const
{
Q_UNUSED(platform_data)
view->show(); // or not
QMetaObject::invokeMethod(view->rootObject(), "activate");
}
private:
QGuiApplication *app;
QQuickView *view;
};
int main(int argc, char *argv[])
{
QScopedPointer<QGuiApplication> app(SailfishApp::application(argc, argv));
QScopedPointer<QQuickView> view(SailfishApp::createView());
// create the FDO activation adapter
new BusAdaptor(app.data(), view.data());
QDBusConnection::sessionBus().registerObject(APP_DBUS_PATH, app.data());
....
}
By remote action I mean a custom button in a notification. I need to use a custom interface because in the real example there are multiple buttons, both serving different purposes, and I need to pass custom arguments to the methods.
After some digging, I found that closed-source part of lipstick (namely, LaunchManager of Sailfish.Lipstick QML module) seems to be doing that. Weirdly enough, this doesnât happen if the notification type is set to âinputâ.
Also, if you change service name to something which is not <X-Sailjail/OrganizationName>.<X-Sailjail/ApplicationName> (values from the .desktop file), it stops opening the app. But, this breaks calling the methods when app is not opened.
I made a minimal reproducible example here. The app is very simple, QML-only, and has minimal changes required to demonstrate the issue:
- addition of the
ExecDBus=harbour-notification-open-test -prestart line in the X-Sailjail section of the desktop file
- replacement of the main QML file with this:
import QtQuick 2.0
import Sailfish.Silica 1.0
import Nemo.Notifications 1.0
ApplicationWindow {
initialPage: Component {
Page {
id: page
Notification {
id: notification
appName: "My app"
summary: "My notification"
// It's not even needed to implement the interface to demonstrate the problem
Component.onCompleted: {
var actions = [remoteAction("", "My action", "org.myorg.notification-open-test", "/org/myorg/notification-open-test", "org.myorg.notification-open-test", "myMethod")]
var inputAction = remoteAction("", "Input action", "org.myorg.notification-open-test", "/org/myorg/notification-open-test", "org.myorg.notification-open-test", "myInputMethod")
inputAction.type = "input"
actions.push(inputAction)
remoteActions = actions
}
}
Button {
anchors.centerIn: parent
text: "Publish notification"
onClicked: notification.publish()
}
}
}
}
To reproduce, click âPublish notificationâ, go to the Events view and select the âMy actionâ action on the notification. After this, the app will open, even though the interface is not even implemented. This means that this is very likely to be done by lipstick. However, when the the action type is set to "input", this behaviour doesnât happen.
EDIT:
Seems like commenting a line in the main compositor QML file does the trick:
SFOS 5.0.0.68, /usr/share/lipstick-jolla-home-qt5/compositor.qml, line 610:
LaunchManager {
id: launchManager
launcherModel: root.launcherModel
//onLaunching: Desktop.instance.switcher.activateWindowFor(item) // <-- need to comment this
}
I still canât find a proper way of doing it, per-app (or, ideally, per a notification action), without patching lipstick.
1 Like