From b009e210a3188971692270955429e7a320311939 Mon Sep 17 00:00:00 2001 From: "Derek J. Clark" Date: Thu, 30 Mar 2023 19:47:44 -0700 Subject: [PATCH] feat(qam-only): Move OGUI Steam from OS call to InteractiveProcess (#92) * Make Steam an InterativeProcess * Add output_to_log_file to InteractiveProcess. * Use SharedThread to write to log file for Steam log. --- core/only_qam.gd | 32 ++++++++++++++------ core/systems/launcher/interactive_process.gd | 19 ++++++++++++ 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/core/only_qam.gd b/core/only_qam.gd index 8d7d444f..51884ce3 100644 --- a/core/only_qam.gd +++ b/core/only_qam.gd @@ -8,6 +8,9 @@ var qam_state = load("res://assets/state/states/quick_access_menu.tres") var display := Gamescope.XWAYLAND.OGUI var qam_window_id: int var pid: int +var shared_thread: SharedThread +var steam_log: FileAccess +var steam_process: InteractiveProcess var steam_window_id: int var logger := Log.get_logger("OQMain", Log.LEVEL.INFO) @@ -24,11 +27,20 @@ func _init(): ## Starts the --only-qam/--qam-only session. func _ready() -> void: + shared_thread = SharedThread.new() + shared_thread.start() # Set window size to native resolution var screen_size : Vector2i = DisplayServer.screen_get_size() var window : Window = get_window() window.set_size(screen_size) + var steam_log_path = OS.get_environment("HOME") + "/.steam-stdout.log" + steam_log = FileAccess.open(steam_log_path, FileAccess.WRITE) + var error := steam_log.get_open_error() + if error != OK: + logger.warn("Got error opening log file.") + else: + logger.debug("Opened Steam log at " + steam_log_path) # Get user arguments var args := OS.get_cmdline_user_args() _setup_qam_only(args) @@ -55,24 +67,24 @@ func _setup_qam_only(args: Array) -> void: # Don't crash if we're not launching another program. if args == []: - print("Nothing to do") + logger.warn("only-qam mode started with no launcher arguments.") return # Launch underlay in the sandbox var sandbox := PackedStringArray() - sandbox.append_array(["firejail", "--noprofile"]) + sandbox.append_array(["--noprofile"]) var blacklist := InputManager.get_managed_gamepads() for device in blacklist: sandbox.append("--blacklist=%s" % device) sandbox.append("--") sandbox.append_array(args) - sandbox.append_array([">", "~/.steam-stdout.log"]) - var sandbox_cmd = " ".join(sandbox) - print("Sandbox cmd: ", sandbox_cmd) - OS.create_process("bash", ["-c", sandbox_cmd]) - + steam_process = InteractiveProcess.new("firejail", sandbox) + if steam_process.start() != OK: + logger.error("Failed to start steam process.") if not "steam" in args: return - + var logger_func := func(delta: float): + steam_process.output_to_log_file(steam_log) + shared_thread.add_process(logger_func) # Look for steam while not steam_window_id: @@ -84,7 +96,7 @@ func _setup_qam_only(args: Array) -> void: continue if Gamescope.has_xprop(window, "STEAM_OVERLAY", display): steam_window_id = window - print("Found steam! ", steam_window_id) + logger.debug("Found steam! " + str(steam_window_id)) break # Wait a bit to reduce cpu load. OS.delay_msec(1000) @@ -113,5 +125,5 @@ func _on_qam_closed(_to: State) -> void: func _check_exit() -> void: if Gamescope.has_xprop(steam_window_id, "STEAM_OVERLAY", display): return - print("Steam closed. Shutting down.") + logger.debug("Steam closed. Shutting down.") get_tree().quit() diff --git a/core/systems/launcher/interactive_process.gd b/core/systems/launcher/interactive_process.gd index 12aee0bf..14c44eb9 100644 --- a/core/systems/launcher/interactive_process.gd +++ b/core/systems/launcher/interactive_process.gd @@ -62,3 +62,22 @@ func stop() -> void: logger.debug("Stopping pid: " + str(pid)) OS.kill(pid) pty = null + + +func output_to_log_file(log_file: FileAccess, chunk_size: int = 1024) -> int: + if not log_file: + logger.warn("Unable to log output. Log file has not been opened.") + return ERR_FILE_CANT_OPEN + # Keep reading from the process until the buffer is empty + if not pty: + logger.warn("Unable to read from closed PTY") + return ERR_DOES_NOT_EXIST + + # Keep reading from the process until the buffer is empty + var buffer := pty.read(chunk_size) + while buffer.size() != 0: + log_file.store_buffer(buffer) + buffer = pty.read(chunk_size) + + log_file.flush() + return OK