From 4f4d9d5cfe403eda985607596fd08a926480bb05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 7 Nov 2016 10:55:18 +0100 Subject: [PATCH] Introduce a VirtualDesktop class Summary: This is the first change for a larger virtual desktop refactoring. So far for X11 virtual desktops are just a number. The current virtual desktop is a number between 1 and the count of virtual desktops. Similar a Toplevel is on the virtual desktop by setting the number as a property. In the long run we want to change that and allow to have windows on multiple virtual desktops and also support virtual desktops on Wayland. On Wayland a virtual desktop will be an object. As a first step a VirtualDesktop class is introduced which currently is just a glorifed wrapper around the x11 desktop number. The VirtualDesktopManager now holds a pointer to the current desktop and the available desktops are a QVector of VirtualDesktops. The implicit mapping to counting of desktops is removed. Though the internal API is still completely count based. In follow up changes this will be turned into being more and more VirtualDesktop based. At least the Core should be completely transferred to be VirtualDesktop based instead of uint based. Test Plan: virtual desktop auto test still passes (test coverage 97 % line, 83 % conditionals) Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D3290 --- virtualdesktops.cpp | 84 +++++++++++++++++++++++++++++++++++---------- virtualdesktops.h | 51 +++++++++++++++++++++------ 2 files changed, 107 insertions(+), 28 deletions(-) diff --git a/virtualdesktops.cpp b/virtualdesktops.cpp index c51958d21e..55c3d0cb04 100644 --- a/virtualdesktops.cpp +++ b/virtualdesktops.cpp @@ -32,6 +32,34 @@ namespace KWin { extern int screen_number; +VirtualDesktop::VirtualDesktop(QObject *parent) + : QObject(parent) +{ +} + +VirtualDesktop::~VirtualDesktop() = default; + +void VirtualDesktop::setId(const QByteArray &id) +{ + Q_ASSERT(m_id.isEmpty()); + m_id = id; +} + +void VirtualDesktop::setX11DesktopNumber(uint number) +{ + Q_ASSERT(m_x11DesktopNumber == 0); + m_x11DesktopNumber = number; +} + +void VirtualDesktop::setName(const QString &name) +{ + if (m_name == name) { + return; + } + m_name = name; + emit nameChanged(); +} + VirtualDesktopGrid::VirtualDesktopGrid() : m_size(1, 2) // Default to tow rows , m_grid(new uint[2]) @@ -90,8 +118,6 @@ KWIN_SINGLETON_FACTORY_VARIABLE(VirtualDesktopManager, s_manager) VirtualDesktopManager::VirtualDesktopManager(QObject *parent) : QObject(parent) - , m_current(0) - , m_count(0) , m_navigationWrapsAround(false) , m_rootInfo(NULL) { @@ -237,14 +263,26 @@ uint VirtualDesktopManager::previous(uint id, bool wrap) const return desktop; } +uint VirtualDesktopManager::current() const +{ + return m_current ? m_current->x11DesktopNumber() : 0; +} + bool VirtualDesktopManager::setCurrent(uint newDesktop) { - if (newDesktop < 1 || newDesktop > count() || newDesktop == m_current) { + if (newDesktop < 1 || newDesktop > count() || newDesktop == current()) { return false; } - const uint oldDesktop = m_current; + auto it = std::find_if(m_desktops.constBegin(), m_desktops.constEnd(), + [newDesktop] (VirtualDesktop *d) { + return d->x11DesktopNumber() == newDesktop; + } + ); + Q_ASSERT(it != m_desktops.constEnd()); + const uint oldDesktop = current(); + // change the desktop - m_current = newDesktop; + m_current = *it; emit currentChanged(oldDesktop, newDesktop); return true; } @@ -252,26 +290,35 @@ bool VirtualDesktopManager::setCurrent(uint newDesktop) void VirtualDesktopManager::setCount(uint count) { count = qBound(1, count, VirtualDesktopManager::maximum()); - if (count == m_count) { + if (count == uint(m_desktops.count())) { // nothing to change return; } - const uint oldCount = m_count; - m_count = count; - - if (oldCount > m_count) { - handleDesktopsRemoved(oldCount); + const uint oldCount = m_desktops.count(); + const uint oldCurrent = current(); + while (uint(m_desktops.count()) > count) { + delete m_desktops.takeLast(); } + while (uint(m_desktops.count()) < count) { + auto vd = new VirtualDesktop(this); + vd->setX11DesktopNumber(m_desktops.count() + 1); + m_desktops << vd; + } + if (oldCount > count) { + handleDesktopsRemoved(oldCount, oldCurrent); + } + updateRootInfo(); save(); - emit countChanged(oldCount, m_count); + emit countChanged(oldCount, m_desktops.count()); } -void VirtualDesktopManager::handleDesktopsRemoved(uint previousCount) +void VirtualDesktopManager::handleDesktopsRemoved(uint previousCount, uint previousCurrent) { - if (current() > count()) { - setCurrent(count()); + if (!m_current) { + m_current = m_desktops.last(); + emit currentChanged(previousCurrent, m_current->x11DesktopNumber()); } emit desktopsRemoved(previousCount); } @@ -399,15 +446,16 @@ QString VirtualDesktopManager::defaultName(int desktop) const void VirtualDesktopManager::setNETDesktopLayout(Qt::Orientation orientation, uint width, uint height, int startingCorner) { Q_UNUSED(startingCorner); // Not really worth implementing right now. + const uint count = m_desktops.count(); // Calculate valid grid size Q_ASSERT(width > 0 || height > 0); if ((width <= 0) && (height > 0)) { - width = (m_count + height - 1) / height; + width = (count + height - 1) / height; } else if ((height <= 0) && (width > 0)) { - height = (m_count + width - 1) / width; + height = (count + width - 1) / width; } - while (width * height < m_count) { + while (width * height < count) { if (orientation == Qt::Horizontal) { ++width; } else { diff --git a/virtualdesktops.h b/virtualdesktops.h index 0d9f1277ac..7454000709 100644 --- a/virtualdesktops.h +++ b/virtualdesktops.h @@ -24,6 +24,7 @@ along with this program. If not, see . // Qt includes #include #include +#include #include // KDE includes #include @@ -34,6 +35,41 @@ class NETRootInfo; namespace KWin { +class VirtualDesktop : public QObject +{ + Q_OBJECT + Q_PROPERTY(QByteArray id READ id CONSTANT) + Q_PROPERTY(uint x11DesktopNumber READ x11DesktopNumber CONSTANT) + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) +public: + explicit VirtualDesktop(QObject *parent = nullptr); + virtual ~VirtualDesktop(); + + void setId(const QByteArray &id); + QByteArray id() const { + return m_id; + } + + void setName(const QString &name); + QString name() const { + return m_name; + } + + void setX11DesktopNumber(uint number); + uint x11DesktopNumber() const { + return m_x11DesktopNumber; + } + +Q_SIGNALS: + void nameChanged(); + +private: + QByteArray m_id; + QString m_name; + int m_x11DesktopNumber = 0; + +}; + /** * @brief Two dimensional grid containing the ID of the virtual desktop at a specific position * in the grid. @@ -309,10 +345,11 @@ private: * Emits the signal @link desktopsRemoved. * * @param previousCount The number of desktops prior to the change. + * @param previousCurrent The number of the previously current desktop. * @see setCount * @see desktopsRemoved **/ - void handleDesktopsRemoved(uint previousCount); + void handleDesktopsRemoved(uint previousCount, uint previousCurrent); /** * Generate a desktop layout from EWMH _NET_DESKTOP_LAYOUT property parameters. */ @@ -350,8 +387,8 @@ private: **/ void addAction(const QString &name, const QString &label, void (VirtualDesktopManager::*slot)()); - uint m_current; - uint m_count; + QVector m_desktops; + QPointer m_current; bool m_navigationWrapsAround; VirtualDesktopGrid m_grid; // TODO: QPointer @@ -520,16 +557,10 @@ uint VirtualDesktopManager::maximum() return 20; } -inline -uint VirtualDesktopManager::current() const -{ - return m_current; -} - inline uint VirtualDesktopManager::count() const { - return m_count; + return m_desktops.count(); } inline