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
icc-effect-5.14.5
Martin Gräßlin 2016-11-07 10:55:18 +01:00
parent 002d667436
commit 4f4d9d5cfe
2 changed files with 107 additions and 28 deletions

View File

@ -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<uint>(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 {

View File

@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Qt includes
#include <QObject>
#include <QPoint>
#include <QPointer>
#include <QSize>
// KDE includes
#include <KConfig>
@ -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<VirtualDesktop*> m_desktops;
QPointer<VirtualDesktop> 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