diff --git a/kcmkwin/kwintabbox/CMakeLists.txt b/kcmkwin/kwintabbox/CMakeLists.txt index da71fdcf1..6a7fc3515 100644 --- a/kcmkwin/kwintabbox/CMakeLists.txt +++ b/kcmkwin/kwintabbox/CMakeLists.txt @@ -1,42 +1,43 @@ # KI18N Translation Domain for this library add_definitions(-DTRANSLATION_DOMAIN=\"kcm_kwintabbox\") include_directories(${KWin_SOURCE_DIR}/effects ${KWin_SOURCE_DIR}/tabbox ${KWin_SOURCE_DIR}) ########### next target ############### set(kcm_kwintabbox_PART_SRCS ${KWin_SOURCE_DIR}/tabbox/tabboxconfig.cpp layoutpreview.cpp main.cpp thumbnailitem.cpp + kwintabboxconfigform.cpp ) ki18n_wrap_ui(kcm_kwintabbox_PART_SRCS main.ui) qt5_add_dbus_interface(kcm_kwintabbox_PART_SRCS ${KWin_SOURCE_DIR}/org.kde.kwin.Effects.xml kwin_effects_interface) kconfig_add_kcfg_files(kcm_kwintabbox_PART_SRCS kwintabboxsettings.kcfgc kwinswitcheffectsettings.kcfgc kwinpluginssettings.kcfgc) add_library(kcm_kwintabbox MODULE ${kcm_kwintabbox_PART_SRCS}) target_link_libraries(kcm_kwintabbox Qt5::Quick KF5::Completion KF5::GlobalAccel KF5::I18n KF5::KCMUtils KF5::NewStuff KF5::Package KF5::Service XCB::XCB kwin4_effect_builtins ) install(TARGETS kcm_kwintabbox DESTINATION ${PLUGIN_INSTALL_DIR} ) ########### install files ############### install(FILES kwintabbox.desktop DESTINATION ${SERVICES_INSTALL_DIR}) install(FILES thumbnails/konqueror.png thumbnails/kmail.png thumbnails/systemsettings.png thumbnails/dolphin.png DESTINATION ${DATA_INSTALL_DIR}/kwin/kcm_kwintabbox) install(FILES kwinswitcher.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR}) diff --git a/kcmkwin/kwintabbox/kwintabboxconfigform.cpp b/kcmkwin/kwintabbox/kwintabboxconfigform.cpp new file mode 100644 index 000000000..cdd6a4eb4 --- /dev/null +++ b/kcmkwin/kwintabbox/kwintabboxconfigform.cpp @@ -0,0 +1,353 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2009 Martin Gräßlin +Copyright (C) 2020 Cyril Rossi + +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 "kwintabboxconfigform.h" +#include "ui_main.h" + +#include + +#include +#include +#include + + +namespace KWin +{ + +using namespace TabBox; + +KWinTabBoxConfigForm::KWinTabBoxConfigForm(TabboxType type, QWidget *parent) + : QWidget(parent) + , m_type(type) + , ui(new Ui::KWinTabBoxConfigForm) +{ + ui->setupUi(this); + + ui->effectConfigButton->setIcon(QIcon::fromTheme(QStringLiteral("view-preview"))); + + if (QApplication::screens().count() < 2) { + ui->filterScreens->hide(); + ui->screenFilter->hide(); + } + + connect(ui->effectConfigButton, &QPushButton::clicked, this, &KWinTabBoxConfigForm::effectConfigButtonClicked); + + connect(ui->kcfg_ShowTabBox, SIGNAL(clicked(bool)), SLOT(tabBoxToggled(bool))); + + connect(ui->filterScreens, SIGNAL(clicked(bool)), SLOT(onFilterScreen())); + connect(ui->currentScreen, SIGNAL(clicked(bool)), SLOT(onFilterScreen())); + connect(ui->otherScreens, SIGNAL(clicked(bool)), SLOT(onFilterScreen())); + + connect(ui->filterDesktops, SIGNAL(clicked(bool)), SLOT(onFilterDesktop())); + connect(ui->currentDesktop, SIGNAL(clicked(bool)), SLOT(onFilterDesktop())); + connect(ui->otherDesktops, SIGNAL(clicked(bool)), SLOT(onFilterDesktop())); + + connect(ui->filterActivities, SIGNAL(clicked(bool)), SLOT(onFilterActivites())); + connect(ui->currentActivity, SIGNAL(clicked(bool)), SLOT(onFilterActivites())); + connect(ui->otherActivities, SIGNAL(clicked(bool)), SLOT(onFilterActivites())); + + connect(ui->filterMinimization, SIGNAL(clicked(bool)), SLOT(onFilterMinimization())); + connect(ui->visibleWindows, SIGNAL(clicked(bool)), SLOT(onFilterMinimization())); + connect(ui->hiddenWindows, SIGNAL(clicked(bool)), SLOT(onFilterMinimization())); + + connect(ui->oneAppWindow, SIGNAL(clicked(bool)), SLOT(onApplicationMode())); + connect(ui->showDesktop, SIGNAL(clicked(bool)), SLOT(onShowDesktopMode())); + + connect(ui->switchingModeCombo, SIGNAL(currentIndexChanged(int)), SLOT(onSwitchingMode())); + connect(ui->effectCombo, SIGNAL(currentIndexChanged(int)), SLOT(onEffectCombo())); + + auto addShortcut = [this](const char *name, KKeySequenceWidget *widget, const QKeySequence &sequence = QKeySequence()) { + QAction *a = m_actionCollection->addAction(name); + a->setProperty("isConfigurationAction", true); + widget->setProperty("shortcutAction", name); + a->setText(i18n(name)); + KGlobalAccel::self()->setShortcut(a, QList() << sequence); + connect(widget, SIGNAL(keySequenceChanged(QKeySequence)), this, SLOT(shortcutChanged(QKeySequence))); + }; + + // Shortcut config. The shortcut belongs to the component "kwin"! + m_actionCollection = new KActionCollection(this, QStringLiteral("kwin")); + m_actionCollection->setComponentDisplayName(i18n("KWin")); + m_actionCollection->setConfigGroup("Navigation"); + m_actionCollection->setConfigGlobal(true); + + if (TabboxType::Main == m_type) { + addShortcut("Walk Through Windows", ui->scAll, Qt::ALT + Qt::Key_Tab); + addShortcut("Walk Through Windows (Reverse)", ui->scAllReverse, Qt::ALT + Qt::SHIFT + Qt::Key_Backtab); + addShortcut("Walk Through Windows of Current Application", ui->scCurrent, Qt::ALT + Qt::Key_QuoteLeft); + addShortcut("Walk Through Windows of Current Application (Reverse)", ui->scCurrentReverse, Qt::ALT + Qt::Key_AsciiTilde); + } else if (TabboxType::Alternative == m_type) { + addShortcut("Walk Through Windows Alternative", ui->scAll); + addShortcut("Walk Through Windows Alternative (Reverse)", ui->scAllReverse); + addShortcut("Walk Through Windows of Current Application Alternative", ui->scCurrent); + addShortcut("Walk Through Windows of Current Application Alternative (Reverse)", ui->scCurrentReverse); + } +} + +KWinTabBoxConfigForm::~KWinTabBoxConfigForm() +{ + delete ui; +} + +bool KWinTabBoxConfigForm::highlightWindows() const +{ + return ui->kcfg_HighlightWindows->isChecked(); +} + +bool KWinTabBoxConfigForm::showTabBox() const +{ + return ui->kcfg_ShowTabBox->isChecked(); +} + +int KWinTabBoxConfigForm::filterScreen() const +{ + if (ui->filterScreens->isChecked()) { + return ui->currentScreen->isChecked() ? TabBoxConfig::OnlyCurrentScreenClients : TabBoxConfig::ExcludeCurrentScreenClients; + } else { + return TabBoxConfig::IgnoreMultiScreen; + } +} + +int KWinTabBoxConfigForm::filterDesktop() const +{ + if (ui->filterDesktops->isChecked()) { + return ui->currentDesktop->isChecked() ? TabBoxConfig::OnlyCurrentDesktopClients : TabBoxConfig::ExcludeCurrentDesktopClients; + } else { + return TabBoxConfig::AllDesktopsClients; + } +} + +int KWinTabBoxConfigForm::filterActivities() const +{ + if (ui->filterActivities->isChecked()) { + return ui->currentActivity->isChecked() ? TabBoxConfig::OnlyCurrentActivityClients : TabBoxConfig::ExcludeCurrentActivityClients; + } else { + return TabBoxConfig::AllActivitiesClients; + } +} + +int KWinTabBoxConfigForm::filterMinimization() const +{ + if (ui->filterMinimization->isChecked()) { + return ui->visibleWindows->isChecked() ? TabBoxConfig::ExcludeMinimizedClients : TabBoxConfig::OnlyMinimizedClients; + } else { + return TabBoxConfig::IgnoreMinimizedStatus; + } +} + +int KWinTabBoxConfigForm::applicationMode() const +{ + return ui->oneAppWindow->isChecked() ? TabBoxConfig::OneWindowPerApplication : TabBoxConfig::AllWindowsAllApplications; +} + +int KWinTabBoxConfigForm::showDesktopMode() const +{ + return ui->showDesktop->isChecked() ? TabBoxConfig::ShowDesktopClient : TabBoxConfig::DoNotShowDesktopClient; +} + +int KWinTabBoxConfigForm::switchingMode() const +{ + return ui->switchingModeCombo->currentIndex(); +} + +QString KWinTabBoxConfigForm::layoutName() const +{ + return ui->effectCombo->currentData().toString(); +} + +void KWinTabBoxConfigForm::setFilterScreen(TabBox::TabBoxConfig::ClientMultiScreenMode mode) +{ + ui->filterScreens->setChecked(mode != TabBoxConfig::IgnoreMultiScreen); + ui->currentScreen->setChecked(mode == TabBoxConfig::OnlyCurrentScreenClients); + ui->otherScreens->setChecked(mode == TabBoxConfig::ExcludeCurrentScreenClients); +} + +void KWinTabBoxConfigForm::setFilterDesktop(TabBox::TabBoxConfig::ClientDesktopMode mode) +{ + ui->filterDesktops->setChecked(mode != TabBoxConfig::AllDesktopsClients); + ui->currentDesktop->setChecked(mode == TabBoxConfig::OnlyCurrentDesktopClients); + ui->otherDesktops->setChecked(mode == TabBoxConfig::ExcludeCurrentDesktopClients); +} + +void KWinTabBoxConfigForm::setFilterActivities(TabBox::TabBoxConfig::ClientActivitiesMode mode) +{ + ui->filterActivities->setChecked(mode != TabBoxConfig::AllActivitiesClients); + ui->currentActivity->setChecked(mode == TabBoxConfig::OnlyCurrentActivityClients); + ui->otherActivities->setChecked(mode == TabBoxConfig::ExcludeCurrentActivityClients); +} + +void KWinTabBoxConfigForm::setFilterMinimization(TabBox::TabBoxConfig::ClientMinimizedMode mode) +{ + ui->filterMinimization->setChecked(mode != TabBoxConfig::IgnoreMinimizedStatus); + ui->visibleWindows->setChecked(mode == TabBoxConfig::ExcludeMinimizedClients); + ui->hiddenWindows->setChecked(mode == TabBoxConfig::OnlyMinimizedClients); +} + +void KWinTabBoxConfigForm::setApplicationMode(TabBox::TabBoxConfig::ClientApplicationsMode mode) +{ + ui->oneAppWindow->setChecked(mode == TabBoxConfig::OneWindowPerApplication); +} + +void KWinTabBoxConfigForm::setShowDesktopMode(TabBox::TabBoxConfig::ShowDesktopMode mode) +{ + ui->showDesktop->setChecked(mode == TabBoxConfig::ShowDesktopClient); +} + +void KWinTabBoxConfigForm::setSwitchingModeChanged(TabBox::TabBoxConfig::ClientSwitchingMode mode) +{ + ui->switchingModeCombo->setCurrentIndex(mode); +} + +void KWinTabBoxConfigForm::setLayoutName(const QString &layoutName) +{ + ui->effectCombo->setCurrentIndex(ui->effectCombo->findData(layoutName)); +} + +void KWinTabBoxConfigForm::setEffectComboModel(QStandardItemModel *model) +{ + int index = ui->effectCombo->currentIndex(); + QVariant data = ui->effectCombo->itemData(index); + + ui->effectCombo->setModel(model); + + if (data.isValid()) { + ui->effectCombo->setCurrentIndex(ui->effectCombo->findData(data)); + } else if (index != -1) { + ui->effectCombo->setCurrentIndex(index); + } +} + +QVariant KWinTabBoxConfigForm::effectComboCurrentData(int role) const +{ + return ui->effectCombo->currentData(role); +} + +void KWinTabBoxConfigForm::loadShortcuts() +{ + auto loadShortcut = [this](KKeySequenceWidget *widget) { + QString actionName = widget->property("shortcutAction").toString(); + qDebug() << "load shortcut for " << actionName; + if (QAction *action = m_actionCollection->action(actionName)) { + auto shortcuts = KGlobalAccel::self()->shortcut(action); + if (!shortcuts.isEmpty()) { + widget->setKeySequence(shortcuts.first()); + } + } + }; + + loadShortcut(ui->scAll); + loadShortcut(ui->scAllReverse); + loadShortcut(ui->scCurrent); + loadShortcut(ui->scCurrentReverse); +} + +void KWinTabBoxConfigForm::resetShortcuts() +{ + QString action; + auto resetShortcut = [this](KKeySequenceWidget *widget, const QKeySequence &sequence = QKeySequence()) { + const QString action = widget->property("shortcutAction").toString(); + QAction *a = m_actionCollection->action(action); + KGlobalAccel::self()->setShortcut(a, QList() << sequence, KGlobalAccel::NoAutoloading); + }; + if (TabboxType::Main == m_type) { + resetShortcut(ui->scAll, Qt::ALT + Qt::Key_Tab); + resetShortcut(ui->scAllReverse, Qt::ALT + Qt::SHIFT + Qt::Key_Backtab); + resetShortcut(ui->scCurrent, Qt::ALT + Qt::Key_QuoteLeft); + resetShortcut(ui->scCurrentReverse, Qt::ALT + Qt::Key_AsciiTilde); + } else if (TabboxType::Alternative == m_type) { + resetShortcut(ui->scAll); + resetShortcut(ui->scAllReverse); + resetShortcut(ui->scCurrent); + resetShortcut(ui->scCurrentReverse); + } + m_actionCollection->writeSettings(); +} + +void KWinTabBoxConfigForm::tabBoxToggled(bool on) +{ + // Highlight Windows options is availabled if no TabBox effect is selected + // or if Tabbox is not builtin effet. + on = !on || ui->effectCombo->currentData(AddonEffect).toBool(); + ui->kcfg_HighlightWindows->setEnabled(on); +} + +void KWinTabBoxConfigForm::onFilterScreen() +{ + emit filterScreenChanged(filterScreen()); +} + +void KWinTabBoxConfigForm::onFilterDesktop() +{ + emit filterDesktopChanged(filterDesktop()); +} + +void KWinTabBoxConfigForm::onFilterActivites() +{ + emit filterActivitiesChanged(filterActivities()); +} + +void KWinTabBoxConfigForm::onFilterMinimization() +{ + emit filterMinimizationChanged(filterMinimization()); +} + +void KWin::KWinTabBoxConfigForm::onApplicationMode() +{ + emit applicationModeChanged(applicationMode()); +} + +void KWinTabBoxConfigForm::onShowDesktopMode() +{ + emit showDesktopModeChanged(showDesktopMode()); +} + +void KWinTabBoxConfigForm::onSwitchingMode() +{ + emit switchingModeChanged(switchingMode()); +} + +void KWinTabBoxConfigForm::onEffectCombo() +{ + const bool isAddonEffect = ui->effectCombo->currentData(AddonEffect).toBool(); + ui->effectConfigButton->setIcon(QIcon::fromTheme(isAddonEffect ? "view-preview" : "configure")); + if (!ui->kcfg_ShowTabBox->isChecked()) { + return; + } + ui->kcfg_HighlightWindows->setEnabled(isAddonEffect); + + emit layoutNameChanged(layoutName()); +} + +void KWinTabBoxConfigForm::shortcutChanged(const QKeySequence &seq) +{ + QString action; + if (sender()) { + action = sender()->property("shortcutAction").toString(); + } + if (action.isEmpty()) { + return; + } + QAction *a = m_actionCollection->action(action); + KGlobalAccel::self()->setShortcut(a, QList() << seq, KGlobalAccel::NoAutoloading); + m_actionCollection->writeSettings(); +} + +} // namespace diff --git a/kcmkwin/kwintabbox/kwintabboxconfigform.h b/kcmkwin/kwintabbox/kwintabboxconfigform.h new file mode 100644 index 000000000..08fabde5f --- /dev/null +++ b/kcmkwin/kwintabbox/kwintabboxconfigform.h @@ -0,0 +1,122 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2009 Martin Gräßlin +Copyright (C) 2020 Cyril Rossi + +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 __KWINTABBOXCONFIGFORM_H__ +#define __KWINTABBOXCONFIGFORM_H__ + +#include +#include + +#include "tabboxconfig.h" + +class KShortcutsEditor; +class KActionCollection; + +namespace Ui +{ +class KWinTabBoxConfigForm; +} + +namespace KWin +{ + +class KWinTabBoxConfigForm : public QWidget +{ + Q_OBJECT + +public: + enum class TabboxType + { + Main, + Alternative, + }; + + + enum EffectComboRole + { + LayoutPath = Qt::UserRole + 1, + AddonEffect, // i.e not builtin effects + }; + + explicit KWinTabBoxConfigForm(TabboxType type, QWidget *parent = nullptr); + ~KWinTabBoxConfigForm() override; + + bool highlightWindows() const; + bool showTabBox() const; + int filterScreen() const; + int filterDesktop() const; + int filterActivities() const; + int filterMinimization() const; + int applicationMode() const; + int showDesktopMode() const; + int switchingMode() const; + QString layoutName() const; + + void setFilterScreen(TabBox::TabBoxConfig::ClientMultiScreenMode mode); + void setFilterDesktop(TabBox::TabBoxConfig::ClientDesktopMode mode); + void setFilterActivities(TabBox::TabBoxConfig::ClientActivitiesMode mode); + void setFilterMinimization(TabBox::TabBoxConfig::ClientMinimizedMode mode); + void setApplicationMode(TabBox::TabBoxConfig::ClientApplicationsMode mode); + void setShowDesktopMode(TabBox::TabBoxConfig::ShowDesktopMode mode); + void setSwitchingModeChanged(TabBox::TabBoxConfig::ClientSwitchingMode mode); + void setLayoutName(const QString &layoutName); + + // EffectCombo Data Model + void setEffectComboModel(QStandardItemModel *model); + QVariant effectComboCurrentData(int role = Qt::UserRole) const; + + void loadShortcuts(); + void resetShortcuts(); + +Q_SIGNALS: + void filterScreenChanged(int value); + void filterDesktopChanged(int value); + void filterActivitiesChanged(int value); + void filterMinimizationChanged(int value); + void applicationModeChanged(int value); + void showDesktopModeChanged(int value); + void switchingModeChanged(int value); + void layoutNameChanged(const QString &layoutName); + void effectConfigButtonClicked(); + +private Q_SLOTS: + void tabBoxToggled(bool on); + void onFilterScreen(); + void onFilterDesktop(); + void onFilterActivites(); + void onFilterMinimization(); + void onApplicationMode(); + void onShowDesktopMode(); + void onSwitchingMode(); + void onEffectCombo(); + void shortcutChanged(const QKeySequence &seq); + +private: + KActionCollection *m_actionCollection = nullptr; + KShortcutsEditor *m_editor = nullptr; + + TabboxType m_type; + Ui::KWinTabBoxConfigForm *ui; +}; + +} // namespace + +#endif diff --git a/kcmkwin/kwintabbox/main.cpp b/kcmkwin/kwintabbox/main.cpp index 551cabf0b..20897de92 100644 --- a/kcmkwin/kwintabbox/main.cpp +++ b/kcmkwin/kwintabbox/main.cpp @@ -1,565 +1,474 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2009 Martin Gräßlin Copyright (C) 2020 Cyril Rossi 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 "main.h" #include #include // Qt #include #include #include #include #include #include #include +#include #include #include +#include // KDE -#include #include -#include #include #include #include #include #include -#include #include // Plasma #include #include // own +#include "kwintabboxconfigform.h" #include "layoutpreview.h" #include "kwintabboxsettings.h" #include "kwinswitcheffectsettings.h" #include "kwinpluginssettings.h" K_PLUGIN_FACTORY(KWinTabBoxConfigFactory, registerPlugin();) namespace KWin { using namespace TabBox; -KWinTabBoxConfigForm::KWinTabBoxConfigForm(QWidget* parent) - : QWidget(parent) -{ - setupUi(this); -} KWinTabBoxConfig::KWinTabBoxConfig(QWidget* parent, const QVariantList& args) : KCModule(parent, args) , m_config(KSharedConfig::openConfig("kwinrc")) , m_tabBoxConfig(new TabBoxSettings(QStringLiteral("TabBox"), this)) , m_tabBoxAlternativeConfig(new TabBoxSettings(QStringLiteral("TabBoxAlternative"), this)) , m_coverSwitchConfig(new SwitchEffectSettings(QStringLiteral("Effect-CoverSwitch"), this)) , m_flipSwitchConfig(new SwitchEffectSettings(QStringLiteral("Effect-FlipSwitch"), this)) , m_pluginsConfig(new PluginsSettings(this)) { QTabWidget* tabWidget = new QTabWidget(this); - m_primaryTabBoxUi = new KWinTabBoxConfigForm(tabWidget); - m_alternativeTabBoxUi = new KWinTabBoxConfigForm(tabWidget); + m_primaryTabBoxUi = new KWinTabBoxConfigForm(KWinTabBoxConfigForm::TabboxType::Main, tabWidget); + m_alternativeTabBoxUi = new KWinTabBoxConfigForm(KWinTabBoxConfigForm::TabboxType::Alternative, tabWidget); tabWidget->addTab(m_primaryTabBoxUi, i18n("Main")); tabWidget->addTab(m_alternativeTabBoxUi, i18n("Alternative")); QPushButton* ghnsButton = new QPushButton(QIcon::fromTheme(QStringLiteral("get-hot-new-stuff")), i18n("Get New Task Switchers...")); connect(ghnsButton, SIGNAL(clicked(bool)), SLOT(slotGHNS())); QHBoxLayout* buttonBar = new QHBoxLayout(); QSpacerItem* buttonBarSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); buttonBar->addItem(buttonBarSpacer); buttonBar->addWidget(ghnsButton); QVBoxLayout* layout = new QVBoxLayout(this); KTitleWidget* infoLabel = new KTitleWidget(tabWidget); infoLabel->setText(i18n("Focus policy settings limit the functionality of navigating through windows."), KTitleWidget::InfoMessage); infoLabel->setPixmap(KTitleWidget::InfoMessage, KTitleWidget::ImageLeft); layout->addWidget(infoLabel,0); layout->addWidget(tabWidget,1); layout->addLayout(buttonBar); setLayout(layout); -#define ADD_SHORTCUT(_NAME_, _CUT_, _BTN_) \ - a = m_actionCollection->addAction(_NAME_);\ - a->setProperty("isConfigurationAction", true);\ - _BTN_->setProperty("shortcutAction", _NAME_);\ - a->setText(i18n(_NAME_));\ - KGlobalAccel::self()->setShortcut(a, QList() << _CUT_); \ - connect(_BTN_, SIGNAL(keySequenceChanged(QKeySequence)), SLOT(shortcutChanged(QKeySequence))) - - // Shortcut config. The shortcut belongs to the component "kwin"! - m_actionCollection = new KActionCollection(this, QStringLiteral("kwin")); - m_actionCollection->setComponentDisplayName(i18n("KWin")); - m_actionCollection->setConfigGroup("Navigation"); - m_actionCollection->setConfigGlobal(true); - QAction* a; - ADD_SHORTCUT("Walk Through Windows", Qt::ALT + Qt::Key_Tab, m_primaryTabBoxUi->scAll); - ADD_SHORTCUT("Walk Through Windows (Reverse)", Qt::ALT + Qt::SHIFT + Qt::Key_Backtab, - m_primaryTabBoxUi->scAllReverse); - ADD_SHORTCUT("Walk Through Windows Alternative", QKeySequence(), m_alternativeTabBoxUi->scAll); - ADD_SHORTCUT("Walk Through Windows Alternative (Reverse)", QKeySequence(), m_alternativeTabBoxUi->scAllReverse); - ADD_SHORTCUT("Walk Through Windows of Current Application", Qt::ALT + Qt::Key_QuoteLeft, - m_primaryTabBoxUi->scCurrent); - ADD_SHORTCUT("Walk Through Windows of Current Application (Reverse)", Qt::ALT + Qt::Key_AsciiTilde, - m_primaryTabBoxUi->scCurrentReverse); - ADD_SHORTCUT("Walk Through Windows of Current Application Alternative", QKeySequence(), m_alternativeTabBoxUi->scCurrent); - ADD_SHORTCUT("Walk Through Windows of Current Application Alternative (Reverse)", QKeySequence(), - m_alternativeTabBoxUi->scCurrentReverse); -#undef ADD_SHORTCUT + addConfig(m_tabBoxConfig, m_primaryTabBoxUi); + addConfig(m_tabBoxAlternativeConfig, m_alternativeTabBoxUi); - initLayoutLists(); - KWinTabBoxConfigForm *ui[2] = { m_primaryTabBoxUi, m_alternativeTabBoxUi }; - for (int i = 0; i < 2; ++i) { - ui[i]->effectConfigButton->setIcon(QIcon::fromTheme(QStringLiteral("view-preview"))); - - connect(ui[i]->highlightWindowCheck, SIGNAL(clicked(bool)), SLOT(changed())); - connect(ui[i]->showTabBox, SIGNAL(clicked(bool)), SLOT(tabBoxToggled(bool))); - connect(ui[i]->effectCombo, SIGNAL(currentIndexChanged(int)), SLOT(changed())); - connect(ui[i]->effectCombo, SIGNAL(currentIndexChanged(int)), SLOT(effectSelectionChanged(int))); - connect(ui[i]->effectConfigButton, SIGNAL(clicked(bool)), SLOT(configureEffectClicked())); - - connect(ui[i]->switchingModeCombo, SIGNAL(currentIndexChanged(int)), SLOT(changed())); - connect(ui[i]->showDesktop, SIGNAL(clicked(bool)), SLOT(changed())); - - connect(ui[i]->filterDesktops, SIGNAL(clicked(bool)), SLOT(changed())); - connect(ui[i]->currentDesktop, SIGNAL(clicked(bool)), SLOT(changed())); - connect(ui[i]->otherDesktops, SIGNAL(clicked(bool)), SLOT(changed())); - - connect(ui[i]->filterActivities, SIGNAL(clicked(bool)), SLOT(changed())); - connect(ui[i]->currentActivity, SIGNAL(clicked(bool)), SLOT(changed())); - connect(ui[i]->otherActivities, SIGNAL(clicked(bool)), SLOT(changed())); - - connect(ui[i]->filterScreens, SIGNAL(clicked(bool)), SLOT(changed())); - if (QApplication::screens().count() < 2) { - ui[i]->filterScreens->hide(); - ui[i]->screenFilter->hide(); - } else { - connect(ui[i]->currentScreen, SIGNAL(clicked(bool)), SLOT(changed())); - connect(ui[i]->otherScreens, SIGNAL(clicked(bool)), SLOT(changed())); - } + createConnections(m_primaryTabBoxUi, m_tabBoxConfig); + createConnections(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig); - connect(ui[i]->oneAppWindow, SIGNAL(clicked(bool)), SLOT(changed())); - connect(ui[i]->filterMinimization, SIGNAL(clicked(bool)), SLOT(changed())); - connect(ui[i]->visibleWindows, SIGNAL(clicked(bool)), SLOT(changed())); - connect(ui[i]->hiddenWindows, SIGNAL(clicked(bool)), SLOT(changed())); - } + initLayoutLists(); // check focus policy - we don't offer configs for unreasonable focus policies KConfigGroup config(m_config, "Windows"); QString policy = config.readEntry("FocusPolicy", "ClickToFocus"); if ((policy == "FocusUnderMouse") || (policy == "FocusStrictlyUnderMouse")) { tabWidget->setEnabled(false); infoLabel->show(); } else { infoLabel->hide(); } } KWinTabBoxConfig::~KWinTabBoxConfig() { } - static QList availableLnFPackages() { QList packages; QStringList paths; const QStringList dataPaths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); for (const QString &path : dataPaths) { QDir dir(path + QLatin1String("/plasma/look-and-feel")); paths << dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); } const auto &p = paths; for (const QString &path : p) { KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel")); pkg.setPath(path); pkg.setFallbackPackage(KPackage::Package()); if (!pkg.filePath("defaults").isEmpty()) { KSharedConfigPtr conf = KSharedConfig::openConfig(pkg.filePath("defaults")); KConfigGroup cg = KConfigGroup(conf, "kwinrc"); cg = KConfigGroup(&cg, "WindowSwitcher"); if (!cg.readEntry("LayoutName", QString()).isEmpty()) { packages << pkg; } } } return packages; } void KWinTabBoxConfig::initLayoutLists() { // search the effect names - QString coverswitch = BuiltInEffects::effectData(BuiltInEffect::CoverSwitch).displayName; - QString flipswitch = BuiltInEffects::effectData(BuiltInEffect::FlipSwitch).displayName; + m_coverSwitch = BuiltInEffects::effectData(BuiltInEffect::CoverSwitch).name; + m_flipSwitch = BuiltInEffects::effectData(BuiltInEffect::FlipSwitch).name; QList offers = KPackage::PackageLoader::self()->listPackages("KWin/WindowSwitcher"); QStringList layoutNames, layoutPlugins, layoutPaths; const auto lnfPackages = availableLnFPackages(); for (const auto &package : lnfPackages) { const auto &metaData = package.metadata(); layoutNames << metaData.name(); layoutPlugins << metaData.pluginId(); layoutPaths << package.filePath("windowswitcher", QStringLiteral("WindowSwitcher.qml")); } for (const auto &offer : offers) { const QString pluginName = offer.pluginId(); if (offer.value("X-Plasma-API") != "declarativeappletscript") { continue; } //we don't have a proper servicetype if (offer.value("X-KWin-Exclude-Listing") == QStringLiteral("true")) { continue; } const QString scriptName = offer.value("X-Plasma-MainScript"); const QString scriptFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("kwin/tabbox/") + pluginName + QLatin1String("/contents/") + scriptName); if (scriptFile.isNull()) { continue; } layoutNames << offer.name(); layoutPlugins << pluginName; layoutPaths << scriptFile; } + KWinTabBoxConfigForm *ui[2] = { m_primaryTabBoxUi, m_alternativeTabBoxUi }; for (int i=0; i<2; ++i) { - int index = ui[i]->effectCombo->currentIndex(); - QVariant data = ui[i]->effectCombo->itemData(index); - ui[i]->effectCombo->clear(); - ui[i]->effectCombo->addItem(coverswitch); - ui[i]->effectCombo->addItem(flipswitch); + QStandardItemModel *model = new QStandardItemModel; + + QStandardItem *coverItem = new QStandardItem(BuiltInEffects::effectData(BuiltInEffect::CoverSwitch).displayName); + coverItem->setData(m_coverSwitch, Qt::UserRole); + coverItem->setData(false, KWinTabBoxConfigForm::AddonEffect); + model->appendRow(coverItem); + + QStandardItem *flipItem = new QStandardItem(BuiltInEffects::effectData(BuiltInEffect::FlipSwitch).displayName); + flipItem->setData(m_flipSwitch, Qt::UserRole); + flipItem->setData(false, KWinTabBoxConfigForm::AddonEffect); + model->appendRow(flipItem); + for (int j = 0; j < layoutNames.count(); ++j) { - ui[i]->effectCombo->addItem(layoutNames[j], layoutPlugins[j]); - ui[i]->effectCombo->setItemData(ui[i]->effectCombo->count() - 1, layoutPaths[j], Qt::UserRole+1); - } - if (data.isValid()) { - ui[i]->effectCombo->setCurrentIndex(ui[i]->effectCombo->findData(data)); - } else if (index != -1) { - ui[i]->effectCombo->setCurrentIndex(index); + QStandardItem *item = new QStandardItem(layoutNames[j]); + item->setData(layoutPlugins[j], Qt::UserRole); + item->setData(layoutPaths[j], KWinTabBoxConfigForm::LayoutPath); + item->setData(true, KWinTabBoxConfigForm::AddonEffect); + model->appendRow(item); } + model->sort(0); + ui[i]->setEffectComboModel(model); } } +void KWinTabBoxConfig::createConnections(KWinTabBoxConfigForm *form, TabBoxSettings *config) +{ + connect(form, SIGNAL(effectConfigButtonClicked()), this, SLOT(configureEffectClicked())); + + connect(form, SIGNAL(filterScreenChanged(int)), this, SLOT(updateUnmanagedState())); + connect(form, SIGNAL(filterDesktopChanged(int)), this, SLOT(updateUnmanagedState())); + connect(form, SIGNAL(filterActivitiesChanged(int)), this, SLOT(updateUnmanagedState())); + connect(form, SIGNAL(filterMinimizationChanged(int)), this, SLOT(updateUnmanagedState())); + connect(form, SIGNAL(applicationModeChanged(int)), this, SLOT(updateUnmanagedState())); + connect(form, SIGNAL(showDesktopModeChanged(int)), this, SLOT(updateUnmanagedState())); + connect(form, SIGNAL(switchingModeChanged(int)), this, SLOT(updateUnmanagedState())); + connect(form, SIGNAL(layoutNameChanged(QString)), this, SLOT(updateUnmanagedState())); +} + +void KWinTabBoxConfig::updateUnmanagedState() +{ + bool isNeedSave = false; + isNeedSave |= updateUnmanagedIsNeedSave(m_primaryTabBoxUi, m_tabBoxConfig); + isNeedSave |= updateUnmanagedIsNeedSave(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig); + + unmanagedWidgetChangeState(isNeedSave); + + bool isDefault = true; + isDefault &= updateUnmanagedIsDefault(m_primaryTabBoxUi, m_tabBoxConfig); + isDefault &= updateUnmanagedIsDefault(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig); + + unmanagedWidgetDefaultState(isDefault); +} + +bool KWinTabBoxConfig::updateUnmanagedIsNeedSave(const KWinTabBoxConfigForm *form, const TabBoxSettings *config) +{ + bool isNeedSave = false; + isNeedSave |= form->filterScreen() != config->multiScreenMode(); + isNeedSave |= form->filterDesktop() != config->desktopMode(); + isNeedSave |= form->filterActivities() != config->activitiesMode(); + isNeedSave |= form->filterMinimization() != config->minimizedMode(); + isNeedSave |= form->applicationMode() != config->applicationsMode(); + isNeedSave |= form->showDesktopMode() != config->showDesktopMode(); + isNeedSave |= form->switchingMode() != config->switchingMode(); + isNeedSave |= form->layoutName() != config->layoutName(); + + return isNeedSave; +} + +bool KWinTabBoxConfig::updateUnmanagedIsDefault(const KWinTabBoxConfigForm *form, const TabBoxSettings *config) +{ + bool isDefault = true; + isDefault &= form->filterScreen() == config->defaultMultiScreenModeValue(); + isDefault &= form->filterDesktop() == config->defaultDesktopModeValue(); + isDefault &= form->filterActivities() == config->defaultActivitiesModeValue(); + isDefault &= form->filterMinimization() == config->defaultMinimizedModeValue(); + isDefault &= form->applicationMode() == config->defaultApplicationsModeValue(); + isDefault &= form->showDesktopMode() == config->defaultShowDesktopModeValue(); + isDefault &= form->switchingMode() == config->defaultSwitchingModeValue(); + isDefault &= form->layoutName() == config->defaultLayoutNameValue(); + + return isDefault; +} + void KWinTabBoxConfig::load() { KCModule::load(); m_tabBoxConfig->load(); m_tabBoxAlternativeConfig->load(); + updateUiFromConfig(m_primaryTabBoxUi, m_tabBoxConfig); + updateUiFromConfig(m_alternativeTabBoxUi , m_tabBoxAlternativeConfig); + m_coverSwitchConfig->load(); m_flipSwitchConfig->load(); m_pluginsConfig->load(); - updateUiFromConfig(m_primaryTabBoxUi, m_tabBoxConfig); - updateUiFromConfig(m_alternativeTabBoxUi , m_tabBoxAlternativeConfig); - if (m_pluginsConfig->coverswitchEnabled()) { if (m_coverSwitchConfig->tabBox()) { - m_primaryTabBoxUi->effectCombo->setCurrentIndex(CoverSwitch); + m_primaryTabBoxUi->setLayoutName(m_coverSwitch); } if (m_coverSwitchConfig->tabBoxAlternative()) { - m_alternativeTabBoxUi->effectCombo->setCurrentIndex(CoverSwitch); + m_alternativeTabBoxUi->setLayoutName(m_coverSwitch); } } if (m_pluginsConfig->flipswitchEnabled()) { if (m_flipSwitchConfig->tabBox()) { - m_primaryTabBoxUi->effectCombo->setCurrentIndex(FlipSwitch); + m_primaryTabBoxUi->setLayoutName(m_flipSwitch); } if (m_flipSwitchConfig->tabBoxAlternative()) { - m_alternativeTabBoxUi->effectCombo->setCurrentIndex(FlipSwitch); + m_alternativeTabBoxUi->setLayoutName(m_flipSwitch); } } - KWinTabBoxConfigForm* ui[2] = { m_primaryTabBoxUi, m_alternativeTabBoxUi }; - for (int i = 0; i < 2; ++i) { - QString action; -#define LOAD_SHORTCUT(_BTN_)\ - action = ui[i]->_BTN_->property("shortcutAction").toString();\ - qDebug() << "load shortcut for " << action;\ - if (QAction *a = m_actionCollection->action(action)) { \ - auto shortcuts = KGlobalAccel::self()->shortcut(a); \ - if (!shortcuts.isEmpty()) \ - ui[i]->_BTN_->setKeySequence(shortcuts.first()); \ - } - LOAD_SHORTCUT(scAll); - LOAD_SHORTCUT(scAllReverse); - LOAD_SHORTCUT(scCurrent); - LOAD_SHORTCUT(scCurrentReverse); -#undef LOAD_SHORTCUT - } - emit changed(false); + m_primaryTabBoxUi->loadShortcuts(); + m_alternativeTabBoxUi->loadShortcuts(); + + updateUnmanagedState(); } void KWinTabBoxConfig::save() { - KCModule::save(); - - // sync ui to config - updateConfigFromUi(m_primaryTabBoxUi, m_tabBoxConfig); - updateConfigFromUi(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig); - m_tabBoxConfig->save(); - m_tabBoxAlternativeConfig->save(); - // effects - bool highlightWindows = m_primaryTabBoxUi->highlightWindowCheck->isChecked() || - m_alternativeTabBoxUi->highlightWindowCheck->isChecked(); - const bool coverSwitch = m_primaryTabBoxUi->showTabBox->isChecked() && - m_primaryTabBoxUi->effectCombo->currentIndex() == CoverSwitch; - const bool flipSwitch = m_primaryTabBoxUi->showTabBox->isChecked() && - m_primaryTabBoxUi->effectCombo->currentIndex() == FlipSwitch; - const bool coverSwitchAlternative = m_alternativeTabBoxUi->showTabBox->isChecked() && - m_alternativeTabBoxUi->effectCombo->currentIndex() == CoverSwitch; - const bool flipSwitchAlternative = m_alternativeTabBoxUi->showTabBox->isChecked() && - m_alternativeTabBoxUi->effectCombo->currentIndex() == FlipSwitch; + const bool highlightWindows = m_primaryTabBoxUi->highlightWindows() || m_alternativeTabBoxUi->highlightWindows(); + const bool coverSwitch = m_primaryTabBoxUi->showTabBox() + && m_primaryTabBoxUi->effectComboCurrentData().toString() == m_coverSwitch; + const bool flipSwitch = m_primaryTabBoxUi->showTabBox() + && m_primaryTabBoxUi->effectComboCurrentData().toString() == m_flipSwitch; + const bool coverSwitchAlternative = m_alternativeTabBoxUi->showTabBox() + && m_alternativeTabBoxUi->effectComboCurrentData().toString() == m_coverSwitch; + const bool flipSwitchAlternative = m_alternativeTabBoxUi->showTabBox() + && m_alternativeTabBoxUi->effectComboCurrentData().toString() == m_flipSwitch; // activate effects if not active if (coverSwitch || coverSwitchAlternative) { m_pluginsConfig->setCoverswitchEnabled(true); } if (flipSwitch || flipSwitchAlternative) { m_pluginsConfig->setFlipswitchEnabled(true); } if (highlightWindows) { m_pluginsConfig->setHighlightwindowEnabled(true); } m_pluginsConfig->save(); m_coverSwitchConfig->setTabBox(coverSwitch); m_coverSwitchConfig->setTabBoxAlternative(coverSwitchAlternative); m_coverSwitchConfig->save(); m_flipSwitchConfig->setTabBox(flipSwitch); m_flipSwitchConfig->setTabBoxAlternative(flipSwitchAlternative); m_flipSwitchConfig->save(); + updateConfigFromUi(m_primaryTabBoxUi, m_tabBoxConfig); + updateConfigFromUi(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig); + + m_tabBoxConfig->save(); + m_tabBoxAlternativeConfig->save(); + + KCModule::save(); + updateUnmanagedState(); + // Reload KWin. QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); QDBusConnection::sessionBus().send(message); // and reconfigure the effects OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QDBusConnection::sessionBus()); interface.reconfigureEffect(BuiltInEffects::nameForEffect(BuiltInEffect::CoverSwitch)); interface.reconfigureEffect(BuiltInEffects::nameForEffect(BuiltInEffect::FlipSwitch)); - - emit changed(false); } void KWinTabBoxConfig::defaults() { - KCModule::defaults(); - - m_tabBoxConfig->setDefaults(); - m_tabBoxAlternativeConfig->setDefaults(); - - m_pluginsConfig->setDefaults(); m_coverSwitchConfig->setDefaults(); m_flipSwitchConfig->setDefaults(); - updateUiFromConfig(m_primaryTabBoxUi, m_tabBoxConfig); - updateUiFromConfig(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig); - - QString action; - auto RESET_SHORTCUT = [this](KKeySequenceWidget *widget, const QKeySequence &sequence = QKeySequence()) { - const QString action = widget->property("shortcutAction").toString(); - QAction *a = m_actionCollection->action(action); - KGlobalAccel::self()->setShortcut(a, QList() << sequence, KGlobalAccel::NoAutoloading); - }; - RESET_SHORTCUT(m_primaryTabBoxUi->scAll, Qt::ALT + Qt::Key_Tab); - RESET_SHORTCUT(m_primaryTabBoxUi->scAllReverse, Qt::ALT + Qt::SHIFT + Qt::Key_Backtab); - RESET_SHORTCUT(m_alternativeTabBoxUi->scAll); - RESET_SHORTCUT(m_alternativeTabBoxUi->scAllReverse); - RESET_SHORTCUT(m_primaryTabBoxUi->scCurrent, Qt::ALT + Qt::Key_QuoteLeft); - RESET_SHORTCUT(m_primaryTabBoxUi->scCurrentReverse, Qt::ALT + Qt::Key_AsciiTilde); - RESET_SHORTCUT(m_alternativeTabBoxUi->scCurrent); - RESET_SHORTCUT(m_alternativeTabBoxUi->scCurrentReverse); - m_actionCollection->writeSettings(); - emit changed(true); -} + updateUiFromDefaultConfig(m_primaryTabBoxUi, m_tabBoxConfig); + updateUiFromDefaultConfig(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig); -void KWinTabBoxConfig::updateUiFromConfig(KWinTabBoxConfigForm *ui, const KWin::TabBox::TabBoxSettings *config) -{ -#define CONFIGURE(SETTING, MODE, IS, VALUE) ui->SETTING->setChecked(config->MODE##Mode() IS TabBoxConfig::VALUE) - CONFIGURE(filterDesktops, desktop, !=, AllDesktopsClients); - CONFIGURE(currentDesktop, desktop, ==, OnlyCurrentDesktopClients); - CONFIGURE(otherDesktops, desktop, ==, ExcludeCurrentDesktopClients); - CONFIGURE(filterActivities, activities, !=, AllActivitiesClients); - CONFIGURE(currentActivity, activities, ==, OnlyCurrentActivityClients); - CONFIGURE(otherActivities, activities, ==, ExcludeCurrentActivityClients); - CONFIGURE(filterScreens, multiScreen, !=, IgnoreMultiScreen); - CONFIGURE(currentScreen, multiScreen, ==, OnlyCurrentScreenClients); - CONFIGURE(otherScreens, multiScreen, ==, ExcludeCurrentScreenClients); - CONFIGURE(oneAppWindow, applications, ==, OneWindowPerApplication); - CONFIGURE(filterMinimization, minimized, !=, IgnoreMinimizedStatus); - CONFIGURE(visibleWindows, minimized, ==, ExcludeMinimizedClients); - CONFIGURE(hiddenWindows, minimized, ==, OnlyMinimizedClients); - - ui->switchingModeCombo->setCurrentIndex(config->switchingMode()); - - // check boxes - ui->showTabBox->setChecked(config->showTabBox()); - ui->highlightWindowCheck->setChecked(config->highlightWindows()); - ui->effectCombo->setCurrentIndex(ui->effectCombo->findData(config->layoutName())); - CONFIGURE(showDesktop, showDesktop, ==, ShowDesktopClient); -#undef CONFIGURE + m_primaryTabBoxUi->resetShortcuts(); + m_alternativeTabBoxUi->resetShortcuts(); + + KCModule::defaults(); + updateUnmanagedState(); } -void KWinTabBoxConfig::updateConfigFromUi(const KWin::KWinTabBoxConfigForm *ui, TabBoxSettings *config) +void KWinTabBoxConfig::updateUiFromConfig(KWinTabBoxConfigForm *form, const KWin::TabBox::TabBoxSettings *config) { - if (ui->filterDesktops->isChecked()) { - config->setDesktopMode(ui->currentDesktop->isChecked() ? TabBoxConfig::OnlyCurrentDesktopClients : TabBoxConfig::ExcludeCurrentDesktopClients); - } else { - config->setDesktopMode(TabBoxConfig::AllDesktopsClients); - } - if (ui->filterActivities->isChecked()) { - config->setActivitiesMode(ui->currentActivity->isChecked() ? TabBoxConfig::OnlyCurrentActivityClients : TabBoxConfig::ExcludeCurrentActivityClients); - } else { - config->setActivitiesMode(TabBoxConfig::AllActivitiesClients); - } - if (ui->filterScreens->isChecked()) { - config->setMultiScreenMode(ui->currentScreen->isChecked() ? TabBoxConfig::OnlyCurrentScreenClients : TabBoxConfig::ExcludeCurrentScreenClients); - } else { - config->setMultiScreenMode(TabBoxConfig::IgnoreMultiScreen); - } - config->setApplicationsMode(ui->oneAppWindow->isChecked() ? TabBoxConfig::OneWindowPerApplication : TabBoxConfig::AllWindowsAllApplications); - if (ui->filterMinimization->isChecked()) { - config->setMinimizedMode(ui->visibleWindows->isChecked() ? TabBoxConfig::ExcludeMinimizedClients : TabBoxConfig::OnlyMinimizedClients); - } else { - config->setMinimizedMode(TabBoxConfig::IgnoreMinimizedStatus); - } - - config->setSwitchingMode(TabBoxConfig::ClientSwitchingMode(ui->switchingModeCombo->currentIndex())); - - config->setShowTabBox(ui->showTabBox->isChecked()); - config->setHighlightWindows(ui->highlightWindowCheck->isChecked()); - if (ui->effectCombo->currentIndex() >= Layout) { - config->setLayoutName(ui->effectCombo->itemData(ui->effectCombo->currentIndex()).toString()); - } - config->setShowDesktopMode(ui->showDesktop->isChecked() ? TabBoxConfig::ShowDesktopClient : TabBoxConfig::DoNotShowDesktopClient); + form->setFilterScreen(static_cast(config->multiScreenMode())); + form->setFilterDesktop(static_cast(config->desktopMode())); + form->setFilterActivities(static_cast(config->activitiesMode())); + form->setFilterMinimization(static_cast(config->minimizedMode())); + form->setApplicationMode(static_cast(config->applicationsMode())); + form->setShowDesktopMode(static_cast(config->showDesktopMode())); + form->setSwitchingModeChanged(static_cast(config->switchingMode())); + form->setLayoutName(config->layoutName()); } -#define CHECK_CURRENT_TABBOX_UI \ - Q_ASSERT(sender());\ - KWinTabBoxConfigForm *ui = nullptr;\ - QObject *dad = sender();\ - while (!ui && (dad = dad->parent()))\ - ui = qobject_cast(dad);\ - Q_ASSERT(ui); - -void KWinTabBoxConfig::effectSelectionChanged(int index) +void KWinTabBoxConfig::updateConfigFromUi(const KWinTabBoxConfigForm *form, TabBoxSettings *config) { - CHECK_CURRENT_TABBOX_UI - ui->effectConfigButton->setIcon(QIcon::fromTheme(index < Layout ? "configure" : "view-preview")); - if (!ui->showTabBox->isChecked()) - return; - ui->highlightWindowCheck->setEnabled(index >= Layout); + config->setMultiScreenMode(form->filterScreen()); + config->setDesktopMode(form->filterDesktop()); + config->setActivitiesMode(form->filterActivities()); + config->setMinimizedMode(form->filterMinimization()); + config->setApplicationsMode(form->applicationMode()); + config->setShowDesktopMode(form->showDesktopMode()); + config->setSwitchingMode(form->switchingMode()); + config->setLayoutName(form->layoutName()); } -void KWinTabBoxConfig::tabBoxToggled(bool on) +void KWinTabBoxConfig::updateUiFromDefaultConfig(KWinTabBoxConfigForm *form, const KWin::TabBox::TabBoxSettings *config) { - CHECK_CURRENT_TABBOX_UI - on = !on || ui->effectCombo->currentIndex() >= Layout; - ui->highlightWindowCheck->setEnabled(on); - markAsChanged(); + form->setFilterScreen(static_cast(config->defaultMultiScreenModeValue())); + form->setFilterDesktop(static_cast(config->defaultDesktopModeValue())); + form->setFilterActivities(static_cast(config->defaultActivitiesModeValue())); + form->setFilterMinimization(static_cast(config->defaultMinimizedModeValue())); + form->setApplicationMode(static_cast(config->defaultApplicationsModeValue())); + form->setShowDesktopMode(static_cast(config->defaultShowDesktopModeValue())); + form->setSwitchingModeChanged(static_cast(config->defaultSwitchingModeValue())); + form->setLayoutName(config->defaultLayoutNameValue()); } void KWinTabBoxConfig::configureEffectClicked() { - CHECK_CURRENT_TABBOX_UI + auto form = qobject_cast(sender()); + Q_ASSERT(form); - const int effect = ui->effectCombo->currentIndex(); - if (effect >= Layout) { - // TODO: here we need to show the preview - new LayoutPreview(ui->effectCombo->itemData(effect, Qt::UserRole+1).toString(), this); + if (form->effectComboCurrentData(KWinTabBoxConfigForm::AddonEffect).toBool()) { + // Show the preview for addon effect + new LayoutPreview(form->effectComboCurrentData(KWinTabBoxConfigForm::LayoutPath).toString(), this); } else { + // For builtin effect, display a configuration dialog QPointer configDialog = new QDialog(this); configDialog->setLayout(new QVBoxLayout); - configDialog->setWindowTitle(ui->effectCombo->currentText()); + configDialog->setWindowTitle(form->effectComboCurrentData(Qt::DisplayRole).toString()); QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel|QDialogButtonBox::RestoreDefaults, configDialog); connect(buttonBox, SIGNAL(accepted()), configDialog, SLOT(accept())); connect(buttonBox, SIGNAL(rejected()), configDialog, SLOT(reject())); - const QString name = BuiltInEffects::nameForEffect(effect == CoverSwitch ? BuiltInEffect::CoverSwitch : BuiltInEffect::FlipSwitch); - + const QString name = form->effectComboCurrentData().toString(); KCModule *kcm = KPluginTrader::createInstanceFromQuery(QStringLiteral("kwin/effects/configs/"), QString(), QStringLiteral("'%1' in [X-KDE-ParentComponents]").arg(name), - configDialog); + configDialog); if (!kcm) { delete configDialog; return; } connect(buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, kcm, &KCModule::defaults); QWidget *showWidget = new QWidget(configDialog); QVBoxLayout *layout = new QVBoxLayout; showWidget->setLayout(layout); layout->addWidget(kcm); configDialog->layout()->addWidget(showWidget); configDialog->layout()->addWidget(buttonBox); if (configDialog->exec() == QDialog::Accepted) { kcm->save(); } else { kcm->load(); } delete configDialog; } } -void KWinTabBoxConfig::shortcutChanged(const QKeySequence &seq) -{ - QString action; - if (sender()) - action = sender()->property("shortcutAction").toString(); - if (action.isEmpty()) - return; - QAction *a = m_actionCollection->action(action); - KGlobalAccel::self()->setShortcut(a, QList() << seq, KGlobalAccel::NoAutoloading); - m_actionCollection->writeSettings(); -} - void KWinTabBoxConfig::slotGHNS() { QPointer downloadDialog = new KNS3::DownloadDialog("kwinswitcher.knsrc", this); if (downloadDialog->exec() == QDialog::Accepted) { if (!downloadDialog->changedEntries().isEmpty()) { initLayoutLists(); } } delete downloadDialog; } } // namespace #include "main.moc" diff --git a/kcmkwin/kwintabbox/main.h b/kcmkwin/kwintabbox/main.h index a6d962962..1cac4bc4b 100644 --- a/kcmkwin/kwintabbox/main.h +++ b/kcmkwin/kwintabbox/main.h @@ -1,98 +1,86 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2009 Martin Gräßlin Copyright (C) 2020 Cyril Rossi 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 __MAIN_H__ #define __MAIN_H__ #include #include - -#include "ui_main.h" - -class KShortcutsEditor; -class KActionCollection; +#include "tabboxconfig.h" namespace KWin { +class KWinTabBoxConfigForm; enum class BuiltInEffect; namespace TabBox { class TabBoxSettings; class SwitchEffectSettings; class PluginsSettings; } - -class KWinTabBoxConfigForm : public QWidget, public Ui::KWinTabBoxConfigForm -{ - Q_OBJECT - -public: - explicit KWinTabBoxConfigForm(QWidget* parent); -}; - class KWinTabBoxConfig : public KCModule { Q_OBJECT public: explicit KWinTabBoxConfig(QWidget* parent, const QVariantList& args); ~KWinTabBoxConfig() override; public Q_SLOTS: void save() override; void load() override; void defaults() override; private Q_SLOTS: - void effectSelectionChanged(int index); + void updateUnmanagedState(); void configureEffectClicked(); - void tabBoxToggled(bool on); - void shortcutChanged(const QKeySequence &seq); void slotGHNS(); + private: - void updateUiFromConfig(KWinTabBoxConfigForm *ui, const TabBox::TabBoxSettings *config); - void updateConfigFromUi(const KWinTabBoxConfigForm *ui, TabBox::TabBoxSettings *config); + void updateUiFromConfig(KWinTabBoxConfigForm *form, const TabBox::TabBoxSettings *config); + void updateConfigFromUi(const KWinTabBoxConfigForm *form, TabBox::TabBoxSettings *config); + void updateUiFromDefaultConfig(KWinTabBoxConfigForm *form, const TabBox::TabBoxSettings *config); void initLayoutLists(); + void createConnections(KWinTabBoxConfigForm *form, TabBox::TabBoxSettings *config); + bool updateUnmanagedIsNeedSave(const KWinTabBoxConfigForm *form, const TabBox::TabBoxSettings *config); + bool updateUnmanagedIsDefault(const KWinTabBoxConfigForm *form, const TabBox::TabBoxSettings *config); private: - enum Mode { - CoverSwitch = 0, - FlipSwitch = 1, - Layout = 2 - }; - KWinTabBoxConfigForm* m_primaryTabBoxUi; - KWinTabBoxConfigForm* m_alternativeTabBoxUi; + KWinTabBoxConfigForm *m_primaryTabBoxUi = nullptr; + KWinTabBoxConfigForm *m_alternativeTabBoxUi = nullptr; KSharedConfigPtr m_config; - KActionCollection* m_actionCollection; - KShortcutsEditor* m_editor; + TabBox::TabBoxSettings *m_tabBoxConfig; TabBox::TabBoxSettings *m_tabBoxAlternativeConfig; TabBox::SwitchEffectSettings *m_coverSwitchConfig; TabBox::SwitchEffectSettings *m_flipSwitchConfig; TabBox::PluginsSettings *m_pluginsConfig; + // Builtin effects' names + QString m_coverSwitch; + QString m_flipSwitch; }; } // namespace #endif diff --git a/kcmkwin/kwintabbox/main.ui b/kcmkwin/kwintabbox/main.ui index 9147dad94..e702e358b 100644 --- a/kcmkwin/kwintabbox/main.ui +++ b/kcmkwin/kwintabbox/main.ui @@ -1,699 +1,699 @@ KWinTabBoxConfigForm 0 0 658 418 Qt::Horizontal 40 20 Content true Include "Show Desktop" icon 0 0 Recently used Stacking order Only one window per application false Sort order: switchingModeCombo Qt::Horizontal 40 20 Filter windows by true Virtual desktops false false 0 0 0 0 Qt::Horizontal QSizePolicy::Fixed 24 20 Current desktop All other desktops Activities false false 0 0 0 0 Qt::Horizontal QSizePolicy::Fixed 24 20 Current activity All other activities Screens false false 0 0 0 0 Qt::Horizontal QSizePolicy::Fixed 24 20 Current screen All other screens Minimization false false 0 0 0 0 Qt::Horizontal QSizePolicy::Fixed 24 20 Visible windows Hidden windows Qt::Vertical 20 40 Qt::Vertical 20 40 Shortcuts true Forward Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Horizontal 75 true All windows Qt::AlignCenter Reverse Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Forward Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Reverse Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 75 true Current application Qt::AlignCenter Visualization true 0 0 0 0 0 0 The effect to replace the list window when desktop effects are active. 0 0 - + true - + The currently selected window will be highlighted by fading out all other windows. This option requires desktop effects to be active. Show selected window Qt::Vertical Qt::Horizontal 40 20 KKeySequenceWidget QWidget
kkeysequencewidget.h
KComboBox QComboBox
kcombobox.h
- highlightWindowCheck - showTabBox + kcfg_HighlightWindows + kcfg_ShowTabBox effectCombo effectConfigButton switchingModeCombo showDesktop oneAppWindow filterDesktops currentDesktop otherDesktops filterActivities currentActivity otherActivities filterScreens currentScreen otherScreens filterMinimization visibleWindows hiddenWindows filterDesktops toggled(bool) desktopFilter setEnabled(bool) 541 172 701 197 filterActivities toggled(bool) activityFilter setEnabled(bool) 543 222 701 247 filterScreens toggled(bool) screenFilter setEnabled(bool) 555 272 701 297 filterMinimization toggled(bool) minimizationFilter setEnabled(bool) 558 322 701 347 - showTabBox + kcfg_ShowTabBox toggled(bool) widget_6 setEnabled(bool) 164 125 230 108