diff --git a/libtaskmanager/CMakeLists.txt b/libtaskmanager/CMakeLists.txt --- a/libtaskmanager/CMakeLists.txt +++ b/libtaskmanager/CMakeLists.txt @@ -14,6 +14,7 @@ tasktools.cpp virtualdesktopinfo.cpp waylandtasksmodel.cpp + windowtasksmodel.cpp ) if (X11_FOUND) @@ -74,6 +75,7 @@ tasktools.h virtualdesktopinfo.h waylandtasksmodel.h + windowtasksmodel.h ${CMAKE_CURRENT_BINARY_DIR}/taskmanager_export.h DESTINATION ${KDE_INSTALL_INCLUDEDIR}/taskmanager COMPONENT Devel ) diff --git a/libtaskmanager/tasksmodel.cpp b/libtaskmanager/tasksmodel.cpp --- a/libtaskmanager/tasksmodel.cpp +++ b/libtaskmanager/tasksmodel.cpp @@ -26,25 +26,14 @@ #include "taskgroupingproxymodel.h" #include "tasktools.h" -#include - #include "launchertasksmodel.h" -#include "waylandtasksmodel.h" #include "startuptasksmodel.h" -#if HAVE_X11 -#include "xwindowtasksmodel.h" -#endif - -#include +#include "windowtasksmodel.h" #include #include #include -#if HAVE_X11 -#include -#endif - #include namespace TaskManager @@ -58,7 +47,7 @@ static int instanceCount; - static AbstractTasksModel* windowTasksModel; + static WindowTasksModel* windowTasksModel; static StartupTasksModel* startupTasksModel; LauncherTasksModel* launcherTasksModel = nullptr; ConcatenateTasksProxyModel* concatProxyModel = nullptr; @@ -124,7 +113,7 @@ }; int TasksModel::Private::instanceCount = 0; -AbstractTasksModel* TasksModel::Private::windowTasksModel = nullptr; +WindowTasksModel* TasksModel::Private::windowTasksModel = nullptr; StartupTasksModel* TasksModel::Private::startupTasksModel = nullptr; ActivityInfo* TasksModel::Private::activityInfo = nullptr; int TasksModel::Private::activityInfoUsers = 0; @@ -156,22 +145,16 @@ void TasksModel::Private::initModels() { // NOTE: Overview over the entire model chain assembled here: - // {X11,Wayland}WindowTasksModel, StartupTasksModel, LauncherTasksModel + // WindowTasksModel, StartupTasksModel, LauncherTasksModel // -> concatProxyModel concatenates them into a single list. // -> filterProxyModel filters by state (e.g. virtual desktop). // -> groupingProxyModel groups by application (we go from flat list to tree). // -> flattenGroupsProxyModel (optionally, if groupInline == true) flattens groups out. // -> TasksModel collapses (top-level) items into task lifecycle abstraction; sorts. - if (!windowTasksModel && KWindowSystem::isPlatformWayland()) { - windowTasksModel = new WaylandTasksModel(); - } - -#if HAVE_X11 - if (!windowTasksModel && KWindowSystem::isPlatformX11()) { - windowTasksModel = new XWindowTasksModel(); + if (!windowTasksModel) { + windowTasksModel = new WindowTasksModel(); } -#endif QObject::connect(windowTasksModel, &QAbstractItemModel::rowsInserted, q, [this]() { diff --git a/libtaskmanager/windowtasksmodel.h b/libtaskmanager/windowtasksmodel.h new file mode 100644 --- /dev/null +++ b/libtaskmanager/windowtasksmodel.h @@ -0,0 +1,167 @@ +/******************************************************************** +Copyright 2016 Eike Hein + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +*********************************************************************/ + +#ifndef WINDOWTASKSMODEL_H +#define WINDOWTASKSMODEL_H + +#include + +#include "abstracttasksmodeliface.h" + +#include "taskmanager_export.h" + +namespace TaskManager +{ + +/** + * @short A window tasks model. + * + * This model presents tasks sourced from window data retrieved from the + * windowing server the host process is connected to. The underlying + * windowing system is abstracted away. + * + * @author Eike Hein + **/ + +class TASKMANAGER_EXPORT WindowTasksModel : public QIdentityProxyModel, public AbstractTasksModelIface +{ + Q_OBJECT + +public: + explicit WindowTasksModel(QObject *parent = 0); + virtual ~WindowTasksModel(); + + QHash roleNames() const override; + + /** + * Request activation of the window at the given index. + * + * @param index An index in this window tasks model. + **/ + void requestActivate(const QModelIndex &index) override; + + /** + * Request an additional instance of the application owning the window + * at the given index. Success depends on whether a + * AbstractTasksModel::LauncherUrl could be derived from window metadata. + * + * @param index An index in this window tasks model. + **/ + void requestNewInstance(const QModelIndex &index) override; + + /** + * Request the window at the given index be closed. + * + * @param index An index in this window tasks model. + **/ + void requestClose(const QModelIndex &index) override; + + /** + * Request starting an interactive move for the window at the given index. + * + * @param index An index in this window tasks model. + **/ + void requestMove(const QModelIndex &index) override; + + /** + * Request starting an interactive resize for the window at the given index. + * + * @param index An index in this window tasks model. + **/ + void requestResize(const QModelIndex &index) override; + + /** + * Request toggling the minimized state of the window at the given index. + * + * @param index An index in this window tasks model. + **/ + void requestToggleMinimized(const QModelIndex &index) override; + + /** + * Request toggling the maximized state of the window at the given index. + * + * @param index An index in this window tasks model. + **/ + void requestToggleMaximized(const QModelIndex &index) override; + + /** + * Request toggling the keep-above state of the window at the given index. + * + * @param index An index in this window tasks model. + **/ + void requestToggleKeepAbove(const QModelIndex &index) override; + + /** + * Request toggling the keep-below state of the window at the given index. + * + * @param index An index in this window tasks model. + **/ + void requestToggleKeepBelow(const QModelIndex &index) override; + + /** + * Request toggling the fullscreen state of the window at the given index. + * + * @param index An index in this window tasks model. + **/ + void requestToggleFullScreen(const QModelIndex &index) override; + + /** + * Request toggling the shaded state of the window at the given index. + * + * @param index An index in this window tasks model. + **/ + void requestToggleShaded(const QModelIndex &index) override; + + /** + * Request moving the window at the given index to the specified virtual + * desktop. + * + * @param index An index in this window tasks model. + * @param desktop A virtual desktop number. + **/ + void requestVirtualDesktop(const QModelIndex &index, qint32 desktop) override; + + /** + * Request moving the window at the given index to the specified activities. + * + * @param index An index in this tasks model. + * @param activities The new list of activities. + **/ + void requestActivities(const QModelIndex &index, const QStringList &activities) override; + + /** + * Request informing the window manager of new geometry for a visual + * delegate for the window at the given index. + * + * @param index An index in this window tasks model. + * @param geometry Visual delegate geometry in screen coordinates. + * @param delegate The delegate. + **/ + void requestPublishDelegateGeometry(const QModelIndex &index, const QRect &geometry, + QObject *delegate = nullptr) override; + +private: + class Private; + QScopedPointer d; +}; + +} + +#endif diff --git a/libtaskmanager/windowtasksmodel.cpp b/libtaskmanager/windowtasksmodel.cpp new file mode 100644 --- /dev/null +++ b/libtaskmanager/windowtasksmodel.cpp @@ -0,0 +1,203 @@ +/******************************************************************** +Copyright 2016 Eike Hein + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +*********************************************************************/ + +#include "windowtasksmodel.h" + +#include + +#include "waylandtasksmodel.h" +#if HAVE_X11 +#include "xwindowtasksmodel.h" +#endif + +#include + +namespace TaskManager +{ + +class WindowTasksModel::Private +{ +public: + Private(WindowTasksModel *q); + ~Private(); + + static int instanceCount; + static AbstractTasksModel* sourceTasksModel; + + void initSourceTasksModel(); + +private: + WindowTasksModel *q; +}; + +int WindowTasksModel::Private::instanceCount = 0; +AbstractTasksModel* WindowTasksModel::Private::sourceTasksModel = nullptr; + +WindowTasksModel::Private::Private(WindowTasksModel *q) + : q(q) +{ + ++instanceCount; +} + +WindowTasksModel::Private::~Private() +{ + --instanceCount; + + + if (!instanceCount) { + delete sourceTasksModel; + sourceTasksModel = nullptr; + } +} + +void WindowTasksModel::Private::initSourceTasksModel() +{ + if (!sourceTasksModel && KWindowSystem::isPlatformWayland()) { + sourceTasksModel = new WaylandTasksModel(); + } + +#if HAVE_X11 + if (!sourceTasksModel && KWindowSystem::isPlatformX11()) { + sourceTasksModel = new XWindowTasksModel(); + } +#endif + + q->setSourceModel(sourceTasksModel); +} + +WindowTasksModel::WindowTasksModel(QObject *parent) + : QIdentityProxyModel(parent) + , d(new Private(this)) +{ + d->initSourceTasksModel(); +} + +WindowTasksModel::~WindowTasksModel() +{ +} + +QHash WindowTasksModel::roleNames() const +{ + if (d->sourceTasksModel) { + return d->sourceTasksModel->roleNames(); + } + + return QHash(); +} + +void WindowTasksModel::requestActivate(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestActivate(mapToSource(index)); + } +} + +void WindowTasksModel::requestNewInstance(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestNewInstance(mapToSource(index)); + } +} + +void WindowTasksModel::requestClose(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestClose(mapToSource(index)); + } +} + +void WindowTasksModel::requestMove(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestMove(mapToSource(index)); + } +} + +void WindowTasksModel::requestResize(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestResize(mapToSource(index)); + } +} + +void WindowTasksModel::requestToggleMinimized(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestToggleMinimized(mapToSource(index)); + } +} + +void WindowTasksModel::requestToggleMaximized(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestToggleMaximized(mapToSource(index)); + } +} + +void WindowTasksModel::requestToggleKeepAbove(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestToggleKeepAbove(mapToSource(index)); + } +} + +void WindowTasksModel::requestToggleKeepBelow(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestToggleKeepBelow(mapToSource(index)); + } +} + +void WindowTasksModel::requestToggleFullScreen(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestToggleFullScreen(mapToSource(index)); + } +} + +void WindowTasksModel::requestToggleShaded(const QModelIndex &index) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestToggleShaded(mapToSource(index)); + } +} + +void WindowTasksModel::requestVirtualDesktop(const QModelIndex &index, qint32 desktop) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestVirtualDesktop(mapToSource(index), desktop); + } +} + +void WindowTasksModel::requestActivities(const QModelIndex &index, const QStringList &activities) +{ + if (d->sourceTasksModel && index.isValid() && index.model() == this) { + d->sourceTasksModel->requestActivities(mapToSource(index), activities); + } +} + +void WindowTasksModel::requestPublishDelegateGeometry(const QModelIndex &index, const QRect &geometry, QObject *delegate) +{ + if (index.isValid() && index.model() == this) { + d->sourceTasksModel->requestPublishDelegateGeometry(mapToSource(index), geometry, delegate); + } +} + +}