Shell: Add Setting to Auto Hide Panels so Applications Can Fill the Entire Device Screen Space

This merge request adds a new setting to auto hide the status and navigation panels so applications will be able to fill out the entire device screen area. Also, this adds a new quick settings toggle to quickly change this property.
This commit is contained in:
Micah Stanley 2025-04-21 15:56:33 +00:00
parent 036cc8502b
commit 842354bd70
11 changed files with 141 additions and 30 deletions

View file

@ -41,6 +41,7 @@ MobileShellSettings::MobileShellSettings(QObject *parent)
Q_EMIT actionDrawerTopLeftModeChanged();
Q_EMIT actionDrawerTopRightModeChanged();
Q_EMIT convergenceModeEnabledChanged();
Q_EMIT autoHidePanelsEnabledChanged();
Q_EMIT allowLogoutChanged();
}
if (group.name() == LOCKSCREEN_CONFIG_GROUP) {
@ -201,6 +202,19 @@ void MobileShellSettings::setConvergenceModeEnabled(bool enabled)
job->start();
}
bool MobileShellSettings::autoHidePanelsEnabled() const
{
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
return group.readEntry("autoHidePanelsEnabled", false);
}
void MobileShellSettings::setAutoHidePanelsEnabled(bool enabled)
{
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
group.writeEntry("autoHidePanelsEnabled", enabled, KConfigGroup::Notify);
m_config->sync();
}
void MobileShellSettings::updateNavigationBarsInPlasma(bool navigationPanelEnabled)
{
// Do not update panels when not in Plasma Mobile

View file

@ -45,6 +45,9 @@ class MobileShellSettings : public QObject
// convergence mode
Q_PROPERTY(bool convergenceModeEnabled READ convergenceModeEnabled WRITE setConvergenceModeEnabled NOTIFY convergenceModeEnabledChanged)
// Auto Hide Panels
Q_PROPERTY(bool autoHidePanelsEnabled READ autoHidePanelsEnabled WRITE setAutoHidePanelsEnabled NOTIFY autoHidePanelsEnabledChanged)
// logout dialog
Q_PROPERTY(bool allowLogout READ allowLogout READ allowLogout NOTIFY allowLogoutChanged)
@ -219,6 +222,18 @@ public:
*/
void setConvergenceModeEnabled(bool enabled);
/**
* Whether Auto Hide Panels is enabled.
*/
bool autoHidePanelsEnabled() const;
/**
* Set whether Auto Hide Panels is enabled.
*
* @param enabled
*/
void setAutoHidePanelsEnabled(bool enabled);
/**
* Whether logout button is shown in the logout/shutdown dialog.
*/
@ -262,6 +277,7 @@ Q_SIGNALS:
void actionDrawerTopLeftModeChanged();
void actionDrawerTopRightModeChanged();
void convergenceModeEnabledChanged();
void autoHidePanelsEnabledChanged();
void allowLogoutChanged();
void lockscreenLeftButtonActionChanged();
void lockscreenRightButtonActionChanged();

View file

@ -14,6 +14,7 @@ import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
@ -51,6 +52,7 @@ ContainmentItem {
root.panel.floating = false;
root.panel.maximize(); // maximize first, then we can apply offsets (otherwise they are overridden)
root.panel.thickness = statusPanelHeight;
root.panel.visibilityMode = ShellSettings.Settings.autoHidePanelsEnabled ? 3 : 0;
MobileShell.ShellUtil.setWindowLayer(root.panel, LayerShell.Window.LayerOverlay)
root.updateTouchArea();
}
@ -67,18 +69,34 @@ ContainmentItem {
}
}
Connections {
target: ShellSettings.Settings
function onAutoHidePanelsEnabled() {
root.setWindowProperties();
}
}
// only opaque if there are no maximized windows on this screen
readonly property bool showingStartupFeedback: MobileShellState.ShellDBusObject.startupFeedbackModel.activeWindowIsStartupFeedback && windowMaximizedTracker.windowCount === 1
readonly property bool showingStartupFeedback: MobileShellState.ShellDBusObject.startupFeedbackModel.activeWindowIsStartupFeedback && startupFeedbackColorAnimation.visible && windowMaximizedTracker.windowCount === 1
readonly property bool showingApp: windowMaximizedTracker.showingWindow && !showingStartupFeedback
readonly property color backgroundColor: topPanel.colorScopeColor
readonly property alias isCurrentWindowFullscreen: windowMaximizedTracker.isCurrentWindowFullscreen
onIsCurrentWindowFullscreenChanged: {
MobileShellState.ShellDBusClient.panelState = isCurrentWindowFullscreen ? "hidden" : "default";
readonly property bool fullscreen: isCurrentWindowFullscreen || (ShellSettings.Settings.autoHidePanelsEnabled && showingApp)
onFullscreenChanged: {
MobileShellState.ShellDBusClient.panelState = fullscreen ? "hidden" : "default";
}
WindowPlugin.WindowMaximizedTracker {
id: windowMaximizedTracker
screenGeometry: Plasmoid.containment.screenGeometry
onShowingWindowChanged: {
if (windowMaximizedTracker.showingWindow && MobileShellState.ShellDBusClient.isTaskSwitcherVisible && (ShellSettings.Settings.autoHidePanelsEnabled || fullscreen)) {
MobileShellState.ShellDBusClient.panelState = "hidden";
statusPanel.offset = -root.statusPanelHeight;
}
}
}
// enforce thickness
@ -138,7 +156,7 @@ ContainmentItem {
screen: Plasmoid.screen
maximizedTracker: windowMaximizedTracker
visible: !root.isCurrentWindowFullscreen
visible: !root.fullscreen
}
Rectangle {
@ -147,7 +165,7 @@ ContainmentItem {
Kirigami.Theme.colorSet: root.showingApp ? Kirigami.Theme.Header : Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
color: statusPanel.state == "default" && root.showingApp ? Kirigami.Theme.backgroundColor : "transparent"
color: statusPanel.state == "default" && (root.showingApp || root.fullscreen) ? Kirigami.Theme.backgroundColor : "transparent"
property real offset: 0
@ -157,7 +175,7 @@ ContainmentItem {
anchors.fill: parent
showDropShadow: !root.showingApp
backgroundColor: statusPanel.state != "default" ? Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.95) : "transparent"
backgroundColor: statusPanel.state != "default" && root.showingApp ? Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.95) : "transparent"
transform: [
Translate {
@ -210,7 +228,7 @@ ContainmentItem {
SequentialAnimation {
ParallelAnimation {
PropertyAnimation {
properties: "offset"; easing.type: statusPanel.state == "hidden" ? Easing.InExpo : Easing.OutExpo; duration: Kirigami.Units.longDuration
properties: "offset"; easing.type: statusPanel.state === "hidden" ? Easing.InExpo : Easing.OutExpo; duration: Kirigami.Units.longDuration
}
}
ScriptAction {
@ -230,18 +248,6 @@ ContainmentItem {
readonly property alias drawerVisible: drawer.visible
readonly property alias offset: drawer.actionDrawer.offset
property bool surfacePressed: false
onOffsetChanged: surfacePressed = false
// allow tapping to bring back up the status bar when it is hidden
onPressedChanged: {
if (!pressed && surfacePressed && root.isCurrentWindowFullscreen) {
haptics.buttonVibrate();
MobileShellState.ShellDBusClient.panelState = "visible";
} else {
surfacePressed = true;
}
}
// if in a fullscreen app, the panels are visible, and the action drawer is opened
// set the panels to a hidden state

View file

@ -26,7 +26,7 @@ MobileShell.NavigationPanel {
// - opaque if an app is shown or vkbd is shown
// - translucent if the task switcher is open
// - transparent if on the homescreen
backgroundColor: navbarState != "default" ? Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.95) : "transparent"
backgroundColor: navbarState != "default" && opaqueBar ? Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.95) : "transparent"
foregroundColorGroup: opaqueBar ? Kirigami.Theme.Window : Kirigami.Theme.Complementary
shadow: !opaqueBar

View file

@ -85,6 +85,7 @@ ContainmentItem {
root.panel.offset = intendedWindowOffset;
root.panel.thickness = navigationPanelHeight;
root.panel.location = intendedWindowLocation;
root.panel.visibilityMode = ShellSettings.Settings.autoHidePanelsEnabled ? 3 : 0;
MobileShell.ShellUtil.setWindowLayer(root.panel, LayerShell.Window.LayerOverlay);
root.updateTouchArea();
}
@ -124,17 +125,31 @@ ContainmentItem {
}
}
Connections {
target: ShellSettings.Settings
function onAutoHidePanelsEnabled() {
root.setWindowProperties();
}
}
Component.onCompleted: setWindowProperties();
// only opaque if there are no maximized windows on this screen
readonly property bool showingStartupFeedback: MobileShellState.ShellDBusObject.startupFeedbackModel.activeWindowIsStartupFeedback && windowMaximizedTracker.windowCount === 1
readonly property bool showingStartupFeedback: MobileShellState.ShellDBusObject.startupFeedbackModel.activeWindowIsStartupFeedback && startupFeedbackColorAnimation.visible && windowMaximizedTracker.windowCount === 1
readonly property bool opaqueBar: (windowMaximizedTracker.showingWindow || isCurrentWindowFullscreen) && !showingStartupFeedback
readonly property alias isCurrentWindowFullscreen: windowMaximizedTracker.isCurrentWindowFullscreen
readonly property bool fullscreen: isCurrentWindowFullscreen || (ShellSettings.Settings.autoHidePanelsEnabled && opaqueBar)
WindowPlugin.WindowMaximizedTracker {
id: windowMaximizedTracker
screenGeometry: Plasmoid.containment.screenGeometry
onShowingWindowChanged: {
if (windowMaximizedTracker.showingWindow && MobileShellState.ShellDBusClient.isTaskSwitcherVisible && (ShellSettings.Settings.autoHidePanelsEnabled || fullscreen)) {
navigationPanel.offset = root.navigationPanelHeight;
}
}
}
MobileShell.StartupFeedbackPanelFill {
@ -147,7 +162,7 @@ ContainmentItem {
screen: Plasmoid.screen
maximizedTracker: windowMaximizedTracker
visible: !root.isCurrentWindowFullscreen
visible: !root.fullscreen
}
Rectangle {
@ -208,7 +223,7 @@ ContainmentItem {
SequentialAnimation {
ParallelAnimation {
PropertyAnimation {
properties: "offset"; easing.type: navigationPanel.state == "hidden" ? Easing.InExpo : Easing.OutExpo; duration: Kirigami.Units.longDuration
properties: "offset"; easing.type: navigationPanel.state === "hidden" ? Easing.InExpo : Easing.OutExpo; duration: Kirigami.Units.longDuration
}
}
ScriptAction {

View file

@ -47,6 +47,20 @@ KCM.SimpleKCM {
}
}
}
FormCard.FormDelegateSeparator { above: shellVibrationsButton; below: animationsSwitch }
FormCard.FormSwitchDelegate {
id: autoHidePanels
text: i18n("Auto Hide Panels")
description: i18n("When active, status and navigation panels will auto hide, allowing applications to fill the entire screen space.")
checked: ShellSettings.Settings.autoHidePanelsEnabled
onCheckedChanged: {
if (checked != ShellSettings.Settings.autoHidePanelsEnabled) {
ShellSettings.Settings.autoHidePanelsEnabled = checked;
}
}
}
}
FormCard.FormHeader {

View file

@ -30,10 +30,12 @@ FocusScope {
readonly property QtObject effect: KWinComponents.SceneView.effect
readonly property QtObject targetScreen: KWinComponents.SceneView.screen
readonly property real topMargin: MobileShell.Constants.topPanelHeight
readonly property real bottomMargin: MobileShell.Constants.navigationPanelOnSide(width, height) ? 0 : MobileShell.Constants.navigationPanelThickness
readonly property real navBottomMargin: MobileShell.Constants.navigationPanelOnSide(width, height) ? 0 : MobileShell.Constants.navigationPanelThickness
readonly property real navRightMargin: MobileShell.Constants.navigationPanelOnSide(width, height) ? MobileShell.Constants.navigationPanelThickness : 0
readonly property real topMargin: ShellSettings.Settings.autoHidePanelsEnabled ? 0 : MobileShell.Constants.topPanelHeight
readonly property real bottomMargin: ShellSettings.Settings.autoHidePanelsEnabled ? 0 : navBottomMargin
readonly property real leftMargin: 0
readonly property real rightMargin: MobileShell.Constants.navigationPanelOnSide(width, height) ? MobileShell.Constants.navigationPanelThickness : 0
readonly property real rightMargin: ShellSettings.Settings.autoHidePanelsEnabled ? 0 : navRightMargin
property var taskSwitcherHelpers: TaskSwitcherHelpers {
taskSwitcher: root
@ -481,7 +483,7 @@ FocusScope {
// navigation panel
MobileShell.NavigationPanel {
id: navigationPanel
z: 1
z: taskSwitcherHelpers.taskDrawerOpened && !taskSwitcherHelpers.currentlyBeingClosed ? 1 : 0
visible: ShellSettings.Settings.navigationPanelEnabled
backgroundColor: Qt.rgba(0, 0, 0, 0.1)
foregroundColorGroup: Kirigami.Theme.Complementary
@ -550,7 +552,7 @@ FocusScope {
}
PropertyChanges {
target: navigationPanel
width: root.rightMargin
width: navRightMargin
anchors.topMargin: root.topMargin
}
},
@ -568,7 +570,7 @@ FocusScope {
}
PropertyChanges {
target: navigationPanel
height: root.bottomMargin
height: navBottomMargin
}
}
]

View file

@ -8,6 +8,7 @@ plasma_install_package(bluetooth org.kde.plasma.quicksetting.bluetooth quicksett
plasma_install_package(caffeine org.kde.plasma.quicksetting.caffeine quicksettings)
plasma_install_package(docked org.kde.plasma.quicksetting.docked quicksettings)
plasma_install_package(donotdisturb org.kde.plasma.quicksetting.donotdisturb quicksettings)
plasma_install_package(autohidepanels org.kde.plasma.quicksetting.autohidepanels quicksettings)
plasma_install_package(keyboardtoggle org.kde.plasma.quicksetting.keyboardtoggle quicksettings)
plasma_install_package(mobiledata org.kde.plasma.quicksetting.mobiledata quicksettings)
plasma_install_package(settingsapp org.kde.plasma.quicksetting.settingsapp quicksettings)

View file

@ -0,0 +1,6 @@
#! /usr/bin/env bash
# SPDX-FileCopyrightText: 2025 Micah Stanley <stanleymicah@proton.me>
# SPDX-License-Identifier: GPL-2.0-or-later
$XGETTEXT `find . -name \*.js -o -name \*.qml -o -name \*.cpp` -o $podir/plasma_org.kde.plasma.quicksetting.autohidepanels.pot

View file

@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: 2025 Micah Stanley <stanleymicah@proton.me>
// SPDX-License-Identifier: LGPL-2.0-or-later
import QtQuick
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.plasma.private.mobileshell.quicksettingsplugin as QS
QS.QuickSetting {
text: i18n("Auto Hide Panels")
icon: "view-fullscreen"
enabled: ShellSettings.Settings.autoHidePanelsEnabled
function toggle() {
ShellSettings.Settings.autoHidePanelsEnabled = !ShellSettings.Settings.autoHidePanelsEnabled;
}
}

View file

@ -0,0 +1,20 @@
{
"KPackageStructure": "KPackage/GenericQML",
"KPlugin": {
"Authors": [
{
"Email": "stanleymicah@proton.me",
"Name": "Micah Stanley",
"Name[x-test]": "xxMicah Stanleyxx"
}
],
"Description": "Auto Hide Panels quick setting for Plasma Mobile",
"Description[x-test]": "xxAuto Hide Panels quick setting for Plasma Mobilexx",
"Icon": "view-fullscreen",
"Id": "org.kde.plasma.quicksetting.autohidepanels",
"License": "GPL-2.0+",
"Name": "Auto Hide Panels",
"Name[x-test]": "xxAuto Hide Panelsxx",
"Website": "https://kde.org"
}
}