diff --git a/plugin.gd b/plugin.gd index caab25b..d8f87e1 100644 --- a/plugin.gd +++ b/plugin.gd @@ -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 "" diff --git a/plugin.json b/plugin.json index 8903dc9..8e11f49 100644 --- a/plugin.json +++ b/plugin.json @@ -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",