File indexing completed on 2024-11-10 04:56:51
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2008 Martin Gräßlin <mgraesslin@kde.org> 0006 SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com> 0007 SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com> 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #include "touch.h" 0013 #include <kwin_effects_interface.h> 0014 0015 #include <KConfigGroup> 0016 #include <KLocalizedString> 0017 #include <KPackage/Package> 0018 #include <KPackage/PackageLoader> 0019 #include <KPluginFactory> 0020 #include <QDBusConnection> 0021 #include <QDBusMessage> 0022 #include <QVBoxLayout> 0023 0024 #include "kwintouchscreendata.h" 0025 #include "kwintouchscreenedgeconfigform.h" 0026 #include "kwintouchscreenedgeeffectsettings.h" 0027 #include "kwintouchscreenscriptsettings.h" 0028 #include "kwintouchscreensettings.h" 0029 0030 K_PLUGIN_FACTORY_WITH_JSON(KWinScreenEdgesConfigFactory, "kcm_kwintouchscreen.json", registerPlugin<KWin::KWinScreenEdgesConfig>(); registerPlugin<KWin::KWinTouchScreenData>();) 0031 0032 namespace KWin 0033 { 0034 0035 KWinScreenEdgesConfig::KWinScreenEdgesConfig(QObject *parent, const KPluginMetaData &data) 0036 : KCModule(parent, data) 0037 , m_form(new KWinTouchScreenEdgeConfigForm(widget())) 0038 , m_config(KSharedConfig::openConfig("kwinrc")) 0039 , m_data(new KWinTouchScreenData(this)) 0040 { 0041 QVBoxLayout *layout = new QVBoxLayout(widget()); 0042 layout->addWidget(m_form); 0043 0044 monitorInit(); 0045 0046 connect(m_form, &KWinTouchScreenEdgeConfigForm::saveNeededChanged, this, &KWinScreenEdgesConfig::unmanagedWidgetChangeState); 0047 connect(m_form, &KWinTouchScreenEdgeConfigForm::defaultChanged, this, &KWinScreenEdgesConfig::unmanagedWidgetDefaultState); 0048 } 0049 0050 KWinScreenEdgesConfig::~KWinScreenEdgesConfig() 0051 { 0052 } 0053 0054 void KWinScreenEdgesConfig::load() 0055 { 0056 KCModule::load(); 0057 m_data->settings()->load(); 0058 for (KWinTouchScreenScriptSettings *setting : std::as_const(m_scriptSettings)) { 0059 setting->load(); 0060 } 0061 for (KWinTouchScreenEdgeEffectSettings *setting : std::as_const(m_effectSettings)) { 0062 setting->load(); 0063 } 0064 0065 monitorLoadSettings(); 0066 monitorLoadDefaultSettings(); 0067 m_form->reload(); 0068 } 0069 0070 void KWinScreenEdgesConfig::save() 0071 { 0072 monitorSaveSettings(); 0073 m_data->settings()->save(); 0074 for (KWinTouchScreenScriptSettings *setting : std::as_const(m_scriptSettings)) { 0075 setting->save(); 0076 } 0077 for (KWinTouchScreenEdgeEffectSettings *setting : std::as_const(m_effectSettings)) { 0078 setting->save(); 0079 } 0080 0081 // Reload saved settings to ScreenEdge UI 0082 monitorLoadSettings(); 0083 m_form->reload(); 0084 0085 // Reload KWin. 0086 QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); 0087 QDBusConnection::sessionBus().send(message); 0088 // and reconfigure the effects 0089 OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), 0090 QStringLiteral("/Effects"), 0091 QDBusConnection::sessionBus()); 0092 interface.reconfigureEffect(QStringLiteral("windowview")); 0093 interface.reconfigureEffect(QStringLiteral("overview")); 0094 for (const auto &effectId : std::as_const(m_effects)) { 0095 interface.reconfigureEffect(effectId); 0096 } 0097 0098 KCModule::save(); 0099 } 0100 0101 void KWinScreenEdgesConfig::defaults() 0102 { 0103 m_form->setDefaults(); 0104 0105 KCModule::defaults(); 0106 } 0107 0108 //----------------------------------------------------------------------------- 0109 // Monitor 0110 0111 void KWinScreenEdgesConfig::monitorInit() 0112 { 0113 m_form->monitorHideEdge(ElectricTopLeft, true); 0114 m_form->monitorHideEdge(ElectricTopRight, true); 0115 m_form->monitorHideEdge(ElectricBottomRight, true); 0116 m_form->monitorHideEdge(ElectricBottomLeft, true); 0117 0118 m_form->monitorAddItem(i18n("No Action")); 0119 m_form->monitorAddItem(i18n("Peek at Desktop")); 0120 m_form->monitorAddItem(i18n("Lock Screen")); 0121 m_form->monitorAddItem(i18n("Show KRunner")); 0122 m_form->monitorAddItem(i18n("Activity Manager")); 0123 m_form->monitorAddItem(i18n("Application Launcher")); 0124 0125 // TODO: Find a better way to get the display name of the present windows, 0126 // Maybe install metadata.json files? 0127 const QString presentWindowsName = i18n("Present Windows"); 0128 m_form->monitorAddItem(i18n("%1 - All Desktops", presentWindowsName)); 0129 m_form->monitorAddItem(i18n("%1 - Current Desktop", presentWindowsName)); 0130 m_form->monitorAddItem(i18n("%1 - Current Application", presentWindowsName)); 0131 0132 m_form->monitorAddItem(i18n("Overview")); 0133 0134 m_form->monitorAddItem(i18n("Toggle window switching")); 0135 m_form->monitorAddItem(i18n("Toggle alternative window switching")); 0136 0137 KConfigGroup config(m_config, QStringLiteral("Plugins")); 0138 const auto effects = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KWin/Script"), QStringLiteral("kwin/builtin-effects/")) << KPackage::PackageLoader::self()->listPackages(QStringLiteral("KWin/Script"), QStringLiteral("kwin/effects/")); 0139 0140 for (const KPluginMetaData &effect : effects) { 0141 if (!effect.value(QStringLiteral("X-KWin-Border-Activate"), false)) { 0142 continue; 0143 } 0144 0145 if (!config.readEntry(effect.pluginId() + QStringLiteral("Enabled"), effect.isEnabledByDefault())) { 0146 continue; 0147 } 0148 m_effects << effect.pluginId(); 0149 m_form->monitorAddItem(effect.name()); 0150 m_effectSettings[effect.pluginId()] = new KWinTouchScreenEdgeEffectSettings(effect.pluginId(), this); 0151 } 0152 0153 const QString scriptFolder = QStringLiteral("kwin/scripts/"); 0154 const auto scripts = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KWin/Script"), scriptFolder); 0155 0156 for (const KPluginMetaData &script : scripts) { 0157 if (script.value(QStringLiteral("X-KWin-Border-Activate"), false) != true) { 0158 continue; 0159 } 0160 0161 if (!config.readEntry(script.pluginId() + QStringLiteral("Enabled"), script.isEnabledByDefault())) { 0162 continue; 0163 } 0164 m_scripts << script.pluginId(); 0165 m_form->monitorAddItem(script.name()); 0166 m_scriptSettings[script.pluginId()] = new KWinTouchScreenScriptSettings(script.pluginId(), this); 0167 } 0168 0169 monitorShowEvent(); 0170 } 0171 0172 void KWinScreenEdgesConfig::monitorLoadSettings() 0173 { 0174 // Load ElectricBorderActions 0175 m_form->monitorChangeEdge(ElectricTop, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->top())); 0176 m_form->monitorChangeEdge(ElectricRight, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->right())); 0177 m_form->monitorChangeEdge(ElectricBottom, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->bottom())); 0178 m_form->monitorChangeEdge(ElectricLeft, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->left())); 0179 0180 // Load effect-specific actions: 0181 0182 // Present Windows BorderActivateAll 0183 m_form->monitorChangeEdge(m_data->settings()->touchBorderActivateAll(), PresentWindowsAll); 0184 // PresentWindows BorderActivate 0185 m_form->monitorChangeEdge(m_data->settings()->touchBorderActivatePresentWindows(), PresentWindowsCurrent); 0186 // PresentWindows BorderActivateClass 0187 m_form->monitorChangeEdge(m_data->settings()->touchBorderActivateClass(), PresentWindowsClass); 0188 0189 // Overview 0190 m_form->monitorChangeEdge(m_data->settings()->touchBorderActivateOverview(), Overview); 0191 0192 // TabBox BorderActivate 0193 m_form->monitorChangeEdge(m_data->settings()->touchBorderActivateTabBox(), TabBox); 0194 // Alternative TabBox 0195 m_form->monitorChangeEdge(m_data->settings()->touchBorderAlternativeActivate(), TabBoxAlternative); 0196 0197 // Dinamically loaded effects 0198 int lastIndex = EffectCount; 0199 for (int i = 0; i < m_effects.size(); i++) { 0200 m_form->monitorChangeEdge(m_effectSettings[m_effects[i]]->touchBorderActivate(), lastIndex); 0201 ++lastIndex; 0202 } 0203 0204 // Scripts 0205 for (int i = 0; i < m_scripts.size(); i++) { 0206 m_form->monitorChangeEdge(m_scriptSettings[m_scripts[i]]->touchBorderActivate(), lastIndex); 0207 ++lastIndex; 0208 } 0209 } 0210 0211 void KWinScreenEdgesConfig::monitorLoadDefaultSettings() 0212 { 0213 m_form->monitorChangeDefaultEdge(ElectricTop, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultTopValue())); 0214 m_form->monitorChangeDefaultEdge(ElectricRight, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultRightValue())); 0215 m_form->monitorChangeDefaultEdge(ElectricBottom, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultBottomValue())); 0216 m_form->monitorChangeDefaultEdge(ElectricLeft, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultLeftValue())); 0217 0218 // Present Windows BorderActivateAll 0219 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultTouchBorderActivateAllValue(), PresentWindowsAll); 0220 // PresentWindows BorderActivate 0221 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultTouchBorderActivatePresentWindowsValue(), PresentWindowsCurrent); 0222 // PresentWindows BorderActivateClass 0223 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultTouchBorderActivateClassValue(), PresentWindowsClass); 0224 0225 // Overview 0226 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultTouchBorderActivateOverviewValue(), Overview); 0227 0228 // TabBox BorderActivate 0229 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultTouchBorderActivateTabBoxValue(), TabBox); 0230 // Alternative TabBox 0231 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultTouchBorderAlternativeActivateValue(), TabBoxAlternative); 0232 } 0233 0234 void KWinScreenEdgesConfig::monitorSaveSettings() 0235 { 0236 // Save ElectricBorderActions 0237 m_data->settings()->setTop(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricTop))); 0238 m_data->settings()->setRight(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricRight))); 0239 m_data->settings()->setBottom(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricBottom))); 0240 m_data->settings()->setLeft(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricLeft))); 0241 0242 // Save effect-specific actions: 0243 0244 // Present Windows 0245 m_data->settings()->setTouchBorderActivateAll(m_form->monitorCheckEffectHasEdge(PresentWindowsAll)); 0246 m_data->settings()->setTouchBorderActivatePresentWindows(m_form->monitorCheckEffectHasEdge(PresentWindowsCurrent)); 0247 m_data->settings()->setTouchBorderActivateClass(m_form->monitorCheckEffectHasEdge(PresentWindowsClass)); 0248 0249 // Overview 0250 m_data->settings()->setTouchBorderActivateOverview(m_form->monitorCheckEffectHasEdge(Overview)); 0251 0252 // TabBox 0253 m_data->settings()->setTouchBorderActivateTabBox(m_form->monitorCheckEffectHasEdge(TabBox)); 0254 m_data->settings()->setTouchBorderAlternativeActivate(m_form->monitorCheckEffectHasEdge(TabBoxAlternative)); 0255 0256 // Dinamically loaded effects 0257 int lastIndex = EffectCount; 0258 for (int i = 0; i < m_effects.size(); i++) { 0259 m_effectSettings[m_effects[i]]->setTouchBorderActivate(m_form->monitorCheckEffectHasEdge(lastIndex)); 0260 ++lastIndex; 0261 } 0262 0263 // Scripts 0264 for (int i = 0; i < m_scripts.size(); i++) { 0265 m_scriptSettings[m_scripts[i]]->setTouchBorderActivate(m_form->monitorCheckEffectHasEdge(lastIndex)); 0266 ++lastIndex; 0267 } 0268 } 0269 0270 void KWinScreenEdgesConfig::monitorShowEvent() 0271 { 0272 // Check if they are enabled 0273 KConfigGroup config(m_config, QStringLiteral("Plugins")); 0274 0275 // Present Windows 0276 bool enabled = config.readEntry("windowviewEnabled", true); 0277 m_form->monitorItemSetEnabled(PresentWindowsCurrent, enabled); 0278 m_form->monitorItemSetEnabled(PresentWindowsAll, enabled); 0279 0280 // Overview 0281 m_form->monitorItemSetEnabled(Overview, config.readEntry("overviewEnabled", true)); 0282 0283 // tabbox, depends on reasonable focus policy. 0284 KConfigGroup config2(m_config, QStringLiteral("Windows")); 0285 QString focusPolicy = config2.readEntry("FocusPolicy", QString()); 0286 bool reasonable = focusPolicy != "FocusStrictlyUnderMouse" && focusPolicy != "FocusUnderMouse"; 0287 m_form->monitorItemSetEnabled(TabBox, reasonable); 0288 m_form->monitorItemSetEnabled(TabBoxAlternative, reasonable); 0289 0290 // Disable Edge if TouchEdges group entries are immutable 0291 m_form->monitorEnableEdge(ElectricTop, !m_data->settings()->isTopImmutable()); 0292 m_form->monitorEnableEdge(ElectricRight, !m_data->settings()->isRightImmutable()); 0293 m_form->monitorEnableEdge(ElectricBottom, !m_data->settings()->isBottomImmutable()); 0294 m_form->monitorEnableEdge(ElectricLeft, !m_data->settings()->isLeftImmutable()); 0295 } 0296 0297 ElectricBorderAction KWinScreenEdgesConfig::electricBorderActionFromString(const QString &string) 0298 { 0299 QString lowerName = string.toLower(); 0300 if (lowerName == QStringLiteral("showdesktop")) { 0301 return ElectricActionShowDesktop; 0302 } 0303 if (lowerName == QStringLiteral("lockscreen")) { 0304 return ElectricActionLockScreen; 0305 } 0306 if (lowerName == QStringLiteral("krunner")) { 0307 return ElectricActionKRunner; 0308 } 0309 if (lowerName == QStringLiteral("activitymanager")) { 0310 return ElectricActionActivityManager; 0311 } 0312 if (lowerName == QStringLiteral("applicationlauncher")) { 0313 return ElectricActionApplicationLauncher; 0314 } 0315 return ElectricActionNone; 0316 } 0317 0318 QString KWinScreenEdgesConfig::electricBorderActionToString(int action) 0319 { 0320 switch (action) { 0321 case 1: 0322 return QStringLiteral("ShowDesktop"); 0323 case 2: 0324 return QStringLiteral("LockScreen"); 0325 case 3: 0326 return QStringLiteral("KRunner"); 0327 case 4: 0328 return QStringLiteral("ActivityManager"); 0329 case 5: 0330 return QStringLiteral("ApplicationLauncher"); 0331 default: 0332 return QStringLiteral("None"); 0333 } 0334 } 0335 0336 } // namespace 0337 0338 #include "touch.moc" 0339 0340 #include "moc_touch.cpp"