diff --git a/libtaskmanager/abstracttasksmodel.h b/libtaskmanager/abstracttasksmodel.h index 7f5dedc5c..8472388ef 100644 --- a/libtaskmanager/abstracttasksmodel.h +++ b/libtaskmanager/abstracttasksmodel.h @@ -79,7 +79,7 @@ public: IsVirtualDesktopChangeable, /**< requestVirtualDesktop (see below) available. */ VirtualDesktop, /**< Virtual desktop for the task (i.e. window). */ IsOnAllVirtualDesktops, /**< Task is on all virtual desktops. */ - ScreenGeometry, /**< Screen geometry for the task (i.e. the window's screen). */ + Screen, /**< Screen for the task (i.e. window). */ Activities, /**< Activities for the task (i.e. window). */ IsDemandingAttention, /**< Task is demanding attention. */ SkipTaskbar /**< Task desires not to be shown in a user interface. */ diff --git a/libtaskmanager/startuptasksmodel.cpp b/libtaskmanager/startuptasksmodel.cpp index 2847ffe98..3fda2db54 100644 --- a/libtaskmanager/startuptasksmodel.cpp +++ b/libtaskmanager/startuptasksmodel.cpp @@ -254,7 +254,11 @@ QVariant StartupTasksModel::data(const QModelIndex &index, int role) const return data.desktop(); } else if (role == IsOnAllVirtualDesktops) { return (data.desktop() == 0); - } + } /* else if (role == Screen) { + // You might be tempted to do this, but KStartupInfoData::screen() + // is actually the X11 screen. + return (data.screen() == 0); + } */ return QVariant(); } diff --git a/libtaskmanager/taskfilterproxymodel.cpp b/libtaskmanager/taskfilterproxymodel.cpp index 5acb79592..79b902e5b 100644 --- a/libtaskmanager/taskfilterproxymodel.cpp +++ b/libtaskmanager/taskfilterproxymodel.cpp @@ -32,7 +32,7 @@ public: AbstractTasksModelIface *sourceTasksModel = nullptr; uint virtualDesktop = 0; - QRect screenGeometry; + int screen = -1; QString activity; bool filterByVirtualDesktop = false; @@ -84,21 +84,21 @@ void TaskFilterProxyModel::setVirtualDesktop(uint virtualDesktop) } } -QRect TaskFilterProxyModel::screenGeometry() const +int TaskFilterProxyModel::screen() const { - return d->screenGeometry; + return d->screen; } -void TaskFilterProxyModel::setScreenGeometry(const QRect &geometry) +void TaskFilterProxyModel::setScreen(int screen) { - if (d->screenGeometry != geometry) { - d->screenGeometry = geometry; + if (d->screen != screen) { + d->screen = screen; if (d->filterByScreen) { invalidateFilter(); } - emit screenGeometryChanged(); + emit screenChanged(); } } @@ -303,11 +303,16 @@ bool TaskFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &so } // Filter by screen. - if (d->filterByScreen && d->screenGeometry.isValid()) { - const QRect &screenGeometry = sourceIdx.data(AbstractTasksModel::ScreenGeometry).toRect(); + if (d->filterByScreen && d->screen != -1) { + const QVariant &screen = sourceIdx.data(AbstractTasksModel::Screen); - if (screenGeometry.isValid() && screenGeometry != d->screenGeometry) { - return false; + if (!screen.isNull()) { + bool ok = false; + const int i = screen.toInt(&ok); + + if (ok && i != -1 && i != d->screen) { + return false; + } } } diff --git a/libtaskmanager/taskfilterproxymodel.h b/libtaskmanager/taskfilterproxymodel.h index 51b63fc99..ebe70b769 100644 --- a/libtaskmanager/taskfilterproxymodel.h +++ b/libtaskmanager/taskfilterproxymodel.h @@ -22,7 +22,6 @@ License along with this library. If not, see . #define TASKFILTERPROXYMODEL_H #include -#include #include "abstracttasksmodeliface.h" @@ -46,7 +45,7 @@ class TASKMANAGER_EXPORT TaskFilterProxyModel : public QSortFilterProxyModel, pu Q_OBJECT Q_PROPERTY(int virtualDesktop READ virtualDesktop WRITE setVirtualDesktop NOTIFY virtualDesktopChanged) - Q_PROPERTY(QRect screenGeomeyry READ screenGeometry WRITE setScreenGeometry NOTIFY screenGeometryChanged) + Q_PROPERTY(int screen READ screen WRITE setScreen NOTIFY screenChanged) Q_PROPERTY(QString activity READ activity WRITE setActivity NOTIFY activityChanged) Q_PROPERTY(bool filterByVirtualDesktop READ filterByVirtualDesktop WRITE setFilterByVirtualDesktop NOTIFY filterByVirtualDesktopChanged) @@ -83,23 +82,23 @@ public: void setVirtualDesktop(uint virtualDesktop); /** - * The geometry of the screen used in filtering by screen. Defaults - * to a null QRect. + * The number of the screen used in filtering by screen. Usually + * set to the number of the current screen. Defaults to @c -1. * - * @see setGeometryScreen - * @returns the geometry of the screen used in filtering. + * @see setScreen + * @returns the number of the screen used in filtering. **/ - QRect screenGeometry() const; + int screen() const; /** - * Set the geometry of the screen to use in filtering by screen. + * Set the number of the screen to use in filtering by screen. * - * If set to an invalid QRect, filtering by screen is disabled. + * If set to @c -1, filtering by screen is disabled. * - * @see screenGeometry - * @param geometry A screen geometry. + * @see screen + * @param screen A screen number. **/ - void setScreenGeometry(const QRect &geometry); + void setScreen(int screen); /** * The id of the activity used in filtering by activity. Usually @@ -341,7 +340,7 @@ public: Q_SIGNALS: void virtualDesktopChanged() const; - void screenGeometryChanged() const; + void screenChanged() const; void activityChanged() const; void filterByVirtualDesktopChanged() const; void filterByScreenChanged() const; diff --git a/libtaskmanager/taskgroupingproxymodel.cpp b/libtaskmanager/taskgroupingproxymodel.cpp index 69ea16a26..5839c52d7 100644 --- a/libtaskmanager/taskgroupingproxymodel.cpp +++ b/libtaskmanager/taskgroupingproxymodel.cpp @@ -742,7 +742,7 @@ QVariant TaskGroupingProxyModel::data(const QModelIndex &proxyIndex, int role) c // TODO: Nothing needs this for now and it would add complexity to // make it a list; skip it until needed. return QVariant(); - } else if (role == AbstractTasksModel::ScreenGeometry) { + } else if (role == AbstractTasksModel::Screen) { // TODO: Nothing needs this for now and it would add complexity to // make it a list; skip it until needed. return QVariant(); diff --git a/libtaskmanager/tasksmodel.cpp b/libtaskmanager/tasksmodel.cpp index 4e3286406..bf37042da 100644 --- a/libtaskmanager/tasksmodel.cpp +++ b/libtaskmanager/tasksmodel.cpp @@ -294,8 +294,8 @@ void TasksModel::Private::initModels() filterProxyModel->setSourceModel(concatProxyModel); QObject::connect(filterProxyModel, &TaskFilterProxyModel::virtualDesktopChanged, q, &TasksModel::virtualDesktopChanged); - QObject::connect(filterProxyModel, &TaskFilterProxyModel::screenGeometryChanged, - q, &TasksModel::screenGeometryChanged); + QObject::connect(filterProxyModel, &TaskFilterProxyModel::screenChanged, + q, &TasksModel::screenChanged); QObject::connect(filterProxyModel, &TaskFilterProxyModel::activityChanged, q, &TasksModel::activityChanged); QObject::connect(filterProxyModel, &TaskFilterProxyModel::filterByVirtualDesktopChanged, @@ -878,14 +878,14 @@ void TasksModel::setVirtualDesktop(int virtualDesktop) d->filterProxyModel->setVirtualDesktop(virtualDesktop); } -QRect TasksModel::screenGeometry() const +int TasksModel::screen() const { - return d->filterProxyModel->screenGeometry(); + return d->filterProxyModel->screen(); } -void TasksModel::setScreenGeometry(const QRect &geometry) +void TasksModel::setScreen(int screen) { - d->filterProxyModel->setScreenGeometry(geometry); + d->filterProxyModel->setScreen(screen); } QString TasksModel::activity() const diff --git a/libtaskmanager/tasksmodel.h b/libtaskmanager/tasksmodel.h index 303e69f9d..5f991bbef 100644 --- a/libtaskmanager/tasksmodel.h +++ b/libtaskmanager/tasksmodel.h @@ -68,7 +68,7 @@ class TASKMANAGER_EXPORT TasksModel : public QSortFilterProxyModel, public Abstr Q_PROPERTY(bool anyTaskDemandsAttention READ anyTaskDemandsAttention NOTIFY anyTaskDemandsAttentionChanged) Q_PROPERTY(int virtualDesktop READ virtualDesktop WRITE setVirtualDesktop NOTIFY virtualDesktopChanged) - Q_PROPERTY(QRect screenGeometry READ screenGeometry WRITE setScreenGeometry NOTIFY screenGeometryChanged) + Q_PROPERTY(int screen READ screen WRITE setScreen NOTIFY screenChanged) Q_PROPERTY(QString activity READ activity WRITE setActivity NOTIFY activityChanged) Q_PROPERTY(bool filterByVirtualDesktop READ filterByVirtualDesktop WRITE setFilterByVirtualDesktop NOTIFY filterByVirtualDesktopChanged) @@ -169,23 +169,23 @@ public: void setVirtualDesktop(int virtualDesktop); /** - * The geometry of the screen used in filtering by screen. Defaults - * to a null QRect. + * The number of the screen used in filtering by screen. Usually + * set to the number of the current screen. Defaults to @c -1. * - * @see setGeometryScreen - * @returns the geometry of the screen used in filtering. + * @see setScreen + * @returns the number of the screen used in filtering. **/ - QRect screenGeometry() const; + int screen() const; /** - * Set the geometry of the screen to use in filtering by screen. + * Set the number of the screen to use in filtering by screen. * - * If set to an invalid QRect, filtering by screen is disabled. + * If set to @c -1, filtering by screen is disabled. * - * @see screenGeometry - * @param geometry A screen geometry. + * @see screen + * @param screen A screen number. **/ - void setScreenGeometry(const QRect &geometry); + void setScreen(int screen); /** * The id of the activity used in filtering by activity. Usually @@ -755,7 +755,7 @@ Q_SIGNALS: void launcherListChanged() const; void anyTaskDemandsAttentionChanged() const; void virtualDesktopChanged() const; - void screenGeometryChanged() const; + void screenChanged() const; void activityChanged() const; void filterByVirtualDesktopChanged() const; void filterByScreenChanged() const; diff --git a/libtaskmanager/tasktools.cpp b/libtaskmanager/tasktools.cpp index 5ca456138..e11850e6e 100644 --- a/libtaskmanager/tasktools.cpp +++ b/libtaskmanager/tasktools.cpp @@ -30,8 +30,6 @@ License along with this library. If not, see . #include #include -#include -#include namespace TaskManager { @@ -241,35 +239,4 @@ bool appsMatch(const QModelIndex &a, const QModelIndex &b) return false; } -QRect screenGeometry(const QPoint &pos) -{ - if (pos.isNull()) { - return QRect(); - } - - const QList &screens = QGuiApplication::screens(); - QRect screenGeometry; - int shortestDistance = INT_MAX; - - for (int i = 0; i < screens.count(); ++i) { - const QRect &geometry = screens.at(i)->geometry(); - - if (geometry.contains(pos)) { - return geometry; - } - - int distance = QPoint(geometry.topLeft() - pos).manhattanLength(); - distance = qMin(distance, QPoint(geometry.topRight() - pos).manhattanLength()); - distance = qMin(distance, QPoint(geometry.bottomRight() - pos).manhattanLength()); - distance = qMin(distance, QPoint(geometry.bottomLeft() - pos).manhattanLength()); - - if (distance < shortestDistance) { - shortestDistance = distance; - screenGeometry = geometry; - } - } - - return screenGeometry; -} - } diff --git a/libtaskmanager/tasktools.h b/libtaskmanager/tasktools.h index da40f9eb7..122e23201 100644 --- a/libtaskmanager/tasktools.h +++ b/libtaskmanager/tasktools.h @@ -101,15 +101,6 @@ TASKMANAGER_EXPORT bool launcherUrlsMatch(const QUrl &a, const QUrl &b, UrlCompa * @returns @c true if the model entries belong to the same app. **/ TASKMANAGER_EXPORT bool appsMatch(const QModelIndex &a, const QModelIndex &b); - -/** - * Given global coordinates, returns the geometry of the screen they are - * on, or the geometry of the screen they are closest to. - * - * @param pos Coordinates in global space. - * @return The geometry of the screen containing pos or closest to pos. - */ -TASKMANAGER_EXPORT QRect screenGeometry(const QPoint &pos); } #endif diff --git a/libtaskmanager/waylandtasksmodel.cpp b/libtaskmanager/waylandtasksmodel.cpp index 5411dfb32..2cbdf188d 100644 --- a/libtaskmanager/waylandtasksmodel.cpp +++ b/libtaskmanager/waylandtasksmodel.cpp @@ -315,7 +315,7 @@ QVariant WaylandTasksModel::data(const QModelIndex &index, int role) const return window->virtualDesktop(); } else if (role == IsOnAllVirtualDesktops) { return window->isOnAllDesktops(); - } else if (role == ScreenGeometry) { + } else if (role == Screen) { // FIXME Implement. } else if (role == Activities) { // FIXME Implement. diff --git a/libtaskmanager/xwindowtasksmodel.cpp b/libtaskmanager/xwindowtasksmodel.cpp index 8f10cae0f..c1e949532 100644 --- a/libtaskmanager/xwindowtasksmodel.cpp +++ b/libtaskmanager/xwindowtasksmodel.cpp @@ -39,7 +39,9 @@ License along with this library. If not, see . #include #include #include +#include #include +#include #include #include #include @@ -88,6 +90,7 @@ public: QUrl launcherUrl(WId window, bool encodeFallbackIcon = true); QUrl serviceUrl(int pid, const QString &type, const QStringList &cmdRemovals); KService::List servicesFromPid(int pid); + int screen(WId window); QStringList activities(WId window); bool demandsAttention(WId window); @@ -375,7 +378,7 @@ void XWindowTasksModel::Private::windowChanged(WId window, NET::Properties prope if (properties & NET::WMGeometry) { wipeInfoCache = true; - changedRoles << ScreenGeometry; + changedRoles << Screen; } if (properties2 & NET::WM2Activities) { @@ -773,6 +776,34 @@ KService::List XWindowTasksModel::Private::servicesFromPid(int pid) return services; } +int XWindowTasksModel::Private::screen(WId window) +{ + const QPoint &windowCenter = windowInfo(window)->frameGeometry().center(); + const QList &screens = QGuiApplication::screens(); + int screen = 0; + int shortestDistance = INT_MAX; + + for (int i = 0; i < screens.count(); ++i) { + const QRect &screenGeomtry = screens.at(i)->geometry(); + + if (screenGeomtry.contains(windowCenter)) { + return i; + } + + int distance = QPoint(screenGeomtry.topLeft() - windowCenter).manhattanLength(); + distance = qMin(distance, QPoint(screenGeomtry.topRight() - windowCenter).manhattanLength()); + distance = qMin(distance, QPoint(screenGeomtry.bottomRight() - windowCenter).manhattanLength()); + distance = qMin(distance, QPoint(screenGeomtry.bottomLeft() - windowCenter).manhattanLength()); + + if (distance < shortestDistance) { + shortestDistance = distance; + screen = i; + } + } + + return screen; +} + QStringList XWindowTasksModel::Private::activities(WId window) { NETWinInfo ni(QX11Info::connection(), window, QX11Info::appRootWindow(), 0, NET::WM2Activities); @@ -872,8 +903,8 @@ QVariant XWindowTasksModel::data(const QModelIndex &index, int role) const return d->windowInfo(window)->desktop(); } else if (role == IsOnAllVirtualDesktops) { return d->windowInfo(window)->onAllDesktops(); - } else if (role == ScreenGeometry) { - return screenGeometry(d->windowInfo(window)->frameGeometry().center()); + } else if (role == Screen) { + return d->screen(window); } else if (role == Activities) { return d->activities(window); } else if (role == IsDemandingAttention) {