From 842354bd70c343c0f2213488ab58168e813feea6 Mon Sep 17 00:00:00 2001 From: Micah Stanley Date: Mon, 21 Apr 2025 15:56:33 +0000 Subject: [PATCH] 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. --- .../mobileshellsettings.cpp | 14 ++++++ .../shellsettingsplugin/mobileshellsettings.h | 16 +++++++ .../panel/package/contents/ui/main.qml | 44 +++++++++++-------- .../contents/ui/NavigationPanelComponent.qml | 2 +- .../taskpanel/package/contents/ui/main.qml | 23 ++++++++-- kcms/mobileshell/ui/main.qml | 14 ++++++ .../package/contents/ui/TaskSwitcher.qml | 14 +++--- quicksettings/CMakeLists.txt | 1 + quicksettings/autohidepanels/Messages.sh | 6 +++ .../autohidepanels/contents/ui/main.qml | 17 +++++++ quicksettings/autohidepanels/metadata.json | 20 +++++++++ 11 files changed, 141 insertions(+), 30 deletions(-) create mode 100644 quicksettings/autohidepanels/Messages.sh create mode 100644 quicksettings/autohidepanels/contents/ui/main.qml create mode 100644 quicksettings/autohidepanels/metadata.json diff --git a/components/shellsettingsplugin/mobileshellsettings.cpp b/components/shellsettingsplugin/mobileshellsettings.cpp index a5ca128e..4e8efdf9 100644 --- a/components/shellsettingsplugin/mobileshellsettings.cpp +++ b/components/shellsettingsplugin/mobileshellsettings.cpp @@ -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 diff --git a/components/shellsettingsplugin/mobileshellsettings.h b/components/shellsettingsplugin/mobileshellsettings.h index d87cc99b..46e4616c 100644 --- a/components/shellsettingsplugin/mobileshellsettings.h +++ b/components/shellsettingsplugin/mobileshellsettings.h @@ -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(); diff --git a/containments/panel/package/contents/ui/main.qml b/containments/panel/package/contents/ui/main.qml index ae1d60af..b0b2bb18 100644 --- a/containments/panel/package/contents/ui/main.qml +++ b/containments/panel/package/contents/ui/main.qml @@ -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 diff --git a/containments/taskpanel/package/contents/ui/NavigationPanelComponent.qml b/containments/taskpanel/package/contents/ui/NavigationPanelComponent.qml index deb8c0da..edd0d89f 100644 --- a/containments/taskpanel/package/contents/ui/NavigationPanelComponent.qml +++ b/containments/taskpanel/package/contents/ui/NavigationPanelComponent.qml @@ -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 diff --git a/containments/taskpanel/package/contents/ui/main.qml b/containments/taskpanel/package/contents/ui/main.qml index 613483a6..9bf3c4da 100644 --- a/containments/taskpanel/package/contents/ui/main.qml +++ b/containments/taskpanel/package/contents/ui/main.qml @@ -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 { diff --git a/kcms/mobileshell/ui/main.qml b/kcms/mobileshell/ui/main.qml index 5d119326..771ddc18 100644 --- a/kcms/mobileshell/ui/main.qml +++ b/kcms/mobileshell/ui/main.qml @@ -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 { diff --git a/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcher.qml b/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcher.qml index 4925a054..12a23856 100644 --- a/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcher.qml +++ b/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcher.qml @@ -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 } } ] diff --git a/quicksettings/CMakeLists.txt b/quicksettings/CMakeLists.txt index 125e4291..0b562291 100644 --- a/quicksettings/CMakeLists.txt +++ b/quicksettings/CMakeLists.txt @@ -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) diff --git a/quicksettings/autohidepanels/Messages.sh b/quicksettings/autohidepanels/Messages.sh new file mode 100644 index 00000000..d65f106c --- /dev/null +++ b/quicksettings/autohidepanels/Messages.sh @@ -0,0 +1,6 @@ +#! /usr/bin/env bash + +# SPDX-FileCopyrightText: 2025 Micah Stanley +# 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 diff --git a/quicksettings/autohidepanels/contents/ui/main.qml b/quicksettings/autohidepanels/contents/ui/main.qml new file mode 100644 index 00000000..70ff13fe --- /dev/null +++ b/quicksettings/autohidepanels/contents/ui/main.qml @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2025 Micah Stanley +// 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; + } +} \ No newline at end of file diff --git a/quicksettings/autohidepanels/metadata.json b/quicksettings/autohidepanels/metadata.json new file mode 100644 index 00000000..72cfbc62 --- /dev/null +++ b/quicksettings/autohidepanels/metadata.json @@ -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" + } +}