Commit cee5ea78 authored by Eike Hein's avatar Eike Hein

[kcmkwin/desktop] KCM using new virtual desktops DBus interface

Summary:
A rewrite of the Virtual Desktops KCM using the new DBus
API.

Depends on D13887.

Reviewers: mart, davidedmundson, ltoscano, zzag

Subscribers: davidedmundson, broulik, plasma-devel, kwin

Tags: #kwin

Maniphest Tasks: T4457

Differential Revision: https://phabricator.kde.org/D14542
parent 9993c6d6
include(ECMQMLModules)
ecm_find_qmlmodule(org.kde.plasma.core 2.0)
########### next target ###############
# KI18N Translation Domain for this library
add_definitions(-DTRANSLATION_DOMAIN=\"kcm_kwindesktop\")
# KI18N Translation Domain for this library.
add_definitions(-DTRANSLATION_DOMAIN=\"kcm_kwin_virtualdesktops\")
include_directories(${KWIN_SOURCE_DIR}/effects)
########### next target ###############
set(kcm_kwindesktop_PART_SRCS main.cpp desktopnameswidget.cpp)
ki18n_wrap_ui(kcm_kwindesktop_PART_SRCS main.ui)
qt5_add_dbus_interface( kcm_kwindesktop_PART_SRCS
${KWIN_SOURCE_DIR}/org.kde.kwin.Effects.xml kwin_effects_interface)
set(kcm_kwin_virtualdesktops_PART_SRCS virtualdesktops.cpp desktopsmodel.cpp ../../virtualdesktopsdbustypes.cpp)
add_library(kcm_kwindesktop MODULE ${kcm_kwindesktop_PART_SRCS})
add_library(kcm_kwin_virtualdesktops MODULE ${kcm_kwin_virtualdesktops_PART_SRCS})
target_link_libraries(kcm_kwindesktop
Qt5::X11Extras
KF5::KCMUtils
KF5::Completion
KF5::GlobalAccel
target_link_libraries(kcm_kwin_virtualdesktops
Qt5::DBus
KF5::I18n
KF5::Package
KF5::WindowSystem
KF5::XmlGui
${X11_LIBRARIES}
kwin4_effect_builtins
KF5::KCMUtils
KF5::QuickAddons
)
install(TARGETS kcm_kwindesktop DESTINATION ${PLUGIN_INSTALL_DIR} )
kcoreaddons_desktop_to_json(kcm_kwin_virtualdesktops "kcm_kwin_virtualdesktops.desktop")
########### install files ###############
install( FILES desktop.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
install(TARGETS kcm_kwin_virtualdesktops DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms)
install(FILES kcm_kwin_virtualdesktops.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
kpackage_install_package(package kcm_kwin_virtualdesktops kcms)
#! /usr/bin/env bash
$EXTRACTRC `find . -name \*.ui` >> rc.cpp || exit 11
$XGETTEXT *.cpp -o $podir/kcm_kwindesktop.pot
rm -f rc.cpp
$XGETTEXT `find . -name \*.cpp -o -name \*.qml` -o $podir/kcm_kwin_virtualdesktops.pot
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 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 "desktopnameswidget.h"
#include "main.h"
#include <QLabel>
#include <QGridLayout>
#include <KLocalizedString>
#include <KLineEdit>
namespace KWin
{
DesktopNamesWidget::DesktopNamesWidget(QWidget *parent)
: QWidget(parent)
, m_maxDesktops(0)
, m_desktopConfig(0)
{
m_namesLayout = new QGridLayout;
m_namesLayout->setMargin(0);
setLayout(m_namesLayout);
}
DesktopNamesWidget::~DesktopNamesWidget()
{
}
void DesktopNamesWidget::numberChanged(int number)
{
if ((number < 1) || (number > m_maxDesktops))
return;
if (m_nameInputs.size() != number) {
if (number < m_nameInputs.size()) {
// remove widgets
while (number != m_nameInputs.size()) {
KLineEdit* edit = m_nameInputs.last();
m_nameInputs.removeLast();
delete edit;
QLabel* label = m_nameLabels.last();
m_nameLabels.removeLast();
delete label;
}
} else {
// add widgets
while (number != m_nameInputs.size()) {
int desktop = m_nameInputs.size();
QLabel* label = new QLabel(i18n("Desktop %1:", desktop + 1), this);
KLineEdit* edit = new KLineEdit(this);
label->setWhatsThis(i18n("Here you can enter the name for desktop %1", desktop + 1));
edit->setWhatsThis(i18n("Here you can enter the name for desktop %1", desktop + 1));
m_namesLayout->addWidget(label, desktop % 10, 0 + 2 *(desktop >= 10), 1, 1);
m_namesLayout->addWidget(edit, desktop % 10, 1 + 2 *(desktop >= 10), 1, 1);
m_nameInputs << edit;
m_nameLabels << label;
setDefaultName(desktop + 1);
if (desktop > 1) {
setTabOrder(m_nameInputs[desktop - 1], m_nameInputs[desktop]);
}
connect(edit, SIGNAL(textChanged(QString)), SIGNAL(changed()));
}
}
}
}
QString DesktopNamesWidget::name(int desktop)
{
if ((desktop < 1) || (desktop > m_maxDesktops) || (desktop > m_nameInputs.size()))
return QString();
return m_nameInputs[ desktop -1 ]->text();
}
void DesktopNamesWidget::setName(int desktop, QString desktopName)
{
if ((desktop < 1) || (desktop > m_maxDesktops) || (desktop > m_nameInputs.size()))
return;
m_nameInputs[ desktop-1 ]->setText(desktopName);
}
void DesktopNamesWidget::setDefaultName(int desktop)
{
if ((desktop < 1) || (desktop > m_maxDesktops))
return;
QString name = m_desktopConfig->cachedDesktopName(desktop);
if (name.isEmpty())
name = i18n("Desktop %1", desktop);
m_nameInputs[ desktop -1 ]->setText(name);
}
void DesktopNamesWidget::setMaxDesktops(int maxDesktops)
{
m_maxDesktops = maxDesktops;
}
void DesktopNamesWidget::setDesktopConfig(KWinDesktopConfig* desktopConfig)
{
m_desktopConfig = desktopConfig;
}
} // namespace
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 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/>.
*********************************************************************/
#ifndef DESKTOPNAMESWIDGET_H
#define DESKTOPNAMESWIDGET_H
#include <QWidget>
#include <QList>
class KLineEdit;
class QLabel;
class QGridLayout;
namespace KWin
{
class KWinDesktopConfig;
class DesktopNamesWidget : public QWidget
{
Q_OBJECT
public:
explicit DesktopNamesWidget(QWidget *parent);
~DesktopNamesWidget();
QString name(int desktop);
void setName(int desktop, QString desktopName);
void setDefaultName(int desktop);
void setMaxDesktops(int maxDesktops);
void setDesktopConfig(KWinDesktopConfig *desktopConfig);
Q_SIGNALS:
void changed();
public Q_SLOTS:
void numberChanged(int number);
private:
QList< QLabel* > m_nameLabels;
QList< KLineEdit* > m_nameInputs;
QGridLayout* m_namesLayout;
int m_maxDesktops;
KWinDesktopConfig *m_desktopConfig;
};
} // namespace
#endif // DESKTOPNAMESWIDGET_H
This diff is collapsed.
/*
* Copyright (C) 2018 Eike Hein <hein@kde.org>
* Copyright (C) 2018 Marco Martin <mart@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/>.
*/
#ifndef DESKTOPSMODEL_H
#define DESKTOPSMODEL_H
#include <QAbstractListModel>
#include "../virtualdesktopsdbustypes.h"
class QDBusArgument;
class QDBusMessage;
class QDBusServiceWatcher;
namespace KWin
{
/**
* @short An item model around KWin's D-Bus API for virtual desktops.
*
* The model initially gets the state from KWin and populates.
*
* As long as the user makes no changes, KWin-side changes are directly
* exposed in the model.
*
* If the user makes changes (see the `userModified` property), it stops
* exposing KWin-side changes live, but it keeps track of the KWin-side
* changes, so it can figure out and apply the delta when `syncWithServer`
* is called.
*
* When KWin-side changes happen while the model is user-modified, the
* model signals this via the `serverModified` property. A call to
* `syncWithServer` will overwrite the KWin-side changes.
*
* After synchronization, the model tracks Kwin-side changes again,
* until the user makes further changes.
*
* @author Eike Hein <hein@kde.org>
**/
class DesktopsModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged)
Q_PROPERTY(QString error READ error NOTIFY errorChanged)
Q_PROPERTY(bool userModified READ userModified NOTIFY userModifiedChanged)
Q_PROPERTY(bool serverModified READ serverModified NOTIFY serverModifiedChanged)
Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
public:
enum AdditionalRoles {
Id = Qt::UserRole + 1,
DesktopRow
};
Q_ENUM(AdditionalRoles)
explicit DesktopsModel(QObject *parent = nullptr);
~DesktopsModel() override;
QHash<int, QByteArray> roleNames() const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = {}) const override;
bool ready() const;
QString error() const;
bool userModified() const;
bool serverModified() const;
int rows() const;
void setRows(int rows);
Q_INVOKABLE void createDesktop(const QString &name);
Q_INVOKABLE void removeDesktop(const QString &id);
Q_INVOKABLE void setDesktopName(const QString &id, const QString &name);
Q_INVOKABLE void syncWithServer();
Q_SIGNALS:
void readyChanged() const;
void errorChanged() const;
void userModifiedChanged() const;
void serverModifiedChanged() const;
void rowsChanged() const;
protected Q_SLOTS:
void reset();
void getAllAndConnect(const QDBusMessage &msg);
void desktopCreated(const QString &id, const KWin::DBusDesktopDataStruct &data);
void desktopRemoved(const QString &id);
void desktopDataChanged(const QString &id, const KWin::DBusDesktopDataStruct &data);
void desktopRowsChanged(uint rows);
void updateModifiedState(bool server = false);
void handleCallError();
private:
QDBusServiceWatcher *m_serviceWatcher;
QString m_error;
bool m_userModified;
bool m_serverModified;
QStringList m_serverSideDesktops;
QHash<QString,QString> m_serverSideNames;
int m_serverSideRows;
QStringList m_desktops;
QHash<QString,QString> m_names;
int m_rows;
bool m_synchronizing;
};
}
#endif
[Desktop Entry]
Exec=kcmshell5 kcm_kwin_virtualdesktops
Icon=preferences-desktop
Type=Service
X-KDE-ServiceTypes=KCModule
X-DocPath=kcontrol/desktop/index.html
Icon=preferences-desktop
Exec=kcmshell5 desktop
X-DocPath=kcontrol/kwin_virtualdesktops/index.html
X-KDE-Library=kcm_kwindesktop
X-KDE-Library=kcm_kwin_virtualdesktops
X-KDE-ParentApp=kcontrol
X-KDE-System-Settings-Parent-Category=desktopbehavior
......@@ -143,7 +143,7 @@ X-KDE-Keywords[nds]=Schriefdisch,Schriefdischen,virtuell,mehr,Schriefdisch-Över
X-KDE-Keywords[nl]=bureaublad,bureaubladen,aantal,virtueel bureaublad,meervoudige bureaubladen,pager,pager-widget,pager-applet,pagerinstellingen
X-KDE-Keywords[nn]=skrivebord,mengd,tal,virtuelt skrivebord,fleire skrivebord,vekslar,vekslarelement,vekslarelement,vekslerinnstillinger,vekslaroppsett
X-KDE-Keywords[pa]=ਡੈਸਕਟਾਪ,ਗਿਣਤੀ,ਨੰਬਰ,ਅੰਕ,ਵਰਚੁਅਲ ਡੈਸਕਟਾਪ,ਕਈ ਡੈਸਕਟਾਪ,ਪੇਜ਼ਰ,ਪੇਜ਼ਰ ਵਿਜੈਟ,ਪੇਜ਼ਰ ਐਪਲਿਟ,ਪੇਜ਼ਰ ਸੈਟਿੰਗਾਂ
X-KDE-Keywords[pl]=pulpit,pulpity,liczba,pulpity wirtualne,wiele pulpitów
X-KDE-Keywords[pl]=pulpit,pulpity,liczba,pulpity wirtualne,wiele pulpitów
X-KDE-Keywords[pt]=ecrã,ecrãs,número,ecrã virtual,múltiplos ecrãs,paginador,elemento paginador,'applet' do paginador,configuração do paginador
X-KDE-Keywords[pt_BR]=área de trabalho,áreas de trabalho,desktop,desktops,número,área de trabalho virtual,múltiplas áreas de trabalho,paginador,elemento paginador,miniaplicativo do paginador,configurações do paginador
X-KDE-Keywords[ru]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,рабочий стол,рабочие столы,число,виртуальный рабочий стол,несколько рабочих столов,переключатель,переключение,виджет переключения,аплет переключения,параметры переключения,настройки переключения
......@@ -159,3 +159,6 @@ X-KDE-Keywords[uk]=desktop,desktops,number,virtual desktop,multiple desktops,pag
X-KDE-Keywords[x-test]=xxdesktopxx,xxdesktopsxx,xxnumberxx,xxvirtual desktopxx,xxmultiple desktopsxx,xxpagerxx,xxpager widgetxx,xxpager appletxx,xxpager settingsxx
X-KDE-Keywords[zh_CN]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,桌面,虚拟桌面,多桌面,分页,分页器,分页器组件,分页器设置
X-KDE-Keywords[zh_TW]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings
Categories=Qt;KDE;X-KDE-settings-translations;
This diff is collapsed.
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 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/>.
*********************************************************************/
#ifndef __MAIN_H__
#define __MAIN_H__
#include <kcmodule.h>
#include <ksharedconfig.h>
#include "ui_main.h"
class KActionCollection;
class KConfigGroup;
class KShortcutsEditor;
namespace KWin
{
// if you change this, update also the number of keyboard shortcuts in kwin/kwinbindings.cpp
static const int maxDesktops = 20;
static const int defaultDesktops = 4;
class KWinDesktopConfigForm : public QWidget, public Ui::KWinDesktopConfigForm
{
Q_OBJECT
public:
explicit KWinDesktopConfigForm(QWidget* parent);
};
class KWinDesktopConfig : public KCModule
{
Q_OBJECT
public:
explicit KWinDesktopConfig(QWidget* parent, const QVariantList& args);
~KWinDesktopConfig();
QString cachedDesktopName(int desktop);
// undo all changes
void undo();
public Q_SLOTS:
virtual void save();
virtual void load();
virtual void defaults();
private Q_SLOTS:
void slotChangeShortcuts(int number);
void slotShowAllShortcuts();
void slotEffectSelectionChanged(int index);
void slotAboutEffectClicked();
void slotConfigureEffectClicked();
private:
void init();
void addAction(const QString &name, const QString &label);
bool effectEnabled(const QString& effect, const KConfigGroup& cfg) const;
QString extrapolatedShortcut(int desktop) const;
private:
KWinDesktopConfigForm* m_ui;
KSharedConfigPtr m_config;
// cache for desktop names given by NETRootInfo
// needed as the widget only stores the names for actual number of desktops
QStringList m_desktopNames;
// Collection for switching desktops like ctrl+f1
KActionCollection* m_actionCollection;
// Collection for next, previous, up, down desktop
KActionCollection* m_switchDesktopCollection;
KShortcutsEditor* m_editor;
};
} // namespace
#endif
This diff is collapsed.
/*
* Copyright (C) 2018 Eike Hein <hein@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
import QtQuick 2.1
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.4 as QtControls
import org.kde.kirigami 2.5 as Kirigami
import org.kde.plasma.core 2.1 as PlasmaCore
import org.kde.kcm 1.2
ScrollViewKCM {
id: root
ConfigModule.quickHelp: i18n("Virtual Desktops")
Connections {
target: kcm.desktopsModel
onReadyChanged: {
rowsSpinBox.value = kcm.desktopsModel.rows;
}
onRowsChanged: {
rowsSpinBox.value = kcm.desktopsModel.rows;
}
}
Component {
id: desktopsListItemComponent
Kirigami.SwipeListItem {
id: listItem
contentItem: RowLayout {
QtControls.TextField {
id: nameField
background: null
leftPadding: Kirigami.Units.largeSpacing
topPadding: 0
bottomPadding: 0
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
text: model.display
readOnly: true
onEditingFinished: {
readOnly = true;
Qt.callLater(kcm.desktopsModel.setDesktopName, model.Id, text);
}
}
}
actions: [
Kirigami.Action {
enabled: !model.IsMissing
iconName: "edit-rename"
tooltip: i18nc("@info:tooltip", "Rename")
onTriggered: {
nameField.readOnly = false;
nameField.selectAll();
nameField.forceActiveFocus();
}
},
Kirigami.Action {
enabled: !model.IsMissing
iconName: "list-remove"
tooltip: i18nc("@info:tooltip", "Remove")
onTriggered: kcm.desktopsModel.removeDesktop(model.Id)
}]
}
}
header: ColumnLayout {
id: messagesLayout
spacing: Kirigami.Units.largeSpacing
Kirigami.InlineMessage {
Layout.fillWidth: true
type: Kirigami.MessageType.Error
text: kcm.desktopsModel.error
visible: kcm.desktopsModel.error != ""
}
Kirigami.InlineMessage {
Layout.fillWidth: true
type: Kirigami.MessageType.Information
text: i18n("Virtual desktops have been changed outside this settings application. Saving now will overwrite the changes.")
visible: kcm.desktopsModel.serverModified
}
RowLayout {
QtControls.Label {
text: i18n("Rows:")
}
QtControls.SpinBox {
id: rowsSpinBox
from: 1
to: 20
onValueModified: kcm.desktopsModel.rows = value
}
Item { // Spacer
Layout.fillWidth: true
}
QtControls.Button {
Layout.alignment: Qt.AlignRight
text: i18nc("@action:button", "Add")
icon.name: "list-add"
onClicked: kcm.desktopsModel.createDesktop(i18n("New Desktop"))
}
}
}
view: ListView {
id: desktopsList
model: kcm.desktopsModel.ready ? kcm.desktopsModel : null
section.property: "DesktopRow"
section.delegate: Kirigami.AbstractListItem {
width: desktopsList.width
backgroundColor: Kirigami.Theme.backgroundColor
hoverEnabled: false
supportsMouseEvents: false
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
QtControls.Label {
text: i18n("Row %1", section)
}
}
delegate: Kirigami.DelegateRecycler {
width: desktopsList.width
sourceComponent: desktopsListItemComponent
}
}
footer: ColumnLayout {