File indexing completed on 2024-04-14 04:52:46

0001 /* This file is part of the KDE project
0002     SPDX-FileCopyrightText: 2017 David Faure <faure@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "konqclientrequest.h"
0008 #include <konq_main_interface.h>
0009 #include <konq_mainwindow_interface.h>
0010 
0011 #include <QDBusConnection>
0012 #include <QDBusConnectionInterface>
0013 #include <QDBusObjectPath>
0014 #include <QDBusReply>
0015 #include <QProcess>
0016 #include <QUrl>
0017 
0018 #if QT_VERSION_MAJOR < 6
0019 #include <QX11Info>
0020 #else
0021 #include <QtGui/private/qtx11extras_p.h>
0022 #endif
0023 
0024 #include <KConfig>
0025 #include <KConfigGroup>
0026 #include <KStartupInfo>
0027 #include <KWindowSystem>
0028 
0029 #include "kfmclient_debug.h"
0030 
0031 class KonqClientRequestPrivate
0032 {
0033 public:
0034     void sendASNChange();
0035 
0036     QUrl url;
0037     bool newTab = false;
0038     bool tempFile = false;
0039     QString mimeType;
0040     QByteArray startup_id_str;
0041 };
0042 
0043 KonqClientRequest::KonqClientRequest()
0044     : d(new KonqClientRequestPrivate)
0045 {
0046     if (KWindowSystem::isPlatformX11()) {
0047         d->startup_id_str = QX11Info::nextStartupId();
0048     } else if (KWindowSystem::isPlatformWayland()) {
0049         d->startup_id_str = qEnvironmentVariable("XDG_ACTIVATION_TOKEN").toUtf8();
0050     }
0051 }
0052 
0053 KonqClientRequest::~KonqClientRequest()
0054 {
0055 }
0056 
0057 void KonqClientRequest::setUrl(const QUrl& url)
0058 {
0059     d->url = url;
0060 }
0061 
0062 void KonqClientRequest::setNewTab(bool newTab)
0063 {
0064     d->newTab = newTab;
0065 }
0066 
0067 void KonqClientRequest::setTempFile(bool tempFile)
0068 {
0069     d->tempFile = tempFile;
0070 }
0071 
0072 void KonqClientRequest::setMimeType(const QString &mimeType)
0073 {
0074     d->mimeType = mimeType;
0075 }
0076 
0077 void KonqClientRequestPrivate::sendASNChange()
0078 {
0079     if (KWindowSystem::isPlatformX11()) {
0080         KStartupInfoId id;
0081         id.initId(startup_id_str);
0082         KStartupInfoData data;
0083         data.addPid(0);     // say there's another process for this ASN with unknown PID
0084         data.setHostname(); // ( no need to bother to get this konqy's PID )
0085         KStartupInfo::sendChangeXcb(QX11Info::connection(), QX11Info::appScreen(), id, data);
0086     }
0087 }
0088 
0089 bool KonqClientRequest::openUrl()
0090 {
0091     QDBusConnection dbus = QDBusConnection::sessionBus();
0092     const QString appId = QStringLiteral("org.kde.konqueror");
0093     org::kde::Konqueror::Main konq(appId, QStringLiteral("/KonqMain"), dbus);
0094 
0095     if (!d->newTab) {
0096         KConfig cfg(QStringLiteral("konquerorrc"));
0097         d->newTab = cfg.group("FMSettings").readEntry("KonquerorTabforExternalURL", false);
0098     }
0099     if (d->newTab) {
0100         QDBusObjectPath foundObj;
0101         QDBusReply<QDBusObjectPath> windowReply = konq.windowForTab();
0102         if (windowReply.isValid()) {
0103             QDBusObjectPath path = windowReply;
0104             // "/" is the indicator for "no object found", since we can't use an empty path
0105             if (path.path() != QLatin1String("/")) {
0106                 org::kde::Konqueror::MainWindow konqWindow(appId, path.path(), dbus);
0107                 QDBusReply<void> newTabReply = konqWindow.newTabASNWithMimeType(d->url.toString(), d->mimeType, d->startup_id_str, d->tempFile);
0108                 if (newTabReply.isValid()) {
0109                     d->sendASNChange();
0110                     return true;
0111                 }
0112             }
0113         }
0114     }
0115 
0116     QDBusReply<QDBusObjectPath> reply = konq.createNewWindow(d->url.toString(), d->mimeType, d->startup_id_str, d->tempFile);
0117     if (reply.isValid()) {
0118         d->sendASNChange();
0119         return true;
0120     } else {
0121         // pass kfmclient's startup id to konqueror using kshell
0122         KStartupInfoId id;
0123         id.initId(d->startup_id_str);
0124         id.setupStartupEnv();
0125         QStringList args;
0126         args << QStringLiteral("konqueror");
0127         if (!d->mimeType.isEmpty()) {
0128             args << QStringLiteral("--mimetype") << d->mimeType;
0129         }
0130         if (d->tempFile) {
0131             args << QStringLiteral("-tempfile");
0132         }
0133         args << d->url.toEncoded();
0134         qint64 pid;
0135 #ifdef Q_OS_WIN
0136         const bool ok = QProcess::startDetached(QStringLiteral("kwrapper5"), args, QString(), &pid);
0137 #else
0138         const bool ok = QProcess::startDetached(QStringLiteral("kshell5"), args, QString(), &pid);
0139 #endif
0140         KStartupInfo::resetStartupEnv();
0141         if (ok) {
0142             qCDebug(KFMCLIENT_LOG) << "Konqueror started, pid=" << pid;
0143         } else {
0144             qCWarning(KFMCLIENT_LOG) << "Error starting konqueror";
0145         }
0146         return ok;
0147     }
0148 }