Commit 6a5d3c26 authored by Alf Gaida's avatar Alf Gaida

Upstream patch: Avoid freeze for DBusActivatable apps (Closes: #928721)

parent ed6fd59b
libqtxdg (3.3.1-2) unstable; urgency=medium
* Upstream patch: Avoid freeze for DBusActivatable apps (Closes: #928721)
-- Alf Gaida <agaida@siduction.org> Thu, 09 May 2019 17:57:01 +0200
libqtxdg (3.3.1-1) unstable; urgency=medium
* Cherry-picked new upstream-release 3.3.1.
......
From bccc6c4030a601892847e9a1495142a1938d1a58 Mon Sep 17 00:00:00 2001
From: Palo Kisa <palo.kisa@gmail.com>
Date: Tue, 9 Apr 2019 12:36:11 +0200
Subject: [PATCH] xdgdesktopfile: Avoid freeze for DBusActivatable apps
For case when the DBusActivatable application is unresponsive the
startDetached() can block for a long time (the Qt default 25s DBus
timeout). Blocking can't be avoided while using QDBusInterface, because
the object can block directly in its constructor.
So we use the generated interface class and set the timeout for the DBus
call to 1500ms (can be overridden env variable QTXDG_DBUSACTIVATE_TIMEOUT).
See also: https://bugreports.qt.io/browse/QTBUG-75016
---
src/qtxdg/CMakeLists.txt | 10 +++++
.../dbus/org.freedesktop.Application.xml | 25 +++++++++++
src/qtxdg/xdgdesktopfile.cpp | 43 ++++++++++++++++---
3 files changed, 72 insertions(+), 6 deletions(-)
create mode 100644 src/qtxdg/dbus/org.freedesktop.Application.xml
diff --git a/src/qtxdg/CMakeLists.txt b/src/qtxdg/CMakeLists.txt
index f75b5a5..60ba48b 100644
--- a/src/qtxdg/CMakeLists.txt
+++ b/src/qtxdg/CMakeLists.txt
@@ -1,3 +1,5 @@
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
set(QTX_LIBRARIES Qt5::Widgets Qt5::Xml Qt5::DBus)
set(libqtxdg_PUBLIC_H_FILES
@@ -50,10 +52,18 @@ set(libqtxdg_CPP_FILES
xdgmimetype.cpp
)
+QT5_ADD_DBUS_INTERFACE(DBUS_INTERFACE_SRCS
+ dbus/org.freedesktop.Application.xml
+ application_interface
+)
+
+set_property(SOURCE ${DBUS_INTERFACE_SRCS} PROPERTY SKIP_AUTOGEN ON)
+
add_library(${QTXDGX_LIBRARY_NAME} SHARED
${libqtxdg_PUBLIC_H_FILES}
${libqtxdg_PRIVATE_H_FILES}
${libqtxdg_CPP_FILES}
+ ${DBUS_INTERFACE_SRCS}
)
target_link_libraries(${QTXDGX_LIBRARY_NAME}
diff --git a/src/qtxdg/dbus/org.freedesktop.Application.xml b/src/qtxdg/dbus/org.freedesktop.Application.xml
new file mode 100644
index 0000000..945ba9e
--- /dev/null
+++ b/src/qtxdg/dbus/org.freedesktop.Application.xml
@@ -0,0 +1,25 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<!--
+ Based on https://specifications.freedesktop.org/desktop-entry-spec/1.1/ar01s07.html
+-->
+<node>
+ <interface name='org.freedesktop.Application'>
+ <method name='Activate'>
+ <arg type='a{sv}' name='platform_data' direction='in'/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
+ </method>
+ <method name='Open'>
+ <arg type='as' name='uris' direction='in'/>
+ <arg type='a{sv}' name='platform_data' direction='in'/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
+ </method>
+ <method name='ActivateAction'>
+ <arg type='s' name='action_name' direction='in'/>
+ <arg type='av' name='parameter' direction='in'/>
+ <arg type='a{sv}' name='platform_data' direction='in'/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="QVariantMap"/>
+ </method>
+ </interface>
+</node>
+
diff --git a/src/qtxdg/xdgdesktopfile.cpp b/src/qtxdg/xdgdesktopfile.cpp
index c22d57d..5fa7604 100644
--- a/src/qtxdg/xdgdesktopfile.cpp
+++ b/src/qtxdg/xdgdesktopfile.cpp
@@ -30,6 +30,7 @@
#include "xdgdesktopfile_p.h"
#include "xdgdirs.h"
#include "xdgicon.h"
+#include "application_interface.h"
#include <stdlib.h>
#include <unistd.h>
@@ -100,6 +101,27 @@ QString &unEscape(QString& str);
QString &unEscapeExec(QString& str);
void loadMimeCacheDir(const QString& dirName, QHash<QString, QList<XdgDesktopFile*> > & cache);
+namespace
+{
+ //! Simple helper for getting timeout for starting of DBus activatable applications
+ class DBusActivateTimeout
+ {
+ private:
+ int mTimeoutMs;
+ DBusActivateTimeout()
+ {
+ bool ok;
+ mTimeoutMs = qgetenv("QTXDG_DBUSACTIVATE_TIMEOUT").toInt(&ok);
+ if (!ok)
+ mTimeoutMs = 1500;
+ }
+ static DBusActivateTimeout msInstance;
+ public:
+ static const DBusActivateTimeout & instance() { return msInstance; }
+ operator int() const { return mTimeoutMs; }
+ };
+ DBusActivateTimeout DBusActivateTimeout::msInstance;
+}
QString &doEscape(QString& str, const QHash<QChar,QChar> &repl)
{
@@ -533,7 +555,7 @@ bool XdgDesktopFileData::startByDBus(const QString & action, const QStringList&
", assembled DBus object path" << path << "is invalid!";
return false;
}
- QDBusInterface app(f.completeBaseName(), path, QLatin1String("org.freedesktop.Application"));
+ org::freedesktop::Application app{f.completeBaseName(), path, QDBusConnection::sessionBus()};
//Note: after the QDBusInterface construction, it can *invalid* (has reasonable lastError())
// but this can be due to some intermediate DBus call(s) which doesn't need to be fatal and
// our next call() can succeed
@@ -543,19 +565,28 @@ bool XdgDesktopFileData::startByDBus(const QString & action, const QStringList&
qWarning().noquote() << "XdgDesktopFileData::startByDBus: invalid interface:" << app.lastError().message()
<< ", but trying to continue...";
}
- QDBusMessage reply;
+ app.setTimeout(DBusActivateTimeout::instance());
+ QDBusPendingReply<> reply;
if (!action.isEmpty())
{
QList<QVariant> v_urls;
for (const auto & url : urls)
v_urls.append(url);
- reply = app.call(QLatin1String("ActivateAction"), action, v_urls, platformData);
+ reply = app.ActivateAction(action, v_urls, platformData);
} else if (urls.isEmpty())
- reply = app.call(QLatin1String("Activate"), platformData);
+ reply = app.Activate(platformData);
else
- reply = app.call(QLatin1String("Open"), urls, platformData);
+ reply = app.Open(urls, platformData);
- return QDBusMessage::ErrorMessage != reply.type();
+ reply.waitForFinished();
+ if (QDBusMessage::ErrorMessage == reply.reply().type())
+ {
+ qWarning().noquote().nospace() << "XdgDesktopFileData::startByDBus(timeout=" << DBusActivateTimeout::instance()
+ << "): failed to start org.freedesktop.Application" << mFileName << ": " << reply.reply();
+ return false;
+ }
+
+ return true;
}
QStringList XdgDesktopFileData::getListValue(const XdgDesktopFile * q, const QString & key, bool tryExtendPrefix) const
avoid-dbus-freeze.patch
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment