diff --git a/org.kde.KWin.VirtualDesktopManager.xml b/org.kde.KWin.VirtualDesktopManager.xml
new file mode 100644
index 000000000..caffd3f10
--- /dev/null
+++ b/org.kde.KWin.VirtualDesktopManager.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/virtualdesktops.cpp b/virtualdesktops.cpp
index f13f99482..6a48c2701 100644
--- a/virtualdesktops.cpp
+++ b/virtualdesktops.cpp
@@ -1,783 +1,889 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 Lucas Murray
Copyright (C) 2012 Martin Gräßlin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*********************************************************************/
#include "virtualdesktops.h"
#include "input.h"
// KDE
#include
#include
#include
#include
// Qt
#include
#include
#include
#include
namespace KWin {
extern int screen_number;
VirtualDesktop::VirtualDesktop(QObject *parent)
: QObject(parent)
{
}
VirtualDesktop::~VirtualDesktop()
{
emit aboutToBeDestroyed();
}
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(QVector>{QVector{}, QVector{}})
{
}
VirtualDesktopGrid::~VirtualDesktopGrid() = default;
void VirtualDesktopGrid::update(const QSize &size, Qt::Orientation orientation, const QVector &desktops)
{
// Set private variables
m_size = size;
const uint width = size.width();
const uint height = size.height();
m_grid.clear();
auto it = desktops.begin();
auto end = desktops.end();
if (orientation == Qt::Horizontal) {
for (uint y = 0; y < height; ++y) {
QVector row;
for (uint x = 0; x < width && it != end; ++x) {
row << *it;
it++;
}
m_grid << row;
}
} else {
for (uint y = 0; y < height; ++y) {
m_grid << QVector();
}
for (uint x = 0; x < width; ++x) {
for (uint y = 0; y < height && it != end; ++y) {
auto &row = m_grid[y];
row << *it;
it++;
}
}
}
}
QPoint VirtualDesktopGrid::gridCoords(uint id) const
{
return gridCoords(VirtualDesktopManager::self()->desktopForX11Id(id));
}
QPoint VirtualDesktopGrid::gridCoords(VirtualDesktop *vd) const
{
for (int y = 0; y < m_grid.count(); ++y) {
const auto &row = m_grid.at(y);
for (int x = 0; x < row.count(); ++x) {
if (row.at(x) == vd) {
return QPoint(x, y);
}
}
}
return QPoint(-1, -1);
}
VirtualDesktop *VirtualDesktopGrid::at(const QPoint &coords) const
{
if (coords.y() >= m_grid.count()) {
return nullptr;
}
const auto &row = m_grid.at(coords.y());
if (coords.x() >= row.count()) {
return nullptr;
}
return row.at(coords.x());
}
KWIN_SINGLETON_FACTORY_VARIABLE(VirtualDesktopManager, s_manager)
VirtualDesktopManager::VirtualDesktopManager(QObject *parent)
: QObject(parent)
, m_navigationWrapsAround(false)
, m_rootInfo(NULL)
{
}
VirtualDesktopManager::~VirtualDesktopManager()
{
s_manager = NULL;
}
QString VirtualDesktopManager::name(uint desktop) const
{
if (!m_rootInfo) {
return defaultName(desktop);
}
return QString::fromUtf8(m_rootInfo->desktopName(desktop));
}
uint VirtualDesktopManager::above(uint id, bool wrap) const
{
auto vd = above(desktopForX11Id(id), wrap);
return vd ? vd->x11DesktopNumber() : 0;
}
VirtualDesktop *VirtualDesktopManager::above(VirtualDesktop *desktop, bool wrap) const
{
Q_ASSERT(m_current);
if (!desktop) {
desktop = m_current;
}
QPoint coords = m_grid.gridCoords(desktop);
Q_ASSERT(coords.x() >= 0);
while (true) {
coords.ry()--;
if (coords.y() < 0) {
if (wrap) {
coords.setY(m_grid.height() - 1);
} else {
return desktop; // Already at the top-most desktop
}
}
if (VirtualDesktop *vd = m_grid.at(coords)) {
return vd;
}
}
return nullptr;
}
uint VirtualDesktopManager::toRight(uint id, bool wrap) const
{
auto vd = toRight(desktopForX11Id(id), wrap);
return vd ? vd->x11DesktopNumber() : 0;
}
VirtualDesktop *VirtualDesktopManager::toRight(VirtualDesktop *desktop, bool wrap) const
{
Q_ASSERT(m_current);
if (!desktop) {
desktop = m_current;
}
QPoint coords = m_grid.gridCoords(desktop);
Q_ASSERT(coords.x() >= 0);
while (true) {
coords.rx()++;
if (coords.x() >= m_grid.width()) {
if (wrap) {
coords.setX(0);
} else {
return desktop; // Already at the right-most desktop
}
}
if (VirtualDesktop *vd = m_grid.at(coords)) {
return vd;
}
}
return nullptr;
}
uint VirtualDesktopManager::below(uint id, bool wrap) const
{
auto vd = below(desktopForX11Id(id), wrap);
return vd ? vd->x11DesktopNumber() : 0;
}
VirtualDesktop *VirtualDesktopManager::below(VirtualDesktop *desktop, bool wrap) const
{
Q_ASSERT(m_current);
if (!desktop) {
desktop = m_current;
}
QPoint coords = m_grid.gridCoords(desktop);
Q_ASSERT(coords.x() >= 0);
while (true) {
coords.ry()++;
if (coords.y() >= m_grid.height()) {
if (wrap) {
coords.setY(0);
} else {
// Already at the bottom-most desktop
return desktop;
}
}
if (VirtualDesktop *vd = m_grid.at(coords)) {
return vd;
}
}
return nullptr;
}
uint VirtualDesktopManager::toLeft(uint id, bool wrap) const
{
auto vd = toLeft(desktopForX11Id(id), wrap);
return vd ? vd->x11DesktopNumber() : 0;
}
VirtualDesktop *VirtualDesktopManager::toLeft(VirtualDesktop *desktop, bool wrap) const
{
Q_ASSERT(m_current);
if (!desktop) {
desktop = m_current;
}
QPoint coords = m_grid.gridCoords(desktop);
Q_ASSERT(coords.x() >= 0);
while (true) {
coords.rx()--;
if (coords.x() < 0) {
if (wrap) {
coords.setX(m_grid.width() - 1);
} else {
return desktop; // Already at the left-most desktop
}
}
if (VirtualDesktop *vd = m_grid.at(coords)) {
return vd;
}
}
return nullptr;
}
VirtualDesktop *VirtualDesktopManager::next(VirtualDesktop *desktop, bool wrap) const
{
Q_ASSERT(m_current);
if (!desktop) {
desktop = m_current;
}
auto it = std::find(m_desktops.begin(), m_desktops.end(), desktop);
Q_ASSERT(it != m_desktops.end());
it++;
if (it == m_desktops.end()) {
if (wrap) {
return m_desktops.first();
} else {
return desktop;
}
}
return *it;
}
VirtualDesktop *VirtualDesktopManager::previous(VirtualDesktop *desktop, bool wrap) const
{
Q_ASSERT(m_current);
if (!desktop) {
desktop = m_current;
}
auto it = std::find(m_desktops.begin(), m_desktops.end(), desktop);
Q_ASSERT(it != m_desktops.end());
if (it == m_desktops.begin()) {
if (wrap) {
return m_desktops.last();
} else {
return desktop;
}
}
it--;
return *it;
}
VirtualDesktop *VirtualDesktopManager::desktopForX11Id(uint id) const
{
if (id == 0 || id > count()) {
return nullptr;
}
return m_desktops.at(id - 1);
}
VirtualDesktop *VirtualDesktopManager::desktopForId(const QByteArray &id) const
{
auto desk = std::find_if(
m_desktops.constBegin(),
m_desktops.constEnd(),
[id] (const VirtualDesktop *desk ) {
return desk->id() == id;
}
);
if (desk != m_desktops.constEnd()) {
return *desk;
}
return nullptr;
}
VirtualDesktop *VirtualDesktopManager::createVirtualDesktop(uint number, const QString &name)
{
//too many, can't insert new ones
if ((uint)m_desktops.count() == VirtualDesktopManager::maximum()) {
return nullptr;
}
const uint actualNumber = qBound(0, number, VirtualDesktopManager::maximum());
auto *vd = new VirtualDesktop(this);
vd->setX11DesktopNumber(actualNumber);
//TODO: depend on Qt 5.11, use toString(QUuid::WithoutBraces)
vd->setId(QUuid::createUuid().toString().toUtf8());
vd->setName(name);
if (m_rootInfo) {
connect(vd, &VirtualDesktop::nameChanged, this,
[this, vd]() {
if (m_rootInfo) {
m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data());
}
}
);
m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data());
}
//update the id of displaced desktops
for (uint i = actualNumber; i < (uint)m_desktops.count(); ++i) {
m_desktops[i]->setX11DesktopNumber(i + 1);
if (m_rootInfo) {
m_rootInfo->setDesktopName(i + 1, m_desktops[i]->name().toUtf8().data());
}
}
m_desktops.insert(actualNumber - 1, vd);
save();
emit desktopCreated(vd);
emit countChanged(m_desktops.count()-1, m_desktops.count());
return vd;
}
void VirtualDesktopManager::removeVirtualDesktop(const QByteArray &id)
{
//don't end up without any desktop
if (m_desktops.count() == 1) {
return;
}
auto desktop = desktopForId(id);
if (!desktop) {
return;
}
const uint oldCurrent = m_current->x11DesktopNumber();
const uint i = desktop->x11DesktopNumber() - 1;
m_desktops.remove(i);
for (uint j = i; j < (uint)m_desktops.count(); ++j) {
m_desktops[j]->setX11DesktopNumber(j + 1);
if (m_rootInfo) {
m_rootInfo->setDesktopName(j + 1, m_desktops[j]->name().toUtf8().data());
}
}
const uint newCurrent = qMin(oldCurrent, (uint)m_desktops.count());
m_current = m_desktops.at(newCurrent - 1);
if (oldCurrent != newCurrent) {
emit currentChanged(oldCurrent, newCurrent);
}
emit desktopRemoved(desktop);
desktop->deleteLater();
}
uint VirtualDesktopManager::current() const
{
return m_current ? m_current->x11DesktopNumber() : 0;
}
VirtualDesktop *VirtualDesktopManager::currentDesktop() const
{
return m_current;
}
bool VirtualDesktopManager::setCurrent(uint newDesktop)
{
if (newDesktop < 1 || newDesktop > count() || newDesktop == current()) {
return false;
}
auto d = desktopForX11Id(newDesktop);
Q_ASSERT(d);
return setCurrent(d);
}
bool VirtualDesktopManager::setCurrent(VirtualDesktop *newDesktop)
{
Q_ASSERT(newDesktop);
if (m_current == newDesktop) {
return false;
}
const uint oldDesktop = current();
m_current = newDesktop;
emit currentChanged(oldDesktop, newDesktop->x11DesktopNumber());
return true;
}
void VirtualDesktopManager::setCount(uint count)
{
count = qBound(1, count, VirtualDesktopManager::maximum());
if (count == uint(m_desktops.count())) {
// nothing to change
return;
}
QList newDesktops;
const uint oldCount = m_desktops.count();
//this explicit check makes it more readable
if ((uint)m_desktops.count() > count) {
const auto desktopsToRemove = m_desktops.mid(count-1);
m_desktops.resize(count);
int oldCurrent = current();
for (auto desktop : desktopsToRemove) {
emit desktopRemoved(desktop);
desktop->deleteLater();
}
int newCurrent = qMin(oldCurrent, m_desktops.count());
m_current = m_desktops.at(newCurrent - 1);
if (oldCurrent != newCurrent) {
emit currentChanged(oldCurrent, newCurrent);
}
} else {
while (uint(m_desktops.count()) < count) {
auto vd = new VirtualDesktop(this);
vd->setX11DesktopNumber(m_desktops.count() + 1);
if (!m_isLoading) {
vd->setId(QUuid::createUuid().toString().toUtf8());
}
m_desktops << vd;
newDesktops << vd;
if (m_rootInfo) {
connect(vd, &VirtualDesktop::nameChanged, this,
[this, vd]() {
if (m_rootInfo) {
m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data());
}
}
);
m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data());
}
}
}
updateRootInfo();
save();
for (auto vd : newDesktops) {
emit desktopCreated(vd);
}
emit countChanged(oldCount, m_desktops.count());
}
void VirtualDesktopManager::updateRootInfo()
{
if (!m_rootInfo) {
// Make sure the layout is still valid
updateLayout();
return;
}
const int n = count();
m_rootInfo->setNumberOfDesktops(n);
NETPoint *viewports = new NETPoint[n];
m_rootInfo->setDesktopViewport(n, *viewports);
delete[] viewports;
// Make sure the layout is still valid
updateLayout();
}
void VirtualDesktopManager::updateLayout()
{
int width = 0;
int height = 0;
Qt::Orientation orientation = Qt::Horizontal;
if (m_rootInfo) {
// TODO: Is there a sane way to avoid overriding the existing grid?
width = m_rootInfo->desktopLayoutColumnsRows().width();
height = m_rootInfo->desktopLayoutColumnsRows().height();
orientation = m_rootInfo->desktopLayoutOrientation() == NET::OrientationHorizontal ? Qt::Horizontal : Qt::Vertical;
}
if (width == 0 && height == 0) {
// Not given, set default layout
height = count() == 1u ? 1 : 2;
}
setNETDesktopLayout(orientation,
width, height, 0 //rootInfo->desktopLayoutCorner() // Not really worth implementing right now.
);
}
static bool s_loadingDesktopSettings = false;
void VirtualDesktopManager::load()
{
s_loadingDesktopSettings = true;
if (!m_config) {
return;
}
//FIXME: how to avoid this?
m_isLoading = true;
QString groupname;
if (screen_number == 0) {
groupname = QStringLiteral("Desktops");
} else {
groupname.sprintf("Desktops-screen-%d", screen_number);
}
KConfigGroup group(m_config, groupname);
const int n = group.readEntry("Number", 1);
setCount(n);
//Use kactivitymanagerdrc directly?
for (int i = 1; i <= n; i++) {
QString s = group.readEntry(QStringLiteral("Name_%1").arg(i), i18n("Desktop %1", i));
if (m_rootInfo) {
m_rootInfo->setDesktopName(i, s.toUtf8().data());
}
m_desktops[i-1]->setName(s.toUtf8().data());
s = group.readEntry(QStringLiteral("Id_%1").arg(i), QString());
if (s.isEmpty()) {
s = QUuid::createUuid().toString();
}
//load gets called 2 times, see workspace.cpp line 416 and BUG 385260
if (m_desktops[i-1]->id().isEmpty()) {
m_desktops[i-1]->setId(s.toUtf8().data());
} else {
Q_ASSERT(m_desktops[i-1]->id() == s.toUtf8().data());
}
// TODO: update desktop focus chain, why?
// m_desktopFocusChain.value()[i-1] = i;
}
if (m_rootInfo) {
int rows = group.readEntry("Rows", 2);
rows = qBound(1, rows, n);
// avoid weird cases like having 3 rows for 4 desktops, where the last row is unused
int columns = n / rows;
if (n % rows > 0) {
columns++;
}
m_rootInfo->setDesktopLayout(NET::OrientationHorizontal, columns, rows, NET::DesktopLayoutCornerTopLeft);
m_rootInfo->activate();
}
s_loadingDesktopSettings = false;
m_isLoading = false;
}
void VirtualDesktopManager::save()
{
if (s_loadingDesktopSettings) {
return;
}
if (!m_config) {
return;
}
QString groupname;
if (screen_number == 0) {
groupname = QStringLiteral("Desktops");
} else {
groupname.sprintf("Desktops-screen-%d", screen_number);
}
KConfigGroup group(m_config, groupname);
group.writeEntry("Number", count());
for (uint i = 1; i <= count(); ++i) {
QString s = name(i);
const QString defaultvalue = defaultName(i);
if (s.isEmpty()) {
s = defaultvalue;
if (m_rootInfo) {
m_rootInfo->setDesktopName(i, s.toUtf8().data());
}
}
if (s != defaultvalue) {
group.writeEntry(QStringLiteral("Name_%1").arg(i), s);
} else {
QString currentvalue = group.readEntry(QStringLiteral("Name_%1").arg(i), QString());
if (currentvalue != defaultvalue) {
group.deleteEntry(QStringLiteral("Name_%1").arg(i));
}
}
group.writeEntry(QStringLiteral("Id_%1").arg(i), m_desktops[i-1]->id());
}
// Save to disk
group.sync();
}
QString VirtualDesktopManager::defaultName(int desktop) const
{
return i18n("Desktop %1", desktop);
}
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 = (count + height - 1) / height;
} else if ((height <= 0) && (width > 0)) {
height = (count + width - 1) / width;
}
while (width * height < count) {
if (orientation == Qt::Horizontal) {
++width;
} else {
++height;
}
}
m_grid.update(QSize(width, height), orientation, m_desktops);
// TODO: why is there no call to m_rootInfo->setDesktopLayout?
emit layoutChanged(width, height);
}
void VirtualDesktopManager::initShortcuts()
{
initSwitchToShortcuts();
QAction *nextAction = addAction(QStringLiteral("Switch to Next Desktop"), i18n("Switch to Next Desktop"), &VirtualDesktopManager::slotNext);
input()->registerTouchpadSwipeShortcut(SwipeDirection::Right, nextAction);
QAction *previousAction = addAction(QStringLiteral("Switch to Previous Desktop"), i18n("Switch to Previous Desktop"), &VirtualDesktopManager::slotPrevious);
input()->registerTouchpadSwipeShortcut(SwipeDirection::Left, previousAction);
addAction(QStringLiteral("Switch One Desktop to the Right"), i18n("Switch One Desktop to the Right"), &VirtualDesktopManager::slotRight);
addAction(QStringLiteral("Switch One Desktop to the Left"), i18n("Switch One Desktop to the Left"), &VirtualDesktopManager::slotLeft);
addAction(QStringLiteral("Switch One Desktop Up"), i18n("Switch One Desktop Up"), &VirtualDesktopManager::slotUp);
addAction(QStringLiteral("Switch One Desktop Down"), i18n("Switch One Desktop Down"), &VirtualDesktopManager::slotDown);
// axis events
input()->registerAxisShortcut(Qt::ControlModifier | Qt::AltModifier, PointerAxisDown,
findChild(QStringLiteral("Switch to Next Desktop")));
input()->registerAxisShortcut(Qt::ControlModifier | Qt::AltModifier, PointerAxisUp,
findChild(QStringLiteral("Switch to Previous Desktop")));
}
void VirtualDesktopManager::initSwitchToShortcuts()
{
const QString toDesktop = QStringLiteral("Switch to Desktop %1");
const KLocalizedString toDesktopLabel = ki18n("Switch to Desktop %1");
addAction(toDesktop, toDesktopLabel, 1, QKeySequence(Qt::CTRL + Qt::Key_F1), &VirtualDesktopManager::slotSwitchTo);
addAction(toDesktop, toDesktopLabel, 2, QKeySequence(Qt::CTRL + Qt::Key_F2), &VirtualDesktopManager::slotSwitchTo);
addAction(toDesktop, toDesktopLabel, 3, QKeySequence(Qt::CTRL + Qt::Key_F3), &VirtualDesktopManager::slotSwitchTo);
addAction(toDesktop, toDesktopLabel, 4, QKeySequence(Qt::CTRL + Qt::Key_F4), &VirtualDesktopManager::slotSwitchTo);
for (uint i = 5; i <= maximum(); ++i) {
addAction(toDesktop, toDesktopLabel, i, QKeySequence(), &VirtualDesktopManager::slotSwitchTo);
}
}
QAction *VirtualDesktopManager::addAction(const QString &name, const KLocalizedString &label, uint value, const QKeySequence &key, void (VirtualDesktopManager::*slot)())
{
QAction *a = new QAction(this);
a->setProperty("componentName", QStringLiteral(KWIN_NAME));
a->setObjectName(name.arg(value));
a->setText(label.subs(value).toString());
a->setData(value);
KGlobalAccel::setGlobalShortcut(a, key);
input()->registerShortcut(key, a, this, slot);
return a;
}
QAction *VirtualDesktopManager::addAction(const QString &name, const QString &label, void (VirtualDesktopManager::*slot)())
{
QAction *a = new QAction(this);
a->setProperty("componentName", QStringLiteral(KWIN_NAME));
a->setObjectName(name);
a->setText(label);
KGlobalAccel::setGlobalShortcut(a, QKeySequence());
input()->registerShortcut(QKeySequence(), a, this, slot);
return a;
}
void VirtualDesktopManager::slotSwitchTo()
{
QAction *act = qobject_cast(sender());
if (!act) {
return;
}
bool ok = false;
const uint i = act->data().toUInt(&ok);
if (!ok) {
return;
}
setCurrent(i);
}
void VirtualDesktopManager::setNavigationWrappingAround(bool enabled)
{
if (enabled == m_navigationWrapsAround) {
return;
}
m_navigationWrapsAround = enabled;
emit navigationWrappingAroundChanged();
}
void VirtualDesktopManager::slotDown()
{
moveTo(isNavigationWrappingAround());
}
void VirtualDesktopManager::slotLeft()
{
moveTo(isNavigationWrappingAround());
}
void VirtualDesktopManager::slotPrevious()
{
moveTo(isNavigationWrappingAround());
}
void VirtualDesktopManager::slotNext()
{
moveTo(isNavigationWrappingAround());
}
void VirtualDesktopManager::slotRight()
{
moveTo(isNavigationWrappingAround());
}
void VirtualDesktopManager::slotUp()
{
moveTo(isNavigationWrappingAround());
}
+
+/////// VirtualDesktopManagerDBus
+
+VirtualDesktopManagerDBus::VirtualDesktopManagerDBus(VirtualDesktopManager *parent)
+ : QObject(parent)
+ , m_manager(parent)
+{
+ connect(m_manager, &VirtualDesktopManager::currentChanged, this,
+ [this](uint previousDesktop, uint newDesktop) {
+ Q_UNUSED(previousDesktop);
+ emit currentChanged(newDesktop);
+ }
+ );
+}
+
+void VirtualDesktopManagerDBus::setCount(uint count)
+{
+ if (m_manager->count() == count) {
+ return;
+ }
+
+ m_manager->setCount(count);
+ emit desktopsChanged(desktops());
+}
+
+uint VirtualDesktopManagerDBus::count() const
+{
+ return m_manager->count();
+}
+
+void VirtualDesktopManagerDBus::setRows(uint rows)
+{
+ // if (m_manager->rows() == rows) {
+ // return;
+ // }
+ //TODO: this should be more granular and perhaps the prientation should be in the dbus/wayland protocol too?
+ //FIXME: NOOP
+// m_manager->grid().update(QSize(m_manager->grid().width(), rows), Qt::Horizontal, m_manager->desktops());
+ emit rowsChanged(rows);
+}
+
+uint VirtualDesktopManagerDBus::rows() const
+{
+ return m_manager->grid().height();
+}
+
+void VirtualDesktopManagerDBus::setCurrent(uint current)
+{
+ if (m_manager->current() == current) {
+ return;
+ }
+
+ m_manager->setCurrent(current);
+ emit currentChanged(current);
+}
+
+uint VirtualDesktopManagerDBus::current() const
+{
+ return m_manager->current();
+}
+
+void VirtualDesktopManagerDBus::setNavigationWrappingAround(bool wraps)
+{
+ if (m_manager->isNavigationWrappingAround() == wraps) {
+ return;
+ }
+
+ m_manager->setNavigationWrappingAround(wraps);
+ emit navigationWrappingAroundChanged(wraps);
+}
+
+bool VirtualDesktopManagerDBus::isNavigationWrappingAround() const
+{
+ return m_manager->isNavigationWrappingAround();
+}
+
+VirtualDesktopManagerDBusDesktopDataVector VirtualDesktopManagerDBus::desktops() const
+{
+ const auto desks = m_manager->desktops();
+ VirtualDesktopManagerDBusDesktopDataVector desktopVect;
+ desktopVect.reserve(m_manager->count());
+
+ std::transform(desks.constBegin(), desks.constEnd(),
+ std::back_inserter(desktopVect),
+ [] (const VirtualDesktop *vd) {
+ return VirtualDesktopManagerDBusDesktopDataStruct{.x11DesktopNumber = vd->x11DesktopNumber(), .id = vd->id(), .name = vd->name()};
+ }
+ );
+
+ return desktopVect;
+}
+
+void VirtualDesktopManagerDBus::setDesktopName(uint number, const QString &name)
+{
+ VirtualDesktop *vd = m_manager->desktopForX11Id(number);
+ if (vd->name() == name) {
+ return;
+ }
+
+ VirtualDesktopManagerDBusDesktopDataStruct data{.x11DesktopNumber = vd->x11DesktopNumber(), .id = vd->id(), .name = name};
+ vd->setName(name);
+
+ emit desktopDataChanged(data);
+ emit desktopsChanged(desktops());
+}
+
} // KWin
diff --git a/virtualdesktops.h b/virtualdesktops.h
index 7b0c38c97..4f80d9575 100644
--- a/virtualdesktops.h
+++ b/virtualdesktops.h
@@ -1,705 +1,773 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2012 Martin Gräßlin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*********************************************************************/
#ifndef KWIN_VIRTUAL_DESKTOPS_H
#define KWIN_VIRTUAL_DESKTOPS_H
// KWin
#include
#include
// Qt includes
#include
#include
#include
#include
// KDE includes
#include
#include
class KLocalizedString;
class NETRootInfo;
class QAction;
namespace KWin {
class KWIN_EXPORT 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();
/**
* Emitted just before the desktop gets destroyed.
**/
void aboutToBeDestroyed();
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.
*
* The VirtualDesktopGrid represents a visual layout of the Virtual Desktops as they are in e.g.
* a Pager. This grid is used for getting a desktop next to a given desktop in any direction by
* making use of the layout information. This allows navigation like move to desktop on left.
**/
class VirtualDesktopGrid
{
public:
VirtualDesktopGrid();
~VirtualDesktopGrid();
void update(const QSize &size, Qt::Orientation orientation, const QVector &desktops);
/**
* @returns The coords of desktop @a id in grid units.
*/
QPoint gridCoords(uint id) const;
/**
* @returns The coords of desktop @a vd in grid units.
*/
QPoint gridCoords(VirtualDesktop *vd) const;
/**
* @returns The desktop at the point @a coords or 0 if no desktop exists at that
* point. @a coords is to be in grid units.
*/
VirtualDesktop *at(const QPoint &coords) const;
int width() const;
int height() const;
const QSize &size() const;
private:
QSize m_size;
QVector> m_grid;
};
/**
* @brief Manages the number of available virtual desktops, the layout of those and which virtual
* desktop is the current one.
*
* This manager is responsible for Virtual Desktop handling inside KWin. It has a property for the
* count of available virtual desktops and a property for the currently active virtual desktop. All
* changes to the number of virtual desktops and the current virtual desktop need to go through this
* manager.
*
* On all changes a signal is emitted and interested parties should connect to the signal. The manager
* itself does not interact with other parts of the system. E.g. it does not hide/show windows of
* desktop changes. This is outside the scope of this manager.
*
* Internally the manager organizes the virtual desktops in a grid allowing to navigate over the
* virtual desktops. For this a set of convenient methods are available which allow to get the id
* of an adjacent desktop or to switch to an adjacent desktop. Interested parties should make use of
* these methods and not replicate the logic to switch to the next desktop.
**/
class KWIN_EXPORT VirtualDesktopManager : public QObject
{
Q_OBJECT
/**
* The number of virtual desktops currently available.
* The ids of the virtual desktops are in the range [1, VirtualDesktopManager::maximum()].
**/
Q_PROPERTY(uint count READ count WRITE setCount NOTIFY countChanged)
/**
* The id of the virtual desktop which is currently in use.
**/
Q_PROPERTY(uint current READ current WRITE setCurrent NOTIFY currentChanged)
/**
* Whether navigation in the desktop layout wraps around at the borders.
**/
Q_PROPERTY(bool navigationWrappingAround READ isNavigationWrappingAround WRITE setNavigationWrappingAround NOTIFY navigationWrappingAroundChanged)
public:
virtual ~VirtualDesktopManager();
/**
* @internal
**/
void setRootInfo(NETRootInfo *info);
/**
* @internal
**/
void setConfig(KSharedConfig::Ptr config);
/**
* @returns Total number of desktops currently in existence.
* @see setCount
* @see countChanged
*/
uint count() const;
/**
* @returns The ID of the current desktop.
* @see setCurrent
* @see currentChanged
*/
uint current() const;
/**
* @returns The current desktop
* @see setCurrent
* @see currentChanged
**/
VirtualDesktop *currentDesktop() const;
/**
* Moves to the desktop through the algorithm described by Direction.
* @param wrap If @c true wraps around to the other side of the layout
* @see setCurrent
**/
template
void moveTo(bool wrap = false);
/**
* @returns The name of the @p desktop
**/
QString name(uint desktop) const;
/**
* @returns @c true if navigation at borders of layout wraps around, @c false otherwise
* @see setNavigationWrappingAround
* @see navigationWrappingAroundChanged
**/
bool isNavigationWrappingAround() const;
/**
* @returns The layout aware virtual desktop grid used by this manager.
**/
const VirtualDesktopGrid &grid() const;
/**
* @returns The ID of the desktop above desktop @a id. Wraps around to the bottom of
* the layout if @a wrap is set. If @a id is not set use the current one.
*/
uint above(uint id = 0, bool wrap = true) const;
/**
* @returns The desktop above desktop @a desktop. Wraps around to the bottom of
* the layout if @a wrap is set. If @a desktop is @c null use the current one.
*/
VirtualDesktop *above(VirtualDesktop *desktop, bool wrap = true) const;
/**
* @returns The ID of the desktop to the right of desktop @a id. Wraps around to the
* left of the layout if @a wrap is set. If @a id is not set use the current one.
*/
uint toRight(uint id = 0, bool wrap = true) const;
/**
* @returns The desktop to the right of desktop @a desktop. Wraps around to the
* left of the layout if @a wrap is set. If @a desktop is @c null use the current one.
*/
VirtualDesktop *toRight(VirtualDesktop *desktop, bool wrap = true) const;
/**
* @returns The ID of the desktop below desktop @a id. Wraps around to the top of the
* layout if @a wrap is set. If @a id is not set use the current one.
*/
uint below(uint id = 0, bool wrap = true) const;
/**
* @returns The desktop below desktop @a desktop. Wraps around to the top of the
* layout if @a wrap is set. If @a desktop is @c null use the current one.
*/
VirtualDesktop *below(VirtualDesktop *desktop, bool wrap = true) const;
/**
* @returns The ID of the desktop to the left of desktop @a id. Wraps around to the
* right of the layout if @a wrap is set. If @a id is not set use the current one.
*/
uint toLeft(uint id = 0, bool wrap = true) const;
/**
* @returns The desktop to the left of desktop @a desktop. Wraps around to the
* right of the layout if @a wrap is set. If @a desktop is @c null use the current one.
*/
VirtualDesktop *toLeft(VirtualDesktop *desktop, bool wrap = true) const;
/**
* @returns The desktop after the desktop @a desktop. Wraps around to the first
* desktop if @a wrap is set. If @a desktop is @c null use the current desktop.
**/
VirtualDesktop *next(VirtualDesktop *desktop = nullptr, bool wrap = true) const;
/**
* @returns The desktop in front of the desktop @a desktop. Wraps around to the
* last desktop if @a wrap is set. If @a desktop is @c null use the current desktop.
**/
VirtualDesktop *previous(VirtualDesktop *desktop = nullptr, bool wrap = true) const;
void initShortcuts();
/**
* @returns all currently managed VirtualDesktops
**/
QVector desktops() const {
return m_desktops;
}
/**
* @returns The VirtualDesktop for the x11 @p id, if no such VirtualDesktop @c null is returned
**/
VirtualDesktop *desktopForX11Id(uint id) const;
/**
* @returns The VirtualDesktop for the internal desktop string @p id, if no such VirtualDesktop @c null is returned
**/
VirtualDesktop *desktopForId(const QByteArray &id) const;
/**
* Create a new virtual desktop at the requested position.
* The difference with setCount is that setCount always adds new desktops at the end of the chain. The Id is automatically generated.
* @param x11DesktopNumber number for the desktop. The desktop created will have an
* x11DesktopNumber guaranteed to be between 1 and numberOfDesktops().
* @param name The name for the new desktop, if empty the default name will be used.
* @returns the new VirtualDesktop, nullptr if we reached the maximum number of desktops
*/
VirtualDesktop *createVirtualDesktop(uint x11DesktopNumber, const QString &name = QString());
/**
* Remove the virtual desktop identified by id, if it exists
* difference with setCount is that is possible to remove an arbitrary desktop,
* not only the last one.
* @param id the string id of the desktop to remove
*/
void removeVirtualDesktop(const QByteArray &id);
/**
* Updates the net root info for new number of desktops
**/
void updateRootInfo();
/**
* @returns The maximum number of desktops that KWin supports.
*/
static uint maximum();
public Q_SLOTS:
/**
* Set the number of available desktops to @a count. This function overrides any previous
* grid layout.
* There needs to be at least one virtual desktop and the new value is capped at the maximum
* number of desktops. A caller of this function cannot expect that the change has been applied.
* It is the callers responsibility to either check the @link numberOfDesktops or connect to the
* @link countChanged signal.
*
* In case the @link current desktop is on a desktop higher than the new count, the current desktop
* is changed to be the new desktop with highest id. In that situation the signal @link desktopsRemoved
* is emitted.
* @param count The new number of desktops to use
* @see count
* @see maximum
* @see countChanged
* @see desktopsRemoved
*/
void setCount(uint count);
/**
* Set the current desktop to @a current.
* @returns True on success, false otherwise.
* @see current
* @see currentChanged
* @see moveTo
*/
bool setCurrent(uint current);
/**
* Set the current desktop to @a current.
* @returns True on success, false otherwise.
* @see current
* @see currentChanged
* @see moveTo
**/
bool setCurrent(VirtualDesktop *current);
/**
* Called from within setCount() to ensure the desktop layout is still valid.
*/
void updateLayout();
/**
* @param enable wrapping around borders for navigation in desktop layout
* @see isNavigationWrappingAround
* @see navigationWrappingAroundChanged
**/
void setNavigationWrappingAround(bool enabled);
/**
* Loads number of desktops and names from configuration file
**/
void load();
/**
* Saves number of desktops and names to configuration file
**/
void save();
Q_SIGNALS:
/**
* Signal emitted whenever the number of virtual desktops changes.
* @param previousCount The number of desktops prior to the change
* @param newCount The new current number of desktops
**/
void countChanged(uint previousCount, uint newCount);
/**
* A new desktop has been created
* @param desktop the new just crated desktop
*/
void desktopCreated(KWin::VirtualDesktop *desktop);
/**
* A desktop has been removed and is about to be deleted
* @param desktop the desktop that has been removed.
* It's guaranteed to stil la valid pointer when the signal arrives,
* but it's about to be deleted.
*/
void desktopRemoved(KWin::VirtualDesktop *desktop);
/**
* Signal emitted whenever the current desktop changes.
* @param previousDesktop The virtual desktop changed from
* @param newDesktop The virtual desktop changed to
**/
void currentChanged(uint previousDesktop, uint newDesktop);
/**
* Signal emitted whenever the desktop layout changes.
* @param columns The new number of columns in the layout
* @param rows The new number of rows in the layout
**/
void layoutChanged(int columns, int rows);
/**
* Signal emitted whenever the navigationWrappingAround property changes.
**/
void navigationWrappingAroundChanged();
private Q_SLOTS:
/**
* Common slot for all "Switch to Desktop n" shortcuts.
* This method uses the sender() method to access some data.
* DO NOT CALL DIRECTLY! ONLY TO BE USED FROM AN ACTION!
**/
void slotSwitchTo();
/**
* Slot for switch to next desktop action.
**/
void slotNext();
/**
* Slot for switch to previous desktop action.
**/
void slotPrevious();
/**
* Slot for switch to right desktop action.
**/
void slotRight();
/**
* Slot for switch to left desktop action.
**/
void slotLeft();
/**
* Slot for switch to desktop above action.
**/
void slotUp();
/**
* Slot for switch to desktop below action.
**/
void slotDown();
private:
/**
* Generate a desktop layout from EWMH _NET_DESKTOP_LAYOUT property parameters.
*/
void setNETDesktopLayout(Qt::Orientation orientation, uint width, uint height, int startingCorner);
/**
* @returns A default name for the given @p desktop
**/
QString defaultName(int desktop) const;
/**
* Creates all the global keyboard shortcuts for "Switch To Desktop n" actions.
**/
void initSwitchToShortcuts();
/**
* Creates an action and connects it to the @p slot in this Manager. This method is
* meant to be used for the case that an additional information needs to be stored in
* the action and the label.
* @param name The name of the action to be created
* @param label The localized name for the action to be created
* @param value An additional value added to the label and to the created action
* @param key The global shortcut for the action
* @param slot The slot to invoke when the action is triggered
**/
QAction *addAction(const QString &name, const KLocalizedString &label, uint value, const QKeySequence &key, void (VirtualDesktopManager::*slot)());
/**
* Creates an action and connects it to the @p slot in this Manager.
* Overloaded method for the case that no additional value needs to be passed to the action and
* no global shortcut is defined by default.
* @param name The name of the action to be created
* @param label The localized name for the action to be created
* @param slot The slot to invoke when the action is triggered
**/
QAction *addAction(const QString &name, const QString &label, void (VirtualDesktopManager::*slot)());
QVector m_desktops;
QPointer m_current;
bool m_navigationWrapsAround;
VirtualDesktopGrid m_grid;
// TODO: QPointer
NETRootInfo *m_rootInfo;
KSharedConfig::Ptr m_config;
bool m_isLoading = false;
KWIN_SINGLETON_VARIABLE(VirtualDesktopManager, s_manager)
};
+struct VirtualDesktopManagerDBusDesktopDataStruct {
+ uint x11DesktopNumber;
+ QString id;
+ QString name;
+};
+typedef QVector VirtualDesktopManagerDBusDesktopDataVector;
+
+class VirtualDesktopManagerDBus : public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "org.kde.KWin.VirtualDesktopManager")
+
+ /**
+ * The number of virtual desktops currently available.
+ * The ids of the virtual desktops are in the range [1, VirtualDesktopManager::maximum()].
+ **/
+ Q_PROPERTY(uint count READ count WRITE setCount NOTIFY countChanged)
+ /**
+ * The number of rows the virtual desktops will be laid out in
+ **/
+ Q_PROPERTY(uint rows READ rows WRITE setRows NOTIFY rowsChanged)
+ /**
+ * The id of the virtual desktop which is currently in use.
+ **/
+ Q_PROPERTY(uint current READ current WRITE setCurrent NOTIFY currentChanged)
+ /**
+ * Whether navigation in the desktop layout wraps around at the borders.
+ **/
+ Q_PROPERTY(bool navigationWrappingAround READ isNavigationWrappingAround WRITE setNavigationWrappingAround NOTIFY navigationWrappingAroundChanged)
+
+ /**
+ * list of key/value pairs which every one of them is representing a desktop
+ */
+ // Q_PROPERTY(VirtualDesktopManagerDBusDesktopDataVector desktops READ desktops, NOTIFY desktopsChanged);
+
+public:
+ VirtualDesktopManagerDBus(VirtualDesktopManager *parent);
+ ~VirtualDesktopManagerDBus() = default;
+
+ void setCount(uint count);
+ uint count() const;
+
+ void setRows(uint rows);
+ uint rows() const;
+
+ void setCurrent(uint current);
+ uint current() const;
+
+ void setNavigationWrappingAround(bool wraps);
+ bool isNavigationWrappingAround() const;
+
+ VirtualDesktopManagerDBusDesktopDataVector desktops() const;
+
+Q_SIGNALS:
+ void countChanged(uint count);
+ void rowsChanged(uint rows);
+ void currentChanged(uint current);
+ void navigationWrappingAroundChanged(bool wraps);
+ void desktopsChanged(VirtualDesktopManagerDBusDesktopDataVector);
+ void desktopDataChanged(VirtualDesktopManagerDBusDesktopDataStruct);
+
+public Q_SLOTS:
+ void setDesktopName(uint number, const QString &name);
+
+private:
+ VirtualDesktopManager *m_manager;
+};
+
/**
* Function object to select the desktop above in the layout.
* Note: does not switch to the desktop!
**/
class DesktopAbove
{
public:
DesktopAbove() {}
/**
* @param desktop The desktop from which the desktop above should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already topmost desktop
* @returns Id of the desktop above @p desktop
**/
uint operator() (uint desktop, bool wrap) {
return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
}
/**
* @param desktop The desktop from which the desktop above should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already topmost desktop
* @returns the desktop above @p desktop
**/
VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
return VirtualDesktopManager::self()->above(desktop, wrap);
}
};
/**
* Function object to select the desktop below in the layout.
* Note: does not switch to the desktop!
**/
class DesktopBelow
{
public:
DesktopBelow() {}
/**
* @param desktop The desktop from which the desktop below should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already lowest desktop
* @returns Id of the desktop below @p desktop
**/
uint operator() (uint desktop, bool wrap) {
return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
}
/**
* @param desktop The desktop from which the desktop below should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already lowest desktop
* @returns the desktop below @p desktop
**/
VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
return VirtualDesktopManager::self()->below(desktop, wrap);
}
};
/**
* Function object to select the desktop to the left in the layout.
* Note: does not switch to the desktop!
**/
class DesktopLeft
{
public:
DesktopLeft() {}
/**
* @param desktop The desktop from which the desktop on the left should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already leftmost desktop
* @returns Id of the desktop left of @p desktop
**/
uint operator() (uint desktop, bool wrap) {
return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
}
/**
* @param desktop The desktop from which the desktop on the left should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already leftmost desktop
* @returns the desktop left of @p desktop
**/
VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
return VirtualDesktopManager::self()->toLeft(desktop, wrap);
}
};
/**
* Function object to select the desktop to the right in the layout.
* Note: does not switch to the desktop!
**/
class DesktopRight
{
public:
DesktopRight() {}
/**
* @param desktop The desktop from which the desktop on the right should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already rightmost desktop
* @returns Id of the desktop right of @p desktop
**/
uint operator() (uint desktop, bool wrap) {
return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
}
/**
* @param desktop The desktop from which the desktop on the right should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already rightmost desktop
* @returns the desktop right of @p desktop
**/
VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
return VirtualDesktopManager::self()->toRight(desktop, wrap);
}
};
/**
* Function object to select the next desktop in the layout.
* Note: does not switch to the desktop!
**/
class DesktopNext
{
public:
DesktopNext() {}
/**
* @param desktop The desktop from which the next desktop should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already last desktop
* @returns Id of the next desktop
**/
uint operator() (uint desktop, bool wrap) {
return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
}
/**
* @param desktop The desktop from which the next desktop should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already last desktop
* @returns the next desktop
**/
VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
return VirtualDesktopManager::self()->next(desktop, wrap);
}
};
/**
* Function object to select the previous desktop in the layout.
* Note: does not switch to the desktop!
**/
class DesktopPrevious
{
public:
DesktopPrevious() {}
/**
* @param desktop The desktop from which the previous desktop should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already first desktop
* @returns Id of the previous desktop
**/
uint operator() (uint desktop, bool wrap) {
return (*this)(VirtualDesktopManager::self()->desktopForX11Id(desktop), wrap)->x11DesktopNumber();
}
/**
* @param desktop The desktop from which the previous desktop should be selected. If @c 0 the current desktop is used
* @param wrap Whether to wrap around if already first desktop
* @returns the previous desktop
**/
VirtualDesktop *operator() (VirtualDesktop *desktop, bool wrap) {
return VirtualDesktopManager::self()->previous(desktop, wrap);
}
};
/**
* Helper function to get the ID of a virtual desktop in the direction from
* the given @p desktop. If @c 0 the current desktop is used as a starting point.
* @param desktop The desktop from which the desktop in given Direction should be selected.
* @param wrap Whether desktop navigation wraps around at the borders of the layout
* @returns The next desktop in specified direction
**/
template
uint getDesktop(int desktop = 0, bool wrap = true);
template
uint getDesktop(int d, bool wrap)
{
Direction direction;
return direction(d, wrap);
}
inline
int VirtualDesktopGrid::width() const
{
return m_size.width();
}
inline
int VirtualDesktopGrid::height() const
{
return m_size.height();
}
inline
const QSize &VirtualDesktopGrid::size() const
{
return m_size;
}
inline
uint VirtualDesktopManager::maximum()
{
return 20;
}
inline
uint VirtualDesktopManager::count() const
{
return m_desktops.count();
}
inline
bool VirtualDesktopManager::isNavigationWrappingAround() const
{
return m_navigationWrapsAround;
}
inline
void VirtualDesktopManager::setRootInfo(NETRootInfo *info)
{
m_rootInfo = info;
}
inline
void VirtualDesktopManager::setConfig(KSharedConfig::Ptr config)
{
m_config = config;
}
inline
const VirtualDesktopGrid &VirtualDesktopManager::grid() const
{
return m_grid;
}
template
void VirtualDesktopManager::moveTo(bool wrap)
{
Direction functor;
setCurrent(functor(nullptr, wrap));
}
} // namespace KWin
#endif