[System Tray] SNI fallback to context menu on failing Activate

This patch primarily is aimed at applications using libappindicator.
For example:
* Steam
* Discord
* Deluge
libappindicator doesn't provide functionality for raising an application,
but only a context menu. Since it also doesn't even provide the corresponding
DBus method, we use the resulting error to try to display the context menu
instead, which matches the behaviour on Unity and Gnome.

BUG: 375351

Reviewers: #plasma, davidedmundson

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D4301
wilder-5.14
Roman Gilg 9 years ago
parent 749216bdcd
commit 5d5518455d
  1. 9
      applets/systemtray/package/contents/ui/items/StatusNotifierItem.qml
  2. 9
      dataengines/statusnotifieritem/statusnotifieritemjob.cpp
  3. 1
      dataengines/statusnotifieritem/statusnotifieritemjob.h
  4. 15
      dataengines/statusnotifieritem/statusnotifieritemsource.cpp
  5. 2
      dataengines/statusnotifieritem/statusnotifieritemsource.h

@ -68,7 +68,14 @@ AbstractItem {
var operation = service.operationDescription("Activate");
operation.x = pos.x;
operation.y = pos.y;
service.startOperationCall(operation);
var job = service.startOperationCall(operation);
job.finished.connect(function () {
if (!job.result) {
// On error try to invoke the context menu.
// Workaround primarily for apps using libappindicator.
contextMenu(mouse);
}
});
break;
}
case Qt.MiddleButton:

@ -25,6 +25,7 @@ StatusNotifierItemJob::StatusNotifierItemJob(StatusNotifierItemSource *source, c
m_source(source)
{
connect(source, SIGNAL(contextMenuReady(QMenu*)), this, SLOT(contextMenuReady(QMenu*)));
connect(source, SIGNAL(activateResult(bool)), this, SLOT(activateCallback(bool)));
}
StatusNotifierItemJob::~StatusNotifierItemJob()
@ -35,7 +36,6 @@ void StatusNotifierItemJob::start()
{
if (operationName() == QString::fromLatin1("Activate")) {
m_source->activate(parameters()[QStringLiteral("x")].toInt(), parameters()[QStringLiteral("y")].toInt());
setResult(0);
} else if (operationName() == QString::fromLatin1("SecondaryActivate")) {
m_source->secondaryActivate(parameters()[QStringLiteral("x")].toInt(), parameters()[QStringLiteral("y")].toInt());
setResult(0);
@ -47,6 +47,13 @@ void StatusNotifierItemJob::start()
}
}
void StatusNotifierItemJob::activateCallback(bool success)
{
if (operationName() == QString::fromLatin1("Activate")) {
setResult(QVariant(success));
}
}
void StatusNotifierItemJob::contextMenuReady(QMenu *menu)
{
if (operationName() == QString::fromLatin1("ContextMenu")) {

@ -44,6 +44,7 @@ protected:
void start() override;
private Q_SLOTS:
void activateCallback(bool success);
void contextMenuReady(QMenu *menu);
private:

@ -469,10 +469,23 @@ void StatusNotifierItemSource::overlayIcon(QIcon *icon, QIcon *overlay)
void StatusNotifierItemSource::activate(int x, int y)
{
if (m_statusNotifierItemInterface && m_statusNotifierItemInterface->isValid()) {
m_statusNotifierItemInterface->call(QDBus::NoBlock, QStringLiteral("Activate"), x, y);
QDBusMessage message = QDBusMessage::createMethodCall(m_statusNotifierItemInterface->service(),
m_statusNotifierItemInterface->path(), m_statusNotifierItemInterface->interface(), QStringLiteral("Activate"));
message << x << y;
QDBusPendingCall call = m_statusNotifierItemInterface->connection().asyncCall(message);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, &StatusNotifierItemSource::activateCallback);
}
}
void StatusNotifierItemSource::activateCallback(QDBusPendingCallWatcher *call)
{
QDBusPendingReply<void> reply = *call;
emit activateResult(!reply.isError());
call->deleteLater();
}
void StatusNotifierItemSource::secondaryActivate(int x, int y)
{
if (m_statusNotifierItemInterface && m_statusNotifierItemInterface->isValid()) {

@ -50,6 +50,7 @@ public:
Q_SIGNALS:
void contextMenuReady(QMenu *menu);
void activateResult(bool success);
private Q_SLOTS:
void contextMenuReady();
@ -60,6 +61,7 @@ private Q_SLOTS:
void performRefresh();
void syncStatus(QString);
void refreshCallback(QDBusPendingCallWatcher *);
void activateCallback(QDBusPendingCallWatcher *);
private:

Loading…
Cancel
Save