diff --git a/containmentactions/switchdesktop/desktop.h b/containmentactions/switchdesktop/desktop.h --- a/containmentactions/switchdesktop/desktop.h +++ b/containmentactions/switchdesktop/desktop.h @@ -17,12 +17,15 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef SWITCHDESKTOP_HEADER -#define SWITCHDESKTOP_HEADER +#pragma once +#include +#include +#include #include class QAction; +class QButtonGroup; class SwitchDesktop : public Plasma::ContainmentActions { @@ -33,15 +36,31 @@ QList contextualActions() override; + void restore(const KConfigGroup& config) override; + QWidget* createConfigurationInterface(QWidget* parent) override; + void configurationAccepted() override; + void save(KConfigGroup &config) override; + void performNextAction() override; void performPreviousAction() override; private Q_SLOTS: void switchTo(); private: QHash m_actions; -}; + QButtonGroup *m_settingsButtons; + // QSharedPtr has non-explicit operator bool which is bugprone, work around that + struct explicitBool { bool val; }; + QSharedPointer m_invertMouseWheel; + QSharedPointer m_kwinrcRollOverDesktops; + struct Option { + QString cfgKey; // also key in options map + QString name; + QSharedPointer valuePtr; + bool readOnly; + }; + QMap m_options; +}; -#endif diff --git a/containmentactions/switchdesktop/desktop.cpp b/containmentactions/switchdesktop/desktop.cpp --- a/containmentactions/switchdesktop/desktop.cpp +++ b/containmentactions/switchdesktop/desktop.cpp @@ -19,15 +19,30 @@ #include "desktop.h" +#include +#include #include -#include +#include +#include +#include #include #include #include +namespace { +constexpr bool invertMouseWheelDefault = false; +constexpr const char *cfgKeyProperty = "cfgKey"; +bool readKwinrcRollOverDesktops() { + auto cfg = KSharedConfig::openConfig("kwinrc"); + return KConfigGroup{cfg, "Windows"}.readEntry("RollOverDesktops", true); +} +} + SwitchDesktop::SwitchDesktop(QObject *parent, const QVariantList &args) : Plasma::ContainmentActions(parent, args) + , m_invertMouseWheel{QSharedPointer::create(explicitBool{invertMouseWheelDefault})} + , m_kwinrcRollOverDesktops(QSharedPointer::create(explicitBool{readKwinrcRollOverDesktops()})) { } @@ -70,6 +85,78 @@ return list; } +void SwitchDesktop::restore(const KConfigGroup &config) +{ + Option invertWheel{ + "invert_mouse_wheel", + "Invert mouse wheel", + m_invertMouseWheel, + false + }; + invertWheel.valuePtr->val = config.readEntry(invertWheel.cfgKey, invertWheel.valuePtr->val); + m_options[invertWheel.cfgKey] = invertWheel; + + Option rollOverDesktop{ + "rollover_kwinrc_readonly", + "Desktops wrap around (set in kwin)", + m_kwinrcRollOverDesktops, + true + }; + m_kwinrcRollOverDesktops->val = readKwinrcRollOverDesktops(); + m_options[rollOverDesktop.cfgKey] = rollOverDesktop; +} + +QWidget *SwitchDesktop::createConfigurationInterface(QWidget *parent) +{ + m_kwinrcRollOverDesktops->val = readKwinrcRollOverDesktops(); + + QWidget *widget = new QWidget(parent); + QVBoxLayout *lay = new QVBoxLayout(); + widget->setLayout(lay); + widget->setWindowTitle(i18nc("plasma_containmentactions_switchdesktop", "Configure Switch Desktop")); + m_settingsButtons = new QButtonGroup(widget); + m_settingsButtons->setExclusive(false); + + for (const Option &e : m_options) { + QCheckBox *item = new QCheckBox(widget); + item->setText(i18nc(e.cfgKey.toStdString().c_str(), + e.name.toStdString().c_str())); + item->setChecked(e.valuePtr->val); + if (e.readOnly) { + item->setEnabled(false); + } else { + item->setProperty(cfgKeyProperty, e.cfgKey); + } + lay->addWidget(item); + m_settingsButtons->addButton(item); + } + + return widget; +} + +void SwitchDesktop::configurationAccepted() +{ + m_kwinrcRollOverDesktops->val = readKwinrcRollOverDesktops(); + + QList buttons = m_settingsButtons->buttons(); + QListIterator it(buttons); + for (QAbstractButton *b : buttons) { + QVariant cfgKey = b->property(cfgKeyProperty); + if (cfgKey.isValid() && m_options.contains(cfgKey.toString())) { + m_options[cfgKey.toString()].valuePtr->val = b->isChecked(); + } + } +} + +void SwitchDesktop::save(KConfigGroup &config) +{ + for (const Option &e : m_options) { + if (!e.readOnly) { + config.writeEntry(e.cfgKey, e.valuePtr->val); + } + } +} + void SwitchDesktop::switchTo() { QAction *action = qobject_cast(sender()); @@ -81,18 +168,33 @@ KWindowSystem::setCurrentDesktop(desktop); } -void SwitchDesktop::performNextAction() -{ +namespace { +void switchDesktop(bool next, bool rollover, bool invert) { const int numDesktops = KWindowSystem::numberOfDesktops(); const int currentDesktop = KWindowSystem::currentDesktop(); - KWindowSystem::setCurrentDesktop(currentDesktop % numDesktops + 1); + if (invert) { + next = !next; + } + bool wouldRollover = (next && currentDesktop == numDesktops) || (!next && currentDesktop == 1); + if (wouldRollover && !rollover) { + return; + } + if (next) { + KWindowSystem::setCurrentDesktop(currentDesktop % numDesktops + 1); + } else { + KWindowSystem::setCurrentDesktop((numDesktops + currentDesktop - 2) % numDesktops + 1); + } +} +} + +void SwitchDesktop::performNextAction() +{ + switchDesktop(true, m_kwinrcRollOverDesktops, m_invertMouseWheel->val); } void SwitchDesktop::performPreviousAction() { - const int numDesktops = KWindowSystem::numberOfDesktops(); - const int currentDesktop = KWindowSystem::currentDesktop(); - KWindowSystem::setCurrentDesktop((numDesktops + currentDesktop - 2) % numDesktops + 1); + switchDesktop(false, m_kwinrcRollOverDesktops, m_invertMouseWheel->val); } K_EXPORT_PLASMA_CONTAINMENTACTIONS_WITH_JSON(switchdesktop, SwitchDesktop, "plasma-containmentactions-switchdesktop.json")