diff --git a/kcmkwin/CMakeLists.txt b/kcmkwin/CMakeLists.txt --- a/kcmkwin/CMakeLists.txt +++ b/kcmkwin/CMakeLists.txt @@ -6,7 +6,7 @@ add_subdirectory( kwinrules ) add_subdirectory( kwinscreenedges ) add_subdirectory( kwinscripts ) -add_subdirectory( kwindesktop ) +add_subdirectory( kwindesktopng ) if( KWIN_BUILD_TABBOX ) add_subdirectory( kwintabbox ) diff --git a/kcmkwin/kwindesktopng/CMakeLists.txt b/kcmkwin/kwindesktopng/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/kcmkwin/kwindesktopng/CMakeLists.txt @@ -0,0 +1,27 @@ +include(ECMQMLModules) +ecm_find_qmlmodule(org.kde.plasma.core 2.0) + +# KI18N Translation Domain for this library. +add_definitions(-DTRANSLATION_DOMAIN=\"kcm_kwin_virtualdesktops\") + +########### next target ############### + +set(kcm_kwin_virtualdesktops_PART_SRCS virtualdesktops.cpp desktopsmodel.cpp) + +add_library(kcm_kwin_virtualdesktops MODULE ${kcm_kwin_virtualdesktops_PART_SRCS}) + +target_link_libraries(kcm_kwin_virtualdesktops + Qt5::DBus + KF5::I18n + KF5::KCMUtils + KF5::QuickAddons +) + +kcoreaddons_desktop_to_json(kcm_kwin_virtualdesktops "kcm_kwin_virtualdesktops.desktop") + +########### install files ############### + +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) + diff --git a/kcmkwin/kwindesktopng/Messages.sh b/kcmkwin/kwindesktopng/Messages.sh new file mode 100644 --- /dev/null +++ b/kcmkwin/kwindesktopng/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.cpp -o -name \*.qml` -o $podir/kcm_kwin_virtualdesktops.pot diff --git a/kcmkwin/kwindesktopng/desktopsmodel.h b/kcmkwin/kwindesktopng/desktopsmodel.h new file mode 100644 --- /dev/null +++ b/kcmkwin/kwindesktopng/desktopsmodel.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2018 Eike Hein + * Copyright (C) 2018 Marco Martin + * + * 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 DESKTOPSMODEL_H +#define DESKTOPSMODEL_H + +#include + +class QDBusArgument; +class QDBusMessage; + + +namespace KWin { + +struct DBusDesktopDataStruct { + uint x11DesktopNumber; + QString id; + QString name; +}; + +typedef QVector DBusDesktopDataVector; + +class DesktopsModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(bool ready READ ready NOTIFY readyChanged) + Q_PROPERTY(QString error READ error NOTIFY errorChanged) + 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 roleNames() const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + bool ready() const; + QString error() 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_SIGNALS: + void readyChanged() const; + void errorChanged() const; + void rowsChanged() const; + + protected Q_SLOTS: + void initialize(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 handleCallError(); + + private: + QString m_error; + QStringList m_desktops; + QHash m_names; + int m_rows; +}; + +} + +const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataStruct &desk); +const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataStruct &desk); + +Q_DECLARE_METATYPE(KWin::DBusDesktopDataStruct) + +const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataVector &deskVector); +const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataVector &deskVector); + +Q_DECLARE_METATYPE(KWin::DBusDesktopDataVector) + +#endif diff --git a/kcmkwin/kwindesktopng/desktopsmodel.cpp b/kcmkwin/kwindesktopng/desktopsmodel.cpp new file mode 100644 --- /dev/null +++ b/kcmkwin/kwindesktopng/desktopsmodel.cpp @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2018 Eike Hein + * Copyright (C) 2018 Marco Martin + * + * 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 "desktopsmodel.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace KWin { + +static const QString s_serviceName(QStringLiteral("org.kde.KWin")); +static const QString s_virtualDesktopsInterface(QStringLiteral("org.kde.KWin.VirtualDesktopManager")); +static const QString s_virtDesktopsPath(QStringLiteral("/VirtualDesktopManager")); +static const QString s_fdoPropertiesInterface(QStringLiteral("org.freedesktop.DBus.Properties")); + +DesktopsModel::DesktopsModel(QObject *parent) + : QAbstractListModel(parent) + , m_rows(-1) +{ + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + + auto handleConnectionError = [this]() { + m_error = i18n("There was an error connecting to the compositor."); + emit errorChanged(); + }; + + bool connected = QDBusConnection::sessionBus().connect( + s_serviceName, + s_virtDesktopsPath, + s_virtualDesktopsInterface, + QStringLiteral("desktopCreated"), + this, + SLOT(desktopCreated(QString,KWin::DBusDesktopDataStruct))); + + if (!connected) { + handleConnectionError(); + + return; + } + + connected = QDBusConnection::sessionBus().connect( + s_serviceName, + s_virtDesktopsPath, + s_virtualDesktopsInterface, + QStringLiteral("desktopRemoved"), + this, + SLOT(desktopRemoved(QString))); + + if (!connected) { + handleConnectionError(); + + return; + } + + connected = QDBusConnection::sessionBus().connect( + s_serviceName, + s_virtDesktopsPath, + s_virtualDesktopsInterface, + QStringLiteral("desktopDataChanged"), + this, + SLOT(desktopDataChanged(QString,KWin::DBusDesktopDataStruct))); + + if (!connected) { + handleConnectionError(); + + return; + } + + connected = QDBusConnection::sessionBus().connect( + s_serviceName, + s_virtDesktopsPath, + s_virtualDesktopsInterface, + QStringLiteral("rowsChanged"), + this, + SLOT(desktopRowsChanged(uint))); + + if (!connected) { + handleConnectionError(); + + return; + } + + auto initializeCall = QDBusMessage::createMethodCall( + s_serviceName, + s_virtDesktopsPath, + s_fdoPropertiesInterface, + QStringLiteral("GetAll")); + + initializeCall.setArguments({s_virtualDesktopsInterface}); + + QDBusConnection::sessionBus().callWithCallback( + initializeCall, + this, + SLOT(initialize(QDBusMessage)), + SLOT(handleCallError())); +} + +DesktopsModel::~DesktopsModel() +{ +} + +QHash DesktopsModel::roleNames() const +{ + QHash roles = QAbstractItemModel::roleNames(); + + QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("AdditionalRoles")); + + for (int i = 0; i < e.keyCount(); ++i) { + roles.insert(e.value(i), e.key(i)); + } + + return roles; +} + +QVariant DesktopsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() < 0 || index.row() > (m_desktops.count() - 1)) { + return QVariant(); + } + + if (role == Qt::DisplayRole) { + return m_names.value(m_desktops.at(index.row())); + } else if (role == Id) { + return m_desktops.at(index.row()); + } else if (role == DesktopRow) { + const int rows = std::max(m_rows, 1); + const int perRow = std::ceil((qreal)m_desktops.count() / (qreal)rows); + + return (index.row() / perRow) + 1; + + } + + return QVariant(); +} + +int DesktopsModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) { + return 0; + } + + return m_desktops.count(); +} + +bool DesktopsModel::ready() const +{ + return !m_desktops.isEmpty(); +} + +QString DesktopsModel::error() const +{ + return m_error; +} + +int DesktopsModel::rows() const +{ + return m_rows; +} + +void DesktopsModel::setRows(int rows) +{ + if (!ready() || rows < 1) { + return; + } + + auto call = QDBusMessage::createMethodCall( + s_serviceName, + s_virtDesktopsPath, + s_fdoPropertiesInterface, + QStringLiteral("Set")); + + call.setArguments({s_virtualDesktopsInterface, + QStringLiteral("rows"), QVariant::fromValue(QDBusVariant(QVariant((uint)rows)))}); + + QDBusConnection::sessionBus().asyncCall(call); +} + +void DesktopsModel::createDesktop(const QString &name) +{ + if (!ready()) { + return; + } + + auto call = QDBusMessage::createMethodCall( + s_serviceName, + s_virtDesktopsPath, + s_virtualDesktopsInterface, + QStringLiteral("createDesktop")); + + // FIXME TODO: Positions are currently not zero- but one-indexed in KWin it seems. + call.setArguments({(uint)m_desktops.count() + 1, name}); + + QDBusConnection::sessionBus().asyncCall(call); +} + +void DesktopsModel::removeDesktop(const QString &id) +{ + if (!ready() || !m_desktops.contains(id)) { + return; + } + + auto call = QDBusMessage::createMethodCall( + s_serviceName, + s_virtDesktopsPath, + s_virtualDesktopsInterface, + QStringLiteral("removeDesktop")); + + call.setArguments({id}); + + QDBusConnection::sessionBus().asyncCall(call); +} + +void DesktopsModel::setDesktopName(const QString &id, const QString &name) +{ + if (!ready() || !m_desktops.contains(id)) { + return; + } + + auto call = QDBusMessage::createMethodCall( + s_serviceName, + s_virtDesktopsPath, + s_virtualDesktopsInterface, + QStringLiteral("setDesktopName")); + + call.setArguments({id, name}); + + QDBusConnection::sessionBus().asyncCall(call); +} + +void DesktopsModel::initialize(const QDBusMessage &msg) +{ + beginResetModel(); + + const QVariantMap &data = qdbus_cast(msg.arguments().at(0).value()); + + const KWin::DBusDesktopDataVector &desktops = qdbus_cast( + data.value(QLatin1String("desktops")).value() + ); + + m_rows = data.value(QLatin1String("rows")).toUInt(); + + foreach(const KWin::DBusDesktopDataStruct &d, desktops) { + m_desktops.append(d.id); + m_names[d.id] = d.name; + } + + endResetModel(); + + emit readyChanged(); +} + +void DesktopsModel::desktopCreated(const QString &id, const KWin::DBusDesktopDataStruct &data) +{ + // FIXME TODO: We don't get an insert index from the API, so for now + // we always append. + + beginInsertRows(QModelIndex(), m_desktops.count(), m_desktops.count()); + + m_desktops.append(id); + m_names[data.id] = data.name; + + endInsertRows(); +} + +void DesktopsModel::desktopRemoved(const QString &id) +{ + const int desktopIndex = m_desktops.indexOf(id); + + beginRemoveRows(QModelIndex(), desktopIndex, desktopIndex); + + m_desktops.removeAt(desktopIndex); + m_names.remove(id); + + endRemoveRows(); +} + +void DesktopsModel::desktopDataChanged(const QString &id, const KWin::DBusDesktopDataStruct &data) +{ + const int desktopIndex = m_desktops.indexOf(id); + + m_desktops[desktopIndex] = id; + m_names[id] = data.name; + + const QModelIndex &idx = index(desktopIndex, 0); + + dataChanged(idx, idx, QVector{Qt::DisplayRole}); +} + +void DesktopsModel::desktopRowsChanged(uint rows) +{ + m_rows = rows; + + emit rowsChanged(); + emit dataChanged(index(0, 0), index(m_desktops.count() - 1, 0), QVector{DesktopRow}); +} + +void DesktopsModel::handleCallError() +{ + m_error = i18n("There was an error requesting information from the compositor."); + emit errorChanged(); +} + +} + +const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataStruct &desk) +{ + argument.beginStructure(); + argument << desk.x11DesktopNumber; + argument << desk.id; + argument << desk.name; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataStruct &desk) +{ + argument.beginStructure(); + argument >> desk.x11DesktopNumber; + argument >> desk.id; + argument >> desk.name; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataVector &deskVector) +{ + argument.beginArray(qMetaTypeId()); + for (int i = 0; i < deskVector.size(); ++i) { + argument << deskVector[i]; + } + argument.endArray(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataVector &deskVector) +{ + argument.beginArray(); + deskVector.clear(); + + while (!argument.atEnd()) { + KWin::DBusDesktopDataStruct element; + argument >> element; + deskVector.append(element); + } + + argument.endArray(); + + return argument; +} diff --git a/kcmkwin/kwindesktopng/kcm_kwin_virtualdesktops.desktop b/kcmkwin/kwindesktopng/kcm_kwin_virtualdesktops.desktop new file mode 100644 --- /dev/null +++ b/kcmkwin/kwindesktopng/kcm_kwin_virtualdesktops.desktop @@ -0,0 +1,164 @@ +[Desktop Entry] +Exec=kcmshell5 kwn_virtualdesktops +Icon=preferences-desktop +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/kwin_virtualdesktops/index.html + +X-KDE-Library=kcm_kwin_virtualdesktops +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=desktopbehavior +X-KDE-Weight=60 + +Name=Virtual Desktops NG +Name[ar]=أسطح المكتب الافتراضية +Name[bg]=Виртуални работни плотове +Name[bs]=Virtuelne površi +Name[ca]=Escriptoris virtuals +Name[ca@valencia]=Escriptoris virtuals +Name[cs]=Virtuální plochy +Name[da]=Virtuelle skriveborde +Name[de]=Virtuelle Arbeitsflächen +Name[el]=Εικονικές επιφάνειες εργασίες +Name[en_GB]=Virtual Desktops +Name[es]=Escritorios virtuales +Name[et]=Virtuaalsed töölauad +Name[eu]=Alegiazko mahaigaina +Name[fi]=Virtuaalityöpöydät +Name[fr]=Bureaux virtuels +Name[ga]=Deasca Fíorúla +Name[gl]=Escritorios virtuais +Name[gu]=વર્ચ્યુઅલ ડેસ્કટોપો +Name[he]=שולחנות עבודה וירטואליים +Name[hi]=आभासी डेस्कटॉप +Name[hr]=Virtualne radne površine +Name[hu]=Virtuális asztalok +Name[ia]=Scriptorios virtual +Name[id]=Desktop Virtual +Name[is]=Sýndarskjáborð +Name[it]=Desktop virtuali +Name[ja]=仮想デスクトップ +Name[kk]=Виртуалды Үстелдер +Name[km]=ផ្ទៃតុ​និម្មិត +Name[kn]=ವಾಸ್ತವಪ್ರಾಯ ಗಣಕತೆರೆಗಳು +Name[ko]=가상 데스크톱 +Name[lt]=Virtualūs darbalaukiai +Name[lv]=Virtuālās darbvirsmas +Name[mr]=आभासी डेस्कटॉप +Name[nb]=Virtuelle skrivebord +Name[nds]=Mehr Schriefdischen +Name[nl]=Virtuele bureaubladen +Name[nn]=Virtuelle skrivebord +Name[pa]=ਵਰਚੁਅਲ ਡੈਸਕਟਾਪ +Name[pl]=Pulpity wirtualne +Name[pt]=Ecrãs Virtuais +Name[pt_BR]=Áreas de trabalho virtuais +Name[ro]=Birouri virtuale +Name[ru]=Рабочие столы +Name[si]=අත්ථ්‍ය වැඩතල +Name[sk]=Virtuálne pracovné plochy +Name[sl]=Navidezna namizja +Name[sr]=Виртуелне површи +Name[sr@ijekavian]=Виртуелне површи +Name[sr@ijekavianlatin]=Virtuelne površi +Name[sr@latin]=Virtuelne površi +Name[sv]=Virtuella skrivbord +Name[tg]=Мизҳои кории виртуалӣ +Name[th]=พื้นที่ทำงานเสมือน +Name[tr]=Sanal Masaüstleri +Name[ug]=مەۋھۇم ئۈستەلئۈستى +Name[uk]=Віртуальні стільниці +Name[wa]=Forveyous scribannes +Name[x-test]=xxVirtual Desktopsxx +Name[zh_CN]=虚拟桌面 +Name[zh_TW]=虛擬桌面 + +Comment=Navigation, Number and Layout of Virtual Desktops +Comment[bs]=Navigacija, broj i izgled virtualnih desktopa +Comment[ca]=Navegació, nombre i disposició dels escriptoris virtuals +Comment[ca@valencia]=Navegació, nombre i disposició dels escriptoris virtuals +Comment[cs]=Navigace, počet a rozvržení virtuálních ploch +Comment[da]=Navigation, antal og layout af virtuelle skriveborde +Comment[de]=Navigation, Anzahl und Layout virtueller Arbeitsflächen +Comment[el]=Περιήγηση, αριθμός και διάταξη εικονικών επιφανειών εργασίας +Comment[en_GB]=Navigation, Number and Layout of Virtual Desktops +Comment[es]=Navegación, número y disposición de los escritorios virtuales +Comment[et]=Virtuaalsete töölaudade vahel liikumine, nende arv ja paigutus +Comment[eu]=Nabigazioa, alegiazko mahaigainen kopurua eta antolamendua +Comment[fi]=Virtuaalityöpöytien vaihtaminen, määrä ja asettelu +Comment[fr]=Navigation, nombre et disposition des bureaux virtuels +Comment[gl]=Navegación, cantidade e disposición dos escritorios virtuais +Comment[he]=ניווט, פריסה ומספר שולחנות עבודה וירטואלים +Comment[hu]=Navigáció, a virtuális asztalok száma és elrendezése +Comment[id]=Navigasi, Jumlah dan Tata Letak Desktop Virtual +Comment[it]=Navigazione, numero e disposizione dei desktop virtuali +Comment[ko]=가상 데스크톱 탐색, 개수, 레이아웃 +Comment[lt]=Naršymas, Skaičius ir išdėstymas virtualių darbalaukių +Comment[nb]=Navigering, antall og utlegg av virtuelle skrivebord +Comment[nds]=Tall, Anornen un dat Anstüern vun de virtuellen Schriefdischen fastleggen +Comment[nl]=Navigatie door, aantal en indeling van virtuele bureaubladen +Comment[nn]=Navigering, nummer og vising av virtuelle skrivebord +Comment[pa]=ਵਰਚੁਅਲ ਡੈਸਕਟਾਪਾਂ ਲਈ ਨੇਵੀਗੇਸ਼ਨ, ਗਿਣਤੀ ਅਤੇ ਢਾਂਚਾ +Comment[pl]=Poruszanie się, liczba i układ wirtualnych pulpitów +Comment[pt]=Navegação, Número e Disposição dos Ecrãs Virtuais +Comment[pt_BR]=Navegação, quantidade e layout das áreas de trabalho virtuais +Comment[ru]=Число, расположение и способ переключения рабочих столов +Comment[sk]=Navigácia, počet a rozloženie virtuálnych plôch +Comment[sl]=Krmarjenje med, število in razporeditev navideznih namizij +Comment[sr]=Кретање, број и распоред виртуелних површи +Comment[sr@ijekavian]=Кретање, број и распоред виртуелних површи +Comment[sr@ijekavianlatin]=Kretanje, broj i raspored virtuelnih površi +Comment[sr@latin]=Kretanje, broj i raspored virtuelnih površi +Comment[sv]=Navigering, antal och layout av virtuella skrivbord +Comment[tr]=Gezinti, Sanal Masaüstlerinin Sayısı ve Yerleşimi +Comment[uk]=Навігація, кількість та компонування віртуальних стільниць +Comment[vi]=Số lượng, bố trí và điều hướng của màn hình ảo +Comment[x-test]=xxNavigation, Number and Layout of Virtual Desktopsxx +Comment[zh_CN]=虚拟桌面的切换,数量和布局 +Comment[zh_TW]=虛擬桌面的導覽、數字與佈局 +X-KDE-Keywords=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings +X-KDE-Keywords[bs]=pozadina,pozadine,broj,virtuelna pozadina,višestruka pozadina,pejdžer,dodatak pejdžeru,aplet pejdžer,pejdžer postavke +X-KDE-Keywords[ca]=escriptori,escriptoris,nombre,escriptori virtual,escriptoris múltiples,paginador,estri paginador,miniaplicació de paginació,arranjament de paginador +X-KDE-Keywords[ca@valencia]=escriptori,escriptoris,nombre,escriptori virtual,escriptoris múltiples,paginador,estri paginador,miniaplicació de paginació,arranjament de paginador +X-KDE-Keywords[da]=skrivebord,skriveborde,desktop,desktops,virtuelt skrivebord,flere skriveborde,spaces,pager,skrivebordsvælger,pager widget,pager applet +X-KDE-Keywords[de]=Arbeitsfläche,Arbeitsflächen,Desktop,Anzahl,Virtuelle Arbeitsfläche,Mehrere Arbeitsflächen,Arbeitsflächenumschalter,Arbeitsflächenumschalter-Bedienelement,Arbeitsflächenumschalter-Miniprogramm,Arbeitsflächenumschalter-Einstellungen +X-KDE-Keywords[el]=επιφάνεια εργασίας,επιφάνειες εργασίας,αριθμός,εικονική επιφάνεια εργασίας,πολλαπλές επιφάνειες εργασίας,χαρτί,γραφικό συστατικό χαρτιού,μικροεφαρμογή χαρτιού,ρυθμίσεις χαρτιού +X-KDE-Keywords[en_GB]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings +X-KDE-Keywords[es]=escritorio,escritorios,número,escritorio virtual,múltiples escritorios,paginador,control de paginación,miniaplicación del paginador,preferencias del paginador +X-KDE-Keywords[et]=töölaud,töölauad,arv,virtuaalne töölaud,mitu töölauda,töölauavahetaja,töölaudade vahetaja,töölauavahetaja aplett,töölauavahetaja vidin,töölauavahetaja seadistused +X-KDE-Keywords[eu]=mahaigain,mahaigainak,kopuru,mahaigain birtuala,alegiazko mahaigaina,hainbat mahaigain,bilagailu,bilagailuaren trepeta,bilagailuaren miniaplikazioa,bilagailuaren ezarpenak +X-KDE-Keywords[fi]=työpöytä,työpöydät,lukumäärä,virtuaalityöpöytä,monta työpöytää,sivutin,sivutinsovelma,sivuttimen asetukset +X-KDE-Keywords[fr]=bureau, bureaux, numéro, bureau virtuel, bureaux multiples, gestionnaire de bureau, composant graphique du gestionnaire de bureau, paramètres du gestionnaire de bureaux +X-KDE-Keywords[gl]=escritorio,escritorios,número,escritorio virtual,escritorios múltiplos,paxinador, trebello paxinador, miniaplicativo paxinador,configuración do paxinador +X-KDE-Keywords[hu]=asztal,asztalok,szám,virtuális asztal,több asztal,papír,papír felületi elem,papír kisalkalmazás,papírbeállítások +X-KDE-Keywords[ia]=scriptorio,scriptorios,numero,scriptorio virtual,scriptorio multiple,pager, widget de pager, applet de pager, preferentias de pager +X-KDE-Keywords[id]=desktop,desktop,jumlah,desktop virtual,banyak desktop,halaman,widget halaman,applet halaman,setelan halaman +X-KDE-Keywords[it]=desktop,numero,desktop virtuali,desktop multipli,cambiadesktop,oggetto cambiadesktop,applet cambiadesktop,impostazioni del cambiadesktop +X-KDE-Keywords[kk]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings +X-KDE-Keywords[km]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings +X-KDE-Keywords[ko]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,데스크톱,가상 데스크톱,다중 데스크톱 +X-KDE-Keywords[nb]=skrivebord,antall,virtuelt skrivebord,flere skrivebord,veksler,vekslerelement,veksler-miniprogram,vekslerinnstillinger +X-KDE-Keywords[nds]=Schriefdisch,Schriefdischen,virtuell,mehr,Schriefdisch-Översicht,instellen +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[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,рабочий стол,рабочие столы,число,виртуальный рабочий стол,несколько рабочих столов,переключатель,переключение,виджет переключения,аплет переключения,параметры переключения,настройки переключения +X-KDE-Keywords[sk]=plocha,plochy,číslo,virtuálna plocha,viac plôch,pager,widget pagera,applet pagera,nastavenia pagera +X-KDE-Keywords[sl]=namizje,namizja,število namizij,navidezna namizja,več namizij,pozivnik +X-KDE-Keywords[sr]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,површ,број,виртуелна површ,више површи,листач,виџет листача,аплет листача,поставке листача +X-KDE-Keywords[sr@ijekavian]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,површ,број,виртуелна површ,више површи,листач,виџет листача,аплет листача,поставке листача +X-KDE-Keywords[sr@ijekavianlatin]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,površ,broj,virtuelna površ,više površi,listač,vidžet listača,aplet listača,postavke listača +X-KDE-Keywords[sr@latin]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,površ,broj,virtuelna površ,više površi,listač,vidžet listača,aplet listača,postavke listača +X-KDE-Keywords[sv]=skrivbord,antal,virtuellt skrivbord,flera skrivbord,skrivbordsvisning,visningskomponent,visningsminiprogram,visningsinställningar +X-KDE-Keywords[tr]=masaüstü,masaüstleri,sayı,sanal masaüstü,çoklu masaüstü,sayfalayıcı,sayfalayıcı gereci,sayfalayıcı gereci,sayfalayıcı ayarları +X-KDE-Keywords[uk]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,стільниця,стільниці,кількість,віртуальна стільниця,перемикач,пейджер,віджет перемикача,віджет пейджера,аплет перемикання,аплет перемикача,параметри перемикання,параметри перемикача +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; diff --git a/kcmkwin/kwindesktopng/org.kde.kwin.virtualdesktopmanager.xml b/kcmkwin/kwindesktopng/org.kde.kwin.virtualdesktopmanager.xml new file mode 100644 --- /dev/null +++ b/kcmkwin/kwindesktopng/org.kde.kwin.virtualdesktopmanager.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/kcmkwin/kwindesktopng/package/contents/ui/main.qml b/kcmkwin/kwindesktopng/package/contents/ui/main.qml new file mode 100644 --- /dev/null +++ b/kcmkwin/kwindesktopng/package/contents/ui/main.qml @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2018 Eike Hein + * + * 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.3 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 NG") + + 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 + + // FIXME TODO: The KCM steals Return and closes otherwise, for some + // reason, so I can't use onAccepted. + Keys.onReturnPressed: { + readOnly = true; + Qt.callLater(kcm.desktopsModel.setDesktopName, model.Id, text); + } + + // FIXME TODO: See above. + Keys.onEnterPressed: { + 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 != "" + } + + QtControls.Label { + Layout.fillWidth: true + + text: i18n("Amazing intro string about virtual desktops.") + } + } + + view: ListView { + id: desktopsList + + model: kcm.desktopsModel.ready ? kcm.desktopsModel : null + + section.property: "DesktopRow" + section.delegate: Kirigami.AbstractListItem { + QtControls.Label { + text: i18n("Row %1", section) + } + } + + delegate: Kirigami.DelegateRecycler { + width: desktopsList.width + + sourceComponent: desktopsListItemComponent + } + } + + footer: RowLayout { + QtControls.Label { + text: i18n("Rows:") + } + + QtControls.SpinBox { + id: rowsSpinBox + + from: 1 + + onValueModified: kcm.rows = value + } + + Item { // FIXME TODO: Quick gross spacing hack. + 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")) + } + } +} + diff --git a/kcmkwin/kwindesktopng/package/metadata.desktop b/kcmkwin/kwindesktopng/package/metadata.desktop new file mode 100644 --- /dev/null +++ b/kcmkwin/kwindesktopng/package/metadata.desktop @@ -0,0 +1,116 @@ +[Desktop Entry] +Name=Virtual Desktops NG +Name[ar]=أسطح المكتب الافتراضية +Name[bg]=Виртуални работни плотове +Name[bs]=Virtuelne površi +Name[ca]=Escriptoris virtuals +Name[ca@valencia]=Escriptoris virtuals +Name[cs]=Virtuální plochy +Name[da]=Virtuelle skriveborde +Name[de]=Virtuelle Arbeitsflächen +Name[el]=Εικονικές επιφάνειες εργασίες +Name[en_GB]=Virtual Desktops +Name[es]=Escritorios virtuales +Name[et]=Virtuaalsed töölauad +Name[eu]=Alegiazko mahaigaina +Name[fi]=Virtuaalityöpöydät +Name[fr]=Bureaux virtuels +Name[ga]=Deasca Fíorúla +Name[gl]=Escritorios virtuais +Name[gu]=વર્ચ્યુઅલ ડેસ્કટોપો +Name[he]=שולחנות עבודה וירטואליים +Name[hi]=आभासी डेस्कटॉप +Name[hr]=Virtualne radne površine +Name[hu]=Virtuális asztalok +Name[ia]=Scriptorios virtual +Name[id]=Desktop Virtual +Name[is]=Sýndarskjáborð +Name[it]=Desktop virtuali +Name[ja]=仮想デスクトップ +Name[kk]=Виртуалды Үстелдер +Name[km]=ផ្ទៃតុ​និម្មិត +Name[kn]=ವಾಸ್ತವಪ್ರಾಯ ಗಣಕತೆರೆಗಳು +Name[ko]=가상 데스크톱 +Name[lt]=Virtualūs darbalaukiai +Name[lv]=Virtuālās darbvirsmas +Name[mr]=आभासी डेस्कटॉप +Name[nb]=Virtuelle skrivebord +Name[nds]=Mehr Schriefdischen +Name[nl]=Virtuele bureaubladen +Name[nn]=Virtuelle skrivebord +Name[pa]=ਵਰਚੁਅਲ ਡੈਸਕਟਾਪ +Name[pl]=Pulpity wirtualne +Name[pt]=Ecrãs Virtuais +Name[pt_BR]=Áreas de trabalho virtuais +Name[ro]=Birouri virtuale +Name[ru]=Рабочие столы +Name[si]=අත්ථ්‍ය වැඩතල +Name[sk]=Virtuálne pracovné plochy +Name[sl]=Navidezna namizja +Name[sr]=Виртуелне површи +Name[sr@ijekavian]=Виртуелне површи +Name[sr@ijekavianlatin]=Virtuelne površi +Name[sr@latin]=Virtuelne površi +Name[sv]=Virtuella skrivbord +Name[tg]=Мизҳои кории виртуалӣ +Name[th]=พื้นที่ทำงานเสมือน +Name[tr]=Sanal Masaüstleri +Name[ug]=مەۋھۇم ئۈستەلئۈستى +Name[uk]=Віртуальні стільниці +Name[wa]=Forveyous scribannes +Name[x-test]=xxVirtual Desktopsxx +Name[zh_CN]=虚拟桌面 +Name[zh_TW]=虛擬桌面 + +Comment=Navigation, Number and Layout of Virtual Desktops +Comment[bs]=Navigacija, broj i izgled virtualnih desktopa +Comment[ca]=Navegació, nombre i disposició dels escriptoris virtuals +Comment[ca@valencia]=Navegació, nombre i disposició dels escriptoris virtuals +Comment[cs]=Navigace, počet a rozvržení virtuálních ploch +Comment[da]=Navigation, antal og layout af virtuelle skriveborde +Comment[de]=Navigation, Anzahl und Layout virtueller Arbeitsflächen +Comment[el]=Περιήγηση, αριθμός και διάταξη εικονικών επιφανειών εργασίας +Comment[en_GB]=Navigation, Number and Layout of Virtual Desktops +Comment[es]=Navegación, número y disposición de los escritorios virtuales +Comment[et]=Virtuaalsete töölaudade vahel liikumine, nende arv ja paigutus +Comment[eu]=Nabigazioa, alegiazko mahaigainen kopurua eta antolamendua +Comment[fi]=Virtuaalityöpöytien vaihtaminen, määrä ja asettelu +Comment[fr]=Navigation, nombre et disposition des bureaux virtuels +Comment[gl]=Navegación, cantidade e disposición dos escritorios virtuais +Comment[he]=ניווט, פריסה ומספר שולחנות עבודה וירטואלים +Comment[hu]=Navigáció, a virtuális asztalok száma és elrendezése +Comment[id]=Navigasi, Jumlah dan Tata Letak Desktop Virtual +Comment[it]=Navigazione, numero e disposizione dei desktop virtuali +Comment[ko]=가상 데스크톱 탐색, 개수, 레이아웃 +Comment[lt]=Naršymas, Skaičius ir išdėstymas virtualių darbalaukių +Comment[nb]=Navigering, antall og utlegg av virtuelle skrivebord +Comment[nds]=Tall, Anornen un dat Anstüern vun de virtuellen Schriefdischen fastleggen +Comment[nl]=Navigatie door, aantal en indeling van virtuele bureaubladen +Comment[nn]=Navigering, nummer og vising av virtuelle skrivebord +Comment[pa]=ਵਰਚੁਅਲ ਡੈਸਕਟਾਪਾਂ ਲਈ ਨੇਵੀਗੇਸ਼ਨ, ਗਿਣਤੀ ਅਤੇ ਢਾਂਚਾ +Comment[pl]=Poruszanie się, liczba i układ wirtualnych pulpitów +Comment[pt]=Navegação, Número e Disposição dos Ecrãs Virtuais +Comment[pt_BR]=Navegação, quantidade e layout das áreas de trabalho virtuais +Comment[ru]=Число, расположение и способ переключения рабочих столов +Comment[sk]=Navigácia, počet a rozloženie virtuálnych plôch +Comment[sl]=Krmarjenje med, število in razporeditev navideznih namizij +Comment[sr]=Кретање, број и распоред виртуелних површи +Comment[sr@ijekavian]=Кретање, број и распоред виртуелних површи +Comment[sr@ijekavianlatin]=Kretanje, broj i raspored virtuelnih površi +Comment[sr@latin]=Kretanje, broj i raspored virtuelnih površi +Comment[sv]=Navigering, antal och layout av virtuella skrivbord +Comment[tr]=Gezinti, Sanal Masaüstlerinin Sayısı ve Yerleşimi +Comment[uk]=Навігація, кількість та компонування віртуальних стільниць +Comment[vi]=Số lượng, bố trí và điều hướng của màn hình ảo +Comment[x-test]=xxNavigation, Number and Layout of Virtual Desktopsxx +Comment[zh_CN]=虚拟桌面的切换,数量和布局 +Comment[zh_TW]=虛擬桌面的導覽、數字與佈局 + +Icon=preferences-desktop +Type=Service +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-Name=kcm_kwin_virtualdesktops +X-KDE-ServiceTypes=Plasma/Generic +X-Plasma-API=declarativeappletscript + +X-Plasma-MainScript=ui/main.qml diff --git a/kcmkwin/kwindesktopng/virtualdesktops.h b/kcmkwin/kwindesktopng/virtualdesktops.h new file mode 100644 --- /dev/null +++ b/kcmkwin/kwindesktopng/virtualdesktops.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2018 Eike Hein + * + * 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 VIRTUALDESKTOPS_H +#define VIRTUALDESKTOPS_H + +#include + +namespace KWin { + +class DesktopsModel; + +class VirtualDesktops : public KQuickAddons::ConfigModule +{ + Q_OBJECT + + Q_PROPERTY(QAbstractItemModel* desktopsModel READ desktopsModel CONSTANT) + Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged) + + public: + explicit VirtualDesktops(QObject* parent = nullptr, const QVariantList &list = QVariantList()); + ~VirtualDesktops() override; + + QAbstractItemModel *desktopsModel() const; + + int rows() const; + void setRows(int rows); + + public Q_SLOTS: + void load() override; + void save() override; + void defaults() override; + + Q_SIGNALS: + void rowsChanged() const; + + private: + KWin::DesktopsModel *m_desktopsModel; + int m_rows; +}; + +} + +#endif diff --git a/kcmkwin/kwindesktopng/virtualdesktops.cpp b/kcmkwin/kwindesktopng/virtualdesktops.cpp new file mode 100644 --- /dev/null +++ b/kcmkwin/kwindesktopng/virtualdesktops.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2018 Eike Hein + * + * 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 "desktopsmodel.h" + +#include + +#include +#include +#include + +K_PLUGIN_FACTORY_WITH_JSON(VirtualDesktopsFactory, "kcm_kwin_virtualdesktops.json", registerPlugin();) + +namespace KWin { + +VirtualDesktops::VirtualDesktops(QObject *parent, const QVariantList &args) + : KQuickAddons::ConfigModule(parent, args) + , m_desktopsModel(new KWin::DesktopsModel(this)) + , m_rows(1) +{ + KAboutData *about = new KAboutData(QStringLiteral("kcm_kwin_virtualdesktops"), + i18n("Configure Virtual Desktops"), + QStringLiteral("2.0"), QString(), KAboutLicense::GPL); + setAboutData(about); + + setButtons(Apply | Default); + + QObject::connect(m_desktopsModel, &KWin::DesktopsModel::rowsChanged, this, + [this]() { + m_rows = m_desktopsModel->rows(); + setNeedsSave(false); + } + ); +} + +VirtualDesktops::~VirtualDesktops() +{ +} + +QAbstractItemModel *VirtualDesktops::desktopsModel() const +{ + return m_desktopsModel; +} + +void VirtualDesktops::load() +{ + m_rows = m_desktopsModel->rows(); +} + +void VirtualDesktops::save() +{ + m_desktopsModel->setRows(m_rows); +} + +void VirtualDesktops::defaults() +{ + m_rows = 1; + m_desktopsModel->setRows(1); +} + +int VirtualDesktops::rows() const +{ + return m_rows; +} + +void VirtualDesktops::setRows(int rows) +{ + if (m_rows != rows) { + m_rows = rows; + + setNeedsSave(true); + + emit rowsChanged(); + } +} + +} + +#include "virtualdesktops.moc"