File: konqclientrequest.cpp

package info (click to toggle)
konqueror 4%3A25.04.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 61,780 kB
  • sloc: cpp: 59,015; python: 943; xml: 683; javascript: 186; sh: 165; makefile: 10
file content (156 lines) | stat: -rw-r--r-- 4,793 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* This file is part of the KDE project
    SPDX-FileCopyrightText: 2017 David Faure <faure@kde.org>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#include "konqclientrequest.h"
#include <konq_main_interface.h>
#include <konq_mainwindow_interface.h>

#include <QDBusConnection>
#include <QDBusConnectionInterface>
#include <QDBusObjectPath>
#include <QDBusReply>
#include <QProcess>
#include <QUrl>
#include <QtGui/private/qtx11extras_p.h>

#include <KConfig>
#include <KConfigGroup>
#include <KStartupInfo>
#include <KWindowSystem>

#include "kfmclient_debug.h"

class KonqClientRequestPrivate
{
public:
    void sendASNChange();

    QUrl url;
    bool newTab = false;
    bool tempFile = false;
    QString mimeType;
    QByteArray startup_id_str;
};

KonqClientRequest::KonqClientRequest()
    : d(new KonqClientRequestPrivate)
{
    if (KWindowSystem::isPlatformX11()) {
        d->startup_id_str = QX11Info::nextStartupId();
    } else if (KWindowSystem::isPlatformWayland()) {
        d->startup_id_str = qEnvironmentVariable("XDG_ACTIVATION_TOKEN").toUtf8();
    }
}

KonqClientRequest::~KonqClientRequest()
{
}

void KonqClientRequest::setUrl(const QUrl& url)
{
    d->url = url;
}

void KonqClientRequest::setNewTab(bool newTab)
{
    d->newTab = newTab;
}

void KonqClientRequest::setTempFile(bool tempFile)
{
    d->tempFile = tempFile;
}

void KonqClientRequest::setMimeType(const QString &mimeType)
{
    d->mimeType = mimeType;
}

void KonqClientRequestPrivate::sendASNChange()
{
    if (KWindowSystem::isPlatformX11()) {
        KStartupInfoId id;
        id.initId(startup_id_str);
        KStartupInfoData data;
        data.addPid(0);     // say there's another process for this ASN with unknown PID
        data.setHostname(); // ( no need to bother to get this konqy's PID )
        KStartupInfo::sendChangeXcb(QX11Info::connection(), QX11Info::appScreen(), id, data);
    }
}

bool KonqClientRequest::openUrl()
{
    QDBusConnection dbus = QDBusConnection::sessionBus();
    const QString appId = QStringLiteral("org.kde.konqueror");
    org::kde::Konqueror::Main konq(appId, QStringLiteral("/KonqMain"), dbus);

    if (!d->newTab) {
        KConfig cfg(QStringLiteral("konquerorrc"));
        d->newTab = cfg.group("FMSettings").readEntry("KonquerorTabforExternalURL", false);
    }
    if (d->newTab) {
        QDBusObjectPath foundObj;
        QDBusReply<QDBusObjectPath> windowReply = konq.windowForTab();
        if (windowReply.isValid()) {
            QDBusObjectPath path = windowReply;
            // "/" is the indicator for "no object found", since we can't use an empty path
            if (path.path() != QLatin1String("/")) {
                org::kde::Konqueror::MainWindow konqWindow(appId, path.path(), dbus);
                QDBusReply<void> newTabReply = konqWindow.newTabASNWithMimeType(d->url.toString(), d->mimeType, d->startup_id_str, d->tempFile);
                if (newTabReply.isValid()) {
                    d->sendASNChange();
                    return true;
                }
            }
        }
    }

    QDBusReply<QDBusObjectPath> reply = konq.createNewWindow(d->url.toString(), d->mimeType, d->startup_id_str, d->tempFile);
    if (reply.isValid()) {
        d->sendASNChange();
        return true;
    } else {
        // pass kfmclient's startup id to konqueror using kshell
        KStartupInfoId id;
        id.initId(d->startup_id_str);
        id.setupStartupEnv();
        QStringList args;
        args << QStringLiteral("konqueror");
        if (!d->mimeType.isEmpty()) {
            args << QStringLiteral("--mimetype") << d->mimeType;
        }
        if (d->tempFile) {
            args << QStringLiteral("--tempfile");
        }
        args << d->url.toEncoded();
        qint64 pid;

        // There is no kinit (therefore no 'kshell5' wrapper) in KF6.
        // TODO: what to do therefore with the startup ID?
        const QByteArray sessionVersion = qgetenv("KDE_SESSION_VERSION");
        if (sessionVersion.toInt()<=5)			// KF5 or below, or not set
        {
#ifdef Q_OS_WIN
            QString wrapper = QStringLiteral("kwrapper")+sessionVersion;
#else
            QString wrapper = QStringLiteral("kshell")+sessionVersion;
#endif
            // Only use the wrapper if it actually exists.
            wrapper = QStandardPaths::findExecutable(wrapper);
            if (!wrapper.isEmpty()) args.prepend(wrapper);
        }

        const QString cmd = args.takeFirst();
        const bool ok = QProcess::startDetached(cmd, args, QString(), &pid);
        KStartupInfo::resetStartupEnv();
        if (ok) {
            qCDebug(KFMCLIENT_LOG) << "Konqueror started, pid=" << pid;
        } else {
            qCWarning(KFMCLIENT_LOG) << "Error starting konqueror";
        }
        return ok;
    }
}