diff --git a/src/kcms/tabbox/CMakeLists.txt b/src/kcms/tabbox/CMakeLists.txt index 67d60ae90b..9f215bd8ba 100644 --- a/src/kcms/tabbox/CMakeLists.txt +++ b/src/kcms/tabbox/CMakeLists.txt @@ -12,6 +12,7 @@ set(kcm_kwintabbox_PART_SRCS thumbnailitem.cpp kwintabboxconfigform.cpp kwintabboxdata.cpp + shortcutsettings.cpp ) ki18n_wrap_ui(kcm_kwintabbox_PART_SRCS main.ui) diff --git a/src/kcms/tabbox/kwintabboxdata.cpp b/src/kcms/tabbox/kwintabboxdata.cpp index cc4f3ac2cb..3377b5cbc1 100644 --- a/src/kcms/tabbox/kwintabboxdata.cpp +++ b/src/kcms/tabbox/kwintabboxdata.cpp @@ -12,6 +12,7 @@ #include "kwinpluginssettings.h" #include "kwinswitcheffectsettings.h" #include "kwintabboxsettings.h" +#include "shortcutsettings.h" namespace KWin { @@ -23,9 +24,11 @@ KWinTabboxData::KWinTabboxData(QObject *parent, const QVariantList &args) , m_tabBoxConfig(new TabBoxSettings(QStringLiteral("TabBox"), this)) , m_tabBoxAlternativeConfig(new TabBoxSettings(QStringLiteral("TabBoxAlternative"), this)) , m_pluginsConfig(new PluginsSettings(this)) + , m_shortcutConfig(new ShortcutSettings(this)) { registerSkeleton(m_tabBoxConfig); registerSkeleton(m_tabBoxAlternativeConfig); + registerSkeleton(m_shortcutConfig); } TabBoxSettings *KWinTabboxData::tabBoxConfig() const @@ -43,6 +46,9 @@ PluginsSettings *KWinTabboxData::pluginsConfig() const return m_pluginsConfig; } +ShortcutSettings *KWinTabboxData::shortcutConfig() const +{ + return m_shortcutConfig; +} } - } diff --git a/src/kcms/tabbox/kwintabboxdata.h b/src/kcms/tabbox/kwintabboxdata.h index 15801599a8..b19e471c42 100644 --- a/src/kcms/tabbox/kwintabboxdata.h +++ b/src/kcms/tabbox/kwintabboxdata.h @@ -20,6 +20,7 @@ namespace TabBox class TabBoxSettings; class SwitchEffectSettings; class PluginsSettings; +class ShortcutSettings; class KWinTabboxData : public KCModuleData { @@ -31,11 +32,13 @@ public: TabBoxSettings *tabBoxConfig() const; TabBoxSettings *tabBoxAlternativeConfig() const; PluginsSettings *pluginsConfig() const; + ShortcutSettings *shortcutConfig() const; private: TabBoxSettings *m_tabBoxConfig; TabBoxSettings *m_tabBoxAlternativeConfig; PluginsSettings *m_pluginsConfig; + ShortcutSettings *m_shortcutConfig; }; } diff --git a/src/kcms/tabbox/shortcutsettings.cpp b/src/kcms/tabbox/shortcutsettings.cpp new file mode 100644 index 0000000000..9900c02900 --- /dev/null +++ b/src/kcms/tabbox/shortcutsettings.cpp @@ -0,0 +1,149 @@ +/* + KWin - the KDE window manager + This file is part of the KDE project. + + SPDX-FileCopyrightText: 2023 Ismael Asensio + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "shortcutsettings.h" + +#include + +#include +#include +#include + +// Implementation of a KConfigSkeletonItem that uses KGlobalAccel to retrieve and store +// shortcut settings instead of storing them in a config file +class ShortcutItem : public KConfigSkeletonItem +{ +public: + ShortcutItem(QAction *action, KActionCollection *actionCollection); + + void readConfig(KConfig *config) override; + void writeConfig(KConfig *config) override; + + void readDefault(KConfig *config) override; + void setDefault() override; + void swapDefault() override; + + bool isEqual(const QVariant &p) const override; + QVariant property() const override; + void setProperty(const QVariant &p) override; + +private: + KActionCollection *m_actionCollection = nullptr; + QAction *m_action = nullptr; + QKeySequence m_savedShortcut; +}; + +ShortcutItem::ShortcutItem(QAction *action, KActionCollection *actionCollection) + : KConfigSkeletonItem(actionCollection->componentName(), action->text()) + , m_actionCollection(actionCollection) + , m_action(action) +{ + setGetDefaultImpl([this] { + return m_actionCollection->defaultShortcut(m_action); + }); + + setIsDefaultImpl([this] { + return m_action->shortcut() == m_actionCollection->defaultShortcut(m_action); + }); + + setIsSaveNeededImpl([this] { + return (m_action->shortcut() != m_savedShortcut); + }); +} + +void ShortcutItem::readConfig(KConfig *config) +{ + const auto shortcuts = KGlobalAccel::self()->globalShortcut(m_actionCollection->componentName(), m_action->objectName()); + m_savedShortcut = shortcuts.isEmpty() ? QKeySequence() : shortcuts.first(); + m_action->setShortcut(m_savedShortcut); +} + +void ShortcutItem::writeConfig(KConfig *config) +{ + m_savedShortcut = m_action->shortcut(); + KGlobalAccel::self()->setShortcut(m_action, {m_action->shortcut()}, KGlobalAccel::NoAutoloading); +} + +void ShortcutItem::readDefault(KConfig *config) +{ +} + +void ShortcutItem::setDefault() +{ + m_action->setShortcut(m_actionCollection->defaultShortcut(m_action)); +} + +void ShortcutItem::swapDefault() +{ + QKeySequence previousShortcut = m_action->shortcut(); + m_action->setShortcut(m_actionCollection->defaultShortcut(m_action)); + m_actionCollection->setDefaultShortcut(m_action, previousShortcut); +} + +bool ShortcutItem::isEqual(const QVariant &p) const +{ + if (!p.canConvert()) { + return false; + } + return m_action->shortcut() == p.value(); +} + +QVariant ShortcutItem::property() const +{ + return QVariant::fromValue(m_action->shortcut()); +} + +void ShortcutItem::setProperty(const QVariant &p) +{ + m_action->setShortcut(p.value()); +} + +namespace KWin +{ +namespace TabBox +{ + +ShortcutSettings::ShortcutSettings(QObject *parent) + : KConfigSkeleton(nullptr, parent) + , m_actionCollection(new KActionCollection(this, QStringLiteral("kwin"))) +{ + m_actionCollection->setConfigGroup("Navigation"); + m_actionCollection->setConfigGlobal(true); + + auto addShortcut = [this](const KLocalizedString &name, const QKeySequence &sequence = QKeySequence()) { + const QString untranslatedName = QString::fromUtf8(name.untranslatedText()); + QAction *action = m_actionCollection->addAction(untranslatedName); + action->setObjectName(untranslatedName); + action->setProperty("isConfigurationAction", true); + action->setText(name.toString()); + + m_actionCollection->setDefaultShortcut(action, sequence); + + addItem(new ShortcutItem(action, m_actionCollection)); + }; + + // TabboxType::Main + addShortcut(ki18nd("kwin", "Walk Through Windows"), Qt::ALT | Qt::Key_Tab); + addShortcut(ki18nd("kwin", "Walk Through Windows (Reverse)"), Qt::ALT | Qt::SHIFT | Qt::Key_Backtab); + addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application"), Qt::ALT | Qt::Key_QuoteLeft); + addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application (Reverse)"), Qt::ALT | Qt::Key_AsciiTilde); + // TabboxType::Alternative + addShortcut(ki18nd("kwin", "Walk Through Windows Alternative")); + addShortcut(ki18nd("kwin", "Walk Through Windows Alternative (Reverse)")); + addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application Alternative")); + addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application Alternative (Reverse)")); +} + +KActionCollection *ShortcutSettings::actionCollection() const +{ + return m_actionCollection; +} + +} // namespace TabBox +} // namespace KWin diff --git a/src/kcms/tabbox/shortcutsettings.h b/src/kcms/tabbox/shortcutsettings.h new file mode 100644 index 0000000000..bf695da5a9 --- /dev/null +++ b/src/kcms/tabbox/shortcutsettings.h @@ -0,0 +1,35 @@ +/* + KWin - the KDE window manager + This file is part of the KDE project. + + SPDX-FileCopyrightText: 2023 Ismael Asensio + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include + +#include + +class KActionCollection; + +namespace KWin +{ +namespace TabBox +{ + +class ShortcutSettings : public KConfigSkeleton +{ +public: + explicit ShortcutSettings(QObject *parent); + + KActionCollection *actionCollection() const; + +private: + KActionCollection *m_actionCollection = nullptr; +}; + +} // namespace TabBox +} // namespace KWin