From dbcf43abfe08de402d056dfb74b766a63f790b91 Mon Sep 17 00:00:00 2001 From: Konstantinos Smanis Date: Fri, 30 Oct 2020 09:39:00 +0000 Subject: [PATCH] Allow configuring click behavior in Desktop Grid effect The following click behaviors are defined: * Switch desktop and activate window [default] * Switch desktop only The former emulates the previous default of activating clicked windows using the Present Windows effect. The latter introduces a new mode where the clicked window is not activated, allowing the user to select a virtual desktop without worrying about disrupting the last active window. The configuration toggle that controlled the use of the Present Windows effect has been subsumed into the first click behavior, i.e., if the effect is enabled, it will be implicitly triggered. --- effects/desktopgrid/desktopgrid.cpp | 33 ++++++++-- effects/desktopgrid/desktopgrid.h | 8 ++- effects/desktopgrid/desktopgrid.kcfg | 4 +- effects/desktopgrid/desktopgrid_config.cpp | 10 ++++ effects/desktopgrid/desktopgrid_config.ui | 60 ++++++++++++++----- kconf_update/CMakeLists.txt | 2 + .../kwin-5.21-desktop-grid-click-behavior.py | 18 ++++++ kconf_update/kwin.upd | 6 ++ 8 files changed, 118 insertions(+), 23 deletions(-) create mode 100644 kconf_update/kwin-5.21-desktop-grid-click-behavior.py diff --git a/effects/desktopgrid/desktopgrid.cpp b/effects/desktopgrid/desktopgrid.cpp index 56fe32d8fb..58f9204c89 100644 --- a/effects/desktopgrid/desktopgrid.cpp +++ b/effects/desktopgrid/desktopgrid.cpp @@ -48,6 +48,7 @@ DesktopGridEffect::DesktopGridEffect() , isValidMove(false) , windowMove(nullptr) , windowMoveDiff() + , windowMoveElevateTimer(new QTimer(this)) , gridSize() , orientation(Qt::Horizontal) , activeCell(1, 1) @@ -79,12 +80,20 @@ DesktopGridEffect::DesktopGridEffect() connect(effects, &EffectsHandler::screenAboutToLock, this, [this]() { setActive(false); + windowMoveElevateTimer->stop(); if (keyboardGrab) { effects->ungrabKeyboard(); keyboardGrab = false; } }); + windowMoveElevateTimer->setInterval(QApplication::startDragTime()); + windowMoveElevateTimer->setSingleShot(true); + connect(windowMoveElevateTimer, &QTimer::timeout, this, [this]() { + effects->setElevatedWindow(windowMove, true); + wasWindowMove = true; + }); + // Load all other configuration details reconfigure(ReconfigureAll); } @@ -115,7 +124,7 @@ void DesktopGridEffect::reconfigure(ReconfigureFlags) desktopNameAlignment = Qt::Alignment(DesktopGridConfig::desktopNameAlignment()); layoutMode = DesktopGridConfig::layoutMode(); customLayoutRows = DesktopGridConfig::customLayoutRows(); - m_usePresentWindows = DesktopGridConfig::presentWindows(); + clickBehavior = DesktopGridConfig::clickBehavior(); // deactivate and activate all touch border const QVector relevantBorders{ElectricLeft, ElectricTop, ElectricRight, ElectricBottom}; @@ -457,6 +466,10 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e) if (windowMove != nullptr && (me->pos() - dragStartPos).manhattanLength() > QApplication::startDragDistance()) { // Handle window moving + if (windowMoveElevateTimer->isActive()) { // Window started moving, but is not elevated yet! + windowMoveElevateTimer->stop(); + effects->setElevatedWindow(windowMove, true); + } if (!wasWindowMove) { // Activate on move if (isUsingPresentWindows()) { foreach (const int i, desktopList(windowMove)) { @@ -574,7 +587,7 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e) // Prepare it for moving windowMoveDiff = w->pos() - unscalePos(me->pos(), nullptr); windowMove = w; - effects->setElevatedWindow(windowMove, true); + windowMoveElevateTimer->start(); } } else if ((me->buttons() == Qt::MiddleButton || me->buttons() == Qt::RightButton) && windowMove == nullptr) { EffectWindow* w = windowAt(me->pos()); @@ -607,8 +620,16 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e) } if (e->type() == QEvent::MouseButtonRelease && me->button() == Qt::LeftButton) { isValidMove = false; - if (windowMove) - effects->activateWindow(windowMove); + if (windowMove) { + if (windowMoveElevateTimer->isActive()) { + // no need to elevate window, it was just a click + windowMoveElevateTimer->stop(); + } + if (clickBehavior == SwitchDesktopAndActivateWindow || wasWindowMove) { + // activate window if relevant config is set or window was moved + effects->activateWindow(windowMove); + } + } if (wasWindowMove || wasDesktopMove) { // reset pointer effects->defineCursor(Qt::PointingHandCursor); } else { // click -> exit @@ -1068,7 +1089,7 @@ void DesktopGridEffect::setup() setCurrentDesktop(effects->currentDesktop()); // setup the motion managers - if (m_usePresentWindows) + if (clickBehavior == SwitchDesktopAndActivateWindow) m_proxy = static_cast(effects->getProxy(BuiltInEffects::nameForEffect(BuiltInEffect::PresentWindows))); if (isUsingPresentWindows()) { m_proxy->reCreateGrids(); // revalidation on multiscreen, bug #351724 @@ -1192,6 +1213,8 @@ void DesktopGridEffect::finish() desktopNames.clear(); } + windowMoveElevateTimer->stop(); + if (keyboardGrab) effects->ungrabKeyboard(); keyboardGrab = false; diff --git a/effects/desktopgrid/desktopgrid.h b/effects/desktopgrid/desktopgrid.h index dff82a4bab..ec1aa4799f 100644 --- a/effects/desktopgrid/desktopgrid.h +++ b/effects/desktopgrid/desktopgrid.h @@ -15,6 +15,8 @@ #include #include +class QTimer; + #include "kwineffectquickview.h" namespace KWin @@ -52,6 +54,7 @@ public: } enum { LayoutPager, LayoutAutomatic, LayoutCustom }; // Layout modes + enum { SwitchDesktopAndActivateWindow, SwitchDesktopOnly }; // Click behavior // for properties int configuredZoomDuration() const { @@ -70,7 +73,7 @@ public: return customLayoutRows; } bool isUsePresentWindows() const { - return m_usePresentWindows; + return clickBehavior == SwitchDesktopAndActivateWindow; } private Q_SLOTS: void toggle(); @@ -114,6 +117,7 @@ private: Qt::Alignment desktopNameAlignment; int layoutMode; int customLayoutRows; + int clickBehavior; bool activated; QTimeLine timeline; @@ -126,6 +130,7 @@ private: EffectWindow* windowMove; QPoint windowMoveDiff; QPoint dragStartPos; + QTimer *windowMoveElevateTimer; // Soft highlighting QList hoverTimeline; @@ -146,7 +151,6 @@ private: PresentWindowsEffectProxy* m_proxy; QList m_managers; - bool m_usePresentWindows; QRect m_windowMoveGeometry; QPoint m_windowMoveStartPoint; diff --git a/effects/desktopgrid/desktopgrid.kcfg b/effects/desktopgrid/desktopgrid.kcfg index 720924d8e8..28a615a349 100644 --- a/effects/desktopgrid/desktopgrid.kcfg +++ b/effects/desktopgrid/desktopgrid.kcfg @@ -22,8 +22,8 @@ 2 - - true + + 0 true diff --git a/effects/desktopgrid/desktopgrid_config.cpp b/effects/desktopgrid/desktopgrid_config.cpp index 23b68065a5..a8e823786c 100644 --- a/effects/desktopgrid/desktopgrid_config.cpp +++ b/effects/desktopgrid/desktopgrid_config.cpp @@ -73,10 +73,14 @@ DesktopGridEffectConfig::DesktopGridEffectConfig(QWidget* parent, const QVariant m_ui->desktopNameAlignmentCombo->addItem(i18n("Top-Left"), QVariant(Qt::AlignLeft | Qt::AlignTop)); m_ui->desktopNameAlignmentCombo->addItem(i18n("Center"), QVariant(Qt::AlignCenter)); + m_ui->clickBehaviorButtonGroup->setId(m_ui->switchDesktopAndActivateWindow, DesktopGridEffect::SwitchDesktopAndActivateWindow); + m_ui->clickBehaviorButtonGroup->setId(m_ui->switchDesktopOnly, DesktopGridEffect::SwitchDesktopOnly); + DesktopGridConfig::instance(KWIN_CONFIG); addConfig(DesktopGridConfig::self(), m_ui); connect(m_ui->kcfg_LayoutMode, qOverload(&KComboBox::currentIndexChanged), this, &DesktopGridEffectConfig::layoutSelectionChanged); connect(m_ui->desktopNameAlignmentCombo, qOverload(&KComboBox::currentIndexChanged), this, &DesktopGridEffectConfig::markAsChanged); + connect(m_ui->clickBehaviorButtonGroup, qOverload(&QButtonGroup::buttonClicked), this, &DesktopGridEffectConfig::markAsChanged); connect(m_ui->shortcutEditor, &KShortcutsEditor::keyChange, this, &DesktopGridEffectConfig::markAsChanged); load(); @@ -93,6 +97,7 @@ void DesktopGridEffectConfig::save() { m_ui->shortcutEditor->save(); DesktopGridConfig::setDesktopNameAlignment(m_ui->desktopNameAlignmentCombo->itemData(m_ui->desktopNameAlignmentCombo->currentIndex()).toInt()); + DesktopGridConfig::setClickBehavior(m_ui->clickBehaviorButtonGroup->checkedId()); KCModule::save(); OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), @@ -105,6 +110,10 @@ void DesktopGridEffectConfig::load() { KCModule::load(); m_ui->desktopNameAlignmentCombo->setCurrentIndex(m_ui->desktopNameAlignmentCombo->findData(QVariant(DesktopGridConfig::desktopNameAlignment()))); + QAbstractButton *clickBehaviorButton = m_ui->clickBehaviorButtonGroup->button(DesktopGridConfig::clickBehavior()); + if (clickBehaviorButton) { + clickBehaviorButton->setChecked(true); + } } void DesktopGridEffectConfig::layoutSelectionChanged() @@ -122,6 +131,7 @@ void DesktopGridEffectConfig::defaults() { KCModule::defaults(); m_ui->desktopNameAlignmentCombo->setCurrentIndex(0); + m_ui->clickBehaviorButtonGroup->button(0)->setChecked(true); } } // namespace diff --git a/effects/desktopgrid/desktopgrid_config.ui b/effects/desktopgrid/desktopgrid_config.ui index 50a73b195b..67d1c94b4a 100644 --- a/effects/desktopgrid/desktopgrid_config.ui +++ b/effects/desktopgrid/desktopgrid_config.ui @@ -171,7 +171,50 @@ + + + + Click behavior: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + switchDesktopAndActivateWindow + + + + + + + If the Present Windows effect is enabled, it will be automatically triggered. + + + Switch desktop and activate window + + + clickBehaviorButtonGroup + + + + + + + Switch desktop only + + + clickBehaviorButtonGroup + + + + + + Show buttons to alter count of virtual desktops + + + + Qt::Vertical @@ -184,20 +227,6 @@ - - - - Use Present Windows effect to layout the windows - - - - - - - Show buttons to alter count of virtual desktops - - - @@ -247,4 +276,7 @@ + + + diff --git a/kconf_update/CMakeLists.txt b/kconf_update/CMakeLists.txt index 1ce575c7ce..89428f2ab8 100644 --- a/kconf_update/CMakeLists.txt +++ b/kconf_update/CMakeLists.txt @@ -4,6 +4,8 @@ install(PROGRAMS kwin-5.16-auto-bordersize.sh DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR}) install(PROGRAMS kwin-5.18-move-animspeed.py DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR}) +install(PROGRAMS kwin-5.21-desktop-grid-click-behavior.py + DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR}) install(FILES kwinrules.upd DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR}) diff --git a/kconf_update/kwin-5.21-desktop-grid-click-behavior.py b/kconf_update/kwin-5.21-desktop-grid-click-behavior.py new file mode 100644 index 0000000000..f85f502496 --- /dev/null +++ b/kconf_update/kwin-5.21-desktop-grid-click-behavior.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import sys + +VALUE_MAP = { + 'true': 0, + 'false': 1, +} + +if __name__ == '__main__': + for line in sys.stdin: + line = line.strip() + if line.startswith('PresentWindows='): + _, value = line.split('=', 1) + print("# DELETE PresentWindows") + print("ClickBehavior=%d" % VALUE_MAP[value]) diff --git a/kconf_update/kwin.upd b/kconf_update/kwin.upd index e44f1cf2c9..a182cffae0 100644 --- a/kconf_update/kwin.upd +++ b/kconf_update/kwin.upd @@ -37,3 +37,9 @@ Id=animation-speed File=kwinrc,kdeglobals Group=Compositing,KDE Script=kwin-5.18-move-animspeed.py,python3 + +# In the Desktop Grid effect, replace the PresentWindows boolean with an enum +Id=desktop-grid-click-behavior +File=kwinrc +Group=Effect-DesktopGrid +Script=kwin-5.21-desktop-grid-click-behavior.py,python