diff --git a/kcmkwin/kwinscreenedges/CMakeLists.txt b/kcmkwin/kwinscreenedges/CMakeLists.txt --- a/kcmkwin/kwinscreenedges/CMakeLists.txt +++ b/kcmkwin/kwinscreenedges/CMakeLists.txt @@ -3,16 +3,17 @@ include_directories(${KWIN_SOURCE_DIR}/effects) set( - kcm_kwinscreenedges_PART_SRCS - main.cpp + kcm_screenedges_SRCS monitor.cpp screenpreviewwidget.cpp ) -ki18n_wrap_ui( kcm_kwinscreenedges_PART_SRCS main.ui ) -qt5_add_dbus_interface( kcm_kwinscreenedges_PART_SRCS +qt5_add_dbus_interface( kcm_screenedges_SRCS ${KWIN_SOURCE_DIR}/org.kde.kwin.Effects.xml kwin_effects_interface) + +set(kcm_kwinscreenedges_PART_SRCS main.cpp ${kcm_screenedges_SRCS}) +ki18n_wrap_ui( kcm_kwinscreenedges_PART_SRCS main.ui ) add_library( kcm_kwinscreenedges MODULE ${kcm_kwinscreenedges_PART_SRCS} ) -target_link_libraries( kcm_kwinscreenedges ${X11_LIBRARIES} +set(kcm_screenedges_LIBS Qt5::DBus KF5::Completion KF5::ConfigCore @@ -22,7 +23,14 @@ KF5::Package KF5::Plasma kwin4_effect_builtins - ) -install( TARGETS kcm_kwinscreenedges DESTINATION ${PLUGIN_INSTALL_DIR} ) +) +target_link_libraries( kcm_kwinscreenedges ${X11_LIBRARIES} ${kcm_screenedges_LIBS}) + +set(kcm_kwintouchscreenedges_PART_SRCS touch.cpp ${kcm_screenedges_SRCS}) +ki18n_wrap_ui( kcm_kwintouchscreenedges_PART_SRCS touch.ui ) +add_library( kcm_kwintouchscreen MODULE ${kcm_kwintouchscreenedges_PART_SRCS} ) +target_link_libraries( kcm_kwintouchscreen ${X11_LIBRARIES} ${kcm_screenedges_LIBS}) + +install( TARGETS kcm_kwinscreenedges kcm_kwintouchscreen DESTINATION ${PLUGIN_INSTALL_DIR} ) -install( FILES kwinscreenedges.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install( FILES kwinscreenedges.desktop kwintouchscreen.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/kcmkwin/kwinscreenedges/kwintouchscreen.desktop b/kcmkwin/kwinscreenedges/kwintouchscreen.desktop new file mode 100644 --- /dev/null +++ b/kcmkwin/kwinscreenedges/kwintouchscreen.desktop @@ -0,0 +1,16 @@ +[Desktop Entry] +Exec=kcmshell5 kwintouchscreen +Icon=preferences-desktop +Type=Service +X-KDE-ServiceTypes=KCModule + +X-KDE-Library=kcm_kwintouchscreen +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=desktopbehavior +X-KDE-Weight=50 + +Name=Touch Screen +Comment=Touch screen swipe gestures + +X-KDE-Keywords=kwin,window,manager,effect,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behavior,touch screen diff --git a/kcmkwin/kwinscreenedges/touch.h b/kcmkwin/kwinscreenedges/touch.h new file mode 100644 --- /dev/null +++ b/kcmkwin/kwinscreenedges/touch.h @@ -0,0 +1,95 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2009 Lucas Murray + +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 __TOUCH_H__ +#define __TOUCH_H__ + +#include +#include + +#include "kwinglobals.h" + +#include "ui_touch.h" + +class QShowEvent; + +namespace KWin +{ +enum class BuiltInEffect; + +class KWinScreenEdgesConfigForm : public QWidget, public Ui::KWinScreenEdgesConfigForm +{ + Q_OBJECT + +public: + explicit KWinScreenEdgesConfigForm(QWidget* parent); +}; + +class KWinScreenEdgesConfig : public KCModule +{ + Q_OBJECT + +public: + explicit KWinScreenEdgesConfig(QWidget* parent, const QVariantList& args); + ~KWinScreenEdgesConfig(); + +public Q_SLOTS: + virtual void save(); + virtual void load(); + virtual void defaults(); +protected: + virtual void showEvent(QShowEvent* e); +private: + KWinScreenEdgesConfigForm* m_ui; + KSharedConfigPtr m_config; + QStringList m_scripts; //list of script IDs ordered in the list they are presented in the menu + + enum EffectActions { + PresentWindowsAll = ELECTRIC_ACTION_COUNT, // Start at the end of built in actions + PresentWindowsCurrent, + PresentWindowsClass, + DesktopGrid, + Cube, + Cylinder, + Sphere, + TabBox, + TabBoxAlternative, + EffectCount + }; + + bool effectEnabled(const BuiltInEffect& effect, const KConfigGroup& cfg) const; + + void monitorAddItem(const QString& item); + void monitorItemSetEnabled(int index, bool enabled); + void monitorInit(); + void monitorLoadAction(ElectricBorder edge, const QString& configName); + void monitorLoad(); + void monitorSaveAction(int edge, const QString& configName); + void monitorSave(); + void monitorDefaults(); + void monitorShowEvent(); + void monitorChangeEdge(ElectricBorder border, int index); + void monitorHideEdge(ElectricBorder border, bool hidden); + QList monitorCheckEffectHasEdge(int index) const; +}; + +} // namespace + +#endif diff --git a/kcmkwin/kwinscreenedges/touch.cpp b/kcmkwin/kwinscreenedges/touch.cpp new file mode 100644 --- /dev/null +++ b/kcmkwin/kwinscreenedges/touch.cpp @@ -0,0 +1,470 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2008 Martin Gräßlin +Copyright (C) 2009 Lucas Murray + +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 "touch.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +K_PLUGIN_FACTORY(KWinScreenEdgesConfigFactory, registerPlugin();) + +namespace KWin +{ + +KWinScreenEdgesConfigForm::KWinScreenEdgesConfigForm(QWidget* parent) + : QWidget(parent) +{ + setupUi(this); +} + +KWinScreenEdgesConfig::KWinScreenEdgesConfig(QWidget* parent, const QVariantList& args) + : KCModule(parent, args) + , m_config(KSharedConfig::openConfig("kwinrc")) +{ + m_ui = new KWinScreenEdgesConfigForm(this); + QVBoxLayout* layout = new QVBoxLayout(this); + layout->addWidget(m_ui); + + monitorInit(); + + connect(m_ui->monitor, SIGNAL(changed()), this, SLOT(changed())); + + load(); +} + +KWinScreenEdgesConfig::~KWinScreenEdgesConfig() +{ +} + +void KWinScreenEdgesConfig::load() +{ + KCModule::load(); + + monitorLoad(); + + emit changed(false); +} + +void KWinScreenEdgesConfig::save() +{ + KCModule::save(); + + monitorSave(); + + // 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::PresentWindows)); + interface.reconfigureEffect(BuiltInEffects::nameForEffect(BuiltInEffect::DesktopGrid)); + interface.reconfigureEffect(BuiltInEffects::nameForEffect(BuiltInEffect::Cube)); + + emit changed(false); +} + +void KWinScreenEdgesConfig::defaults() +{ + monitorDefaults(); + + emit changed(true); +} + +void KWinScreenEdgesConfig::showEvent(QShowEvent* e) +{ + KCModule::showEvent(e); + + monitorShowEvent(); +} + +// Copied from kcmkwin/kwincompositing/main.cpp +bool KWinScreenEdgesConfig::effectEnabled(const BuiltInEffect& effect, const KConfigGroup& cfg) const +{ + return cfg.readEntry(BuiltInEffects::nameForEffect(effect) + "Enabled", BuiltInEffects::enabledByDefault(effect)); +} + +//----------------------------------------------------------------------------- +// Monitor + +void KWinScreenEdgesConfig::monitorAddItem(const QString& item) +{ + for (int i = 0; i < 8; i++) + m_ui->monitor->addEdgeItem(i, item); +} + +void KWinScreenEdgesConfig::monitorItemSetEnabled(int index, bool enabled) +{ + for (int i = 0; i < 8; i++) + m_ui->monitor->setEdgeItemEnabled(i, index, enabled); +} + +void KWinScreenEdgesConfig::monitorInit() +{ + monitorAddItem(i18n("No Action")); + monitorAddItem(i18n("Show Desktop")); + monitorAddItem(i18n("Lock Screen")); + monitorAddItem(i18nc("Open krunner", "Run Command")); + monitorAddItem(i18n("Activity Manager")); + monitorAddItem(i18n("Application Launcher")); + + // Add the effects + const QString presentWindowsName = BuiltInEffects::effectData(BuiltInEffect::PresentWindows).displayName; + monitorAddItem(i18n("%1 - All Desktops", presentWindowsName)); + monitorAddItem(i18n("%1 - Current Desktop", presentWindowsName)); + monitorAddItem(i18n("%1 - Current Application", presentWindowsName)); + monitorAddItem(BuiltInEffects::effectData(BuiltInEffect::DesktopGrid).displayName); + const QString cubeName = BuiltInEffects::effectData(BuiltInEffect::Cube).displayName; + monitorAddItem(i18n("%1 - Cube", cubeName)); + monitorAddItem(i18n("%1 - Cylinder", cubeName)); + monitorAddItem(i18n("%1 - Sphere", cubeName)); + + monitorAddItem(i18n("Toggle window switching")); + monitorAddItem(i18n("Toggle alternative window switching")); + + const QString scriptFolder = QStringLiteral("kwin/scripts/"); + const auto scripts = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KWin/Script"), scriptFolder); + + KConfigGroup config(m_config, "Plugins"); + for (const KPluginMetaData &script: scripts) { + if (script.value(QStringLiteral("X-KWin-Border-Activate")) != QLatin1String("true")) { + continue; + } + + if (!config.readEntry(script.pluginId() + QStringLiteral("Enabled"), script.isEnabledByDefault())) { + continue; + } + m_scripts << script.pluginId(); + monitorAddItem(script.name()); + } + + monitorHideEdge(ElectricTopLeft, true); + monitorHideEdge(ElectricTopRight, true); + monitorHideEdge(ElectricBottomRight, true); + monitorHideEdge(ElectricBottomLeft, true); + + monitorShowEvent(); +} + +void KWinScreenEdgesConfig::monitorLoadAction(ElectricBorder edge, const QString& configName) +{ + KConfigGroup config(m_config, "TouchEdges"); + QString lowerName = config.readEntry(configName, "None").toLower(); + if (lowerName == "showdesktop") monitorChangeEdge(edge, int(ElectricActionShowDesktop)); + else if (lowerName == "lockscreen") monitorChangeEdge(edge, int(ElectricActionLockScreen)); + else if (lowerName == "krunner") monitorChangeEdge(edge, int(ElectricActionKRunner)); + else if (lowerName == "activitymanager") monitorChangeEdge(edge, int(ElectricActionActivityManager)); + else if (lowerName == "applicationlauncher") monitorChangeEdge(edge, int(ElectricActionApplicationLauncher)); +} + +void KWinScreenEdgesConfig::monitorLoad() +{ + // Load ElectricBorderActions + monitorLoadAction(ElectricTop, "Top"); + monitorLoadAction(ElectricRight, "Right"); + monitorLoadAction(ElectricBottom, "Bottom"); + monitorLoadAction(ElectricLeft, "Left"); + + // Load effect-specific actions: + + // Present Windows + KConfigGroup presentWindowsConfig(m_config, "Effect-PresentWindows"); + QList list = QList(); + // PresentWindows BorderActivateAll + list.append(int(ElectricTopLeft)); + list = presentWindowsConfig.readEntry("TouchBorderActivateAll", list); + foreach (int i, list) { + monitorChangeEdge(ElectricBorder(i), int(PresentWindowsAll)); + } + // PresentWindows BorderActivate + list.clear(); + list.append(int(ElectricNone)); + list = presentWindowsConfig.readEntry("TouchBorderActivate", list); + foreach (int i, list) { + monitorChangeEdge(ElectricBorder(i), int(PresentWindowsCurrent)); + } + // PresentWindows BorderActivateClass + list.clear(); + list.append(int(ElectricNone)); + list = presentWindowsConfig.readEntry("TouchBorderActivateClass", list); + foreach (int i, list) { + monitorChangeEdge(ElectricBorder(i), int(PresentWindowsClass)); + } + + // Desktop Grid + KConfigGroup gridConfig(m_config, "Effect-DesktopGrid"); + list.clear(); + list.append(int(ElectricNone)); + list = gridConfig.readEntry("TouchBorderActivate", list); + foreach (int i, list) { + monitorChangeEdge(ElectricBorder(i), int(DesktopGrid)); + } + + // Desktop Cube + KConfigGroup cubeConfig(m_config, "Effect-Cube"); + list.clear(); + list.append(int(ElectricNone)); + list = cubeConfig.readEntry("TouchBorderActivate", list); + foreach (int i, list) { + monitorChangeEdge(ElectricBorder(i), int(Cube)); + } + list.clear(); + list.append(int(ElectricNone)); + list = cubeConfig.readEntry("TouchBorderActivateCylinder", list); + foreach (int i, list) { + monitorChangeEdge(ElectricBorder(i), int(Cylinder)); + } + list.clear(); + list.append(int(ElectricNone)); + list = cubeConfig.readEntry("TouchBorderActivateSphere", list); + foreach (int i, list) { + monitorChangeEdge(ElectricBorder(i), int(Sphere)); + } + + // TabBox + KConfigGroup tabBoxConfig(m_config, "TabBox"); + list.clear(); + // TabBox + list.append(int(ElectricNone)); + list = tabBoxConfig.readEntry("TouchBorderActivate", list); + foreach (int i, list) { + monitorChangeEdge(ElectricBorder(i), int(TabBox)); + } + // Alternative TabBox + list.clear(); + list.append(int(ElectricNone)); + list = tabBoxConfig.readEntry("TouchBorderAlternativeActivate", list); + foreach (int i, list) { + monitorChangeEdge(ElectricBorder(i), int(TabBoxAlternative)); + } + + for (int i=0; i < m_scripts.size(); i++) { + int index = EffectCount + i; + KConfigGroup scriptConfig(m_config, "Script-"+m_scripts[i]); + list.append(int(ElectricNone)); + list = scriptConfig.readEntry("TouchBorderActivate", list); + for (int i: list) { + monitorChangeEdge(ElectricBorder(i), index); + } + } +} + +void KWinScreenEdgesConfig::monitorSaveAction(int edge, const QString& configName) +{ + KConfigGroup config(m_config, "ElectricBorders"); + int item = m_ui->monitor->selectedEdgeItem(edge); + if (item == 1) + config.writeEntry(configName, "ShowDesktop"); + else if (item == 2) + config.writeEntry(configName, "LockScreen"); + else if (item == 3) + config.writeEntry(configName, "KRunner"); + else if (item == 4) + config.writeEntry(configName, "ActivityManager"); + else if (item == 5) + config.writeEntry(configName, "ApplicationLauncher"); + else // Anything else + config.writeEntry(configName, "None"); +} + +void KWinScreenEdgesConfig::monitorSave() +{ + // Save ElectricBorderActions + monitorSaveAction(int(Monitor::Top), "Top"); + monitorSaveAction(int(Monitor::Right), "Right"); + monitorSaveAction(int(Monitor::Bottom), "Bottom"); + monitorSaveAction(int(Monitor::Left), "Left"); + + // Save effect-specific actions: + + // Present Windows + KConfigGroup presentWindowsConfig(m_config, "Effect-PresentWindows"); + presentWindowsConfig.writeEntry("TouchBorderActivate", + monitorCheckEffectHasEdge(int(PresentWindowsAll))); + presentWindowsConfig.writeEntry("TouchBorderActivateAll", + monitorCheckEffectHasEdge(int(PresentWindowsCurrent))); + presentWindowsConfig.writeEntry("TouchBorderActivateClass", + monitorCheckEffectHasEdge(int(PresentWindowsClass))); + + // Desktop Grid + KConfigGroup gridConfig(m_config, "Effect-DesktopGrid"); + gridConfig.writeEntry("TouchBorderActivate", + monitorCheckEffectHasEdge(int(DesktopGrid))); + + // Desktop Cube + KConfigGroup cubeConfig(m_config, "Effect-Cube"); + cubeConfig.writeEntry("TouchBorderActivate", + monitorCheckEffectHasEdge(int(Cube))); + cubeConfig.writeEntry("TouchBorderActivateCylinder", + monitorCheckEffectHasEdge(int(Cylinder))); + cubeConfig.writeEntry("TouchBorderActivateSphere", + monitorCheckEffectHasEdge(int(Sphere))); + + // TabBox + KConfigGroup tabBoxConfig(m_config, "TabBox"); + tabBoxConfig.writeEntry("TouchBorderActivate", + monitorCheckEffectHasEdge(int(TabBox))); + tabBoxConfig.writeEntry("TouchBorderAlternativeActivate", + monitorCheckEffectHasEdge(int(TabBoxAlternative))); + + for (int i=0; i < m_scripts.size(); i++) { + int index = EffectCount + i; + KConfigGroup scriptConfig(m_config, "Script-"+m_scripts[i]); + scriptConfig.writeEntry("TouchBorderActivate", + monitorCheckEffectHasEdge(index)); + } +} + +void KWinScreenEdgesConfig::monitorDefaults() +{ + // Clear all edges + for (int i = 0; i < 8; i++) + m_ui->monitor->selectEdgeItem(i, 0); +} + +void KWinScreenEdgesConfig::monitorShowEvent() +{ + // Check if they are enabled + KConfigGroup config(m_config, "Plugins"); + + // Present Windows + bool enabled = effectEnabled(BuiltInEffect::PresentWindows, config); + monitorItemSetEnabled(int(PresentWindowsCurrent), enabled); + monitorItemSetEnabled(int(PresentWindowsAll), enabled); + + // Desktop Grid + enabled = effectEnabled(BuiltInEffect::DesktopGrid, config); + monitorItemSetEnabled(int(DesktopGrid), enabled); + + // Desktop Cube + enabled = effectEnabled(BuiltInEffect::Cube, config); + monitorItemSetEnabled(int(Cube), enabled); + monitorItemSetEnabled(int(Cylinder), enabled); + monitorItemSetEnabled(int(Sphere), enabled); + // tabbox, depends on reasonable focus policy. + KConfigGroup config2(m_config, "Windows"); + QString focusPolicy = config2.readEntry("FocusPolicy", QString()); + bool reasonable = focusPolicy != "FocusStrictlyUnderMouse" && focusPolicy != "FocusUnderMouse"; + monitorItemSetEnabled(int(TabBox), reasonable); + monitorItemSetEnabled(int(TabBoxAlternative), reasonable); +} + +void KWinScreenEdgesConfig::monitorChangeEdge(ElectricBorder border, int index) +{ + switch(border) { + case ElectricTop: + m_ui->monitor->selectEdgeItem(int(Monitor::Top), index); + break; + case ElectricTopRight: + m_ui->monitor->selectEdgeItem(int(Monitor::TopRight), index); + break; + case ElectricRight: + m_ui->monitor->selectEdgeItem(int(Monitor::Right), index); + break; + case ElectricBottomRight: + m_ui->monitor->selectEdgeItem(int(Monitor::BottomRight), index); + break; + case ElectricBottom: + m_ui->monitor->selectEdgeItem(int(Monitor::Bottom), index); + break; + case ElectricBottomLeft: + m_ui->monitor->selectEdgeItem(int(Monitor::BottomLeft), index); + break; + case ElectricLeft: + m_ui->monitor->selectEdgeItem(int(Monitor::Left), index); + break; + case ElectricTopLeft: + m_ui->monitor->selectEdgeItem(int(Monitor::TopLeft), index); + break; + default: // Nothing + break; + } +} + +void KWinScreenEdgesConfig::monitorHideEdge(ElectricBorder border, bool hidden) +{ + switch(border) { + case ElectricTop: + m_ui->monitor->setEdgeHidden(int(Monitor::Top), hidden); + break; + case ElectricTopRight: + m_ui->monitor->setEdgeHidden(int(Monitor::TopRight), hidden); + break; + case ElectricRight: + m_ui->monitor->setEdgeHidden(int(Monitor::Right), hidden); + break; + case ElectricBottomRight: + m_ui->monitor->setEdgeHidden(int(Monitor::BottomRight), hidden); + break; + case ElectricBottom: + m_ui->monitor->setEdgeHidden(int(Monitor::Bottom), hidden); + break; + case ElectricBottomLeft: + m_ui->monitor->setEdgeHidden(int(Monitor::BottomLeft), hidden); + break; + case ElectricLeft: + m_ui->monitor->setEdgeHidden(int(Monitor::Left), hidden); + break; + case ElectricTopLeft: + m_ui->monitor->setEdgeHidden(int(Monitor::TopLeft), hidden); + break; + default: // Nothing + break; + } +} + +QList KWinScreenEdgesConfig::monitorCheckEffectHasEdge(int index) const +{ + QList list = QList(); + if (m_ui->monitor->selectedEdgeItem(int(Monitor::Top)) == index) + list.append(int(ElectricTop)); + if (m_ui->monitor->selectedEdgeItem(int(Monitor::TopRight)) == index) + list.append(int(ElectricTopRight)); + if (m_ui->monitor->selectedEdgeItem(int(Monitor::Right)) == index) + list.append(int(ElectricRight)); + if (m_ui->monitor->selectedEdgeItem(int(Monitor::BottomRight)) == index) + list.append(int(ElectricBottomRight)); + if (m_ui->monitor->selectedEdgeItem(int(Monitor::Bottom)) == index) + list.append(int(ElectricBottom)); + if (m_ui->monitor->selectedEdgeItem(int(Monitor::BottomLeft)) == index) + list.append(int(ElectricBottomLeft)); + if (m_ui->monitor->selectedEdgeItem(int(Monitor::Left)) == index) + list.append(int(ElectricLeft)); + if (m_ui->monitor->selectedEdgeItem(int(Monitor::TopLeft)) == index) + list.append(int(ElectricTopLeft)); + + if (list.isEmpty()) + list.append(int(ElectricNone)); + return list; +} + +} // namespace + +#include "touch.moc" diff --git a/kcmkwin/kwinscreenedges/touch.ui b/kcmkwin/kwinscreenedges/touch.ui new file mode 100644 --- /dev/null +++ b/kcmkwin/kwinscreenedges/touch.ui @@ -0,0 +1,71 @@ + + + KWinScreenEdgesConfigForm + + + + 0 + 0 + 748 + 332 + + + + + + + + 0 + 0 + + + + + 200 + 200 + + + + Qt::StrongFocus + + + + + + + To trigger an action swipe from the screen edge towards the center of the screen. + + + Qt::AlignCenter + + + true + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + KWin::Monitor + QWidget +
monitor.h
+ 1 +
+
+ + +