diff --git a/src/core/desktopexecparser.cpp b/src/core/desktopexecparser.cpp --- a/src/core/desktopexecparser.cpp +++ b/src/core/desktopexecparser.cpp @@ -38,6 +38,8 @@ #include // CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 #include "kiocoredebug.h" +#include +#include class KRunMX1 : public KMacroExpanderBase { @@ -308,19 +310,52 @@ // Check if we need kioexec bool useKioexec = false; if (!mx1.hasUrls) { - Q_FOREACH (const QUrl &url, d->urls) + for(QUrl &url : d->urls) { if (!url.isLocalFile() && !hasSchemeHandler(url)) { - useKioexec = true; - //qCDebug(KIO_CORE) << "non-local files, application does not support urls, using kioexec"; - break; + // Lets try a KIOFuse mount instead. + QDBusInterface kiofused(QStringLiteral("org.kde.kded5"), + QStringLiteral("/modules/kiofuse"), + QStringLiteral("org.kde.KIOFuse"), + QDBusConnection::sessionBus()); + if (!kiofused.isValid() || kiofused.lastError().isValid()) { + useKioexec = true; + //qCDebug(KIO_CORE) << "non-local files, application does not support urls, using kioexec"; + break; + } + QDBusReply reply = kiofused.call(QStringLiteral("mountUrl"), url.toString()); + // Empty string means mounting failed... + if(reply.isValid() && !reply.value().isEmpty()) { + url = QUrl::fromLocalFile(reply.value()); + } else { + useKioexec = true; + //qCDebug(KIO_CORE) << "non-local files, application does not support urls, using kioexec"; + break; + } } + } } else { // app claims to support %u/%U, check which protocols QStringList appSupportedProtocols = supportedProtocols(d->service); - Q_FOREACH (const QUrl &url, d->urls) { + for (QUrl &url : d->urls) { if (!isProtocolInSupportedList(url, appSupportedProtocols) && !hasSchemeHandler(url)) { - useKioexec = true; - //qCDebug(KIO_CORE) << "application does not support url, using kioexec:" << url; - break; + // Lets try a KIOFuse mount instead. + QDBusInterface kiofused(QStringLiteral("org.kde.kded5"), + QStringLiteral("/modules/kiofuse"), + QStringLiteral("org.kde.KIOFuse"), + QDBusConnection::sessionBus()); + if (!kiofused.isValid() || kiofused.lastError().isValid()) { + useKioexec = true; + //qCDebug(KIO_CORE) << "non-local files, application does not support urls, using kioexec"; + break; + } + QDBusReply reply = kiofused.call(QStringLiteral("mountUrl"), url.toString()); + // Empty string means mounting failed... + if(reply.isValid() && !reply.value().isEmpty()) { + url = QUrl::fromLocalFile(reply.value()); + } else { + useKioexec = true; + //qCDebug(KIO_CORE) << "non-local files, application does not support urls, using kioexec"; + break; + } } } } diff --git a/src/widgets/krun.cpp b/src/widgets/krun.cpp --- a/src/widgets/krun.cpp +++ b/src/widgets/krun.cpp @@ -508,18 +508,54 @@ if (!appSupportedProtocols.contains(QStringLiteral("KIO"))) { for (QList::Iterator it = urls.begin(); it != urls.end(); ++it) { const QUrl url = *it; - bool supported = KIO::DesktopExecParser::isProtocolInSupportedList(url, appSupportedProtocols); + // NOTE: Some non-KIO apps may support the URLs (i.e. VLC supports smb://) + // but will struggle with passwords. + // @see https://pointieststick.com/2018/01/17/videos-on-samba-shares/ + // TODO: if protocol is supported by non-KIO app and there is no password, + // don't mount over KIOFuse. + //bool supported = KIO::DesktopExecParser::isProtocolInSupportedList(url, appSupportedProtocols); //qDebug() << "Looking at url=" << url << " supported=" << supported; - if (!supported && KProtocolInfo::protocolClass(url.scheme()) == QLatin1String(":local")) { + if (KProtocolInfo::protocolClass(url.scheme()) == QLatin1String(":local")) { // Maybe we can resolve to a local URL? KIO::StatJob *job = KIO::mostLocalUrl(url); if (job->exec()) { // ## nasty nested event loop! const QUrl localURL = job->mostLocalUrl(); if (localURL != url) { *it = localURL; //qDebug() << "Changed to" << localURL; + } else { + // Can't convert... + // Lets try a KIOFuse mount instead. + QDBusInterface kiofused(QStringLiteral("org.kde.kded5"), + QStringLiteral("/modules/kiofuse"), + QStringLiteral("org.kde.KIOFuse"), + QDBusConnection::sessionBus()); + if (!kiofused.isValid() || kiofused.lastError().isValid()) { + // Module isn't loaded... + continue; + } + QDBusReply reply = kiofused.call(QStringLiteral("mountUrl"), url.toString()); + // Empty string means mounting failed... + if(reply.isValid() && !reply.value().isEmpty()) { + *it = QUrl::fromLocalFile(reply.value()); + } } } + } else { + // It's a remote url, lets try a KIOFuse mount. + QDBusInterface kiofused(QStringLiteral("org.kde.kded5"), + QStringLiteral("/modules/kiofuse"), + QStringLiteral("org.kde.KIOFuse"), + QDBusConnection::sessionBus()); + if (!kiofused.isValid() || kiofused.lastError().isValid()) { + // Module isn't loaded... + continue; + } + QDBusReply reply = kiofused.call(QStringLiteral("mountUrl"), url.toString()); + // Empty string means mounting failed... + if(reply.isValid() && !reply.value().isEmpty()) { + *it = QUrl::fromLocalFile(reply.value()); + } } } }