diff --git a/libtaskmanager/abstracttasksmodel.h b/libtaskmanager/abstracttasksmodel.h --- a/libtaskmanager/abstracttasksmodel.h +++ b/libtaskmanager/abstracttasksmodel.h @@ -79,7 +79,7 @@ IsVirtualDesktopChangeable, /**< requestVirtualDesktop (see below) available. */ VirtualDesktop, /**< Virtual desktop for the task (i.e. window). */ IsOnAllVirtualDesktops, /**< Task is on all virtual desktops. */ - Screen, /**< Screen for the task (i.e. window). */ + ScreenGeometry, /**< Screen geometry for the task (i.e. the window's screen). */ 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 --- a/libtaskmanager/startuptasksmodel.cpp +++ b/libtaskmanager/startuptasksmodel.cpp @@ -254,11 +254,7 @@ 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.h b/libtaskmanager/taskfilterproxymodel.h --- a/libtaskmanager/taskfilterproxymodel.h +++ b/libtaskmanager/taskfilterproxymodel.h @@ -22,6 +22,7 @@ #define TASKFILTERPROXYMODEL_H #include +#include #include "abstracttasksmodeliface.h" @@ -45,7 +46,7 @@ Q_OBJECT Q_PROPERTY(int virtualDesktop READ virtualDesktop WRITE setVirtualDesktop NOTIFY virtualDesktopChanged) - Q_PROPERTY(int screen READ screen WRITE setScreen NOTIFY screenChanged) + Q_PROPERTY(QRect screenGeomeyry READ screenGeometry WRITE setScreenGeometry NOTIFY screenGeometryChanged) Q_PROPERTY(QString activity READ activity WRITE setActivity NOTIFY activityChanged) Q_PROPERTY(bool filterByVirtualDesktop READ filterByVirtualDesktop WRITE setFilterByVirtualDesktop NOTIFY filterByVirtualDesktopChanged) @@ -82,23 +83,23 @@ void setVirtualDesktop(uint virtualDesktop); /** - * The number of the screen used in filtering by screen. Usually - * set to the number of the current screen. Defaults to @c -1. + * The geometry of the screen used in filtering by screen. Defaults + * to a null QRect. * - * @see setScreen - * @returns the number of the screen used in filtering. + * @see setGeometryScreen + * @returns the geometry of the screen used in filtering. **/ - int screen() const; + QRect screenGeometry() const; /** - * Set the number of the screen to use in filtering by screen. + * Set the geometry of the screen to use in filtering by screen. * - * If set to @c -1, filtering by screen is disabled. + * If set to an invalid QRect, filtering by screen is disabled. * - * @see screen - * @param screen A screen number. + * @see screenGeometry + * @param geometry A screen geometry. **/ - void setScreen(int screen); + void setScreenGeometry(const QRect &geometry); /** * The id of the activity used in filtering by activity. Usually @@ -340,7 +341,7 @@ Q_SIGNALS: void virtualDesktopChanged() const; - void screenChanged() const; + void screenGeometryChanged() const; void activityChanged() const; void filterByVirtualDesktopChanged() const; void filterByScreenChanged() const; diff --git a/libtaskmanager/taskfilterproxymodel.cpp b/libtaskmanager/taskfilterproxymodel.cpp --- a/libtaskmanager/taskfilterproxymodel.cpp +++ b/libtaskmanager/taskfilterproxymodel.cpp @@ -32,7 +32,7 @@ AbstractTasksModelIface *sourceTasksModel = nullptr; uint virtualDesktop = 0; - int screen = -1; + QRect screenGeometry; QString activity; bool filterByVirtualDesktop = false; @@ -84,21 +84,21 @@ } } -int TaskFilterProxyModel::screen() const +QRect TaskFilterProxyModel::screenGeometry() const { - return d->screen; + return d->screenGeometry; } -void TaskFilterProxyModel::setScreen(int screen) +void TaskFilterProxyModel::setScreenGeometry(const QRect &geometry) { - if (d->screen != screen) { - d->screen = screen; + if (d->screenGeometry != geometry) { + d->screenGeometry = geometry; if (d->filterByScreen) { invalidateFilter(); } - emit screenChanged(); + emit screenGeometryChanged(); } } @@ -303,16 +303,11 @@ } // Filter by screen. - if (d->filterByScreen && d->screen != -1) { - const QVariant &screen = sourceIdx.data(AbstractTasksModel::Screen); + if (d->filterByScreen && d->screenGeometry.isValid()) { + const QRect &screenGeometry = sourceIdx.data(AbstractTasksModel::ScreenGeometry).toRect(); - if (!screen.isNull()) { - bool ok = false; - const int i = screen.toInt(&ok); - - if (ok && i != -1 && i != d->screen) { - return false; - } + if (screenGeometry.isValid() && screenGeometry != d->screenGeometry) { + return false; } } diff --git a/libtaskmanager/taskgroupingproxymodel.cpp b/libtaskmanager/taskgroupingproxymodel.cpp --- a/libtaskmanager/taskgroupingproxymodel.cpp +++ b/libtaskmanager/taskgroupingproxymodel.cpp @@ -742,7 +742,7 @@ // 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::Screen) { + } else if (role == AbstractTasksModel::ScreenGeometry) { // 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.h b/libtaskmanager/tasksmodel.h --- a/libtaskmanager/tasksmodel.h +++ b/libtaskmanager/tasksmodel.h @@ -68,7 +68,7 @@ Q_PROPERTY(bool anyTaskDemandsAttention READ anyTaskDemandsAttention NOTIFY anyTaskDemandsAttentionChanged) Q_PROPERTY(int virtualDesktop READ virtualDesktop WRITE setVirtualDesktop NOTIFY virtualDesktopChanged) - Q_PROPERTY(int screen READ screen WRITE setScreen NOTIFY screenChanged) + Q_PROPERTY(QRect screenGeometry READ screenGeometry WRITE setScreenGeometry NOTIFY screenGeometryChanged) Q_PROPERTY(QString activity READ activity WRITE setActivity NOTIFY activityChanged) Q_PROPERTY(bool filterByVirtualDesktop READ filterByVirtualDesktop WRITE setFilterByVirtualDesktop NOTIFY filterByVirtualDesktopChanged) @@ -169,23 +169,23 @@ void setVirtualDesktop(int virtualDesktop); /** - * The number of the screen used in filtering by screen. Usually - * set to the number of the current screen. Defaults to @c -1. + * The geometry of the screen used in filtering by screen. Defaults + * to a null QRect. * - * @see setScreen - * @returns the number of the screen used in filtering. + * @see setGeometryScreen + * @returns the geometry of the screen used in filtering. **/ - int screen() const; + QRect screenGeometry() const; /** - * Set the number of the screen to use in filtering by screen. + * Set the geometry of the screen to use in filtering by screen. * - * If set to @c -1, filtering by screen is disabled. + * If set to an invalid QRect, filtering by screen is disabled. * - * @see screen - * @param screen A screen number. + * @see screenGeometry + * @param geometry A screen geometry. **/ - void setScreen(int screen); + void setScreenGeometry(const QRect &geometry); /** * The id of the activity used in filtering by activity. Usually @@ -755,7 +755,7 @@ void launcherListChanged() const; void anyTaskDemandsAttentionChanged() const; void virtualDesktopChanged() const; - void screenChanged() const; + void screenGeometryChanged() const; void activityChanged() const; void filterByVirtualDesktopChanged() const; void filterByScreenChanged() const; diff --git a/libtaskmanager/tasksmodel.cpp b/libtaskmanager/tasksmodel.cpp --- a/libtaskmanager/tasksmodel.cpp +++ b/libtaskmanager/tasksmodel.cpp @@ -294,8 +294,8 @@ filterProxyModel->setSourceModel(concatProxyModel); QObject::connect(filterProxyModel, &TaskFilterProxyModel::virtualDesktopChanged, q, &TasksModel::virtualDesktopChanged); - QObject::connect(filterProxyModel, &TaskFilterProxyModel::screenChanged, - q, &TasksModel::screenChanged); + QObject::connect(filterProxyModel, &TaskFilterProxyModel::screenGeometryChanged, + q, &TasksModel::screenGeometryChanged); QObject::connect(filterProxyModel, &TaskFilterProxyModel::activityChanged, q, &TasksModel::activityChanged); QObject::connect(filterProxyModel, &TaskFilterProxyModel::filterByVirtualDesktopChanged, @@ -878,14 +878,14 @@ d->filterProxyModel->setVirtualDesktop(virtualDesktop); } -int TasksModel::screen() const +QRect TasksModel::screenGeometry() const { - return d->filterProxyModel->screen(); + return d->filterProxyModel->screenGeometry(); } -void TasksModel::setScreen(int screen) +void TasksModel::setScreenGeometry(const QRect &geometry) { - d->filterProxyModel->setScreen(screen); + d->filterProxyModel->setScreenGeometry(geometry); } QString TasksModel::activity() const diff --git a/libtaskmanager/tasktools.h b/libtaskmanager/tasktools.h --- a/libtaskmanager/tasktools.h +++ b/libtaskmanager/tasktools.h @@ -101,6 +101,15 @@ * @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/tasktools.cpp b/libtaskmanager/tasktools.cpp --- a/libtaskmanager/tasktools.cpp +++ b/libtaskmanager/tasktools.cpp @@ -30,6 +30,8 @@ #include #include +#include +#include namespace TaskManager { @@ -239,4 +241,35 @@ 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/waylandtasksmodel.cpp b/libtaskmanager/waylandtasksmodel.cpp --- a/libtaskmanager/waylandtasksmodel.cpp +++ b/libtaskmanager/waylandtasksmodel.cpp @@ -315,7 +315,7 @@ return window->virtualDesktop(); } else if (role == IsOnAllVirtualDesktops) { return window->isOnAllDesktops(); - } else if (role == Screen) { + } else if (role == ScreenGeometry) { // FIXME Implement. } else if (role == Activities) { // FIXME Implement. diff --git a/libtaskmanager/xwindowtasksmodel.cpp b/libtaskmanager/xwindowtasksmodel.cpp --- a/libtaskmanager/xwindowtasksmodel.cpp +++ b/libtaskmanager/xwindowtasksmodel.cpp @@ -39,9 +39,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -90,7 +88,6 @@ 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); @@ -378,7 +375,7 @@ if (properties & NET::WMGeometry) { wipeInfoCache = true; - changedRoles << Screen; + changedRoles << ScreenGeometry; } if (properties2 & NET::WM2Activities) { @@ -776,34 +773,6 @@ 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); @@ -903,8 +872,8 @@ return d->windowInfo(window)->desktop(); } else if (role == IsOnAllVirtualDesktops) { return d->windowInfo(window)->onAllDesktops(); - } else if (role == Screen) { - return d->screen(window); + } else if (role == ScreenGeometry) { + return screenGeometry(d->windowInfo(window)->frameGeometry().center()); } else if (role == Activities) { return d->activities(window); } else if (role == IsDemandingAttention) {