File indexing completed on 2024-11-10 04:56:52

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2009 Martin Gräßlin <mgraesslin@kde.org>
0006     SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com>
0007     SPDX-FileCopyrightText: 2023 Ismael Asensio <isma.af@gmail.com>
0008 
0009     SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 
0012 #include "kwintabboxconfigform.h"
0013 #include "kwintabboxsettings.h"
0014 #include "shortcutsettings.h"
0015 #include "ui_main.h"
0016 
0017 namespace KWin
0018 {
0019 
0020 using namespace TabBox;
0021 
0022 KWinTabBoxConfigForm::KWinTabBoxConfigForm(TabboxType type, TabBoxSettings *config, ShortcutSettings *shortcutsConfig, QWidget *parent)
0023     : QWidget(parent)
0024     , m_config(config)
0025     , m_shortcuts(shortcutsConfig)
0026     , ui(new Ui::KWinTabBoxConfigForm)
0027 {
0028     ui->setupUi(this);
0029 
0030     ui->effectConfigButton->setIcon(QIcon::fromTheme(QStringLiteral("view-preview")));
0031 
0032     if (QApplication::screens().count() < 2) {
0033         ui->filterScreens->hide();
0034         ui->screenFilter->hide();
0035     }
0036 
0037     connect(this, &KWinTabBoxConfigForm::configChanged, this, &KWinTabBoxConfigForm::updateDefaultIndicators);
0038 
0039     connect(ui->effectConfigButton, &QPushButton::clicked, this, &KWinTabBoxConfigForm::effectConfigButtonClicked);
0040 
0041     connect(ui->kcfg_ShowTabBox, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::tabBoxToggled);
0042 
0043     connect(ui->filterScreens, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterScreen);
0044     connect(ui->currentScreen, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterScreen);
0045     connect(ui->otherScreens, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterScreen);
0046 
0047     connect(ui->filterDesktops, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterDesktop);
0048     connect(ui->currentDesktop, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterDesktop);
0049     connect(ui->otherDesktops, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterDesktop);
0050 
0051     connect(ui->filterActivities, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterActivites);
0052     connect(ui->currentActivity, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterActivites);
0053     connect(ui->otherActivities, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterActivites);
0054 
0055     connect(ui->filterMinimization, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterMinimization);
0056     connect(ui->visibleWindows, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterMinimization);
0057     connect(ui->hiddenWindows, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onFilterMinimization);
0058 
0059     connect(ui->oneAppWindow, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onApplicationMode);
0060     connect(ui->orderMinimized, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onOrderMinimizedMode);
0061     connect(ui->showDesktop, &QAbstractButton::clicked, this, &KWinTabBoxConfigForm::onShowDesktopMode);
0062 
0063     connect(ui->switchingModeCombo, &QComboBox::activated, this, &KWinTabBoxConfigForm::onSwitchingMode);
0064     connect(ui->effectCombo, &QComboBox::activated, this, &KWinTabBoxConfigForm::onEffectCombo);
0065 
0066     auto initShortcutWidget = [this](KKeySequenceWidget *widget, const char *name) {
0067         widget->setCheckActionCollections({m_shortcuts->actionCollection()});
0068         widget->setProperty("shortcutAction", name);
0069         connect(widget, &KKeySequenceWidget::keySequenceChanged, this, &KWinTabBoxConfigForm::onShortcutChanged);
0070     };
0071 
0072     if (TabboxType::Main == type) {
0073         initShortcutWidget(ui->scAll, "Walk Through Windows");
0074         initShortcutWidget(ui->scAllReverse, "Walk Through Windows (Reverse)");
0075         initShortcutWidget(ui->scCurrent, "Walk Through Windows of Current Application");
0076         initShortcutWidget(ui->scCurrentReverse, "Walk Through Windows of Current Application (Reverse)");
0077     } else if (TabboxType::Alternative == type) {
0078         initShortcutWidget(ui->scAll, "Walk Through Windows Alternative");
0079         initShortcutWidget(ui->scAllReverse, "Walk Through Windows Alternative (Reverse)");
0080         initShortcutWidget(ui->scCurrent, "Walk Through Windows of Current Application Alternative");
0081         initShortcutWidget(ui->scCurrentReverse, "Walk Through Windows of Current Application Alternative (Reverse)");
0082     }
0083 
0084     updateUiFromConfig();
0085 }
0086 
0087 KWinTabBoxConfigForm::~KWinTabBoxConfigForm()
0088 {
0089     delete ui;
0090 }
0091 
0092 TabBoxSettings *KWinTabBoxConfigForm::config() const
0093 {
0094     return m_config;
0095 }
0096 
0097 bool KWinTabBoxConfigForm::highlightWindows() const
0098 {
0099     return ui->kcfg_HighlightWindows->isChecked();
0100 }
0101 
0102 bool KWinTabBoxConfigForm::showTabBox() const
0103 {
0104     return ui->kcfg_ShowTabBox->isChecked();
0105 }
0106 
0107 int KWinTabBoxConfigForm::filterScreen() const
0108 {
0109     if (ui->filterScreens->isChecked()) {
0110         return ui->currentScreen->isChecked() ? TabBoxConfig::OnlyCurrentScreenClients : TabBoxConfig::ExcludeCurrentScreenClients;
0111     } else {
0112         return TabBoxConfig::IgnoreMultiScreen;
0113     }
0114 }
0115 
0116 int KWinTabBoxConfigForm::filterDesktop() const
0117 {
0118     if (ui->filterDesktops->isChecked()) {
0119         return ui->currentDesktop->isChecked() ? TabBoxConfig::OnlyCurrentDesktopClients : TabBoxConfig::ExcludeCurrentDesktopClients;
0120     } else {
0121         return TabBoxConfig::AllDesktopsClients;
0122     }
0123 }
0124 
0125 int KWinTabBoxConfigForm::filterActivities() const
0126 {
0127     if (ui->filterActivities->isChecked()) {
0128         return ui->currentActivity->isChecked() ? TabBoxConfig::OnlyCurrentActivityClients : TabBoxConfig::ExcludeCurrentActivityClients;
0129     } else {
0130         return TabBoxConfig::AllActivitiesClients;
0131     }
0132 }
0133 
0134 int KWinTabBoxConfigForm::filterMinimization() const
0135 {
0136     if (ui->filterMinimization->isChecked()) {
0137         return ui->visibleWindows->isChecked() ? TabBoxConfig::ExcludeMinimizedClients : TabBoxConfig::OnlyMinimizedClients;
0138     } else {
0139         return TabBoxConfig::IgnoreMinimizedStatus;
0140     }
0141 }
0142 
0143 int KWinTabBoxConfigForm::applicationMode() const
0144 {
0145     return ui->oneAppWindow->isChecked() ? TabBoxConfig::OneWindowPerApplication : TabBoxConfig::AllWindowsAllApplications;
0146 }
0147 
0148 int KWinTabBoxConfigForm::orderMinimizedMode() const
0149 {
0150     return ui->orderMinimized->isChecked() ? TabBoxConfig::GroupByMinimized : TabBoxConfig::NoGroupByMinimized;
0151 }
0152 
0153 int KWinTabBoxConfigForm::showDesktopMode() const
0154 {
0155     return ui->showDesktop->isChecked() ? TabBoxConfig::ShowDesktopClient : TabBoxConfig::DoNotShowDesktopClient;
0156 }
0157 
0158 int KWinTabBoxConfigForm::switchingMode() const
0159 {
0160     return ui->switchingModeCombo->currentIndex();
0161 }
0162 
0163 QString KWinTabBoxConfigForm::layoutName() const
0164 {
0165     return ui->effectCombo->currentData().toString();
0166 }
0167 
0168 void KWinTabBoxConfigForm::setFilterScreen(TabBox::TabBoxConfig::ClientMultiScreenMode mode)
0169 {
0170     ui->filterScreens->setChecked(mode != TabBoxConfig::IgnoreMultiScreen);
0171     ui->currentScreen->setChecked(mode == TabBoxConfig::OnlyCurrentScreenClients);
0172     ui->otherScreens->setChecked(mode == TabBoxConfig::ExcludeCurrentScreenClients);
0173 }
0174 
0175 void KWinTabBoxConfigForm::setFilterDesktop(TabBox::TabBoxConfig::ClientDesktopMode mode)
0176 {
0177     ui->filterDesktops->setChecked(mode != TabBoxConfig::AllDesktopsClients);
0178     ui->currentDesktop->setChecked(mode == TabBoxConfig::OnlyCurrentDesktopClients);
0179     ui->otherDesktops->setChecked(mode == TabBoxConfig::ExcludeCurrentDesktopClients);
0180 }
0181 
0182 void KWinTabBoxConfigForm::setFilterActivities(TabBox::TabBoxConfig::ClientActivitiesMode mode)
0183 {
0184     ui->filterActivities->setChecked(mode != TabBoxConfig::AllActivitiesClients);
0185     ui->currentActivity->setChecked(mode == TabBoxConfig::OnlyCurrentActivityClients);
0186     ui->otherActivities->setChecked(mode == TabBoxConfig::ExcludeCurrentActivityClients);
0187 }
0188 
0189 void KWinTabBoxConfigForm::setFilterMinimization(TabBox::TabBoxConfig::ClientMinimizedMode mode)
0190 {
0191     ui->filterMinimization->setChecked(mode != TabBoxConfig::IgnoreMinimizedStatus);
0192     ui->visibleWindows->setChecked(mode == TabBoxConfig::ExcludeMinimizedClients);
0193     ui->hiddenWindows->setChecked(mode == TabBoxConfig::OnlyMinimizedClients);
0194 }
0195 
0196 void KWinTabBoxConfigForm::setApplicationMode(TabBox::TabBoxConfig::ClientApplicationsMode mode)
0197 {
0198     ui->oneAppWindow->setChecked(mode == TabBoxConfig::OneWindowPerApplication);
0199 }
0200 
0201 void KWinTabBoxConfigForm::setOrderMinimizedMode(TabBox::TabBoxConfig::OrderMinimizedMode mode)
0202 {
0203     ui->orderMinimized->setChecked(mode == TabBoxConfig::GroupByMinimized);
0204 }
0205 
0206 void KWinTabBoxConfigForm::setShowDesktopMode(TabBox::TabBoxConfig::ShowDesktopMode mode)
0207 {
0208     ui->showDesktop->setChecked(mode == TabBoxConfig::ShowDesktopClient);
0209 }
0210 
0211 void KWinTabBoxConfigForm::setSwitchingModeChanged(TabBox::TabBoxConfig::ClientSwitchingMode mode)
0212 {
0213     ui->switchingModeCombo->setCurrentIndex(mode);
0214 }
0215 
0216 void KWinTabBoxConfigForm::setLayoutName(const QString &layoutName)
0217 {
0218     const int index = ui->effectCombo->findData(layoutName);
0219     if (index >= 0) {
0220         ui->effectCombo->setCurrentIndex(index);
0221     }
0222 }
0223 
0224 void KWinTabBoxConfigForm::setEffectComboModel(QStandardItemModel *model)
0225 {
0226     // We don't want to lose the config layout when resetting the combo model
0227     const QString layout = m_config->layoutName();
0228     ui->effectCombo->setModel(model);
0229     setLayoutName(layout);
0230 }
0231 
0232 QVariant KWinTabBoxConfigForm::effectComboCurrentData(int role) const
0233 {
0234     return ui->effectCombo->currentData(role);
0235 }
0236 
0237 void KWinTabBoxConfigForm::tabBoxToggled(bool on)
0238 {
0239     // Highlight Windows options is availabled if no TabBox effect is selected
0240     // or if Tabbox is not builtin effet.
0241     on = !on || ui->effectCombo->currentData(AddonEffect).toBool();
0242     ui->kcfg_HighlightWindows->setEnabled(on && m_isHighlightWindowsEnabled);
0243 }
0244 
0245 void KWinTabBoxConfigForm::onFilterScreen()
0246 {
0247     m_config->setMultiScreenMode(filterScreen());
0248     Q_EMIT configChanged();
0249 }
0250 
0251 void KWinTabBoxConfigForm::onFilterDesktop()
0252 {
0253     m_config->setDesktopMode(filterDesktop());
0254     Q_EMIT configChanged();
0255 }
0256 
0257 void KWinTabBoxConfigForm::onFilterActivites()
0258 {
0259     m_config->setActivitiesMode(filterActivities());
0260     Q_EMIT configChanged();
0261 }
0262 
0263 void KWinTabBoxConfigForm::onFilterMinimization()
0264 {
0265     m_config->setMinimizedMode(filterMinimization());
0266     Q_EMIT configChanged();
0267 }
0268 
0269 void KWin::KWinTabBoxConfigForm::onApplicationMode()
0270 {
0271     m_config->setApplicationsMode(applicationMode());
0272     Q_EMIT configChanged();
0273 }
0274 
0275 void KWinTabBoxConfigForm::onOrderMinimizedMode()
0276 {
0277     m_config->setOrderMinimizedMode(orderMinimizedMode());
0278     Q_EMIT configChanged();
0279 }
0280 
0281 void KWinTabBoxConfigForm::onShowDesktopMode()
0282 {
0283     m_config->setShowDesktopMode(showDesktopMode());
0284     Q_EMIT configChanged();
0285 }
0286 
0287 void KWinTabBoxConfigForm::onSwitchingMode()
0288 {
0289     m_config->setSwitchingMode(switchingMode());
0290     Q_EMIT configChanged();
0291 }
0292 
0293 void KWinTabBoxConfigForm::onEffectCombo()
0294 {
0295     const bool isAddonEffect = ui->effectCombo->currentData(AddonEffect).toBool();
0296     ui->effectConfigButton->setIcon(QIcon::fromTheme(isAddonEffect ? "view-preview" : "configure"));
0297     if (!ui->kcfg_ShowTabBox->isChecked()) {
0298         return;
0299     }
0300     ui->kcfg_HighlightWindows->setEnabled(isAddonEffect && m_isHighlightWindowsEnabled);
0301 
0302     m_config->setLayoutName(layoutName());
0303     Q_EMIT configChanged();
0304 }
0305 
0306 void KWinTabBoxConfigForm::onShortcutChanged(const QKeySequence &seq)
0307 {
0308     const QString actionName = sender()->property("shortcutAction").toString();
0309     m_shortcuts->setShortcut(actionName, seq);
0310 
0311     Q_EMIT configChanged();
0312 }
0313 
0314 void KWinTabBoxConfigForm::updateUiFromConfig()
0315 {
0316     setFilterScreen(static_cast<TabBoxConfig::ClientMultiScreenMode>(m_config->multiScreenMode()));
0317     setFilterDesktop(static_cast<TabBoxConfig::ClientDesktopMode>(m_config->desktopMode()));
0318     setFilterActivities(static_cast<TabBoxConfig::ClientActivitiesMode>(m_config->activitiesMode()));
0319     setFilterMinimization(static_cast<TabBoxConfig::ClientMinimizedMode>(m_config->minimizedMode()));
0320     setApplicationMode(static_cast<TabBoxConfig::ClientApplicationsMode>(m_config->applicationsMode()));
0321     setOrderMinimizedMode(static_cast<TabBoxConfig::OrderMinimizedMode>(m_config->orderMinimizedMode()));
0322     setShowDesktopMode(static_cast<TabBoxConfig::ShowDesktopMode>(m_config->showDesktopMode()));
0323     setSwitchingModeChanged(static_cast<TabBoxConfig::ClientSwitchingMode>(m_config->switchingMode()));
0324     setLayoutName(m_config->layoutName());
0325 
0326     for (const auto &widget : {ui->scAll, ui->scAllReverse, ui->scCurrent, ui->scCurrentReverse}) {
0327         const QString actionName = widget->property("shortcutAction").toString();
0328         widget->setKeySequence(m_shortcuts->shortcut(actionName));
0329     }
0330 
0331     updateDefaultIndicators();
0332 }
0333 
0334 void KWinTabBoxConfigForm::setEnabledUi()
0335 {
0336     m_isHighlightWindowsEnabled = !m_config->isHighlightWindowsImmutable();
0337     ui->kcfg_HighlightWindows->setEnabled(!m_config->isHighlightWindowsImmutable());
0338 
0339     ui->filterScreens->setEnabled(!m_config->isMultiScreenModeImmutable());
0340     ui->currentScreen->setEnabled(!m_config->isMultiScreenModeImmutable());
0341     ui->otherScreens->setEnabled(!m_config->isMultiScreenModeImmutable());
0342 
0343     ui->filterDesktops->setEnabled(!m_config->isDesktopModeImmutable());
0344     ui->currentDesktop->setEnabled(!m_config->isDesktopModeImmutable());
0345     ui->otherDesktops->setEnabled(!m_config->isDesktopModeImmutable());
0346 
0347     ui->filterActivities->setEnabled(!m_config->isActivitiesModeImmutable());
0348     ui->currentActivity->setEnabled(!m_config->isActivitiesModeImmutable());
0349     ui->otherActivities->setEnabled(!m_config->isActivitiesModeImmutable());
0350 
0351     ui->filterMinimization->setEnabled(!m_config->isMinimizedModeImmutable());
0352     ui->visibleWindows->setEnabled(!m_config->isMinimizedModeImmutable());
0353     ui->hiddenWindows->setEnabled(!m_config->isMinimizedModeImmutable());
0354 
0355     ui->oneAppWindow->setEnabled(!m_config->isApplicationsModeImmutable());
0356     ui->orderMinimized->setEnabled(!m_config->isOrderMinimizedModeImmutable());
0357     ui->showDesktop->setEnabled(!m_config->isShowDesktopModeImmutable());
0358     ui->switchingModeCombo->setEnabled(!m_config->isSwitchingModeImmutable());
0359     ui->effectCombo->setEnabled(!m_config->isLayoutNameImmutable());
0360 }
0361 
0362 void KWinTabBoxConfigForm::setDefaultIndicatorVisible(bool show)
0363 {
0364     m_showDefaultIndicator = show;
0365     updateDefaultIndicators();
0366 }
0367 
0368 void KWinTabBoxConfigForm::updateDefaultIndicators()
0369 {
0370     applyDefaultIndicator({ui->filterScreens, ui->currentScreen, ui->otherScreens},
0371                           m_config->multiScreenMode() == m_config->defaultMultiScreenModeValue());
0372     applyDefaultIndicator({ui->filterDesktops, ui->currentDesktop, ui->otherDesktops},
0373                           m_config->desktopMode() == m_config->defaultDesktopModeValue());
0374     applyDefaultIndicator({ui->filterActivities, ui->currentActivity, ui->otherActivities},
0375                           m_config->activitiesMode() == m_config->defaultActivitiesModeValue());
0376     applyDefaultIndicator({ui->filterMinimization, ui->visibleWindows, ui->hiddenWindows},
0377                           m_config->minimizedMode() == m_config->defaultMinimizedModeValue());
0378     applyDefaultIndicator({ui->oneAppWindow}, m_config->applicationsMode() == m_config->defaultApplicationsModeValue());
0379     applyDefaultIndicator({ui->orderMinimized}, m_config->orderMinimizedMode() == m_config->defaultOrderMinimizedModeValue());
0380     applyDefaultIndicator({ui->showDesktop}, m_config->showDesktopMode() == m_config->defaultShowDesktopModeValue());
0381     applyDefaultIndicator({ui->switchingModeCombo}, m_config->switchingMode() == m_config->defaultSwitchingModeValue());
0382     applyDefaultIndicator({ui->effectCombo}, m_config->layoutName() == m_config->defaultLayoutNameValue());
0383 
0384     for (const auto &widget : {ui->scAll, ui->scAllReverse, ui->scCurrent, ui->scCurrentReverse}) {
0385         const QString actionName = widget->property("shortcutAction").toString();
0386         applyDefaultIndicator({widget}, m_shortcuts->isDefault(actionName));
0387     }
0388 }
0389 
0390 void KWinTabBoxConfigForm::applyDefaultIndicator(QList<QWidget *> widgets, bool isDefault)
0391 {
0392     for (auto widget : widgets) {
0393         widget->setProperty("_kde_highlight_neutral", m_showDefaultIndicator && !isDefault);
0394         widget->update();
0395     }
0396 }
0397 
0398 } // namespace
0399 
0400 #include "moc_kwintabboxconfigform.cpp"