mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-29 15:03:09 +00:00
Suppress shell chrome in gaming mode
Hide the navigation panel, status bar, and app drawer while gamingModeEnabled is active. The KWin convergent-windows script skips its window policy so game windows are not forcibly tiled or maximized. The Home button in gaming mode re-opens the Game Center overlay rather than the app drawer. A configurable hint nudges the user toward the HUD button after launching a game.
This commit is contained in:
parent
d901815c9d
commit
b0739dd9a7
4 changed files with 134 additions and 6 deletions
|
|
@ -25,12 +25,32 @@ import org.kde.kirigamiaddons.components as KirigamiAddonsComponents
|
|||
|
||||
import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio
|
||||
|
||||
import "./gaming"
|
||||
|
||||
import "./private"
|
||||
|
||||
ContainmentItem {
|
||||
id: root
|
||||
property Folio.HomeScreen folio: root.plasmoid
|
||||
|
||||
// Tracks whether the Game Center grid is visible within gaming mode.
|
||||
// Starts true when gaming mode turns on; set to false by a game launch.
|
||||
property bool gameCenterOpen: false
|
||||
property bool showGameCenterHint: false
|
||||
|
||||
Timer {
|
||||
id: gameCenterHintTimer
|
||||
interval: 2600
|
||||
onTriggered: root.showGameCenterHint = false
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ShellSettings.Settings
|
||||
function onGamingModeEnabledChanged() {
|
||||
root.gameCenterOpen = ShellSettings.Settings.gamingModeEnabled
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
folio.FolioSettings.load();
|
||||
folio.FavouritesModel.load();
|
||||
|
|
@ -89,6 +109,12 @@ ContainmentItem {
|
|||
MobileShellState.ShellDBusClient.closeActionDrawer();
|
||||
}
|
||||
|
||||
if (ShellSettings.Settings.gamingModeEnabled) {
|
||||
// In gaming mode Home/Menu should reopen the Game Center overlay.
|
||||
root.gameCenterOpen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ShellSettings.Settings.convergenceModeEnabled) {
|
||||
// Convergence: toggle the app drawer as a layer-shell overlay
|
||||
// without disturbing open windows.
|
||||
|
|
@ -186,7 +212,7 @@ ContainmentItem {
|
|||
// task panel containment; this window only provides the visible dock.
|
||||
Window {
|
||||
id: dockOverlay
|
||||
visible: ShellSettings.Settings.convergenceModeEnabled
|
||||
visible: ShellSettings.Settings.convergenceModeEnabled && !ShellSettings.Settings.gamingModeEnabled
|
||||
color: "transparent"
|
||||
width: Screen.width
|
||||
height: Kirigami.Units.gridUnit * 3
|
||||
|
|
@ -286,6 +312,7 @@ ContainmentItem {
|
|||
Window {
|
||||
id: drawerOverlay
|
||||
visible: ShellSettings.Settings.convergenceModeEnabled
|
||||
&& !ShellSettings.Settings.gamingModeEnabled
|
||||
&& folio.HomeScreenState.appDrawerOpenProgress > 0
|
||||
color: "transparent"
|
||||
width: Screen.width
|
||||
|
|
@ -645,6 +672,68 @@ ContainmentItem {
|
|||
}
|
||||
}
|
||||
|
||||
// Game Center overlay — full-screen grid of games shown when gaming mode
|
||||
// is active. Sits at LayerTop so it covers running application windows
|
||||
// without going above system notifications.
|
||||
GameCenterOverlay {
|
||||
id: gameCenterOverlay
|
||||
folio: root.folio
|
||||
visible: ShellSettings.Settings.gamingModeEnabled && root.gameCenterOpen
|
||||
|
||||
onGameStarted: root.gameCenterOpen = false
|
||||
onDismissRequested: {
|
||||
root.gameCenterOpen = false
|
||||
if (ShellSettings.Settings.gamingDismissHintEnabled) {
|
||||
root.showGameCenterHint = true
|
||||
gameCenterHintTimer.restart()
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
folio.ApplicationListSearchModel.categoryFilter = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Small persistent button at the top-right corner of the screen that lets
|
||||
// the user return to the Game Center after launching a game.
|
||||
GamingHUD {
|
||||
visible: ShellSettings.Settings.gamingModeEnabled && !root.gameCenterOpen
|
||||
onOpenRequested: root.gameCenterOpen = true
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: gameCenterHint
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Kirigami.Units.gridUnit * 2
|
||||
visible: root.showGameCenterHint && ShellSettings.Settings.gamingDismissHintEnabled
|
||||
opacity: visible ? 1 : 0
|
||||
z: 2000
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
color: Qt.rgba(0, 0, 0, 0.65)
|
||||
border.width: 1
|
||||
border.color: Qt.rgba(1, 1, 1, 0.2)
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.InOutQuad }
|
||||
}
|
||||
|
||||
implicitWidth: hintText.implicitWidth + Kirigami.Units.gridUnit * 2
|
||||
implicitHeight: hintText.implicitHeight + Kirigami.Units.largeSpacing
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: hintText
|
||||
anchors.centerIn: parent
|
||||
text: i18n("Gaming mode is still on. Use Home or the gamepad icon to reopen Game Center.")
|
||||
color: "white"
|
||||
wrapMode: Text.WordWrap
|
||||
width: Math.min(root.width * 0.8, Kirigami.Units.gridUnit * 30)
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
|
||||
MobileShell.HomeScreen {
|
||||
id: homeScreen
|
||||
anchors.fill: parent
|
||||
|
|
|
|||
|
|
@ -34,11 +34,17 @@ ContainmentItem {
|
|||
// Whether the startup feedback is showing
|
||||
readonly property bool showingStartupFeedback: MobileShellState.ShellDBusObject.startupFeedbackModel.activeWindowIsStartupFeedback
|
||||
|
||||
readonly property bool gamingMode: ShellSettings.Settings.gamingModeEnabled
|
||||
|
||||
// Whether an app is maximized and showing (does not include startup feedback)
|
||||
readonly property bool showingApp: windowMaximizedTracker.showingWindow && !showingStartupFeedback
|
||||
|
||||
// Whether the currently showing app is in "fullscreen"
|
||||
readonly property bool fullscreen: {
|
||||
if (gamingMode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// In convergence mode the status bar is always visible, like a desktop panel.
|
||||
if (ShellSettings.Settings.convergenceModeEnabled) {
|
||||
return false;
|
||||
|
|
@ -69,7 +75,7 @@ ContainmentItem {
|
|||
}
|
||||
}
|
||||
|
||||
readonly property real panelHeight: MobileShell.Constants.topPanelHeight
|
||||
readonly property real panelHeight: gamingMode ? 0 : MobileShell.Constants.topPanelHeight
|
||||
onPanelHeightChanged: setWindowProperties()
|
||||
|
||||
function setWindowProperties() {
|
||||
|
|
@ -123,6 +129,11 @@ ContainmentItem {
|
|||
function onConvergenceModeEnabledChanged() {
|
||||
root.setWindowProperties();
|
||||
}
|
||||
|
||||
function onGamingModeEnabledChanged() {
|
||||
root.setWindowProperties();
|
||||
MobileShellState.ShellDBusClient.panelState = ShellSettings.Settings.gamingModeEnabled ? "hidden" : "default";
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
|
|
@ -136,7 +147,7 @@ ContainmentItem {
|
|||
// MaximizeArea by the panel height.
|
||||
Window {
|
||||
id: topBarSpaceReserver
|
||||
visible: ShellSettings.Settings.convergenceModeEnabled
|
||||
visible: ShellSettings.Settings.convergenceModeEnabled && !ShellSettings.Settings.gamingModeEnabled
|
||||
color: "transparent"
|
||||
flags: Qt.FramelessWindowHint | Qt.WindowTransparentForInput
|
||||
height: root.panelHeight
|
||||
|
|
@ -152,6 +163,7 @@ ContainmentItem {
|
|||
// Visual panel component
|
||||
StatusPanel {
|
||||
id: statusPanel
|
||||
visible: !ShellSettings.Settings.gamingModeEnabled
|
||||
anchors.fill: parent
|
||||
containmentItem: root
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,12 +38,14 @@ ContainmentItem {
|
|||
|
||||
readonly property bool inLandscape: MobileShell.Constants.navigationPanelOnSide(Screen.width, Screen.height)
|
||||
|
||||
readonly property real navigationPanelHeight: MobileShell.Constants.navigationPanelThickness
|
||||
readonly property bool gamingMode: ShellSettings.Settings.gamingModeEnabled
|
||||
|
||||
readonly property real navigationPanelHeight: gamingMode ? 0 : MobileShell.Constants.navigationPanelThickness
|
||||
onNavigationPanelHeightChanged: setWindowProperties()
|
||||
|
||||
readonly property real intendedWindowThickness: navigationPanelHeight
|
||||
readonly property real intendedWindowLength: inLandscape ? Screen.height : Screen.width
|
||||
readonly property real intendedWindowOffset: inLandscape ? MobileShell.Constants.topPanelHeight : 0; // offset for top panel
|
||||
readonly property real intendedWindowOffset: (inLandscape && !gamingMode) ? MobileShell.Constants.topPanelHeight : 0; // offset for top panel
|
||||
readonly property int intendedWindowLocation: inLandscape ? PlasmaCore.Types.RightEdge : PlasmaCore.Types.BottomEdge
|
||||
|
||||
onIntendedWindowLengthChanged: maximizeTimer.restart() // ensure it always takes up the full length of the screen
|
||||
|
|
@ -136,6 +138,11 @@ ContainmentItem {
|
|||
function onConvergenceModeEnabledChanged() {
|
||||
root.setWindowProperties();
|
||||
}
|
||||
|
||||
function onGamingModeEnabledChanged() {
|
||||
root.setWindowProperties();
|
||||
navigationPanel.offset = ShellSettings.Settings.gamingModeEnabled ? root.navigationPanelHeight : 0;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: setWindowProperties();
|
||||
|
|
@ -153,6 +160,7 @@ ContainmentItem {
|
|||
Window {
|
||||
id: dockSpaceReserver
|
||||
visible: ShellSettings.Settings.convergenceModeEnabled
|
||||
&& !ShellSettings.Settings.gamingModeEnabled
|
||||
&& !(ShellSettings.Settings.autoHidePanelsEnabled
|
||||
&& windowMaximizedTracker.showingWindow)
|
||||
color: "transparent"
|
||||
|
|
@ -177,7 +185,9 @@ ContainmentItem {
|
|||
return (windowMaximizedTracker.showingWindow || isCurrentWindowFullscreen) && !showingStartupFeedback
|
||||
}
|
||||
readonly property alias isCurrentWindowFullscreen: windowMaximizedTracker.isCurrentWindowFullscreen
|
||||
readonly property bool fullscreen: isCurrentWindowFullscreen || (ShellSettings.Settings.autoHidePanelsEnabled && opaqueBar)
|
||||
readonly property bool fullscreen: ShellSettings.Settings.gamingModeEnabled
|
||||
|| isCurrentWindowFullscreen
|
||||
|| (ShellSettings.Settings.autoHidePanelsEnabled && opaqueBar)
|
||||
|
||||
WindowPlugin.WindowMaximizedTracker {
|
||||
id: windowMaximizedTracker
|
||||
|
|
@ -205,6 +215,7 @@ ContainmentItem {
|
|||
|
||||
Item {
|
||||
id: navigationPanel
|
||||
visible: !ShellSettings.Settings.gamingModeEnabled
|
||||
anchors.fill: parent
|
||||
|
||||
property real offset: 0
|
||||
|
|
|
|||
|
|
@ -60,6 +60,12 @@ Loader {
|
|||
return;
|
||||
}
|
||||
|
||||
if (ShellSettings.Settings.gamingModeEnabled) {
|
||||
window.noBorder = true;
|
||||
window.setMaximize(true, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ShellSettings.Settings.convergenceModeEnabled) {
|
||||
window.noBorder = false;
|
||||
} else {
|
||||
|
|
@ -128,6 +134,16 @@ Loader {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onGamingModeEnabledChanged() {
|
||||
const windows = KWinComponents.Workspace.windows;
|
||||
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
if (windows[i].normalWindow) {
|
||||
root.run(windows[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
|
|
|||
Loading…
Reference in a new issue