2012-11-16 07:23:47 +00:00
|
|
|
/********************************************************************
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
|
|
|
|
|
|
|
Copyright (C) 2009 Lucas Murray <lmurray@undefinedfire.com>
|
|
|
|
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
|
|
|
|
|
|
|
|
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 <http://www.gnu.org/licenses/>.
|
|
|
|
*********************************************************************/
|
|
|
|
#include "virtualdesktops.h"
|
2013-07-10 09:45:51 +00:00
|
|
|
#include "input.h"
|
2012-11-16 07:23:47 +00:00
|
|
|
// KDE
|
2014-03-17 15:24:10 +00:00
|
|
|
#include <KConfigGroup>
|
|
|
|
#include <KGlobalAccel>
|
|
|
|
#include <KLocalizedString>
|
2014-03-18 13:32:53 +00:00
|
|
|
#include <NETWM>
|
2013-12-10 08:11:16 +00:00
|
|
|
// Qt
|
|
|
|
#include <QAction>
|
2012-11-16 07:23:47 +00:00
|
|
|
|
2016-11-10 13:02:14 +00:00
|
|
|
#include <algorithm>
|
|
|
|
|
2012-11-16 07:23:47 +00:00
|
|
|
namespace KWin {
|
|
|
|
|
|
|
|
extern int screen_number;
|
|
|
|
|
2016-11-07 09:55:18 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2012-11-16 07:23:47 +00:00
|
|
|
VirtualDesktopGrid::VirtualDesktopGrid()
|
|
|
|
: m_size(1, 2) // Default to tow rows
|
2016-11-10 13:02:14 +00:00
|
|
|
, m_grid(QVector<QVector<VirtualDesktop*>>{QVector<VirtualDesktop*>{}, QVector<VirtualDesktop*>{}})
|
2012-11-16 07:23:47 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-11-10 13:02:14 +00:00
|
|
|
VirtualDesktopGrid::~VirtualDesktopGrid() = default;
|
2012-11-16 07:23:47 +00:00
|
|
|
|
2016-11-10 13:02:14 +00:00
|
|
|
void VirtualDesktopGrid::update(const QSize &size, Qt::Orientation orientation, const QVector<VirtualDesktop*> &desktops)
|
2012-11-16 07:23:47 +00:00
|
|
|
{
|
|
|
|
// Set private variables
|
|
|
|
m_size = size;
|
|
|
|
const uint width = size.width();
|
|
|
|
const uint height = size.height();
|
|
|
|
|
2016-11-10 13:02:14 +00:00
|
|
|
m_grid.clear();
|
|
|
|
auto it = desktops.begin();
|
|
|
|
auto end = desktops.end();
|
2012-11-16 07:23:47 +00:00
|
|
|
if (orientation == Qt::Horizontal) {
|
|
|
|
for (uint y = 0; y < height; ++y) {
|
2016-11-10 13:02:14 +00:00
|
|
|
QVector<VirtualDesktop*> row;
|
|
|
|
for (uint x = 0; x < width && it != end; ++x) {
|
|
|
|
row << *it;
|
|
|
|
it++;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
m_grid << row;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
} else {
|
2016-11-10 13:02:14 +00:00
|
|
|
for (uint y = 0; y < height; ++y) {
|
|
|
|
m_grid << QVector<VirtualDesktop*>();
|
|
|
|
}
|
2012-11-16 07:23:47 +00:00
|
|
|
for (uint x = 0; x < width; ++x) {
|
2016-11-10 13:02:14 +00:00
|
|
|
for (uint y = 0; y < height && it != end; ++y) {
|
|
|
|
auto &row = m_grid[y];
|
|
|
|
row << *it;
|
|
|
|
it++;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QPoint VirtualDesktopGrid::gridCoords(uint id) const
|
|
|
|
{
|
2016-11-10 13:02:14 +00:00
|
|
|
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) {
|
2012-11-16 07:23:47 +00:00
|
|
|
return QPoint(x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return QPoint(-1, -1);
|
|
|
|
}
|
|
|
|
|
2016-11-10 13:02:14 +00:00
|
|
|
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());
|
|
|
|
}
|
|
|
|
|
2013-04-05 07:41:25 +00:00
|
|
|
KWIN_SINGLETON_FACTORY_VARIABLE(VirtualDesktopManager, s_manager)
|
2012-11-16 07:23:47 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2016-11-10 13:02:14 +00:00
|
|
|
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;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
QPoint coords = m_grid.gridCoords(desktop);
|
2012-11-16 07:23:47 +00:00
|
|
|
Q_ASSERT(coords.x() >= 0);
|
|
|
|
while (true) {
|
|
|
|
coords.ry()--;
|
|
|
|
if (coords.y() < 0) {
|
|
|
|
if (wrap) {
|
|
|
|
coords.setY(m_grid.height() - 1);
|
|
|
|
} else {
|
2016-11-10 13:02:14 +00:00
|
|
|
return desktop; // Already at the top-most desktop
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
if (VirtualDesktop *vd = m_grid.at(coords)) {
|
|
|
|
return vd;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
return nullptr;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint VirtualDesktopManager::toRight(uint id, bool wrap) const
|
|
|
|
{
|
2016-11-10 13:02:14 +00:00
|
|
|
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;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
QPoint coords = m_grid.gridCoords(desktop);
|
2012-11-16 07:23:47 +00:00
|
|
|
Q_ASSERT(coords.x() >= 0);
|
|
|
|
while (true) {
|
|
|
|
coords.rx()++;
|
|
|
|
if (coords.x() >= m_grid.width()) {
|
|
|
|
if (wrap) {
|
|
|
|
coords.setX(0);
|
|
|
|
} else {
|
2016-11-10 13:02:14 +00:00
|
|
|
return desktop; // Already at the right-most desktop
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
if (VirtualDesktop *vd = m_grid.at(coords)) {
|
|
|
|
return vd;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
return nullptr;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint VirtualDesktopManager::below(uint id, bool wrap) const
|
|
|
|
{
|
2016-11-10 13:02:14 +00:00
|
|
|
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;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
QPoint coords = m_grid.gridCoords(desktop);
|
2012-11-16 07:23:47 +00:00
|
|
|
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
|
2016-11-10 13:02:14 +00:00
|
|
|
return desktop;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
if (VirtualDesktop *vd = m_grid.at(coords)) {
|
|
|
|
return vd;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
return nullptr;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint VirtualDesktopManager::toLeft(uint id, bool wrap) const
|
|
|
|
{
|
2016-11-10 13:02:14 +00:00
|
|
|
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;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
QPoint coords = m_grid.gridCoords(desktop);
|
2012-11-16 07:23:47 +00:00
|
|
|
Q_ASSERT(coords.x() >= 0);
|
|
|
|
while (true) {
|
|
|
|
coords.rx()--;
|
|
|
|
if (coords.x() < 0) {
|
|
|
|
if (wrap) {
|
|
|
|
coords.setX(m_grid.width() - 1);
|
|
|
|
} else {
|
2016-11-10 13:02:14 +00:00
|
|
|
return desktop; // Already at the left-most desktop
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
if (VirtualDesktop *vd = m_grid.at(coords)) {
|
|
|
|
return vd;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
return nullptr;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
|
2016-11-10 13:02:14 +00:00
|
|
|
VirtualDesktop *VirtualDesktopManager::next(VirtualDesktop *desktop, bool wrap) const
|
2012-11-16 07:23:47 +00:00
|
|
|
{
|
2016-11-10 13:02:14 +00:00
|
|
|
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()) {
|
2012-11-16 07:23:47 +00:00
|
|
|
if (wrap) {
|
2016-11-10 13:02:14 +00:00
|
|
|
return m_desktops.first();
|
2012-11-16 07:23:47 +00:00
|
|
|
} else {
|
2016-11-10 13:02:14 +00:00
|
|
|
return desktop;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
return *it;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
|
2016-11-10 13:02:14 +00:00
|
|
|
VirtualDesktop *VirtualDesktopManager::previous(VirtualDesktop *desktop, bool wrap) const
|
2012-11-16 07:23:47 +00:00
|
|
|
{
|
2016-11-10 13:02:14 +00:00
|
|
|
Q_ASSERT(m_current);
|
|
|
|
if (!desktop) {
|
|
|
|
desktop = m_current;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
auto it = std::find(m_desktops.begin(), m_desktops.end(), desktop);
|
|
|
|
Q_ASSERT(it != m_desktops.end());
|
|
|
|
if (it == m_desktops.begin()) {
|
2012-11-16 07:23:47 +00:00
|
|
|
if (wrap) {
|
2016-11-10 13:02:14 +00:00
|
|
|
return m_desktops.last();
|
2012-11-16 07:23:47 +00:00
|
|
|
} else {
|
2016-11-10 13:02:14 +00:00
|
|
|
return desktop;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
it--;
|
|
|
|
return *it;
|
|
|
|
}
|
|
|
|
|
|
|
|
VirtualDesktop *VirtualDesktopManager::desktopForX11Id(uint id) const
|
|
|
|
{
|
|
|
|
if (id == 0 || id > count()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return m_desktops.at(id - 1);
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
|
2016-11-07 09:55:18 +00:00
|
|
|
uint VirtualDesktopManager::current() const
|
|
|
|
{
|
|
|
|
return m_current ? m_current->x11DesktopNumber() : 0;
|
|
|
|
}
|
|
|
|
|
2012-11-16 07:23:47 +00:00
|
|
|
bool VirtualDesktopManager::setCurrent(uint newDesktop)
|
|
|
|
{
|
2016-11-07 09:55:18 +00:00
|
|
|
if (newDesktop < 1 || newDesktop > count() || newDesktop == current()) {
|
2012-11-16 07:23:47 +00:00
|
|
|
return false;
|
|
|
|
}
|
2016-11-10 13:02:14 +00:00
|
|
|
auto d = desktopForX11Id(newDesktop);
|
|
|
|
Q_ASSERT(d);
|
|
|
|
return setCurrent(d);
|
|
|
|
}
|
2016-11-07 09:55:18 +00:00
|
|
|
|
2016-11-10 13:02:14 +00:00
|
|
|
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());
|
2012-11-16 07:23:47 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VirtualDesktopManager::setCount(uint count)
|
|
|
|
{
|
|
|
|
count = qBound<uint>(1, count, VirtualDesktopManager::maximum());
|
2016-11-07 09:55:18 +00:00
|
|
|
if (count == uint(m_desktops.count())) {
|
2012-11-16 07:23:47 +00:00
|
|
|
// nothing to change
|
|
|
|
return;
|
|
|
|
}
|
2016-11-07 09:55:18 +00:00
|
|
|
const uint oldCount = m_desktops.count();
|
|
|
|
const uint oldCurrent = current();
|
|
|
|
while (uint(m_desktops.count()) > count) {
|
|
|
|
delete m_desktops.takeLast();
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
2016-11-07 09:55:18 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2012-11-16 07:23:47 +00:00
|
|
|
updateRootInfo();
|
|
|
|
|
|
|
|
save();
|
2016-11-07 09:55:18 +00:00
|
|
|
emit countChanged(oldCount, m_desktops.count());
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
|
2016-11-07 09:55:18 +00:00
|
|
|
void VirtualDesktopManager::handleDesktopsRemoved(uint previousCount, uint previousCurrent)
|
2012-11-16 07:23:47 +00:00
|
|
|
{
|
2016-11-07 09:55:18 +00:00
|
|
|
if (!m_current) {
|
|
|
|
m_current = m_desktops.last();
|
|
|
|
emit currentChanged(previousCurrent, m_current->x11DesktopNumber());
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
emit desktopsRemoved(previousCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2014-09-25 10:49:18 +00:00
|
|
|
height = count() == 1u ? 1 : 2;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
setNETDesktopLayout(orientation,
|
|
|
|
width, height, 0 //rootInfo->desktopLayoutCorner() // Not really worth implementing right now.
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool s_loadingDesktopSettings = false;
|
|
|
|
|
|
|
|
void VirtualDesktopManager::load()
|
|
|
|
{
|
|
|
|
s_loadingDesktopSettings = true;
|
2013-08-26 09:26:12 +00:00
|
|
|
if (!m_config) {
|
2012-11-16 07:23:47 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
QString groupname;
|
|
|
|
if (screen_number == 0) {
|
2013-07-23 05:02:52 +00:00
|
|
|
groupname = QStringLiteral("Desktops");
|
2012-11-16 07:23:47 +00:00
|
|
|
} else {
|
|
|
|
groupname.sprintf("Desktops-screen-%d", screen_number);
|
|
|
|
}
|
|
|
|
KConfigGroup group(m_config, groupname);
|
|
|
|
const int n = group.readEntry("Number", 1);
|
|
|
|
setCount(n);
|
|
|
|
if (m_rootInfo) {
|
|
|
|
for (int i = 1; i <= n; i++) {
|
2013-07-23 05:02:52 +00:00
|
|
|
QString s = group.readEntry(QStringLiteral("Name_%1").arg(i), i18n("Desktop %1", i));
|
2012-11-16 07:23:47 +00:00
|
|
|
m_rootInfo->setDesktopName(i, s.toUtf8().data());
|
|
|
|
// TODO: update desktop focus chain, why?
|
|
|
|
// m_desktopFocusChain.value()[i-1] = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
int rows = group.readEntry<int>("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;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VirtualDesktopManager::save()
|
|
|
|
{
|
|
|
|
if (s_loadingDesktopSettings) {
|
|
|
|
return;
|
|
|
|
}
|
2013-08-26 09:26:12 +00:00
|
|
|
if (!m_config) {
|
2012-11-16 07:23:47 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
QString groupname;
|
|
|
|
if (screen_number == 0) {
|
2013-07-23 05:02:52 +00:00
|
|
|
groupname = QStringLiteral("Desktops");
|
2012-11-16 07:23:47 +00:00
|
|
|
} 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) {
|
2013-07-23 05:02:52 +00:00
|
|
|
group.writeEntry(QStringLiteral("Name_%1").arg(i), s);
|
2012-11-16 07:23:47 +00:00
|
|
|
} else {
|
2013-07-23 05:02:52 +00:00
|
|
|
QString currentvalue = group.readEntry(QStringLiteral("Name_%1").arg(i), QString());
|
2012-11-16 07:23:47 +00:00
|
|
|
if (currentvalue != defaultvalue) {
|
2013-07-23 05:02:52 +00:00
|
|
|
group.deleteEntry(QStringLiteral("Name_%1").arg(i));
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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.
|
2016-11-07 09:55:18 +00:00
|
|
|
const uint count = m_desktops.count();
|
2012-11-16 07:23:47 +00:00
|
|
|
|
|
|
|
// Calculate valid grid size
|
|
|
|
Q_ASSERT(width > 0 || height > 0);
|
|
|
|
if ((width <= 0) && (height > 0)) {
|
2016-11-07 09:55:18 +00:00
|
|
|
width = (count + height - 1) / height;
|
2012-11-16 07:23:47 +00:00
|
|
|
} else if ((height <= 0) && (width > 0)) {
|
2016-11-07 09:55:18 +00:00
|
|
|
height = (count + width - 1) / width;
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
2016-11-07 09:55:18 +00:00
|
|
|
while (width * height < count) {
|
2012-11-16 07:23:47 +00:00
|
|
|
if (orientation == Qt::Horizontal) {
|
|
|
|
++width;
|
|
|
|
} else {
|
|
|
|
++height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-10 13:02:14 +00:00
|
|
|
m_grid.update(QSize(width, height), orientation, m_desktops);
|
2012-11-16 07:23:47 +00:00
|
|
|
// TODO: why is there no call to m_rootInfo->setDesktopLayout?
|
|
|
|
emit layoutChanged(width, height);
|
|
|
|
}
|
|
|
|
|
2013-12-10 08:11:16 +00:00
|
|
|
void VirtualDesktopManager::initShortcuts()
|
2012-11-16 07:23:47 +00:00
|
|
|
{
|
2013-12-10 08:11:16 +00:00
|
|
|
initSwitchToShortcuts();
|
|
|
|
|
|
|
|
addAction(QStringLiteral("Switch to Next Desktop"), i18n("Switch to Next Desktop"), &VirtualDesktopManager::slotNext);
|
|
|
|
addAction(QStringLiteral("Switch to Previous Desktop"), i18n("Switch to Previous Desktop"), &VirtualDesktopManager::slotPrevious);
|
|
|
|
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);
|
2013-07-15 09:34:36 +00:00
|
|
|
|
|
|
|
// axis events
|
|
|
|
input()->registerAxisShortcut(Qt::ControlModifier | Qt::AltModifier, PointerAxisDown,
|
|
|
|
findChild<QAction*>(QStringLiteral("Switch to Next Desktop")));
|
|
|
|
input()->registerAxisShortcut(Qt::ControlModifier | Qt::AltModifier, PointerAxisUp,
|
|
|
|
findChild<QAction*>(QStringLiteral("Switch to Previous Desktop")));
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 08:11:16 +00:00
|
|
|
void VirtualDesktopManager::initSwitchToShortcuts()
|
2012-11-16 07:23:47 +00:00
|
|
|
{
|
2013-07-23 05:02:52 +00:00
|
|
|
const QString toDesktop = QStringLiteral("Switch to Desktop %1");
|
2012-11-16 07:23:47 +00:00
|
|
|
const KLocalizedString toDesktopLabel = ki18n("Switch to Desktop %1");
|
2013-12-10 08:11:16 +00:00
|
|
|
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);
|
2012-11-16 07:23:47 +00:00
|
|
|
|
|
|
|
for (uint i = 5; i <= maximum(); ++i) {
|
2013-12-10 08:11:16 +00:00
|
|
|
addAction(toDesktop, toDesktopLabel, i, QKeySequence(), &VirtualDesktopManager::slotSwitchTo);
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-10 08:11:16 +00:00
|
|
|
void VirtualDesktopManager::addAction(const QString &name, const KLocalizedString &label, uint value, const QKeySequence &key, void (VirtualDesktopManager::*slot)())
|
2012-11-16 07:23:47 +00:00
|
|
|
{
|
2013-12-10 08:11:16 +00:00
|
|
|
QAction *a = new QAction(this);
|
2016-09-13 11:02:20 +00:00
|
|
|
a->setProperty("componentName", QStringLiteral(KWIN_NAME));
|
2013-12-10 08:11:16 +00:00
|
|
|
a->setObjectName(name.arg(value));
|
2012-11-16 07:23:47 +00:00
|
|
|
a->setText(label.subs(value).toString());
|
|
|
|
a->setData(value);
|
2014-07-01 06:09:27 +00:00
|
|
|
KGlobalAccel::setGlobalShortcut(a, key);
|
2015-02-19 09:38:49 +00:00
|
|
|
input()->registerShortcut(key, a, this, slot);
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 08:11:16 +00:00
|
|
|
void VirtualDesktopManager::addAction(const QString &name, const QString &label, void (VirtualDesktopManager::*slot)())
|
2012-11-16 07:23:47 +00:00
|
|
|
{
|
2013-12-10 08:11:16 +00:00
|
|
|
QAction *a = new QAction(this);
|
2016-09-13 11:02:20 +00:00
|
|
|
a->setProperty("componentName", QStringLiteral(KWIN_NAME));
|
2013-12-10 08:11:16 +00:00
|
|
|
a->setObjectName(name);
|
2012-11-16 07:23:47 +00:00
|
|
|
a->setText(label);
|
2014-07-01 06:09:27 +00:00
|
|
|
KGlobalAccel::setGlobalShortcut(a, QKeySequence());
|
2015-02-19 09:38:49 +00:00
|
|
|
input()->registerShortcut(QKeySequence(), a, this, slot);
|
2012-11-16 07:23:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void VirtualDesktopManager::slotSwitchTo()
|
|
|
|
{
|
|
|
|
QAction *act = qobject_cast<QAction*>(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<DesktopBelow>(isNavigationWrappingAround());
|
|
|
|
}
|
|
|
|
|
|
|
|
void VirtualDesktopManager::slotLeft()
|
|
|
|
{
|
|
|
|
moveTo<DesktopLeft>(isNavigationWrappingAround());
|
|
|
|
}
|
|
|
|
|
|
|
|
void VirtualDesktopManager::slotPrevious()
|
|
|
|
{
|
|
|
|
moveTo<DesktopPrevious>(isNavigationWrappingAround());
|
|
|
|
}
|
|
|
|
|
|
|
|
void VirtualDesktopManager::slotNext()
|
|
|
|
{
|
|
|
|
moveTo<DesktopNext>(isNavigationWrappingAround());
|
|
|
|
}
|
|
|
|
|
|
|
|
void VirtualDesktopManager::slotRight()
|
|
|
|
{
|
|
|
|
moveTo<DesktopRight>(isNavigationWrappingAround());
|
|
|
|
}
|
|
|
|
|
|
|
|
void VirtualDesktopManager::slotUp()
|
|
|
|
{
|
|
|
|
moveTo<DesktopAbove>(isNavigationWrappingAround());
|
|
|
|
}
|
|
|
|
|
|
|
|
} // KWin
|