kwin/kcmkwin/kwintabbox/main.cpp
Nate Graham 9a59e3fb6c [KCMs] move GHNS buttons to the normal location
Summary:
All other KCMs have their {nav Get New [things]...} buttons in the bottom-right corner. This patch adjusts KWin's KCMs to adopt the same convention there too.

With this patch, all KCMs will have their GHNS buttons in the same location.

Closes T9954

Test Plan:
{F6375278}

{F6375277}

{F6375276}

{F6375275}

Reviewers: #kwin, #vdg, zzag

Reviewed By: #kwin, zzag

Subscribers: Codezela, kwin, kde-doc-english

Tags: #kwin, #documentation

Maniphest Tasks: T9954

Differential Revision: https://phabricator.kde.org/D16537
2018-10-31 07:29:22 -06:00

604 lines
28 KiB
C++

/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 Martin Gräßlin <mgraesslin@kde.org>
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 <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "main.h"
#include <effect_builtins.h>
#include <kwin_effects_interface.h>
// Qt
#include <QtDBus>
#include <QDesktopWidget>
#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>
#include <QSpacerItem>
#include <QStandardPaths>
#include <QPointer>
// KDE
#include <KActionCollection>
#include <KCModuleProxy>
#include <KGlobalAccel>
#include <KLocalizedString>
#include <KPluginFactory>
#include <KPluginInfo>
#include <KPluginLoader>
#include <KPluginTrader>
#include <KTitleWidget>
#include <KServiceTypeTrader>
#include <KShortcutsEditor>
#include <KNewStuff3/KNS3/DownloadDialog>
// Plasma
#include <KPackage/Package>
#include <KPackage/PackageLoader>
// own
#include "tabboxconfig.h"
#include "layoutpreview.h"
K_PLUGIN_FACTORY(KWinTabBoxConfigFactory, registerPlugin<KWin::KWinTabBoxConfig>();)
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"))
{
QTabWidget* tabWidget = new QTabWidget(this);
m_primaryTabBoxUi = new KWinTabBoxConfigForm(tabWidget);
m_alternativeTabBoxUi = new KWinTabBoxConfigForm(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<QKeySequence>() << _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
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::desktop()->screenCount() < 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()));
}
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()));
}
// 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<KPackage::Package> availableLnFPackages()
{
QList<KPackage::Package> 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;
QList<KPluginMetaData> 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);
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);
}
}
}
void KWinTabBoxConfig::load()
{
KCModule::load();
const QString group[2] = { "TabBox", "TabBoxAlternative" };
KWinTabBoxConfigForm* ui[2] = { m_primaryTabBoxUi, m_alternativeTabBoxUi };
TabBoxConfig *tabBoxConfig[2] = { &m_tabBoxConfig, &m_tabBoxAlternativeConfig };
for (int i = 0; i < 2; ++i) {
KConfigGroup config(m_config, group[i]);
loadConfig(config, *(tabBoxConfig[i]));
updateUiFromConfig(ui[i], *(tabBoxConfig[i]));
KConfigGroup effectconfig(m_config, "Plugins");
if (effectEnabled(BuiltInEffect::CoverSwitch, effectconfig) && KConfigGroup(m_config, "Effect-CoverSwitch").readEntry(group[i], false))
ui[i]->effectCombo->setCurrentIndex(CoverSwitch);
else if (effectEnabled(BuiltInEffect::FlipSwitch, effectconfig) && KConfigGroup(m_config, "Effect-FlipSwitch").readEntry(group[i], false))
ui[i]->effectCombo->setCurrentIndex(FlipSwitch);
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);
}
void KWinTabBoxConfig::loadConfig(const KConfigGroup& config, KWin::TabBox::TabBoxConfig& tabBoxConfig)
{
tabBoxConfig.setClientDesktopMode(TabBoxConfig::ClientDesktopMode(
config.readEntry<int>("DesktopMode", TabBoxConfig::defaultDesktopMode())));
tabBoxConfig.setClientActivitiesMode(TabBoxConfig::ClientActivitiesMode(
config.readEntry<int>("ActivitiesMode", TabBoxConfig::defaultActivitiesMode())));
tabBoxConfig.setClientApplicationsMode(TabBoxConfig::ClientApplicationsMode(
config.readEntry<int>("ApplicationsMode", TabBoxConfig::defaultApplicationsMode())));
tabBoxConfig.setClientMinimizedMode(TabBoxConfig::ClientMinimizedMode(
config.readEntry<int>("MinimizedMode", TabBoxConfig::defaultMinimizedMode())));
tabBoxConfig.setShowDesktopMode(TabBoxConfig::ShowDesktopMode(
config.readEntry<int>("ShowDesktopMode", TabBoxConfig::defaultShowDesktopMode())));
tabBoxConfig.setClientMultiScreenMode(TabBoxConfig::ClientMultiScreenMode(
config.readEntry<int>("MultiScreenMode", TabBoxConfig::defaultMultiScreenMode())));
tabBoxConfig.setClientSwitchingMode(TabBoxConfig::ClientSwitchingMode(
config.readEntry<int>("SwitchingMode", TabBoxConfig::defaultSwitchingMode())));
tabBoxConfig.setShowTabBox(config.readEntry<bool>("ShowTabBox", TabBoxConfig::defaultShowTabBox()));
tabBoxConfig.setHighlightWindows(config.readEntry<bool>("HighlightWindows", TabBoxConfig::defaultHighlightWindow()));
tabBoxConfig.setLayoutName(config.readEntry<QString>("LayoutName", TabBoxConfig::defaultLayoutName()));
}
void KWinTabBoxConfig::saveConfig(KConfigGroup& config, const KWin::TabBox::TabBoxConfig& tabBoxConfig)
{
// combo boxes
config.writeEntry("DesktopMode", int(tabBoxConfig.clientDesktopMode()));
config.writeEntry("ActivitiesMode", int(tabBoxConfig.clientActivitiesMode()));
config.writeEntry("ApplicationsMode", int(tabBoxConfig.clientApplicationsMode()));
config.writeEntry("MinimizedMode", int(tabBoxConfig.clientMinimizedMode()));
config.writeEntry("ShowDesktopMode", int(tabBoxConfig.showDesktopMode()));
config.writeEntry("MultiScreenMode", int(tabBoxConfig.clientMultiScreenMode()));
config.writeEntry("SwitchingMode", int(tabBoxConfig.clientSwitchingMode()));
config.writeEntry("LayoutName", tabBoxConfig.layoutName());
// check boxes
config.writeEntry("ShowTabBox", tabBoxConfig.isShowTabBox());
config.writeEntry("HighlightWindows", tabBoxConfig.isHighlightWindows());
config.sync();
}
void KWinTabBoxConfig::save()
{
KCModule::save();
KConfigGroup config(m_config, "TabBox");
// sync ui to config
updateConfigFromUi(m_primaryTabBoxUi, m_tabBoxConfig);
updateConfigFromUi(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig);
saveConfig(config, m_tabBoxConfig);
config = KConfigGroup(m_config, "TabBoxAlternative");
saveConfig(config, m_tabBoxAlternativeConfig);
// 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;
// activate effects if not active
KConfigGroup effectconfig(m_config, "Plugins");
if (coverSwitch || coverSwitchAlternative)
effectconfig.writeEntry("coverswitchEnabled", true);
if (flipSwitch || flipSwitchAlternative)
effectconfig.writeEntry("flipswitchEnabled", true);
if (highlightWindows)
effectconfig.writeEntry("highlightwindowEnabled", true);
effectconfig.sync();
KConfigGroup coverswitchconfig(m_config, "Effect-CoverSwitch");
coverswitchconfig.writeEntry("TabBox", coverSwitch);
coverswitchconfig.writeEntry("TabBoxAlternative", coverSwitchAlternative);
coverswitchconfig.sync();
KConfigGroup flipswitchconfig(m_config, "Effect-FlipSwitch");
flipswitchconfig.writeEntry("TabBox", flipSwitch);
flipswitchconfig.writeEntry("TabBoxAlternative", flipSwitchAlternative);
flipswitchconfig.sync();
// 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()
{
const KWinTabBoxConfigForm* ui[2] = { m_primaryTabBoxUi, m_alternativeTabBoxUi};
for (int i = 0; i < 2; ++i) {
// combo boxes
#define CONFIGURE(SETTING, MODE, IS, VALUE) \
ui[i]->SETTING->setChecked(TabBoxConfig::default##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[i]->switchingModeCombo->setCurrentIndex(TabBoxConfig::defaultSwitchingMode());
// checkboxes
ui[i]->showTabBox->setChecked(TabBoxConfig::defaultShowTabBox());
ui[i]->highlightWindowCheck->setChecked(TabBoxConfig::defaultHighlightWindow());
CONFIGURE(showDesktop, ShowDesktop, ==, ShowDesktopClient);
#undef CONFIGURE
// effects
ui[i]->effectCombo->setCurrentIndex(ui[i]->effectCombo->findData("sidebar"));
}
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<QKeySequence>() << 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);
}
bool KWinTabBoxConfig::effectEnabled(const BuiltInEffect& effect, const KConfigGroup& cfg) const
{
return cfg.readEntry(BuiltInEffects::nameForEffect(effect) + "Enabled", BuiltInEffects::enabledByDefault(effect));
}
void KWinTabBoxConfig::updateUiFromConfig(KWinTabBoxConfigForm* ui, const KWin::TabBox::TabBoxConfig& config)
{
#define CONFIGURE(SETTING, MODE, IS, VALUE) ui->SETTING->setChecked(config.MODE##Mode() IS TabBoxConfig::VALUE)
CONFIGURE(filterDesktops, clientDesktop, !=, AllDesktopsClients);
CONFIGURE(currentDesktop, clientDesktop, ==, OnlyCurrentDesktopClients);
CONFIGURE(otherDesktops, clientDesktop, ==, ExcludeCurrentDesktopClients);
CONFIGURE(filterActivities, clientActivities, !=, AllActivitiesClients);
CONFIGURE(currentActivity, clientActivities, ==, OnlyCurrentActivityClients);
CONFIGURE(otherActivities, clientActivities, ==, ExcludeCurrentActivityClients);
CONFIGURE(filterScreens, clientMultiScreen, !=, IgnoreMultiScreen);
CONFIGURE(currentScreen, clientMultiScreen, ==, OnlyCurrentScreenClients);
CONFIGURE(otherScreens, clientMultiScreen, ==, ExcludeCurrentScreenClients);
CONFIGURE(oneAppWindow, clientApplications, ==, OneWindowPerApplication);
CONFIGURE(filterMinimization, clientMinimized, !=, IgnoreMinimizedStatus);
CONFIGURE(visibleWindows, clientMinimized, ==, ExcludeMinimizedClients);
CONFIGURE(hiddenWindows, clientMinimized, ==, OnlyMinimizedClients);
ui->switchingModeCombo->setCurrentIndex(config.clientSwitchingMode());
// check boxes
ui->showTabBox->setChecked(config.isShowTabBox());
ui->highlightWindowCheck->setChecked(config.isHighlightWindows());
ui->effectCombo->setCurrentIndex(ui->effectCombo->findData(config.layoutName()));
CONFIGURE(showDesktop, showDesktop, ==, ShowDesktopClient);
#undef CONFIGURE
}
void KWinTabBoxConfig::updateConfigFromUi(const KWin::KWinTabBoxConfigForm* ui, TabBox::TabBoxConfig& config)
{
if (ui->filterDesktops->isChecked())
config.setClientDesktopMode(ui->currentDesktop->isChecked() ? TabBoxConfig::OnlyCurrentDesktopClients : TabBoxConfig::ExcludeCurrentDesktopClients);
else
config.setClientDesktopMode(TabBoxConfig::AllDesktopsClients);
if (ui->filterActivities->isChecked())
config.setClientActivitiesMode(ui->currentActivity->isChecked() ? TabBoxConfig::OnlyCurrentActivityClients : TabBoxConfig::ExcludeCurrentActivityClients);
else
config.setClientActivitiesMode(TabBoxConfig::AllActivitiesClients);
if (ui->filterScreens->isChecked())
config.setClientMultiScreenMode(ui->currentScreen->isChecked() ? TabBoxConfig::OnlyCurrentScreenClients : TabBoxConfig::ExcludeCurrentScreenClients);
else
config.setClientMultiScreenMode(TabBoxConfig::IgnoreMultiScreen);
config.setClientApplicationsMode(ui->oneAppWindow->isChecked() ? TabBoxConfig::OneWindowPerApplication : TabBoxConfig::AllWindowsAllApplications);
if (ui->filterMinimization->isChecked())
config.setClientMinimizedMode(ui->visibleWindows->isChecked() ? TabBoxConfig::ExcludeMinimizedClients : TabBoxConfig::OnlyMinimizedClients);
else
config.setClientMinimizedMode(TabBoxConfig::IgnoreMinimizedStatus);
config.setClientSwitchingMode(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);
}
#define CHECK_CURRENT_TABBOX_UI \
Q_ASSERT(sender());\
KWinTabBoxConfigForm *ui = nullptr;\
QObject *dad = sender();\
while (!ui && (dad = dad->parent()))\
ui = qobject_cast<KWinTabBoxConfigForm*>(dad);\
Q_ASSERT(ui);
void KWinTabBoxConfig::effectSelectionChanged(int index)
{
CHECK_CURRENT_TABBOX_UI
ui->effectConfigButton->setIcon(QIcon::fromTheme(index < Layout ? "configure" : "view-preview"));
if (!ui->showTabBox->isChecked())
return;
ui->highlightWindowCheck->setEnabled(index >= Layout);
}
void KWinTabBoxConfig::tabBoxToggled(bool on) {
CHECK_CURRENT_TABBOX_UI
on = !on || ui->effectCombo->currentIndex() >= Layout;
ui->highlightWindowCheck->setEnabled(on);
emit changed();
}
void KWinTabBoxConfig::configureEffectClicked()
{
CHECK_CURRENT_TABBOX_UI
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);
} else {
QPointer<QDialog> configDialog = new QDialog(this);
configDialog->setLayout(new QVBoxLayout);
configDialog->setWindowTitle(ui->effectCombo->currentText());
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);
KCModule *kcm = KPluginTrader::createInstanceFromQuery<KCModule>(QStringLiteral("kwin/effects/configs/"), QString(),
QStringLiteral("'%1' in [X-KDE-ParentComponents]").arg(name),
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<QKeySequence>() << seq, KGlobalAccel::NoAutoloading);
m_actionCollection->writeSettings();
}
void KWinTabBoxConfig::slotGHNS()
{
QPointer<KNS3::DownloadDialog> downloadDialog = new KNS3::DownloadDialog("kwinswitcher.knsrc", this);
if (downloadDialog->exec() == QDialog::Accepted) {
if (!downloadDialog->changedEntries().isEmpty()) {
initLayoutLists();
}
}
delete downloadDialog;
}
} // namespace
#include "main.moc"