Add Session Switch plugin: 'Switch to Steam' power menu button for OpenGamepadUI
This commit is contained in:
commit
f3ae701000
5 changed files with 205 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
.godot
|
||||||
|
dist
|
||||||
69
Makefile
Normal file
69
Makefile
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
PLUGIN_ID ?= $(shell grep 'plugin\.id' plugin.json | grep -o ':.*' | grep -o '"[^"]\+"' | sed 's/"//g')
|
||||||
|
PLUGIN_NAME ?= $(shell grep 'plugin\.name' plugin.json | grep -o ':.*' | grep -o '"[^"]\+"' | sed 's/"//g')
|
||||||
|
|
||||||
|
GODOT ?= /usr/bin/godot
|
||||||
|
OPENGAMEPAD_UI_REPO ?= https://github.com/ShadowBlip/OpenGamepadUI.git
|
||||||
|
OPENGAMEPAD_UI_BASE ?= ../OpenGamepadUI
|
||||||
|
EXPORT_PRESETS ?= $(OPENGAMEPAD_UI_BASE)/export_presets.cfg
|
||||||
|
PLUGINS_DIR := $(OPENGAMEPAD_UI_BASE)/plugins
|
||||||
|
BUILD_DIR := $(OPENGAMEPAD_UI_BASE)/build
|
||||||
|
INSTALL_DIR := $(HOME)/.local/share/opengamepadui/plugins
|
||||||
|
|
||||||
|
##@ General
|
||||||
|
|
||||||
|
# The help target prints out all targets with their descriptions organized
|
||||||
|
# beneath their categories. The categories are represented by '##@' and the
|
||||||
|
# target descriptions by '##'. The awk commands is responsible for reading the
|
||||||
|
# entire set of makefiles included in this invocation, looking for lines of the
|
||||||
|
# file as xyz: ## something, and then pretty-format the target and help. Then,
|
||||||
|
# if there's a line with ##@ something, that gets pretty-printed as a category.
|
||||||
|
# More info on the usage of ANSI control characters for terminal formatting:
|
||||||
|
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
|
||||||
|
# More info on the awk command:
|
||||||
|
# http://linuxcommand.org/lc3_adv_awk.php
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help: ## Display this help.
|
||||||
|
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
|
##@ Development
|
||||||
|
|
||||||
|
.PHONY: dist
|
||||||
|
dist: build ## Build and package plugin
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build: $(PLUGINS_DIR)/$(PLUGIN_ID) export_preset ## Build the plugin
|
||||||
|
@echo "Exporting plugin package"
|
||||||
|
cd $(OPENGAMEPAD_UI_BASE) && $(MAKE) addons
|
||||||
|
mkdir -p dist
|
||||||
|
touch dist/.gdignore
|
||||||
|
$(GODOT) --headless \
|
||||||
|
--path $(OPENGAMEPAD_UI_BASE) \
|
||||||
|
--export-pack "$(PLUGIN_NAME)" \
|
||||||
|
plugins/$(PLUGIN_ID)/dist/$(PLUGIN_ID).zip
|
||||||
|
cd dist && sha256sum $(PLUGIN_ID).zip > $(PLUGIN_ID).zip.sha256.txt
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install: dist ## Installs the plugin
|
||||||
|
mkdir -p "$(INSTALL_DIR)"
|
||||||
|
cp -r dist/* "$(INSTALL_DIR)"
|
||||||
|
rm -rf $(INSTALL_DIR)/$(PLUGIN_ID)
|
||||||
|
@echo "Installed plugin to $(INSTALL_DIR)"
|
||||||
|
|
||||||
|
$(OPENGAMEPAD_UI_BASE):
|
||||||
|
git clone $(OPENGAMEPAD_UI_REPO) $@
|
||||||
|
|
||||||
|
$(PLUGINS_DIR)/$(PLUGIN_ID): $(OPENGAMEPAD_UI_BASE)
|
||||||
|
if ! [ -L $(PLUGINS_DIR)/$(PLUGIN_ID) ]; then ln -s $(PWD) $(PLUGINS_DIR)/$(PLUGIN_ID); fi
|
||||||
|
|
||||||
|
.PHONY: export_preset
|
||||||
|
export_preset: $(OPENGAMEPAD_UI_BASE) ## Configure plugin export preset
|
||||||
|
$(eval LAST_PRESET=$(shell grep -oEi '^\[preset\.([0-9]+)]' $(EXPORT_PRESETS) | tail -n 1))
|
||||||
|
$(eval LAST_PRESET_NUM=$(shell echo "$(LAST_PRESET)" | grep -oE '([0-9]+)'))
|
||||||
|
$(eval PRESET_NUM=$(shell echo "$(LAST_PRESET_NUM)+1" | bc))
|
||||||
|
@if grep 'name="$(PLUGIN_NAME)"' $(EXPORT_PRESETS) > /dev/null; then \
|
||||||
|
echo "Export preset already configured"; \
|
||||||
|
else \
|
||||||
|
echo "Preset not configured"; \
|
||||||
|
sed 's/PRESET_NUM/$(PRESET_NUM)/g; s/PLUGIN_NAME/$(PLUGIN_NAME)/g; s/PLUGIN_ID/$(PLUGIN_ID)/g' export_presets.cfg >> $(EXPORT_PRESETS); \
|
||||||
|
fi
|
||||||
42
export_presets.cfg
Normal file
42
export_presets.cfg
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
[preset.PRESET_NUM]
|
||||||
|
|
||||||
|
name="PLUGIN_NAME"
|
||||||
|
platform="Linux/X11"
|
||||||
|
runnable=false
|
||||||
|
dedicated_server=false
|
||||||
|
custom_features=""
|
||||||
|
export_filter="resources"
|
||||||
|
export_files=PackedStringArray()
|
||||||
|
include_filter="plugins/PLUGIN_ID/*"
|
||||||
|
exclude_filter="addons/*"
|
||||||
|
export_path="build/PLUGIN_ID.x86_64"
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
script_encryption_key=""
|
||||||
|
|
||||||
|
[preset.PRESET_NUM.options]
|
||||||
|
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
debug/export_console_script=1
|
||||||
|
binary_format/embed_pck=false
|
||||||
|
texture_format/bptc=true
|
||||||
|
texture_format/s3tc=true
|
||||||
|
texture_format/etc=false
|
||||||
|
texture_format/etc2=false
|
||||||
|
binary_format/architecture="x86_64"
|
||||||
|
ssh_remote_deploy/enabled=false
|
||||||
|
ssh_remote_deploy/host="user@host_ip"
|
||||||
|
ssh_remote_deploy/port="22"
|
||||||
|
ssh_remote_deploy/extra_args_ssh=""
|
||||||
|
ssh_remote_deploy/extra_args_scp=""
|
||||||
|
ssh_remote_deploy/run_script="#!/usr/bin/env bash
|
||||||
|
export DISPLAY=:0
|
||||||
|
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
|
||||||
|
\"{temp_dir}/{exe_name}\" {cmd_args}"
|
||||||
|
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
|
||||||
|
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
|
||||||
|
rm -rf \"{temp_dir}\""
|
||||||
78
plugin.gd
Normal file
78
plugin.gd
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
extends Plugin
|
||||||
|
|
||||||
|
## Adds a "Switch to Steam" button to the power menu on ChimeraOS and SteamOS.
|
||||||
|
##
|
||||||
|
## OpenGamepadUI's built-in ChimeraOS platform support adds a "Switch to
|
||||||
|
## Desktop" button but has no way to return to Steam game mode. This plugin
|
||||||
|
## adds that missing button so users can round-trip between an exclusive
|
||||||
|
## OpenGamepadUI session and Steam.
|
||||||
|
|
||||||
|
const SESSION_SELECT_PATH := "/usr/lib/os-session-select"
|
||||||
|
const POWER_MENU_GROUP := "power_menu"
|
||||||
|
const BUTTON_NAME := "SwitchToSteamButton"
|
||||||
|
const MAX_ATTEMPTS := 600
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
logger = Log.get_logger("SessionSwitch", Log.LEVEL.INFO)
|
||||||
|
if not _has_session_switcher():
|
||||||
|
logger.info("No session switcher script detected: " + SESSION_SELECT_PATH)
|
||||||
|
return
|
||||||
|
_add_button_when_ready()
|
||||||
|
|
||||||
|
|
||||||
|
func _add_button_when_ready() -> void:
|
||||||
|
for i in MAX_ATTEMPTS:
|
||||||
|
if _try_add_button():
|
||||||
|
return
|
||||||
|
await get_tree().process_frame
|
||||||
|
logger.info("Power menu never became available. Skipping 'Switch to Steam' button.")
|
||||||
|
|
||||||
|
|
||||||
|
func _try_add_button() -> bool:
|
||||||
|
var power_menu := get_tree().get_first_node_in_group(POWER_MENU_GROUP)
|
||||||
|
if not power_menu:
|
||||||
|
return false
|
||||||
|
|
||||||
|
var exit_button = power_menu.get("exit_button")
|
||||||
|
if not exit_button:
|
||||||
|
return false
|
||||||
|
|
||||||
|
var container = exit_button.get_parent()
|
||||||
|
if not container:
|
||||||
|
return false
|
||||||
|
if container.has_node(BUTTON_NAME):
|
||||||
|
return true
|
||||||
|
|
||||||
|
var button_scene := load("res://core/ui/components/card_button.tscn") as PackedScene
|
||||||
|
if not button_scene:
|
||||||
|
logger.error("Unable to load card_button scene.")
|
||||||
|
return true
|
||||||
|
var button := button_scene.instantiate()
|
||||||
|
button.name = BUTTON_NAME
|
||||||
|
button.set("click_focuses", false)
|
||||||
|
button.set("text", "Switch to Steam")
|
||||||
|
button.pressed.connect(_switch_session.bind("steam"))
|
||||||
|
|
||||||
|
container.add_child(button)
|
||||||
|
container.move_child(button, exit_button.get_index())
|
||||||
|
|
||||||
|
var focus_group = power_menu.get("focus_group")
|
||||||
|
if focus_group and focus_group.has_method("recalculate_focus"):
|
||||||
|
focus_group.recalculate_focus()
|
||||||
|
|
||||||
|
logger.info("Added 'Switch to Steam' button to the power menu.")
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
## Returns true if the session switcher script is present.
|
||||||
|
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:
|
||||||
|
var out: Array = []
|
||||||
|
var code := OS.execute(SESSION_SELECT_PATH, [name], out)
|
||||||
|
if code != OK:
|
||||||
|
logger.error("Unable to switch sessions: " + out[0])
|
||||||
14
plugin.json
Normal file
14
plugin.json
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"plugin.id": "session-switch",
|
||||||
|
"plugin.name": "Session Switch",
|
||||||
|
"plugin.version": "0.1.0",
|
||||||
|
"plugin.min-api-version": "1.1.0",
|
||||||
|
"plugin.link": "https://github.com/YOUR_USERNAME/session-switch",
|
||||||
|
"plugin.source": "https://github.com/YOUR_USERNAME/session-switch",
|
||||||
|
"plugin.description": "Adds a 'Switch to Steam' button to the power menu so OpenGamepadUI can return to Steam game mode on ChimeraOS and SteamOS.",
|
||||||
|
"store.tags": [],
|
||||||
|
"store.images": [],
|
||||||
|
"author.name": "First Last",
|
||||||
|
"author.email": "person@example.com",
|
||||||
|
"entrypoint": "plugin.gd"
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue