[plasma/kwin] /: Add new option for behavior when window on different desktop is activated

Nate Graham null at kde.org
Wed Aug 31 19:57:25 BST 2022


Git commit 6b38b0372443b49246b2313673efb0e48a63a978 by Nate Graham, on behalf of Natalie Clarius.
Committed on 31/08/2022 at 18:57.
Pushed by ngraham into branch 'master'.

Add new option for behavior when window on different desktop is activated
        
When a window that is on a different virtual desktop than the current one gets
activated, the current behavior is that the active virtual desktop will be switched
to the one the activated window is on. This may seem reasonable for a scenario where
the user explicitly intends to activate an existing window on a different desktop.
However, the following scenario is also (perhaps even more?) common: When an
application responds to a launch command by requesting to activate an existing
instance instead of opening a new one (such as Firefox or KDE System Settings), an
existing window on any desktop will get activated even when what the user had in
mind was opening a new window (on the desktop they are currently in). 

This means that opening an application, such as following a URL or accessing a
system setting, unexpectedly results in the user being teleported to a different
virtual desktop. This can be very irritating. The more expected behavior for these
users would be to have windows always open on the desktop where they are called
from. That's is what this commit adds as a new option.

BUG: 438375
FIXED-IN: 5.26

M  +17   -2    doc/windowbehaviour/index.docbook
M  +8    -1    src/activation.cpp
M  +36   -2    src/kcmkwin/kwinoptions/advanced.ui
M  +8    -0    src/kcmkwin/kwinoptions/kwinoptions_settings.kcfg
M  +3    -0    src/kcmkwin/kwinoptions/windows.cpp
M  +7    -0    src/kwin.kcfg
M  +11   -0    src/options.cpp
M  +19   -0    src/options.h

https://invent.kde.org/plasma/kwin/commit/6b38b0372443b49246b2313673efb0e48a63a978

diff --git a/doc/windowbehaviour/index.docbook b/doc/windowbehaviour/index.docbook
index bebe41253e..606897c5ec 100644
--- a/doc/windowbehaviour/index.docbook
+++ b/doc/windowbehaviour/index.docbook
@@ -16,8 +16,8 @@
 <!-- TRANS:ROLES_OF_TRANSLATORS -->
 </authorgroup>
 
-<date>2021-04-09</date>
-<releaseinfo>Plasma 5.20</releaseinfo>
+<date>2022-08-31</date>
+<releaseinfo>Plasma 5.26</releaseinfo>
 
 <keywordset>
 <keyword>KDE</keyword>
@@ -699,6 +699,21 @@ with the proper window type for this feature to work.</para></listitem>
 
 </variablelist>
 
+<sect3 id="action-virtual-desktop-behavior">
+<title>Virtual Desktop behavior</title>
+<para>Sometimes calling an application will activate an existing window rather than opening a new window. This setting controls what should happen if that activated window is located on a Virtual Desktop other than the current one.</para>
+<variablelist>
+<varlistentry>
+<term><guilabel>Switch to that Virtual Desktop</guilabel></term>
+<listitem><para>Will switch to the Virtual Desktop where the window is currently located. Choose this option if you would like the active desktop to automatically follow windows to their assigned desktop.</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><guilabel>Bring window to current Virtual Desktop</guilabel></term>
+<listitem><para>Will cause the window to jump to the active Virtual Desktop. Choose this option if you would like windows to always open on the current Virtual Desktop, and the active Virtual Desktop to only switch when navigating there manually.</para></listitem>
+</varlistentry>
+</variablelist>
+</sect3>
+
 </sect2>
 
 </sect1>
diff --git a/src/activation.cpp b/src/activation.cpp
index 36256d98f9..fe31de2513 100644
--- a/src/activation.cpp
+++ b/src/activation.cpp
@@ -290,7 +290,14 @@ void Workspace::activateWindow(Window *window, bool force)
     raiseWindow(window);
     if (!window->isOnCurrentDesktop()) {
         ++block_focus;
-        VirtualDesktopManager::self()->setCurrent(window->desktops().constLast());
+        switch (options->activationDesktopPolicy()) {
+        case Options::ActivationDesktopPolicy::SwitchToOtherDesktop:
+            VirtualDesktopManager::self()->setCurrent(window->desktops().constLast());
+            break;
+        case Options::ActivationDesktopPolicy::BringToCurrentDesktop:
+            window->enterDesktop(VirtualDesktopManager::self()->currentDesktop());
+            break;
+        }
         --block_focus;
     }
 #if KWIN_BUILD_ACTIVITIES
