Restart InputPlumber and return to source session when switching back to Steam

Fixes broken input after returning from an exclusive OpenGamepadUI session:
the OGPU session leaves InputPlumber intercepting the gamepad in Block mode,
so Steam cannot read it. Restart InputPlumber before switching, and return to
the session recorded by os-session-select instead of hardcoding 'steam' so
the autologin config is preserved.
This commit is contained in:
Jose Falanga 2026-08-07 16:17:55 -03:00
parent 6beb8c79c5
commit 769285f28a
2 changed files with 52 additions and 6 deletions

View file

@ -12,6 +12,20 @@ const POWER_MENU_GROUP := "power_menu"
const BUTTON_NAME := "SwitchToSteamButton"
const MAX_ATTEMPTS := 600
# ChimeraOS records the session that was active before OpenGamepadUI took over
# in this file when the OpenGamepadUI session is entered. We return to that
# session instead of hardcoding a name so the autologin config is not mangled.
const RETURN_SESSION_FILE := "/.config/chimeraos-session-return"
const DEFAULT_RETURN_SESSION := "gamescope-session-steam-plus"
# Sessions os-session-select can be told to return to (matching the values it
# writes to the return-session file).
const RETURN_SESSIONS := [
"gamescope-session-steam-plus",
"gamescope-session-steam",
"gamescope-session-opengamepadui",
]
func _ready() -> void:
logger = Log.get_logger("SessionSwitch", Log.LEVEL.INFO)
@ -52,7 +66,7 @@ func _try_add_button() -> bool:
button.name = BUTTON_NAME
button.set("click_focuses", false)
button.set("text", "Switch to Steam")
button.pressed.connect(_switch_session.bind("steam"))
button.pressed.connect(_switch_session)
container.add_child(button)
container.move_child(button, exit_button.get_index())
@ -70,9 +84,41 @@ func _has_session_switcher() -> bool:
return FileAccess.file_exists(SESSION_SELECT_PATH)
## Switches to the given session using the OS session switcher.
func _switch_session(name: String) -> void:
## Switches back to the session that was active before OpenGamepadUI took
## over, using the OS session switcher.
func _switch_session() -> void:
_restart_inputplumber()
var target := _get_return_session()
var out: Array = []
var code := OS.execute(SESSION_SELECT_PATH, [name], out)
var code := OS.execute(SESSION_SELECT_PATH, [target], out)
if code != OK:
logger.error("Unable to switch sessions: " + out[0])
logger.error("Unable to switch sessions: " + _result_text(out))
## Restarts InputPlumber before switching back so the exclusive OpenGamepadUI
## session does not leave the gamepad intercepted (blocked) for Steam.
## ChimeraOS ships passwordless sudo for exactly this command in its default
## sudoers, so the switch itself remains non-interactive.
func _restart_inputplumber() -> void:
var out: Array = []
var code := OS.execute("sudo", ["-n", "systemctl", "restart", "inputplumber"], out)
if code != OK:
logger.warning("Unable to restart InputPlumber: " + _result_text(out))
## Returns the session recorded by os-session-select before OpenGamepadUI was
## entered, falling back to the ChimeraOS default Steam session.
func _get_return_session() -> String:
var home := OS.get_environment("HOME")
if home.is_empty():
return DEFAULT_RETURN_SESSION
var file := FileAccess.open(home + RETURN_SESSION_FILE, FileAccess.READ)
if file:
var session := file.get_as_text().strip_edges()
if session in RETURN_SESSIONS:
return session
return DEFAULT_RETURN_SESSION
func _result_text(out: Array) -> String:
return out[0] if not out.is_empty() else ""

View file

@ -1,7 +1,7 @@
{
"plugin.id": "session-switch",
"plugin.name": "Session Switch",
"plugin.version": "0.1.0",
"plugin.version": "0.1.1",
"plugin.min-api-version": "1.1.0",
"plugin.link": "https://forge.thergic.ar/jose/steam-button-opengamepadui-plugin",
"plugin.source": "https://forge.thergic.ar/jose/steam-button-opengamepadui-plugin",