diff --git a/libtaskmanager/abstracttasksmodel.cpp b/libtaskmanager/abstracttasksmodel.cpp index 18e062385..4952e0bc7 100644 --- a/libtaskmanager/abstracttasksmodel.cpp +++ b/libtaskmanager/abstracttasksmodel.cpp @@ -62,6 +62,12 @@ void AbstractTasksModel::requestNewInstance(const QModelIndex &index) Q_UNUSED(index) } +void AbstractTasksModel::requestOpenUrls(const QModelIndex &index, const QList &urls) +{ + Q_UNUSED(index) + Q_UNUSED(urls) +} + void AbstractTasksModel::requestClose(const QModelIndex &index) { Q_UNUSED(index) diff --git a/libtaskmanager/abstracttasksmodel.h b/libtaskmanager/abstracttasksmodel.h index 5c27a97b2..5994970f9 100644 --- a/libtaskmanager/abstracttasksmodel.h +++ b/libtaskmanager/abstracttasksmodel.h @@ -114,6 +114,17 @@ public: **/ virtual void requestNewInstance(const QModelIndex &index) override; + /** + * Requests to open the given URLs with the application backing the task + * at the given index. + * + * This base implementation does nothing. + * + * @param index An index in this tasks model. + * @param urls The URLs to be passed to the application. + **/ + virtual void requestOpenUrls(const QModelIndex &index, const QList &urls); + /** * Request the task at the given index be closed. * diff --git a/libtaskmanager/abstracttasksmodeliface.h b/libtaskmanager/abstracttasksmodeliface.h index c162e89bb..951b16b8a 100644 --- a/libtaskmanager/abstracttasksmodeliface.h +++ b/libtaskmanager/abstracttasksmodeliface.h @@ -60,6 +60,15 @@ public: **/ virtual void requestNewInstance(const QModelIndex &index) = 0; + /** + * Requests to open the given URLs with the application backing the task + * at the given index. + * + * @param index An index in this tasks model. + * @param urls The URLs to be passed to the application. + **/ + virtual void requestOpenUrls(const QModelIndex &index, const QList &urls) = 0; + /** * Request the task at the given index be closed. * diff --git a/libtaskmanager/concatenatetasksproxymodel.cpp b/libtaskmanager/concatenatetasksproxymodel.cpp index 3b1fd15c6..daa0864df 100644 --- a/libtaskmanager/concatenatetasksproxymodel.cpp +++ b/libtaskmanager/concatenatetasksproxymodel.cpp @@ -64,6 +64,22 @@ void ConcatenateTasksProxyModel::requestNewInstance(const QModelIndex &index) } } +void ConcatenateTasksProxyModel::requestOpenUrls(const QModelIndex &index, const QList &urls) +{ + if (!index.isValid() || index.model() != this) { + return; + } + + const QModelIndex &sourceIndex = mapToSource(index); + const AbstractTasksModelIface *m = dynamic_cast(sourceIndex.model()); + + if (m) { + // NOTE: KConcatenateRowsProxyModel offers no way to get a non-const pointer + // to one of the source models, so we have to go through a mapped index. + const_cast(m)->requestOpenUrls(sourceIndex, urls); + } +} + void ConcatenateTasksProxyModel::requestClose(const QModelIndex &index) { if (!index.isValid() || index.model() != this) { diff --git a/libtaskmanager/concatenatetasksproxymodel.h b/libtaskmanager/concatenatetasksproxymodel.h index 0e94cb81a..e04ef4d91 100644 --- a/libtaskmanager/concatenatetasksproxymodel.h +++ b/libtaskmanager/concatenatetasksproxymodel.h @@ -65,6 +65,15 @@ public: **/ void requestNewInstance(const QModelIndex &index); + /** + * Requests to open the given URLs with the application backing the task + * at the given index. + * + * @param index An index in this tasks model. + * @param urls The URLs to be passed to the application. + **/ + virtual void requestOpenUrls(const QModelIndex &index, const QList &urls); + /** * Request the task at the given index be closed. * diff --git a/libtaskmanager/flattentaskgroupsproxymodel.cpp b/libtaskmanager/flattentaskgroupsproxymodel.cpp index f100aedac..22fe52c1c 100644 --- a/libtaskmanager/flattentaskgroupsproxymodel.cpp +++ b/libtaskmanager/flattentaskgroupsproxymodel.cpp @@ -70,6 +70,13 @@ void FlattenTaskGroupsProxyModel::requestNewInstance(const QModelIndex &index) } } +void FlattenTaskGroupsProxyModel::requestOpenUrls(const QModelIndex &index, const QList &urls) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestOpenUrls(mapToSource(index), urls); + } +} + void FlattenTaskGroupsProxyModel::requestClose(const QModelIndex &index) { if (d->sourceTasksModel && index.isValid() && index.model() == this) { diff --git a/libtaskmanager/flattentaskgroupsproxymodel.h b/libtaskmanager/flattentaskgroupsproxymodel.h index 572e42988..95a5675bd 100644 --- a/libtaskmanager/flattentaskgroupsproxymodel.h +++ b/libtaskmanager/flattentaskgroupsproxymodel.h @@ -68,6 +68,15 @@ public: **/ void requestNewInstance(const QModelIndex &index) override; + /** + * Requests to open the given URLs with the application backing the task + * at the given index. + * + * @param index An index in this tasks model. + * @param urls The URLs to be passed to the application. + **/ + virtual void requestOpenUrls(const QModelIndex &index, const QList &urls); + /** * Request the task at the given index be closed. * diff --git a/libtaskmanager/launchertasksmodel.cpp b/libtaskmanager/launchertasksmodel.cpp index 8c4441ae1..d2231a286 100644 --- a/libtaskmanager/launchertasksmodel.cpp +++ b/libtaskmanager/launchertasksmodel.cpp @@ -308,4 +308,37 @@ void LauncherTasksModel::requestNewInstance(const QModelIndex &index) } } +void LauncherTasksModel::requestOpenUrls(const QModelIndex &index, const QList &urls) +{ + if (!index.isValid() || index.model() != this + || index.row() < 0 || index.row() >= d->launchers.count() + || urls.isEmpty()) { + return; + } + + const QUrl &url = d->launchers.at(index.row()); + + quint32 timeStamp = 0; + +#if HAVE_X11 + if (KWindowSystem::isPlatformX11()) { + timeStamp = QX11Info::appUserTime(); + } +#endif + + KService::Ptr service; + + if (url.scheme() == QLatin1String("preferred")) { + service = KService::serviceByStorageId(defaultApplication(url)); + } else { + service = KService::serviceByDesktopPath(url.toLocalFile()); + } + + if (!service) { + return; + } + + KRun::runApplication(*service, urls, nullptr, false, {}, KStartupInfo::createNewStartupIdForTimestamp(timeStamp)); +} + } diff --git a/libtaskmanager/launchertasksmodel.h b/libtaskmanager/launchertasksmodel.h index 8ee3010af..e9e2d036f 100644 --- a/libtaskmanager/launchertasksmodel.h +++ b/libtaskmanager/launchertasksmodel.h @@ -132,6 +132,14 @@ public: */ void requestNewInstance(const QModelIndex &index) override; + /** + * Runs the application backing the launcher at the given index with the given URLs. + * + * @param index An index in this launcher tasks model + * @param urls The URLs to be passed to the application + */ + void requestOpenUrls(const QModelIndex &index, const QList &urls) override; + Q_SIGNALS: void launcherListChanged() const; diff --git a/libtaskmanager/taskfilterproxymodel.cpp b/libtaskmanager/taskfilterproxymodel.cpp index f9bdb1034..096481bc9 100644 --- a/libtaskmanager/taskfilterproxymodel.cpp +++ b/libtaskmanager/taskfilterproxymodel.cpp @@ -215,6 +215,14 @@ void TaskFilterProxyModel::requestNewInstance(const QModelIndex &index) } } +void TaskFilterProxyModel::requestOpenUrls(const QModelIndex &index, const QList &urls) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestOpenUrls(mapToSource(index), urls); + } +} + + void TaskFilterProxyModel::requestClose(const QModelIndex &index) { if (d->sourceTasksModel && index.isValid() && index.model() == this) { diff --git a/libtaskmanager/taskfilterproxymodel.h b/libtaskmanager/taskfilterproxymodel.h index 30b39e4a6..c0f966b8e 100644 --- a/libtaskmanager/taskfilterproxymodel.h +++ b/libtaskmanager/taskfilterproxymodel.h @@ -247,6 +247,15 @@ public: **/ void requestNewInstance(const QModelIndex &index) override; + /** + * Requests to open the given URLs with the application backing the task + * at the given index. + * + * @param index An index in this tasks model. + * @param urls The URLs to be passed to the application. + **/ + virtual void requestOpenUrls(const QModelIndex &index, const QList &urls); + /** * Request the task at the given index be closed. * diff --git a/libtaskmanager/taskgroupingproxymodel.cpp b/libtaskmanager/taskgroupingproxymodel.cpp index a16582454..26870a0b8 100644 --- a/libtaskmanager/taskgroupingproxymodel.cpp +++ b/libtaskmanager/taskgroupingproxymodel.cpp @@ -938,6 +938,15 @@ void TaskGroupingProxyModel::requestNewInstance(const QModelIndex &index) d->abstractTasksSourceModel->requestNewInstance(mapToSource(index)); } +void TaskGroupingProxyModel::requestOpenUrls(const QModelIndex &index, const QList &urls) +{ + if (!d->abstractTasksSourceModel || !index.isValid() || index.model() != this) { + return; + } + + d->abstractTasksSourceModel->requestOpenUrls(mapToSource(index), urls); +} + void TaskGroupingProxyModel::requestClose(const QModelIndex &index) { if (!d->abstractTasksSourceModel || !index.isValid() || index.model() != this) { diff --git a/libtaskmanager/taskgroupingproxymodel.h b/libtaskmanager/taskgroupingproxymodel.h index 4428c3e9a..1c58d2af5 100644 --- a/libtaskmanager/taskgroupingproxymodel.h +++ b/libtaskmanager/taskgroupingproxymodel.h @@ -211,6 +211,15 @@ public: **/ void requestNewInstance(const QModelIndex &index) override; + /** + * Requests to open the given URLs with the application backing the task + * at the given index. + * + * @param index An index in this tasks model. + * @param urls The URLs to be passed to the application. + **/ + virtual void requestOpenUrls(const QModelIndex &index, const QList &urls); + /** * Request the task at the given index be closed. * diff --git a/libtaskmanager/tasksmodel.cpp b/libtaskmanager/tasksmodel.cpp index 8cd5ce2ac..6125e39d9 100644 --- a/libtaskmanager/tasksmodel.cpp +++ b/libtaskmanager/tasksmodel.cpp @@ -1175,6 +1175,13 @@ void TasksModel::requestNewInstance(const QModelIndex &index) } } +void TasksModel::requestOpenUrls(const QModelIndex &index, const QList &urls) +{ + if (index.isValid() && index.model() == this) { + d->abstractTasksSourceModel->requestOpenUrls(mapToSource(index), urls); + } +} + void TasksModel::requestClose(const QModelIndex &index) { if (index.isValid() && index.model() == this) { diff --git a/libtaskmanager/tasksmodel.h b/libtaskmanager/tasksmodel.h index 006929c5e..1a7eb2ca6 100644 --- a/libtaskmanager/tasksmodel.h +++ b/libtaskmanager/tasksmodel.h @@ -576,6 +576,15 @@ public: **/ Q_INVOKABLE void requestNewInstance(const QModelIndex &index) override; + /** + * Requests to open the given URLs with the application backing the task + * at the given index. + * + * @param index An index in this tasks model. + * @param urls The URLs to be passed to the application. + **/ + Q_INVOKABLE void requestOpenUrls(const QModelIndex &index, const QList &urls); + /** * Request the task at the given index be closed. * diff --git a/libtaskmanager/waylandtasksmodel.cpp b/libtaskmanager/waylandtasksmodel.cpp index 4cbd7c081..985fd2423 100644 --- a/libtaskmanager/waylandtasksmodel.cpp +++ b/libtaskmanager/waylandtasksmodel.cpp @@ -375,6 +375,26 @@ void WaylandTasksModel::requestNewInstance(const QModelIndex &index) } } +void WaylandTasksModel::requestOpenUrls(const QModelIndex &index, const QList &urls) +{ + if (!index.isValid() || index.model() != this || index.row() < 0 + || index.row() >= d->windows.count() + || urls.isEmpty()) { + return; + } + + KWayland::Client::PlasmaWindow *window = d->windows.at(index.row()); + + if (d->serviceCache.contains(window)) { + const KService::Ptr service = d->serviceCache.value(window); + + KRun::runApplication(*service, urls, nullptr, false); + + KActivities::ResourceInstance::notifyAccessed(QUrl("applications:" + service->storageId()), + "org.kde.libtaskmanager"); + } +} + void WaylandTasksModel::requestClose(const QModelIndex &index) { if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { diff --git a/libtaskmanager/waylandtasksmodel.h b/libtaskmanager/waylandtasksmodel.h index f93529620..5bf46fef5 100644 --- a/libtaskmanager/waylandtasksmodel.h +++ b/libtaskmanager/waylandtasksmodel.h @@ -80,6 +80,16 @@ public: **/ void requestNewInstance(const QModelIndex &index) override; + /** + * Runs the application backing the launcher at the given index with the given URLs. + * Success depends on whether a AbstractTasksModel::LauncherUrl could be + * derived from window metadata and a KService could be found from that. + * + * @param index An index in this launcher tasks model + * @param urls The URLs to be passed to the application + */ + void requestOpenUrls(const QModelIndex &index, const QList &urls) override; + /** * Request the window at the given index be closed. * diff --git a/libtaskmanager/windowtasksmodel.cpp b/libtaskmanager/windowtasksmodel.cpp index a2ccfa35a..8ac96529a 100644 --- a/libtaskmanager/windowtasksmodel.cpp +++ b/libtaskmanager/windowtasksmodel.cpp @@ -116,6 +116,13 @@ void WindowTasksModel::requestNewInstance(const QModelIndex &index) } } +void WindowTasksModel::requestOpenUrls(const QModelIndex &index, const QList &urls) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestOpenUrls(mapToSource(index), urls); + } +} + void WindowTasksModel::requestClose(const QModelIndex &index) { if (d->sourceTasksModel && index.isValid() && index.model() == this) { diff --git a/libtaskmanager/windowtasksmodel.h b/libtaskmanager/windowtasksmodel.h index 8fa56f7ba..5a75ef4c2 100644 --- a/libtaskmanager/windowtasksmodel.h +++ b/libtaskmanager/windowtasksmodel.h @@ -66,6 +66,16 @@ public: **/ void requestNewInstance(const QModelIndex &index) override; + /** + * Runs the application backing the launcher at the given index with the given URLs. + * Success depends on whether a AbstractTasksModel::LauncherUrl could be + * derived from window metadata and a KService could be found from that. + * + * @param index An index in this launcher tasks model + * @param urls The URLs to be passed to the application + */ + void requestOpenUrls(const QModelIndex &index, const QList &urls) override; + /** * Request the window at the given index be closed. * diff --git a/libtaskmanager/xwindowtasksmodel.cpp b/libtaskmanager/xwindowtasksmodel.cpp index 75ebe42a5..d7e9f1108 100644 --- a/libtaskmanager/xwindowtasksmodel.cpp +++ b/libtaskmanager/xwindowtasksmodel.cpp @@ -943,6 +943,21 @@ void XWindowTasksModel::requestNewInstance(const QModelIndex &index) } } +void XWindowTasksModel::requestOpenUrls(const QModelIndex &index, const QList &urls) +{ + if (!index.isValid() || index.model() != this || index.row() < 0 + || index.row() >= d->windows.count() + || urls.isEmpty()) { + return; + } + + const QUrl &url = d->appData(d->windows.at(index.row())).url; + const KService::Ptr service = KService::serviceByDesktopPath(url.toLocalFile()); + if (service) { + KRun::runApplication(*service, urls, nullptr, false, {}, KStartupInfo::createNewStartupIdForTimestamp(QX11Info::appUserTime())); + } +} + void XWindowTasksModel::requestClose(const QModelIndex &index) { if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { diff --git a/libtaskmanager/xwindowtasksmodel.h b/libtaskmanager/xwindowtasksmodel.h index cd9710053..fbc016c6e 100644 --- a/libtaskmanager/xwindowtasksmodel.h +++ b/libtaskmanager/xwindowtasksmodel.h @@ -79,6 +79,16 @@ public: **/ void requestNewInstance(const QModelIndex &index) override; + /** + * Runs the application backing the launcher at the given index with the given URLs. + * Success depends on whether a AbstractTasksModel::LauncherUrl could be + * derived from window metadata and a KService could be found from that. + * + * @param index An index in this launcher tasks model + * @param urls The URLs to be passed to the application + */ + void requestOpenUrls(const QModelIndex &index, const QList &urls) override; + /** * Request the window at the given index be closed. *