diff --git a/src/kcmkwin/kwinoptions/advanced.ui b/src/kcmkwin/kwinoptions/advanced.ui
index ae519802a9..f4e3f00c45 100644
--- a/src/kcmkwin/kwinoptions/advanced.ui
+++ b/src/kcmkwin/kwinoptions/advanced.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>600</width>
-    <height>500</height>
+    <width>1001</width>
+    <height>297</height>
    </rect>
   </property>
   <layout class="QFormLayout" name="formLayout">
@@ -142,6 +142,40 @@
      </property>
     </widget>
    </item>
+   <item row="4" column="0">
+    <widget class="QLabel" name="activationDesktopPolicyLabel">
+     <property name="text">
+      <string>Virtual Desktop behavior:</string>
+     </property>
+     <property name="buddy">
+      <cstring>kcfg_ActivationDesktopPolicy</cstring>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="1">
+    <widget class="QLabel" name="activationDesktopPolicyDescriptionLabel">
+     <property name="text">
+      <string>When activating a window on a different Virtual Desktop:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="1">
+    <widget class="QComboBox" name="kcfg_ActivationDesktopPolicy">
+     <property name="whatsThis">
+      <string><html><head/><body><p>This setting controls what happens when an open window located on a Virtual Desktop other than the current one is activated. </p><p><span style=" font-style:italic;">Switch to other Virtual Desktop</span> will switch to the Virtual Desktop where the window is currently located. </p><p><span style=" font-style:italic;">Bring window to current Virtual Desktop</span> will cause the window to jump to the active Virtual Desktop. </p></body></html></string>
+     </property>
+     <item>
+      <property name="text">
+       <string>Switch to that Virtual Desktop</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Bring window to current Virtual Desktop</string>
+      </property>
+     </item>
+    </widget>
+   </item>
   </layout>
  </widget>
  <resources/>
diff --git a/src/kcmkwin/kwinoptions/kwinoptions_settings.kcfg b/src/kcmkwin/kwinoptions/kwinoptions_settings.kcfg
index 2ac7e8bebe..2057f94299 100644
--- a/src/kcmkwin/kwinoptions/kwinoptions_settings.kcfg
+++ b/src/kcmkwin/kwinoptions/kwinoptions_settings.kcfg
@@ -54,6 +54,14 @@
         <default>true</default>
     </entry>
 
+    <entry name="ActivationDesktopPolicy" type="Enum">
+        <choices name="ActivationDesktopPolicyChoices">
+            <choice name="SwitchToOtherDesktop"></choice>
+            <choice name="BringToCurrentDesktop"></choice>
+        </choices>
+        <default>SwitchToOtherDesktop</default>
+    </entry>
+
     <entry key="TitlebarDoubleClickCommand" type="Enum">
         <default>Maximize</default>
         <choices>
diff --git a/src/kcmkwin/kwinoptions/windows.cpp b/src/kcmkwin/kwinoptions/windows.cpp
index f8fbac3dd8..2a95ebbc5a 100644
--- a/src/kcmkwin/kwinoptions/windows.cpp
+++ b/src/kcmkwin/kwinoptions/windows.cpp
@@ -257,6 +257,9 @@ void KAdvancedConfig::initialize(KWinOptionsSettings *settings, KWinOptionsKDEGl
     // This option lives in the kdeglobals file because it is consumed by
     // kxmlgui.
     m_ui->kcfg_AllowKDEAppsToRememberWindowPositions->setVisible(KWindowSystem::isPlatformX11());
+
+    m_ui->kcfg_ActivationDesktopPolicy->setItemData(KWinOptionsSettings::ActivationDesktopPolicyChoices::SwitchToOtherDesktop, "SwitchToOtherDesktop");
+    m_ui->kcfg_ActivationDesktopPolicy->setItemData(KWinOptionsSettings::ActivationDesktopPolicyChoices::BringToCurrentDesktop, "BringToCurrentDesktop");
 }
 
 void KAdvancedConfig::showEvent(QShowEvent *ev)
diff --git a/src/kwin.kcfg b/src/kwin.kcfg
index 624b9a27c8..05d6b1dcbd 100644
--- a/src/kwin.kcfg
+++ b/src/kwin.kcfg
@@ -133,6 +133,13 @@
                 #endif
             }()</default>
         </entry>
+        <entry name="ActivationDesktopPolicy" type="Enum">
+            <choices name="KWin::Options::ActivationDesktopPolicy">
+                <choice name="SwitchToOtherDesktop"/>
+                <choice name="BringToCurrentDesktop"/>
+            </choices>
+            <default>KWin::Options::ActivationDesktopPolicy::SwitchToOtherDesktop</default>
+        </entry>
         <entry name="AutoRaise" type="Bool">
             <default>false</default>
         </entry>
diff --git a/src/options.cpp b/src/options.cpp
index 27555a9c19..ec2b41ba84 100644
--- a/src/options.cpp
+++ b/src/options.cpp
@@ -44,6 +44,7 @@ Options::Options(QObject *parent)
     , m_separateScreenFocus(false)
     , m_activeMouseScreen(false)
     , m_placement(Placement::NoPlacement)
+    , m_activationDesktopPolicy(Options::defaultActivationDesktopPolicy())
     , m_borderSnapZone(0)
     , m_windowSnapZone(0)
     , m_centerSnapZone(0)
@@ -243,6 +244,15 @@ void Options::setPlacement(int placement)
     Q_EMIT placementChanged();
 }
 
+void Options::setActivationDesktopPolicy(ActivationDesktopPolicy activationDesktopPolicy)
+{
+    if (m_activationDesktopPolicy == activationDesktopPolicy) {
+        return;
+    }
+    m_activationDesktopPolicy = activationDesktopPolicy;
+    Q_EMIT activationDesktopPolicyChanged();
+}
+
 void Options::setBorderSnapZone(int borderSnapZone)
 {
     if (m_borderSnapZone == borderSnapZone) {
@@ -759,6 +769,7 @@ void Options::syncFromKcfgc()
     setActiveMouseScreen(m_settings->activeMouseScreen());
     setRollOverDesktops(m_settings->rollOverDesktops());
     setFocusStealingPreventionLevel(m_settings->focusStealingPreventionLevel());
+    setActivationDesktopPolicy(m_settings->activationDesktopPolicy());
     setXwaylandCrashPolicy(m_settings->xwaylandCrashPolicy());
     setXwaylandMaxCrashCount(m_settings->xwaylandMaxCrashCount());
     setPlacement(m_settings->placement());
diff --git a/src/options.h b/src/options.h
index 3d2615530b..cc2ac3c626 100644
--- a/src/options.h
+++ b/src/options.h
@@ -105,6 +105,7 @@ class KWIN_EXPORT Options : public QObject
     Q_PROPERTY(bool separateScreenFocus READ isSeparateScreenFocus WRITE setSeparateScreenFocus NOTIFY separateScreenFocusChanged)
     Q_PROPERTY(bool activeMouseScreen READ activeMouseScreen WRITE setActiveMouseScreen NOTIFY activeMouseScreenChanged)
     Q_PROPERTY(int placement READ placement WRITE setPlacement NOTIFY placementChanged)
+    Q_PROPERTY(ActivationDesktopPolicy activationDesktopPolicy READ activationDesktopPolicy WRITE setActivationDesktopPolicy NOTIFY activationDesktopPolicyChanged)
     Q_PROPERTY(bool focusPolicyIsReasonable READ focusPolicyIsReasonable NOTIFY focusPolicyIsResonableChanged)
     /**
      * The size of the zone that triggers snapping on desktop borders.
@@ -327,6 +328,17 @@ public:
         return m_focusPolicy == ClickToFocus || m_focusPolicy == FocusFollowsMouse;
     }
 
+    enum ActivationDesktopPolicy {
+        SwitchToOtherDesktop,
+        BringToCurrentDesktop
+    };
+    Q_ENUM(ActivationDesktopPolicy)
+
+    ActivationDesktopPolicy activationDesktopPolicy() const
+    {
+        return m_activationDesktopPolicy;
+    }
+
     /**
      * The size of the zone that triggers snapping on desktop borders.
      */
@@ -688,6 +700,7 @@ public:
     void setSeparateScreenFocus(bool separateScreenFocus);
     void setActiveMouseScreen(bool activeMouseScreen);
     void setPlacement(int placement);
+    void setActivationDesktopPolicy(ActivationDesktopPolicy activationDesktopPolicy);
     void setBorderSnapZone(int borderSnapZone);
     void setWindowSnapZone(int windowSnapZone);
     void setCenterSnapZone(int centerSnapZone);
@@ -861,6 +874,10 @@ public:
     {
         return RenderTimeEstimatorMaximum;
     }
+    static ActivationDesktopPolicy defaultActivationDesktopPolicy()
+    {
+        return ActivationDesktopPolicy::SwitchToOtherDesktop;
+    }
     /**
      * Performs loading all settings except compositing related.
      */
@@ -888,6 +905,7 @@ Q_SIGNALS:
     void separateScreenFocusChanged(bool);
     void activeMouseScreenChanged();
     void placementChanged();
+    void activationDesktopPolicyChanged();
     void borderSnapZoneChanged();
     void windowSnapZoneChanged();
     void centerSnapZoneChanged();
@@ -950,6 +968,7 @@ private:
     bool m_separateScreenFocus;
     bool m_activeMouseScreen;
     Placement::Policy m_placement;
+    ActivationDesktopPolicy m_activationDesktopPolicy;
     int m_borderSnapZone;
     int m_windowSnapZone;
     int m_centerSnapZone;


More information about the kde-doc-english mailing list