Polish gaming mode session flow and legends

Save and restore dynamic tiling across gaming sessions, close conflicting homescreen surfaces when entering gaming mode, and make gamepad legends adaptive for non-gamepad input with wrapped labels.
This commit is contained in:
Marco Allegretti 2026-06-01 15:20:36 +02:00
parent b0ce6acdea
commit 33ebcce63b
3 changed files with 56 additions and 15 deletions

View file

@ -42,6 +42,32 @@ Window {
readonly property int longAnimationDuration: MobileShell.Motion.duration(MobileShell.Motion.EffectsDefault)
readonly property int launchFadeDuration: MobileShell.Motion.duration(MobileShell.Motion.StandardAccel)
function controlLegendText() {
if (GamingShell.GamepadManager.hasGamepad) {
if (runningGames.activeFocus) {
return i18n("%1: Select %2: Close %3: Back %4: Exit %5: Settings %6: Search",
actionButtonLabel, closeButtonLabel, backButtonLabel, exitButtonLabel,
quickSettingsButtonLabel, searchButtonLabel)
}
if (recentList.activeFocus) {
return i18n("%1: Play %2: Details %3: Back %4: Exit %5: Settings %6: Search",
actionButtonLabel, closeButtonLabel, backButtonLabel, exitButtonLabel,
quickSettingsButtonLabel, searchButtonLabel)
}
return i18n("%1: Play %2: Details %3: Back %4: Exit %5/%6: Filter %7: Settings %8: Search",
actionButtonLabel, closeButtonLabel, backButtonLabel, exitButtonLabel,
leftShoulderLabel, rightShoulderLabel, quickSettingsButtonLabel, searchButtonLabel)
}
if (runningGames.activeFocus) {
return i18n("Mouse: click a running game to focus it. Keyboard: arrows move between cards, Enter selects, Esc closes.")
}
if (recentList.activeFocus) {
return i18n("Mouse: click a recent game to play it. Keyboard: arrows move between cards, Enter plays, Esc closes.")
}
return i18n("Mouse: click a game or details button. Keyboard: arrows navigate, Enter plays, I shows details, Esc closes.")
}
function pulsePrimaryGamepad(lowIntensity, highIntensity, durationMs) {
var pad = GamingShell.GamepadManager.primaryGamepad
if (!pad || !pad.hasRumble) {
@ -1085,19 +1111,12 @@ Window {
// Gamepad legend
PC3.Label {
text: runningGames.activeFocus
? i18n("%1: Select %2: Close %3: Back %4: Exit %5: Settings %6: Search",
actionButtonLabel, closeButtonLabel, backButtonLabel, exitButtonLabel,
quickSettingsButtonLabel, searchButtonLabel)
: recentList.activeFocus
? i18n("%1: Play %2: Details %3: Back %4: Exit %5: Settings %6: Search",
actionButtonLabel, closeButtonLabel, backButtonLabel, exitButtonLabel,
quickSettingsButtonLabel, searchButtonLabel)
: i18n("%1: Play %2: Details %3: Back %4: Exit %5/%6: Filter %7: Settings %8: Search",
actionButtonLabel, closeButtonLabel, backButtonLabel, exitButtonLabel,
leftShoulderLabel, rightShoulderLabel, quickSettingsButtonLabel, searchButtonLabel)
Layout.fillWidth: true
text: root.controlLegendText()
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.75
opacity: 0.5
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignRight
}
}
}

View file

@ -25,6 +25,14 @@ Item {
readonly property string acceptButtonLabel: GamingShell.GamepadManager.buttonLabel(GamingShell.GamepadManager.ButtonA)
readonly property string closeButtonLabel: GamingShell.GamepadManager.buttonLabel(GamingShell.GamepadManager.ButtonB)
function controlLegendText() {
if (GamingShell.GamepadManager.hasGamepad) {
return i18n("↕: Navigate ↔: Adjust %1: Toggle %2: Close", acceptButtonLabel, closeButtonLabel)
}
return i18n("↑↓: Navigate ←→: Adjust Enter: Toggle Esc: Close")
}
function pulsePrimaryGamepad(lowIntensity, highIntensity, durationMs) {
var pad = GamingShell.GamepadManager.primaryGamepad
if (!pad || !pad.hasRumble) {
@ -688,11 +696,11 @@ Item {
// ---- Gamepad legend ----
PC3.Label {
Layout.fillWidth: true
text: i18n("↕: Navigate ↔: Adjust %1: Toggle %2: Close",
acceptButtonLabel, closeButtonLabel)
text: root.controlLegendText()
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.8
opacity: 0.5
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
}
Item { Layout.fillHeight: true }

View file

@ -44,6 +44,7 @@ ContainmentItem {
// State saved when gaming mode activates, restored when it deactivates
property string _savedPowerProfile: ""
property bool _savedDnd: false
property bool _savedDynamicTiling: false
property bool _gamingSessionActive: false
function _applyGamingModeState(enabled) {
@ -57,7 +58,20 @@ ContainmentItem {
if (enabled) {
// Save current state and apply gaming optimizations
root._savedDnd = MobileShellState.ShellDBusClient.doNotDisturb
root._savedDynamicTiling = ShellSettings.Settings.dynamicTilingEnabled
root._gamingSessionActive = true
MobileShellState.ShellDBusClient.doNotDisturb = true
ShellSettings.Settings.dynamicTilingEnabled = false
if (MobileShellState.ShellDBusClient.isActionDrawerOpen) {
MobileShellState.ShellDBusClient.closeActionDrawer()
}
folio.HomeScreenState.closeFolder()
folio.HomeScreenState.closeSearchWidget()
folio.HomeScreenState.closeAppDrawer()
if (folio.HomeScreenState.viewState === Folio.HomeScreenState.SettingsView) {
folio.HomeScreenState.closeSettingsView()
}
if (GamingShell.PowerProfileControl.available) {
root._savedPowerProfile = GamingShell.PowerProfileControl.activeProfile
@ -65,17 +79,17 @@ ContainmentItem {
}
GamingShell.GameModeControl.requestStart()
root._gamingSessionActive = true
} else {
// Restore previous state
root._gamingSessionActive = false
MobileShellState.ShellDBusClient.doNotDisturb = root._savedDnd
ShellSettings.Settings.dynamicTilingEnabled = root._savedDynamicTiling
if (GamingShell.PowerProfileControl.available && root._savedPowerProfile.length > 0) {
GamingShell.PowerProfileControl.activeProfile = root._savedPowerProfile
}
GamingShell.GameModeControl.requestEnd()
root._gamingSessionActive = false
}
}