Add snap layouts shell setting

Expose snapLayoutsEnabled through MobileShellSettings and store it\nin plasmamobilerc.\n\nUse the setting in the Shift snap assist effect eligibility logic\nand add a Convergence KCM switch to control it.\n\nKeep the switch disabled when convergence is off, gaming mode is on,\nor dynamic tiling is enabled so window-placement ownership stays\nconsistent.
This commit is contained in:
Marco Allegretti 2026-05-06 11:44:54 +02:00
parent 8d59ce6153
commit 3fba9798e4
4 changed files with 51 additions and 1 deletions

View file

@ -47,6 +47,7 @@ MobileShellSettings::MobileShellSettings(QObject *parent)
Q_EMIT gamingModeEnabledChanged();
Q_EMIT gamingDismissHintEnabledChanged();
Q_EMIT dynamicTilingEnabledChanged();
Q_EMIT snapLayoutsEnabledChanged();
Q_EMIT allowLogoutChanged();
}
if (group.name() == LOCKSCREEN_CONFIG_GROUP) {
@ -290,6 +291,19 @@ void MobileShellSettings::setDynamicTilingEnabled(bool enabled)
m_config->sync();
}
bool MobileShellSettings::snapLayoutsEnabled() const
{
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
return group.readEntry("snapLayoutsEnabled", true);
}
void MobileShellSettings::setSnapLayoutsEnabled(bool enabled)
{
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
group.writeEntry("snapLayoutsEnabled", enabled, KConfigGroup::Notify);
m_config->sync();
}
void MobileShellSettings::updateNavigationBarsInPlasma()
{
// Do not update panels when not in Plasma Mobile

View file

@ -60,6 +60,9 @@ class MobileShellSettings : public QObject
// When false, KWin's native quick-tile behaviour is used unmodified.
Q_PROPERTY(bool dynamicTilingEnabled READ dynamicTilingEnabled WRITE setDynamicTilingEnabled NOTIFY dynamicTilingEnabledChanged)
// Snap layout picker — only meaningful in convergence mode when dynamic tiling is off.
Q_PROPERTY(bool snapLayoutsEnabled READ snapLayoutsEnabled WRITE setSnapLayoutsEnabled NOTIFY snapLayoutsEnabledChanged)
// logout dialog
Q_PROPERTY(bool allowLogout READ allowLogout READ allowLogout NOTIFY allowLogoutChanged)
@ -286,6 +289,14 @@ public:
bool dynamicTilingEnabled() const;
void setDynamicTilingEnabled(bool enabled);
/**
* Whether the SHIFT snap layout picker is enabled.
* Defaults to true; only takes effect in convergence mode when gaming mode
* and dynamic tiling are off.
*/
bool snapLayoutsEnabled() const;
void setSnapLayoutsEnabled(bool enabled);
/**
* Whether logout button is shown in the logout/shutdown dialog.
*/
@ -335,6 +346,7 @@ Q_SIGNALS:
void gamingModeEnabledChanged();
void gamingDismissHintEnabledChanged();
void dynamicTilingEnabledChanged();
void snapLayoutsEnabledChanged();
void allowLogoutChanged();
void lockscreenLeftButtonActionChanged();
void lockscreenRightButtonActionChanged();

View file

@ -95,7 +95,24 @@ KCM.SimpleKCM {
}
}
FormCard.FormDelegateSeparator { above: dynamicTilingSwitch; below: autoHidePanels }
FormCard.FormDelegateSeparator { above: dynamicTilingSwitch; below: snapLayoutsSwitch }
FormCard.FormSwitchDelegate {
id: snapLayoutsSwitch
text: i18n("Snap Layouts")
description: i18n("Show the snap layout picker from the maximize button. Disabled while convergence mode is off, gaming mode is active, or dynamic tiling is enabled.")
enabled: ShellSettings.Settings.convergenceModeEnabled
&& !ShellSettings.Settings.gamingModeEnabled
&& !ShellSettings.Settings.dynamicTilingEnabled
checked: ShellSettings.Settings.snapLayoutsEnabled
onCheckedChanged: {
if (checked != ShellSettings.Settings.snapLayoutsEnabled) {
ShellSettings.Settings.snapLayoutsEnabled = checked;
}
}
}
FormCard.FormDelegateSeparator { above: snapLayoutsSwitch; below: autoHidePanels }
FormCard.FormSwitchDelegate {
id: autoHidePanels

View file

@ -24,6 +24,7 @@ KWinComponents.SceneEffect {
readonly property bool snapLayoutsEligible: ShellSettings.Settings.convergenceModeEnabled
&& !ShellSettings.Settings.gamingModeEnabled
&& !ShellSettings.Settings.dynamicTilingEnabled
&& ShellSettings.Settings.snapLayoutsEnabled
readonly property int hoverBarHeight: 30
readonly property int decorationButtonSize: 16
readonly property int decorationButtonSpacing: 8
@ -372,6 +373,12 @@ KWinComponents.SceneEffect {
effect.hideSnapLayouts();
}
}
function onSnapLayoutsEnabledChanged() {
if (!effect.snapLayoutsEligible) {
effect.hideSnapLayouts();
}
}
}
// Gap constant (must match shift-tiling)