Commit 6b38b037 authored by Natalie Clarius's avatar Natalie Clarius Committed by Nate Graham
Browse files

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
parent 3973b740
Pipeline #225566 passed with stage
in 29 minutes and 39 seconds
......@@ -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>
......
......@@ -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
......
......@@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This setting controls what happens when an open window located on a Virtual Desktop other than the current one is activated. &lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Switch to other Virtual Desktop&lt;/span&gt; will switch to the Virtual Desktop where the window is currently located. &lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Bring window to current Virtual Desktop&lt;/span&gt; will cause the window to jump to the active Virtual Desktop. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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/>
......
......@@ -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>
......
......@@ -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)
......
......@@ -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>
......
......@@ -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());
......
......@@ -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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment