File indexing completed on 2024-04-14 04:53:15
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 1998, 1999 Simon Hausmann <hausmann@kde.org> 0003 SPDX-FileCopyrightText: 2000, 2006 David Faure <faure@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "KonquerorAdaptor.h" 0009 #include "konqmisc.h" 0010 #include "KonqMainWindowAdaptor.h" 0011 #include "konqmainwindow.h" 0012 #include "konqmainwindowfactory.h" 0013 #include "konqviewmanager.h" 0014 #include "konqview.h" 0015 #include "konqsettingsxt.h" 0016 #include "konqsettings.h" 0017 #include "konqapplication.h" 0018 0019 #include "konqdebug.h" 0020 #include <KStartupInfo> 0021 #include <KWindowInfo> 0022 #include <kwindowsystem.h> 0023 0024 #include <QFile> 0025 0026 #if QT_VERSION_MAJOR < 6 0027 #include <QX11Info> 0028 #else 0029 #include <QtGui/private/qtx11extras_p.h> 0030 #endif 0031 0032 #ifdef KActivities_FOUND 0033 #if QT_VERSION_MAJOR < 6 0034 #include <KActivities/Consumer> 0035 #else //QT_VERSION_MAJOR 0036 #include <PlasmaActivities/Consumer> 0037 #endif //QT_VERSION_MAJOR 0038 #endif //KActivities_FOUND 0039 0040 // these DBus calls come from outside, so any windows created by these 0041 // calls would have old user timestamps (for KWin's no-focus-stealing), 0042 // it's better to reset the timestamp and rely on other means 0043 // of detecting the time when the user action that triggered all this 0044 // happened 0045 // TODO a valid timestamp should be passed in the DBus calls that 0046 // are not for user scripting 0047 0048 KonquerorAdaptor::KonquerorAdaptor() 0049 : QObject(qApp) 0050 { 0051 QDBusConnection dbus = QDBusConnection::sessionBus(); 0052 dbus.registerObject(KONQ_MAIN_PATH, this, QDBusConnection::ExportNonScriptableSlots); 0053 } 0054 0055 KonquerorAdaptor::~KonquerorAdaptor() 0056 { 0057 } 0058 0059 static void setStartupId(const QByteArray &startup_id) 0060 { 0061 KStartupInfo::setStartupId(startup_id); 0062 QX11Info::setAppUserTime(0); 0063 } 0064 0065 QDBusObjectPath KonquerorAdaptor::openBrowserWindow(const QString &url, const QByteArray &startup_id) 0066 { 0067 setStartupId(startup_id); 0068 KonqMainWindow *res = KonqMainWindowFactory::createNewWindow(QUrl::fromUserInput(url)); 0069 if (!res) { 0070 return QDBusObjectPath("/"); 0071 } 0072 return QDBusObjectPath(res->dbusName()); 0073 } 0074 0075 QDBusObjectPath KonquerorAdaptor::createNewWindow(const QString &url, const QString &mimetype, const QByteArray &startup_id, bool tempFile) 0076 { 0077 setStartupId(startup_id); 0078 KParts::OpenUrlArguments args; 0079 args.setMimeType(mimetype); 0080 // Filter the URL, so that "kfmclient openURL gg:foo" works also when konq is already running 0081 QUrl finalURL = KonqMisc::konqFilteredURL(nullptr, url); 0082 KonqOpenURLRequest req; 0083 req.args = args; 0084 req.tempFile = tempFile; 0085 KonqMainWindow *res = KonqMainWindowFactory::createNewWindow(finalURL, req); 0086 if (!res) { 0087 return QDBusObjectPath("/"); 0088 } 0089 res->show(); 0090 return QDBusObjectPath(res->dbusName()); 0091 } 0092 0093 QDBusObjectPath KonquerorAdaptor::createNewWindowWithSelection(const QString &url, const QStringList &filesToSelect, const QByteArray &startup_id) 0094 { 0095 setStartupId(startup_id); 0096 KonqOpenURLRequest req; 0097 req.filesToSelect = QUrl::fromStringList(filesToSelect); 0098 KonqMainWindow *res = KonqMainWindowFactory::createNewWindow(QUrl::fromUserInput(url), req); 0099 if (!res) { 0100 return QDBusObjectPath("/"); 0101 } 0102 res->show(); 0103 return QDBusObjectPath(res->dbusName()); 0104 } 0105 0106 QList<QDBusObjectPath> KonquerorAdaptor::getWindows() 0107 { 0108 QList<QDBusObjectPath> lst; 0109 QList<KonqMainWindow *> *mainWindows = KonqMainWindow::mainWindowList(); 0110 if (mainWindows) { 0111 for (KonqMainWindow *window: *mainWindows) { 0112 lst.append(QDBusObjectPath(window->dbusName())); 0113 } 0114 } 0115 return lst; 0116 } 0117 0118 QStringList KonquerorAdaptor::urls() const 0119 { 0120 QStringList lst; 0121 QList<KonqMainWindow *> *mainWindows = KonqMainWindow::mainWindowList(); 0122 if (mainWindows) { 0123 for (KonqMainWindow *window : *mainWindows) { 0124 if (!window->isPreloaded()) { 0125 for (KonqView *view : window->viewMap()) { 0126 lst.append(view->url().toString()); 0127 } 0128 } 0129 } 0130 } 0131 return lst; 0132 } 0133 0134 QDBusObjectPath KonquerorAdaptor::windowForTab() 0135 { 0136 QList<KonqMainWindow *> *mainWindows = KonqMainWindow::mainWindowList(); 0137 if (!mainWindows) { 0138 return QDBusObjectPath("/"); 0139 } 0140 //Accept only windows which are on the current desktop and in the current activity 0141 //(if activities are enabled) 0142 auto filter = [](KonqMainWindow *mw) { 0143 KWindowInfo winfo(mw->winId(), NET::WMDesktop, NET::WM2Activities); 0144 QString currentActivity = KonquerorApplication::currentActivity(); 0145 bool isInCurrentActivity = true; 0146 //if currentActivity is empty, it means that the activity service status is not running or that activity support is disabled, 0147 //so it's useless to check which activity the window is on 0148 if (!currentActivity.isEmpty()) { 0149 QStringList windowActivities = winfo.activities(); 0150 //WARNING: a window is in the current activity either when windowActivities contains the current activity 0151 //or when windowActivities is empty, since KWindowInfo::activities() returns an empty list when the 0152 //window is on all activities 0153 isInCurrentActivity = windowActivities.isEmpty() || windowActivities.contains(currentActivity); 0154 } 0155 if (winfo.isOnCurrentDesktop() && (isInCurrentActivity)) { 0156 Q_ASSERT(!mw->dbusName().isEmpty()); 0157 return true; 0158 } else { 0159 return false; 0160 } 0161 }; 0162 QList<KonqMainWindow*> visibleWindows; 0163 std::copy_if(mainWindows->constBegin(), mainWindows->constEnd(), std::back_inserter(visibleWindows), filter); 0164 0165 //Sort the windows according to the last deactivation order, so that windows deactivated last come first 0166 //(if a window is active, it'll come before the others) 0167 auto sorter = [](KonqMainWindow *w1, KonqMainWindow *w2) { 0168 if (w1->isActiveWindow()) { 0169 return true; 0170 } else if (w2->isActiveWindow()) { 0171 return false; 0172 } else { 0173 return w2->lastDeactivationTime() < w1->lastDeactivationTime(); 0174 } 0175 }; 0176 std::sort(visibleWindows.begin(), visibleWindows.end(), sorter); 0177 if (!visibleWindows.isEmpty()) { 0178 return QDBusObjectPath(visibleWindows.first()->dbusName()); 0179 } else { 0180 return QDBusObjectPath("/"); 0181 } 0182 }