-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathmain.gd
161 lines (128 loc) · 5.26 KB
/
main.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
extends Control
class_name Main
const Platform := preload("res://core/global/platform.tres")
const Gamescope := preload("res://core/global/gamescope.tres")
const LibraryManager := preload("res://core/global/library_manager.tres")
var PID: int = OS.get_process_id()
var overlay_window_id = Gamescope.get_window_id(PID, Gamescope.XWAYLAND.OGUI)
var state_machine := (
preload("res://assets/state/state_machines/global_state_machine.tres") as StateMachine
)
var home_state := preload("res://assets/state/states/home.tres") as State
var in_game_state := preload("res://assets/state/states/in_game.tres") as State
var osk_state := preload("res://assets/state/states/osk.tres") as State
var power_state := load("res://assets/state/states/power_menu.tres") as State
var logger = Log.get_logger("Main", Log.LEVEL.DEBUG)
@onready var ui_container := $UIContainer
@onready var fade_transition := $%FadeTransitionPlayer
@onready var fade_texture := $FadeTexture
@onready var boot_video := $%BootVideoPlayer
@onready var power_timer := $%PowerTimer
func _init() -> void:
# Tell gamescope that we're an overlay
if overlay_window_id < 0:
logger.error("Unable to detect Window ID. Overlay is not going to work!")
logger.debug("Found primary window id: {0}".format([overlay_window_id]))
_setup(overlay_window_id)
# Lets us run as an overlay in gamescope
func _setup(window_id: int) -> void:
if window_id < 0:
logger.error("Unable to configure gamescope atoms")
return
# Pretend to be Steam
# Gamescope is hard-coded to look for appId 769
if Gamescope.set_main_app(window_id) != OK:
logger.error("Unable to set STEAM_GAME atom!")
# Sets ourselves to the input focus
if Gamescope.set_input_focus(window_id, 1) != OK:
logger.error("Unable to set STEAM_INPUT_FOCUS atom!")
# Called when the node enters the scene tree for the first time.
# gamescope --xwayland-count 2 -- build/opengamepad-ui.x86_64
func _ready() -> void:
# Set bg to transparent
get_tree().get_root().transparent_bg = true
fade_texture.visible = true
# Load any platform-specific logic
Platform.load(get_tree().get_root())
# Initialize the state machine with its initial state
state_machine.push_state(home_state)
state_machine.state_changed.connect(_on_state_changed)
# Show/hide the overlay when we enter/exit the in-game state
in_game_state.state_entered.connect(_on_game_state_entered)
in_game_state.state_exited.connect(_on_game_state_exited)
in_game_state.state_removed.connect(_on_game_state_removed)
get_viewport().gui_focus_changed.connect(_on_focus_changed)
LibraryManager.reload_library()
func _on_focus_changed(control: Control) -> void:
if control != null:
logger.debug("Focus changed to: " + control.get_parent().name + " | " + control.name)
# Always push the home state if we end up with an empty stack.
func _on_state_changed(_from: State, _to: State) -> void:
if state_machine.stack_length() == 0:
state_machine.push_state.call_deferred(home_state)
func _on_game_state_entered(_from: State) -> void:
_set_overlay(false)
_set_blur(Gamescope.BLUR_MODE.OFF)
for child in ui_container.get_children():
child.visible = false
func _on_game_state_exited(to: State) -> void:
if state_machine.has_state(in_game_state):
_set_overlay(true)
if to != osk_state:
_set_blur(Gamescope.BLUR_MODE.ALWAYS)
else:
_on_game_state_removed()
for child in ui_container.get_children():
child.visible = true
func _on_game_state_removed() -> void:
_set_overlay(false)
_set_blur(Gamescope.BLUR_MODE.OFF)
# Set overlay will set the Gamescope atom to indicate that we should be drawn
# over a running game or not.
func _set_overlay(enable: bool) -> void:
var overlay_enabled = 0
if enable:
overlay_enabled = 1
# Sometimes setting this may fail when Steam closes. Retry several times.
for try in range(10):
if Gamescope.set_overlay(overlay_window_id, overlay_enabled) != OK:
logger.warn("Unable to set overlay atom!")
var current := Gamescope.get_overlay(overlay_window_id)
if overlay_enabled == current:
break
logger.warn("Retrying in " + str(try) + "ms")
OS.delay_msec(try)
# Sets the blur mode in gamescope
func _set_blur(mode: Gamescope.BLUR_MODE) -> void:
# Sometimes setting this may fail when Steam closes. Retry several times.
for try in range(10):
if Gamescope.set_blur_mode(mode) != OK:
logger.warn("Unable to set blur mode atom!")
var current := Gamescope.get_blur_mode()
if mode == current:
break
logger.warn("Retrying in " + str(try) + "ms")
OS.delay_msec(try)
func _on_boot_video_player_finished() -> void:
fade_transition.play("fade")
boot_video.visible = false
func _input(event: InputEvent) -> void:
if not event.is_action("ogui_power"):
return
# Handle power events
if event.is_action_pressed("ogui_power"):
var open_power_menu := func():
logger.info("Power menu requested")
state_machine.push_state(power_state)
power_timer.timeout.connect(open_power_menu, CONNECT_ONE_SHOT)
power_timer.start()
return
# Handle suspend events
if not power_timer.is_stopped():
logger.info("Received suspend signal")
for connection in power_timer.timeout.get_connections():
power_timer.timeout.disconnect(connection["callable"])
power_timer.stop()
var output: Array = []
if OS.execute("systemctl", ["suspend"], output) != OK:
logger.warn("Failed to suspend: '" + output[0] + "'")