File indexing completed on 2024-03-24 05:01:11
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2006 David Faure <faure@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <QtGlobal> 0008 0009 #include "konqapplication.h" 0010 #include "konqsettings.h" 0011 #include <konqueror-version.h> 0012 #include "konqmainwindow.h" 0013 #include "KonquerorAdaptor.h" 0014 #include "konqviewmanager.h" 0015 #include "konqurl.h" 0016 #include "konqsettingsxt.h" 0017 #include "konqsessionmanager.h" 0018 #include "konqclosedwindowsmanager.h" 0019 #include "konqdebug.h" 0020 #include "konqmainwindow.h" 0021 #include "konqmainwindowfactory.h" 0022 #include "konqmisc.h" 0023 #include <config-konqueror.h> 0024 #include "implementations/konqbrowser.h" 0025 0026 #include "interfaces/browser.h" 0027 0028 #include <QDBusConnection> 0029 #include <QDBusMessage> 0030 #include <QCommandLineParser> 0031 #include <QCommandLineOption> 0032 #include <QDir> 0033 #include <QProcess> 0034 #include <QDirIterator> 0035 #include <QTextStream> 0036 0037 #if QT_VERSION_MAJOR < 6 0038 #include <QX11Info> 0039 #else 0040 #include <QtGui/private/qtx11extras_p.h> 0041 #endif 0042 0043 #include <KCrash> 0044 #include <KLocalizedString> 0045 #include <KSharedConfig> 0046 #include <KDBusService> 0047 #include <KStartupInfo> 0048 #include <KWindowSystem> 0049 #include <kwindowsystem_version.h> 0050 #include <KX11Extras> 0051 #include <KMessageBox> 0052 0053 #ifdef KActivities_FOUND 0054 #include "activitymanager.h" 0055 #if QT_VERSION_MAJOR < 6 0056 #include <KActivities/Consumer> 0057 #else //QT_VERSION_MAJOR 0058 #include <PlasmaActivities/Consumer> 0059 #endif //QT_VERSION_MAJOR 0060 #endif //KActivities_FOUND 0061 0062 #include <iostream> 0063 #include <unistd.h> 0064 0065 #ifdef KActivities_FOUND 0066 #endif 0067 0068 using namespace KonqInterfaces; 0069 0070 QString KonquerorApplication::currentActivity() 0071 { 0072 #ifdef KActivities_FOUND 0073 KonquerorApplication* app = qobject_cast<KonquerorApplication*>(QApplication::instance()); 0074 if (!app || !app->m_activityConsumer || app->m_activityConsumer->serviceStatus() != KActivities::Consumer::Running) { 0075 return QString(); 0076 } 0077 return app->m_activityConsumer->currentActivity(); 0078 #else 0079 return QString(); 0080 #endif 0081 } 0082 0083 KonquerorApplication::KonquerorApplication(int &argc, char **argv) 0084 : QApplication(argc, argv), m_browser(nullptr) 0085 #ifdef KActivities_FOUND 0086 , m_activityConsumer(new KActivities::Consumer(this)) 0087 #endif 0088 { 0089 // enable high dpi support 0090 setAttribute(Qt::AA_UseHighDpiPixmaps, true); 0091 0092 new KonquerorAdaptor; // not really an adaptor 0093 const QString dbusInterface = QStringLiteral("org.kde.Konqueror.Main"); 0094 QDBusConnection dbus = QDBusConnection::sessionBus(); 0095 dbus.connect(QString(), KONQ_MAIN_PATH, dbusInterface, QStringLiteral("reparseConfiguration"), this, SLOT(slotReparseConfiguration())); 0096 dbus.connect(QString(), KONQ_MAIN_PATH, dbusInterface, QStringLiteral("addToCombo"), this, 0097 SLOT(slotAddToCombo(QString,QDBusMessage))); 0098 dbus.connect(QString(), KONQ_MAIN_PATH, dbusInterface, QStringLiteral("removeFromCombo"), this, 0099 SLOT(slotRemoveFromCombo(QString,QDBusMessage))); 0100 dbus.connect(QString(), KONQ_MAIN_PATH, dbusInterface, QStringLiteral("comboCleared"), this, SLOT(slotComboCleared(QDBusMessage))); 0101 0102 #ifdef WEBENGINEPART_OWN_DICTIONARY_DIR 0103 //If the user alredy set QTWEBENGINE_DICTIONARIES_PATH, don't override it 0104 if (!qEnvironmentVariableIsSet("QTWEBENGINE_DICTIONARIES_PATH")) { 0105 qputenv("QTWEBENGINE_DICTIONARIES_PATH", WEBENGINEPART_OWN_DICTIONARY_DIR); 0106 } 0107 #endif 0108 0109 m_runningAsRootBehavior = checkRootBehavior(); 0110 0111 QByteArray flags = qgetenv("QTWEBENGINE_CHROMIUM_FLAGS"); 0112 flags.append(" --enable-features=WebRTCPipeWireCapturer"); 0113 if (m_runningAsRootBehavior == RunInDangerousMode) { 0114 flags.append (" --no-sandbox"); 0115 } 0116 0117 qputenv("QTWEBENGINE_CHROMIUM_FLAGS", flags); 0118 KLocalizedString::setApplicationDomain("konqueror"); 0119 0120 #ifdef KActivities_FOUND 0121 m_activityConsumer = new KActivities::Consumer(this); 0122 #endif 0123 } 0124 0125 KonquerorApplication::KonquerorAsRootBehavior KonquerorApplication::checkRootBehavior() 0126 { 0127 uid_t uid = geteuid(); 0128 if (uid == 0) { 0129 QString msg = i18n("<p>You're running Konqueror as root. This requires enabling a highly insecure mode in the browser component.</p><p>What do you want to do?</p>"); 0130 KGuiItem enableInsecureMode(QLatin1String("Enable the insecure mode")); //Continue 0131 KGuiItem exitKonq(QLatin1String("Exit Konqueror")); //Cancel 0132 KMessageBox::ButtonCode ans = KMessageBox::warningContinueCancel(nullptr, msg, QString(), enableInsecureMode, exitKonq); 0133 return ans == KMessageBox::Continue ? RunInDangerousMode : PreventRunningAsRoot; 0134 } else { 0135 return NotRoot; 0136 } 0137 } 0138 0139 void KonquerorApplication::slotReparseConfiguration() 0140 { 0141 KSharedConfig::openConfig()->reparseConfiguration(); 0142 KonqFMSettings::reparseConfiguration(); 0143 m_browser->applyConfiguration(); 0144 0145 QList<KonqMainWindow *> *mainWindows = KonqMainWindow::mainWindowList(); 0146 if (mainWindows) { 0147 for (KonqMainWindow *window: *mainWindows) { 0148 window->reparseConfiguration(); 0149 } 0150 } 0151 0152 emit configurationChanged(); 0153 } 0154 0155 void KonquerorApplication::slotAddToCombo(const QString &url, const QDBusMessage &msg) 0156 { 0157 KonqMainWindow::comboAction(KonqMainWindow::ComboAdd, url, msg.service()); 0158 } 0159 0160 void KonquerorApplication::slotRemoveFromCombo(const QString &url, const QDBusMessage &msg) 0161 { 0162 KonqMainWindow::comboAction(KonqMainWindow::ComboRemove, url, msg.service()); 0163 } 0164 0165 void KonquerorApplication::slotComboCleared(const QDBusMessage &msg) 0166 { 0167 KonqMainWindow::comboAction(KonqMainWindow::ComboClear, QString(), msg.service()); 0168 } 0169 0170 void KonquerorApplication::setupAboutData() 0171 { 0172 KAboutData m_aboutData("konqueror", i18n("Konqueror"), KONQUEROR_VERSION); 0173 m_aboutData.setShortDescription(i18n("Web browser, file manager and document viewer.")); 0174 m_aboutData.addLicense(KAboutLicense::GPL_V2); 0175 m_aboutData.setCopyrightStatement(i18n("(C) 1999-2023, The Konqueror developers")); 0176 m_aboutData.setHomepage("https://apps.kde.org/konqueror"); 0177 0178 m_aboutData.addAuthor(i18n("Stefano Crocco"), i18n("Current maintainer"), "stefano.crocco@alice.it"); 0179 m_aboutData.addAuthor(i18n("David Faure"), i18n("Developer (framework, parts, JavaScript, I/O library) and former maintainer"), "faure@kde.org"); 0180 m_aboutData.addAuthor(i18n("Simon Hausmann"), i18n("Developer (framework, parts)"), "hausmann@kde.org"); 0181 m_aboutData.addAuthor(i18n("Michael Reiher"), i18n("Developer (framework)"), "michael.reiher@gmx.de"); 0182 m_aboutData.addAuthor(i18n("Matthias Welk"), i18n("Developer"), "welk@fokus.gmd.de"); 0183 m_aboutData.addAuthor(i18n("Alexander Neundorf"), i18n("Developer (List views)"), "neundorf@kde.org"); 0184 m_aboutData.addAuthor(i18n("Michael Brade"), i18n("Developer (List views, I/O library)"), "brade@kde.org"); 0185 m_aboutData.addAuthor(i18n("Lars Knoll"), i18n("Developer (HTML rendering engine)"), "knoll@kde.org"); 0186 m_aboutData.addAuthor(i18n("Dirk Mueller"), i18n("Developer (HTML rendering engine)"), "mueller@kde.org"); 0187 m_aboutData.addAuthor(i18n("Peter Kelly"), i18n("Developer (HTML rendering engine)"), "pmk@post.com"); 0188 m_aboutData.addAuthor(i18n("Waldo Bastian"), i18n("Developer (HTML rendering engine, I/O library)"), "bastian@kde.org"); 0189 m_aboutData.addAuthor(i18n("Germain Garand"), i18n("Developer (HTML rendering engine)"), "germain@ebooksfrance.org"); 0190 m_aboutData.addAuthor(i18n("Leo Savernik"), i18n("Developer (HTML rendering engine)"), "l.savernik@aon.at"); 0191 m_aboutData.addAuthor(i18n("Stephan Kulow"), i18n("Developer (HTML rendering engine, I/O library, regression test framework)"), "coolo@kde.org"); 0192 m_aboutData.addAuthor(i18n("Antti Koivisto"), i18n("Developer (HTML rendering engine)"), "koivisto@kde.org"); 0193 m_aboutData.addAuthor(i18n("Zack Rusin"), i18n("Developer (HTML rendering engine)"), "zack@kde.org"); 0194 m_aboutData.addAuthor(i18n("Tobias Anton"), i18n("Developer (HTML rendering engine)"), "anton@stud.fbi.fh-darmstadt.de"); 0195 m_aboutData.addAuthor(i18n("Lubos Lunak"), i18n("Developer (HTML rendering engine)"), "l.lunak@kde.org"); 0196 m_aboutData.addAuthor(i18n("Maks Orlovich"), i18n("Developer (HTML rendering engine, JavaScript)"), "maksim@kde.org"); 0197 m_aboutData.addAuthor(i18n("Allan Sandfeld Jensen"), i18n("Developer (HTML rendering engine)"), "kde@carewolf.com"); 0198 m_aboutData.addAuthor(i18n("Apple Safari Developers"), i18n("Developer (HTML rendering engine, JavaScript)")); 0199 m_aboutData.addAuthor(i18n("Harri Porten"), i18n("Developer (JavaScript)"), "porten@kde.org"); 0200 m_aboutData.addAuthor(i18n("Koos Vriezen"), i18n("Developer (Java applets and other embedded objects)"), "koos.vriezen@xs4all.nl"); 0201 m_aboutData.addAuthor(i18n("Matt Koss"), i18n("Developer (I/O library)"), "koss@miesto.sk"); 0202 m_aboutData.addAuthor(i18n("Alex Zepeda"), i18n("Developer (I/O library)"), "zipzippy@sonic.net"); 0203 m_aboutData.addAuthor(i18n("Richard Moore"), i18n("Developer (Java applet support)"), "rich@kde.org"); 0204 m_aboutData.addAuthor(i18n("Dima Rogozin"), i18n("Developer (Java applet support)"), "dima@mercury.co.il"); 0205 m_aboutData.addAuthor(i18n("Wynn Wilkes"), i18n("Developer (Java 2 security manager support,\n and other major improvements to applet support)"), "wynnw@calderasystems.com"); 0206 m_aboutData.addAuthor(i18n("Stefan Schimanski"), i18n("Developer (Netscape plugin support)"), "schimmi@kde.org"); 0207 m_aboutData.addAuthor(i18n("George Staikos"), i18n("Developer (SSL, Netscape plugins)"), "staikos@kde.org"); 0208 m_aboutData.addAuthor(i18n("Dawit Alemayehu"), i18n("Developer (I/O library, Authentication support)"), "adawit@kde.org"); 0209 m_aboutData.addAuthor(i18n("Carsten Pfeiffer"), i18n("Developer (framework)"), "pfeiffer@kde.org"); 0210 m_aboutData.addAuthor(i18n("Torsten Rahn"), i18n("Graphics/icons"), "torsten@kde.org"); 0211 m_aboutData.addAuthor(i18n("Torben Weis"), i18n("KFM author"), "weis@kde.org"); 0212 m_aboutData.addAuthor(i18n("Joseph Wenninger"), i18n("Developer (navigation panel framework)"), "jowenn@kde.org"); 0213 m_aboutData.addAuthor(i18n("Stephan Binner"), i18n("Developer (misc stuff)"), "binner@kde.org"); 0214 m_aboutData.addAuthor(i18n("Ivor Hewitt"), i18n("Developer (AdBlock filter)"), "ivor@ivor.org"); 0215 m_aboutData.addAuthor(i18n("Eduardo Robles Elvira"), i18n("Developer (framework)"), "edulix@gmail.com"); 0216 m_aboutData.addAuthor(i18n("Matthias Kalle Dalheimer"), QLatin1String(""), QStringLiteral("kalle@kde.org")); 0217 m_aboutData.addAuthor(i18n("Daniel Molkentin"), QLatin1String(""), QStringLiteral("molkentin@kde.org")); 0218 m_aboutData.addCredit(i18n("Leo Savernik"), i18n("JavaScript access controls\n" 0219 "Per-domain policies extensions"), 0220 QStringLiteral("l.savernik@aon.at")); 0221 KAboutData::setApplicationData(m_aboutData); 0222 } 0223 0224 void KonquerorApplication::setupParser() 0225 { 0226 m_parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); 0227 m_aboutData.setupCommandLine(&m_parser); 0228 0229 m_parser.addOption(QCommandLineOption(QStringList{QStringLiteral("silent")}, i18n("Start without a default window, when called without URLs"))); 0230 m_parser.addOption(QCommandLineOption(QStringList{QStringLiteral("preload")}, i18n("Preload for later use. This mode does not support URLs on the command line"))); 0231 m_parser.addOption(QCommandLineOption(QStringList{QStringLiteral("profile")}, i18n("Profile to open (DEPRECATED, IGNORED)"), i18n("profile"))); 0232 m_parser.addOption(QCommandLineOption(QStringList{QStringLiteral("sessions")}, i18n("List available sessions"))); 0233 m_parser.addOption(QCommandLineOption(QStringList{QStringLiteral("open-session")}, i18n("Session to open"), i18n("session"))); 0234 m_parser.addOption(QCommandLineOption(QStringList{QStringLiteral("mimetype")}, i18n("Mimetype to use for this URL (e.g. text/html or inode/directory)"), i18n("mimetype"))); 0235 m_parser.addOption(QCommandLineOption(QStringList{QStringLiteral("part")}, i18n("Part to use (e.g. khtml or kwebkitpart)"), i18n("service"))); 0236 m_parser.addOption(QCommandLineOption(QStringList{QStringLiteral("select")}, i18n("For URLs that point to files, opens the directory and selects the file, instead of opening the actual file"))); 0237 m_parser.addOption(QCommandLineOption(QStringList{QStringLiteral("tempfile")}, i18n("The files/URLs opened by the application will be deleted after use"))); 0238 #ifdef DEVELOPER_MODE 0239 m_parser.addOption(QCommandLineOption({QStringLiteral("force-new-process")}, i18n("Create a new Konqueror process, even if one already exists. Meant to be used only when developing Konqueror itself"))); 0240 #endif 0241 m_parser.addOption(QCommandLineOption({QStringLiteral("test-restore")}, i18n("TEST"))); 0242 m_parser.addPositionalArgument(QStringLiteral("[URL]"), i18n("Location to open")); 0243 } 0244 0245 static void fixOldStartUrl() { 0246 QUrl startUrl(KonqSettings::startURL()); 0247 if (startUrl.scheme() == "about") { 0248 startUrl.setScheme(KonqUrl::scheme()); 0249 KonqSettings::setStartURL(startUrl.url()); 0250 KonqSettings::self()->save(); 0251 } 0252 } 0253 0254 int KonquerorApplication::startFirstInstance() 0255 { 0256 fixOldStartUrl(); 0257 0258 m_browser = new KonqBrowser(this); 0259 connect(this, &KonquerorApplication::configurationChanged, m_browser, &KonqBrowser::configurationChanged); 0260 0261 if (isSessionRestored()) { 0262 restoreSession(); 0263 } else { 0264 performStart(QDir::currentPath(), true); 0265 } 0266 0267 QString programName = QApplication::applicationFilePath(); 0268 0269 //Ensure a session manager is created 0270 KonqSessionManager::self(); 0271 0272 const int ret = exec(); 0273 0274 //Don't preload if Konqueror is run as root 0275 bool alwaysPreload = m_runningAsRootBehavior == NotRoot && KonqSettings::alwaysHavePreloaded(); 0276 0277 // Delete all KonqMainWindows, so that we don't have 0278 // any parts loaded when KLibLoader::cleanUp is called. 0279 // (and Qt doesn't delete WA_DeleteOnClose widgets on exit anyway :() 0280 while (KonqMainWindow::mainWindowList() != nullptr) { 0281 // the list will be deleted by last KonqMainWindow 0282 delete KonqMainWindow::mainWindowList()->first(); 0283 } 0284 0285 // Notify the session manager that the instance was closed without errors, and normally. 0286 KonqSessionManager::self()->disableAutosave(); 0287 KonqSessionManager::self()->deleteOwnedSessions(); 0288 0289 KonqClosedWindowsManager::destroy(); 0290 0291 if (alwaysPreload) { 0292 QProcess::startDetached(programName, {"--preload"}); 0293 } 0294 0295 return ret; 0296 } 0297 0298 int KonquerorApplication::start() 0299 { 0300 if (m_runningAsRootBehavior == PreventRunningAsRoot) { 0301 return 0; 0302 } 0303 0304 setupAboutData(); 0305 setupParser(); 0306 0307 KCrash::initialize(); 0308 0309 m_parser.process(*this); 0310 m_aboutData.processCommandLine(&m_parser); 0311 0312 #ifdef DEVELOPER_MODE 0313 bool forceNewProcess = m_runningAsRootBehavior != NotRoot || m_parser.isSet(QStringLiteral("force-new-process")); 0314 #else 0315 bool forceNewProcess = m_runningAsRootBehavior != NotRoot; 0316 #endif 0317 0318 //Explicitly disable reusing existing instances if running as root. The behavior is not clear 0319 //and could be dangerous if new windows are unknowingly launched as root. 0320 //I thought that creating the KDBusService instance inside the if block should do it; however, doing 0321 //so prevents the new window to be created because the new instance produces a critical failure with message: 0322 //Couldn't register name 'org.kde.konqueror' with DBUS - another process owns it already! 0323 //Moving the service creation outside the if block seems to solve the issue. 0324 // 0325 //This also disables reusing an existing instance when running in developer mode 0326 KDBusService dbusService(forceNewProcess ? KDBusService::Multiple | KDBusService::NoExitOnFailure : KDBusService::Unique); 0327 if (!forceNewProcess) { 0328 auto activateApp = [this](const QStringList &arguments, const QString &workingDirectory) { 0329 m_parser.parse(arguments); 0330 performStart(workingDirectory, false); 0331 }; 0332 QObject::connect(&dbusService, &KDBusService::activateRequested, activateApp); 0333 } 0334 0335 return startFirstInstance(); 0336 } 0337 0338 int KonquerorApplication::performStart(const QString& workingDirectory, bool firstInstance) 0339 { 0340 const QStringList args = m_parser.positionalArguments(); 0341 0342 if (m_parser.isSet("sessions")) { 0343 listSessions(); 0344 return 0; 0345 } else if (m_parser.isSet("open-session")) { 0346 //If the given session can't be opened for any reason, inform the user 0347 QString sessionName = m_parser.value("open-session"); 0348 int result = openSession(sessionName); 0349 if (result != 0) { 0350 KMessageBox::error(nullptr, i18nc("The session asked by the user doesn't exist or can't be opened", 0351 "Session %1 couldn't be opened", sessionName)); 0352 } 0353 //If there was an error opening the session and this is the first instance, don't return immediately 0354 //as this would lead to the application being run but with no windows open. Instead, open an empty 0355 //window 0356 if (result != 0 && firstInstance) { 0357 return result; 0358 } 0359 } 0360 0361 //We check for the --preload switch before attempting recovering session because we shouldn't 0362 //display windows when the user only asked to preload a window 0363 if (m_parser.isSet("preload")) { 0364 preloadWindow(args); 0365 return 0; 0366 } 0367 0368 //Don't attempt to restore session when running as root 0369 if (!m_sessionRecoveryAttempted && m_runningAsRootBehavior == NotRoot) { 0370 // Ask the user to recover session if applicable 0371 KonqSessionManager::self()->askUserToRestoreAutosavedAbandonedSessions(); 0372 m_sessionRecoveryAttempted = true; 0373 } 0374 0375 WindowCreationResult result; 0376 0377 bool sessionRestored = KonqSessionManager::self()->restoreSessionSavedAtExit(); 0378 if (!args.isEmpty()) { 0379 //KonqSessionManager::restoreSessionSavedAtExit only returns true if there's at least one main window, 0380 //so there's no need to check whether the list is empty 0381 result = createWindowsForUrlArguments(args, workingDirectory, sessionRestored ? KonqMainWindow::mainWindows().at(0) : nullptr); 0382 } else if (sessionRestored){ 0383 result = WindowCreationResult{KonqMainWindow::mainWindows().at(0), 0}; 0384 } else { 0385 result = createEmptyWindow(firstInstance, true); 0386 } 0387 0388 KonqMainWindow *mw = result.first; 0389 if (!firstInstance && mw) { 0390 mw ->setAttribute(Qt::WA_NativeWindow, true); 0391 if (KWindowSystem::isPlatformX11()) { 0392 KStartupInfo::setNewStartupId(mw->windowHandle(), QX11Info::nextStartupId()); 0393 KX11Extras::forceActiveWindow(mw->winId()); 0394 } else { 0395 KStartupInfo::setNewStartupId(mw->windowHandle(), qEnvironmentVariable("XDG_ACTIVATION_TOKEN").toUtf8()); 0396 } 0397 } 0398 0399 return result.second; 0400 } 0401 0402 KonquerorApplication::WindowCreationResult KonquerorApplication::createWindowsForUrlArguments(const QStringList& args, const QString &workingDirectory, KonqMainWindow *mainwin) 0403 { 0404 QList<QUrl> urlList; 0405 urlList.reserve(args.length()); 0406 0407 auto urlFromArg = [workingDirectory](const QString &arg) { 0408 const QUrl url = QUrl::fromUserInput(arg, workingDirectory); 0409 // KonqMisc::konqFilteredURL doesn't cope with local files... A bit of hackery below 0410 if (url.isLocalFile() && QFile::exists(url.toLocalFile())) { // "konqueror index.html" 0411 return url; 0412 } else { // "konqueror slashdot.org" 0413 return KonqMisc::konqFilteredURL(nullptr, arg); 0414 } 0415 }; 0416 0417 for (const QString &arg : args) { 0418 urlList.append(urlFromArg(arg)); 0419 }; 0420 0421 QList<QUrl> filesToSelect; 0422 if (m_parser.isSet("select")) { 0423 // Get all distinct directories from 'files' and open a tab 0424 // for each directory. 0425 QList<QUrl> dirs; 0426 for (const QUrl &url : urlList) { 0427 const QUrl dir(url.adjusted(QUrl::RemoveFilename)); 0428 if (!dirs.contains(dir)) { 0429 dirs.append(dir); 0430 } 0431 } 0432 filesToSelect = urlList; 0433 urlList = dirs; 0434 } 0435 0436 QUrl firstUrl = urlList.takeFirst(); 0437 0438 KParts::OpenUrlArguments urlargs; 0439 if (m_parser.isSet("mimetype")) { 0440 urlargs.setMimeType(m_parser.value("mimetype")); 0441 } 0442 0443 KonqOpenURLRequest req; 0444 req.args = urlargs; 0445 req.filesToSelect = filesToSelect; 0446 req.tempFile = m_parser.isSet("tempfile"); 0447 req.serviceName = m_parser.value("part"); 0448 0449 if (!mainwin) { 0450 mainwin = KonqMainWindowFactory::createNewWindow(firstUrl, req); 0451 if (!mainwin) { 0452 return qMakePair(nullptr, 1); 0453 } 0454 } else { 0455 req.browserArgs.setNewTab(true); 0456 mainwin->openUrl(nullptr, firstUrl, req.args.mimeType(), req); 0457 } 0458 0459 mainwin->show(); 0460 if (!urlList.isEmpty()) { 0461 // Open the other urls as tabs in that window 0462 mainwin->openMultiURL(urlList); 0463 } 0464 0465 //Ensure the last tab is activated. This happens automatically if a new main window was created 0466 //but not if an existing main window was passed as argument, which is the case if the last Konqueror 0467 //session was restored 0468 mainwin->activateTab(mainwin->tabsCount()-1); 0469 return qMakePair(mainwin, 0); 0470 } 0471 0472 void KonquerorApplication::preloadWindow(const QStringList &args) 0473 { 0474 if (!args.isEmpty()) { 0475 QTextStream ts(stderr, QIODevice::WriteOnly); 0476 ts << i18n("You can't pass URLs when using the --preload switch. The URLs will be ignored\n"); 0477 } 0478 KonqMainWindowFactory::createPreloadWindow(); 0479 } 0480 0481 KonquerorApplication::WindowCreationResult KonquerorApplication::createEmptyWindow(bool firstInstance, bool calledFromPerformStart ) 0482 { 0483 //Always create a new window except when called with the --silent switch or a session has been recovered (see #388333) 0484 if (m_parser.isSet("silent")) { 0485 return qMakePair(nullptr, 0); 0486 } 0487 0488 //WORKAROUND for activities 0489 //Consider the following situation: 0490 //- multiple windows, in different activities 0491 //- the user stops one or more activities. The corresponding windows are closed 0492 //- the user exits Konqueror 0493 //- the user restarts Konqueror 0494 //- the user restarts one of the stopped activities which had Konqueror windows on them 0495 //What should happen is that the previously open windows in the restarted activity are restored 0496 //What really happens is that, besides those window, a new, empty window is created. This is because KWin/KSMService attempts 0497 //to start Konqueror again, passing it the information needed to restore the windows. However, for some reason, no information 0498 //is given and Konqueror creates an emtpy window. The following check avoids creating the window. 0499 #ifdef KActivities_FOUND 0500 ActivityManager *am = KonqSessionManager::self()->activityManager(); 0501 if (calledFromPerformStart && am && am->restoringStoppedActivity()) { 0502 am->restoringStoppedActivityDone(); 0503 return qMakePair(nullptr, 0); 0504 } 0505 #endif 0506 0507 if (firstInstance) { // If session recovery created some windows, no need for an empty window here. 0508 QList<KonqMainWindow *> *mainWindowList = KonqMainWindow::mainWindowList(); 0509 if (mainWindowList && !mainWindowList->isEmpty()) { 0510 return qMakePair(mainWindowList->at(0), 0); 0511 } 0512 } 0513 0514 KonqMainWindow *mainWin = KonqMainWindowFactory::createNewWindow(); 0515 if (mainWin) { 0516 mainWin->show(); 0517 return qMakePair(mainWin, 0); 0518 } else { 0519 return qMakePair(nullptr, 1); 0520 } 0521 } 0522 0523 void KonquerorApplication::listSessions() 0524 { 0525 const QString dir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QLatin1Char('/') + "sessions/"; 0526 QDirIterator it(dir, QDir::Readable | QDir::NoDotAndDotDot | QDir::Dirs); 0527 QTextStream ts(stdout, QIODevice::WriteOnly); 0528 while (it.hasNext()) { 0529 QFileInfo fileInfo(it.next()); 0530 ts << fileInfo.baseName(); 0531 } 0532 } 0533 0534 int KonquerorApplication::openSession(const QString& session) 0535 { 0536 QString sessionPath = session; 0537 if (!session.startsWith('/')) { 0538 sessionPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QLatin1Char('/') + "sessions/" + session; 0539 } 0540 0541 QDirIterator it(sessionPath, QDir::Readable | QDir::Files); 0542 if (!it.hasNext()) { 0543 qCWarning(KONQUEROR_LOG) << "session" << session << "not found or empty"; 0544 return 1; 0545 } 0546 0547 KonqSessionManager::self()->restoreSessions(sessionPath); 0548 0549 QList<KonqMainWindow*> *mainWindows = KonqMainWindow::mainWindowList(); 0550 return (mainWindows && !mainWindows->isEmpty()) ? 0 : 1; 0551 } 0552 0553 void KonquerorApplication::restoreSession() 0554 { 0555 KonqSessionManager::self()->restoreSessionSavedAtLogout(); 0556 }