diff --git a/doc/kwindecoration/index.docbook b/doc/kwindecoration/index.docbook
index 0f2992be2..1a7dc9b66 100644
--- a/doc/kwindecoration/index.docbook
+++ b/doc/kwindecoration/index.docbook
@@ -1,142 +1,142 @@
]>
&Rik.Hemsley; &Rik.Hemsley.mail;
&Anne-Marie.Mahfouf; &Anne-Marie.Mahfouf.mail;
2018-03-18
Plasma 5.12
KDE
Systemsettings
kwin
window
border
theme
style
Window Decoration
This module allows you to select a style for the buttons and borders around
windows.
Window Decorations
Window Decoration Configuration Module
Window Decoration Configuration Module
Choose a window decoration style from the preview list, using the
search field at the top of the screen or download a new style using the
-Get New Decorations button.
+Get New Window Decorations button.
The default window decoration is called Breeze
.
Each style has a different look, but also a different
feel
. Some have (sometimes invisible)
resize
borders all around the edge, which make resizing
easier but moving more difficult. Some have no borders on certain
edges.
You are encouraged to experiment with the different styles until
you find one which best suits your pattern of work.
In the preview of each style you find a
configure button to open configuration dialogs for the decoration.
The options in this configuration dialog are applied to all windows.
Some window decorations (⪚ Breeze
)
provide a Window-Specific Overrides tab.
On this tab you can change the border size and the visibility
of the window titlebar for particular windows.
Different options for particular windows you find in the &systemsettings;
module Window Rules.
For accessibility purposes, some window decorations support
extra wide borders. If this is available, you can also choose a
border size here. These large borders are easier to see for low
vision users, and easier to grab for people with limited mobility or
difficulty using a mouse.
Decorations
In this dialog you can change the decoration of the window.
The available options depend on the selected style.
Breeze Decoration Options
Breeze Decoration Options
Buttons
This tab allows you to customize the button location on the titlebar.
You can drag buttons ⪚ the Application menu into the
titlebar, remove them or drag around the
buttons until you have the order that makes you comfortable.
Button Options
Button Options
Enable Close windows by double clicking the menu button
to have an additional option to the Close button or if you have removed the Close button from the titlebar.
diff --git a/kcmkwin/kwincompositing/qml/EffectView.qml b/kcmkwin/kwincompositing/qml/EffectView.qml
index fe1f91763..e92a8f3a3 100644
--- a/kcmkwin/kwincompositing/qml/EffectView.qml
+++ b/kcmkwin/kwincompositing/qml/EffectView.qml
@@ -1,177 +1,183 @@
/**************************************************************************
* KWin - the KDE window manager *
* This file is part of the KDE project. *
* *
* Copyright (C) 2013 Antonis Tsiapaliokas *
* *
* 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 . *
**************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Controls 2.0 as QQC2
import QtQuick.Layouts 1.0
import org.kde.kwin.kwincompositing 1.0
Rectangle {
signal changed
implicitWidth: col.implicitWidth
implicitHeight: col.implicitHeight
Component {
id: sectionHeading
Rectangle {
width: parent.width
implicitHeight: sectionText.implicitHeight + 2 * col.spacing
color: searchModel.backgroundNormalColor
QQC2.Label {
id: sectionText
x: col.spacing
y: col.spacing
text: section
font.weight: Font.Bold
color: searchModel.sectionColor
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
EffectConfig {
id: effectConfig
onEffectListChanged: {
searchModel.load()
}
}
ColumnLayout {
id: col
anchors.fill: parent
QQC2.Label {
id: hint
text: i18n("Hint: To find out or configure how to activate an effect, look at the effect's settings.")
anchors {
top: parent.top
left: parent.left
}
}
RowLayout {
QQC2.TextField {
// TODO: needs clear button, missing in Qt
id: searchField
placeholderText: i18n("Search")
Layout.fillWidth: true
focus: true
}
Button {
iconName: "configure"
tooltip: i18n("Configure filter")
menu: Menu {
MenuItem {
text: i18n("Exclude Desktop Effects not supported by the Compositor")
checkable: true
checked: searchModel.filterOutUnsupported
onTriggered: {
searchModel.filterOutUnsupported = !searchModel.filterOutUnsupported;
}
}
MenuItem {
text: i18n("Exclude internal Desktop Effects")
checkable: true
checked: searchModel.filterOutInternal
onTriggered: {
searchModel.filterOutInternal = !searchModel.filterOutInternal
}
}
}
}
-
- Button {
- id: ghnsButton
- text: i18n("Get New Effects...")
- iconName: "get-hot-new-stuff"
- onClicked: effectConfig.openGHNS()
- }
}
EffectFilterModel {
id: searchModel
objectName: "filterModel"
filter: searchField.text
}
ScrollView {
id: scroll
frameVisible: true
highlightOnFocus: true
Layout.fillWidth: true
Layout.fillHeight: true
Rectangle {
color: effectView.backgroundNormalColor
anchors.fill: parent
}
ListView {
function exclusiveGroupForCategory(category) {
for (var i = 0; i < effectView.exclusiveGroups.length; ++i) {
var item = effectView.exclusiveGroups[i];
if (item.category == category) {
return item.group;
}
}
var newGroup = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Controls 1.1; ExclusiveGroup {}',
effectView,
"dynamicExclusiveGroup" + effectView.exclusiveGroups.length);
effectView.exclusiveGroups[effectView.exclusiveGroups.length] = {
'category': category,
'group': newGroup
};
return newGroup;
}
id: effectView
property var exclusiveGroups: []
property color backgroundActiveColor: searchModel.backgroundActiveColor
property color backgroundNormalColor: searchModel.backgroundNormalColor
property color backgroundAlternateColor: searchModel.backgroundAlternateColor
anchors.fill: parent
model: searchModel
delegate: Effect{
id: effectDelegate
Connections {
id: effectStateConnection
target: null
onChanged: {
searchModel.updateEffectStatus(index, checkedState);
}
}
Component.onCompleted: {
effectStateConnection.target = effectDelegate
}
}
section.property: "CategoryRole"
section.delegate: sectionHeading
spacing: col.spacing
focus: true
}
}
+ RowLayout {
+ Layout.fillWidth: true
+
+ Item {
+ Layout.fillWidth: true
+ }
+ Button {
+ id: ghnsButton
+ text: i18n("Get New Desktop Effects...")
+ iconName: "get-hot-new-stuff"
+ onClicked: effectConfig.openGHNS()
+ }
+ }
}//End ColumnLayout
Connections {
target: searchModel
onDataChanged: changed()
}
}//End item
diff --git a/kcmkwin/kwindecoration/kcm.ui b/kcmkwin/kwindecoration/kcm.ui
index ff2983186..9e8e53234 100644
--- a/kcmkwin/kwindecoration/kcm.ui
+++ b/kcmkwin/kwindecoration/kcm.ui
@@ -1,182 +1,182 @@
KCMForm
0
0
386
272
-
0
Theme
-
-
Search
true
- -
-
-
- false
-
-
- Get New Decorations...
-
-
-
-
Close windows by double clicking &the menu button
-
-
0
0
0
100
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
Border si&ze:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
borderSizesCombo
-
-
No Borders
-
No Side Borders
-
Tiny
-
Normal
-
Large
-
Very Large
-
Huge
-
Very Huge
-
Oversized
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ false
+
+
+ Get New Window Decorations...
+
+
+
Buttons
KComboBox
QComboBox
KMessageWidget
QFrame
1
diff --git a/kcmkwin/kwinscripts/module.ui b/kcmkwin/kwinscripts/module.ui
index 60ef9a84d..6a4215ba8 100644
--- a/kcmkwin/kwinscripts/module.ui
+++ b/kcmkwin/kwinscripts/module.ui
@@ -1,95 +1,96 @@
Module
0
0
484
300
KWin script configuration
-
+
-
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::WheelFocus
+
+
+
-
-
-
-
-
-
-
-
- 0
- 0
-
-
-
- Qt::WheelFocus
-
-
-
-
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+
+ 80
+ 40
+
+
+
+
+ -
+
+
+ Install from File...
+
+
+
+
+
+
+
-
-
-
-
-
-
- Import KWin script...
-
-
-
- -
-
-
- Get New Scripts...
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
+
+
+ Get New Scripts...
+
+
KPluginSelector
QWidget
1
KNS3::Button
QPushButton
KMessageWidget
QFrame
1
diff --git a/kcmkwin/kwintabbox/main.cpp b/kcmkwin/kwintabbox/main.cpp
index 0017911b3..f1827ee7c 100644
--- a/kcmkwin/kwintabbox/main.cpp
+++ b/kcmkwin/kwintabbox/main.cpp
@@ -1,593 +1,604 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 Martin Gräßlin
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
// KDE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// Plasma
#include
#include
// own
#include "tabboxconfig.h"
#include "layoutpreview.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"))
{
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() << _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")));
- ui[i]->ghns->setIcon(QIcon::fromTheme(QStringLiteral("get-hot-new-stuff")));
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()));
- connect(ui[i]->ghns, SIGNAL(clicked(bool)), SLOT(slotGHNS()));
}
// 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;
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);
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("DesktopMode", TabBoxConfig::defaultDesktopMode())));
tabBoxConfig.setClientActivitiesMode(TabBoxConfig::ClientActivitiesMode(
config.readEntry("ActivitiesMode", TabBoxConfig::defaultActivitiesMode())));
tabBoxConfig.setClientApplicationsMode(TabBoxConfig::ClientApplicationsMode(
config.readEntry("ApplicationsMode", TabBoxConfig::defaultApplicationsMode())));
tabBoxConfig.setClientMinimizedMode(TabBoxConfig::ClientMinimizedMode(
config.readEntry("MinimizedMode", TabBoxConfig::defaultMinimizedMode())));
tabBoxConfig.setShowDesktopMode(TabBoxConfig::ShowDesktopMode(
config.readEntry("ShowDesktopMode", TabBoxConfig::defaultShowDesktopMode())));
tabBoxConfig.setClientMultiScreenMode(TabBoxConfig::ClientMultiScreenMode(
config.readEntry("MultiScreenMode", TabBoxConfig::defaultMultiScreenMode())));
tabBoxConfig.setClientSwitchingMode(TabBoxConfig::ClientSwitchingMode(
config.readEntry("SwitchingMode", TabBoxConfig::defaultSwitchingMode())));
tabBoxConfig.setShowTabBox(config.readEntry("ShowTabBox", TabBoxConfig::defaultShowTabBox()));
tabBoxConfig.setHighlightWindows(config.readEntry("HighlightWindows", TabBoxConfig::defaultHighlightWindow()));
tabBoxConfig.setLayoutName(config.readEntry("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() << 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(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 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(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() << 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.ui b/kcmkwin/kwintabbox/main.ui
index 9baa26d80..e7fa24ccb 100644
--- a/kcmkwin/kwintabbox/main.ui
+++ b/kcmkwin/kwintabbox/main.ui
@@ -1,720 +1,700 @@
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::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Get New Window Switcher Layout
-
-
-
-
Qt::Vertical
-
Qt::Horizontal
40
20
KKeySequenceWidget
QWidget
KComboBox
QComboBox
highlightWindowCheck
showTabBox
effectCombo
effectConfigButton
ghns
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
toggled(bool)
widget_6
setEnabled(bool)
164
125
230
108