Skip to content

Commit 27494e3

Browse files
committed
feat(InputPlumber): Get target device type, keep device default target on first boot
1 parent d7426ac commit 27494e3

12 files changed

Lines changed: 301 additions & 52 deletions

File tree

‎core/global/launch_manager.gd‎

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ func _init() -> void:
185185

186186
in_game_state.state_entered.connect(on_game_state_entered)
187187
in_game_state.state_exited.connect(on_game_state_exited)
188-
set_gamepad_profile("")
189188

190189

191190
# Loads persistent data like recent games launched, etc.
@@ -217,8 +216,12 @@ func setup(input_manager: InputManager):
217216
if not input_manager:
218217
logger.error("No input manager found.")
219218
return
219+
if not is_instance_valid(input_manager):
220+
logger.error("Input Manager instance is not valid")
221+
return
220222

221223
_input_manager = input_manager
224+
set_gamepad_profile("")
222225

223226

224227
## Launches the given application and switches to the in-game state. Returns a
@@ -491,43 +494,47 @@ func set_app_gamepad_profile(app: RunningApp) -> void:
491494

492495

493496
## Sets the gamepad profile for the running app with the given profile
494-
func set_gamepad_profile(path: String, target_gamepad: String = "") -> void:
497+
func set_gamepad_profile(profile_path: String, target_gamepad: String = "") -> void:
495498
# Discover the currently set gamepad to properly add additional capabilities based on that gamepad
496-
var profile_modifier := target_gamepad
497499
if target_gamepad.is_empty():
498-
profile_modifier = settings_manager.get_value("input", "gamepad_profile_target", "gamepad") as String
500+
# First, find the currently set gamepad on the composite device
501+
for device: CompositeDevice in input_plumber.get_composite_devices():
502+
var targets = device.get_target_devices()
503+
for target in targets:
504+
var target_dbus_path: String = target.get("dbus_path")
505+
if not target_dbus_path.contains("target/gamepad"):
506+
continue
507+
target_gamepad = target.get("device_type")
508+
break
509+
if not target_gamepad.is_empty():
510+
break
511+
# Then, if overriden by settings, use that instead
512+
target_gamepad = settings_manager.get_value("input", "gamepad_profile_target", target_gamepad) as String
499513

500514
# If no profile was specified, unset the gamepad profiles
501-
if path == "":
515+
if profile_path == "":
502516
# Get the input manager default path
503-
var default_path = ""
504-
if _input_manager:
505-
default_path = _input_manager.get_default_global_profile_path()
517+
if is_instance_valid(_input_manager):
518+
profile_path = _input_manager.get_default_global_profile_path()
506519

507520
# Try check to see if there is a global gamepad setting
508-
path = settings_manager.get_value("input", "gamepad_profile", default_path) as String
521+
profile_path = settings_manager.get_value("input", "gamepad_profile", profile_path) as String
509522

510523
# Verify can load a valid profile, or fallback.
511-
if not path.ends_with(".json") or not FileAccess.file_exists(path):
512-
if default_path == "":
513-
logger.warn("Unable to set default gamepad profile path from input manager.")
524+
if not profile_path.ends_with(".json") or not FileAccess.file_exists(profile_path):
525+
logger.warn("Profile path is not valid: \"" + profile_path + "\"")
514526
return
515-
path = default_path
516-
517-
logger.info("Loading gamepad profile: " + path)
518-
if not FileAccess.file_exists(path):
519-
logger.warn("Gamepad profile not found: " + path)
520-
return
521527

522528
# Load the profile to get its name
523-
var profile := InputPlumberProfile.load(path)
529+
logger.info("Loading gamepad profile: " + profile_path)
530+
var profile := InputPlumberProfile.load(profile_path)
524531
if not profile:
525-
logger.warn("Failed to load gamepad profile: " + path)
532+
logger.warn("Failed to load gamepad profile: " + profile_path)
526533
return
527534

528535
# TODO: Save profiles for individual controllers?
529536
for gamepad in input_plumber.get_composite_devices():
530-
InputPlumber.load_target_modified_profile(gamepad, path, profile_modifier)
537+
InputPlumber.load_target_modified_profile(gamepad, profile_path, target_gamepad)
531538

532539
# Set the target gamepad if one was specified
533540
if not target_gamepad.is_empty():

‎core/systems/input/input_plumber_profile.gd‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ static func get_target_device(target_device_str: String) -> TargetDevice:
140140
target_device = TargetDevice.DualSense
141141
"ds5-edge":
142142
target_device = TargetDevice.DualSenseEdge
143+
"deck":
144+
target_device = TargetDevice.SteamDeck
143145
"deck-uhid":
144146
target_device = TargetDevice.SteamDeck
145147
"hori-steam":

‎core/ui/card_ui/card_ui.tscn‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ grow_horizontal = 2
9494
grow_vertical = 2
9595
script = ExtResource("1_f8851")
9696

97+
[node name="InputManager" parent="." instance=ExtResource("1_34t85")]
98+
9799
[node name="InputIconProcessor" type="Node" parent="."]
98100
script = ExtResource("3_y116l")
99101

@@ -369,8 +371,6 @@ grow_vertical = 2
369371
stream = ExtResource("21_s3peg")
370372
autoplay = true
371373

372-
[node name="InputManager" parent="." instance=ExtResource("1_34t85")]
373-
374374
[node name="PowerSaver" parent="." instance=ExtResource("8_hyc1j")]
375375

376376
[editable path="AlwaysVisibleContent/OnScreenKeyboard"]

‎core/ui/card_ui/gamepad/gamepad_settings.gd‎

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ extends Control
22

33
const USER_TEMPLATES := "user://data/gamepad/templates"
44
const USER_PROFILES := "user://data/gamepad/profiles"
5-
const GLOBAL_PROFILE_PATH := "user://data/gamepad/profiles/global.json"
65

76
var change_input_state := preload("res://assets/state/states/gamepad_change_input.tres") as State
87
var gamepad_state := load("res://assets/state/states/gamepad_settings.tres") as State
@@ -74,8 +73,16 @@ func _ready() -> void:
7473
# Load the default profile
7574
var profile_path = settings_manager.get_value("input", "gamepad_profile", "")
7675
self.profile_gamepad = settings_manager.get_value("input", "gamepad_profile_target", "")
77-
for composite_device in input_plumber.get_composite_devices():
78-
_set_gamepad_profile(composite_device, profile_path)
76+
if not self.profile_gamepad:
77+
# Set the current profile_gamepad type to the currently configured CompositeDevice target gamepad
78+
var targets = gamepad.get_target_devices()
79+
for target in targets:
80+
var target_dbus_path: String = target.get("dbus_path")
81+
if not target_dbus_path.contains("target/gamepad"):
82+
continue
83+
self.profile_gamepad = target.get("device_type")
84+
break
85+
_set_gamepad_profile(gamepad, profile_path)
7986

8087
# Grab focus when the mapper exits
8188
var on_state_changed := func(_from: State, to: State):
@@ -131,7 +138,7 @@ func _on_state_entered(_from: State) -> void:
131138

132139
# Set the gamepad name label
133140
gamepad_label.text = self.gamepad.name
134-
141+
135142
# Populate the menu with the source inputs for the given gamepad
136143
populate_mappings_for(self.gamepad)
137144

@@ -146,17 +153,31 @@ func _on_state_entered(_from: State) -> void:
146153
if not self.library_item:
147154
self.library_item = launch_manager.get_current_app_library_item()
148155

156+
# Set the current profile_gamepad type to the currently configured CompositeDevice target gamepad
157+
var targets = gamepad.get_target_devices()
158+
for target in targets:
159+
var target_dbus_path: String = target.get("dbus_path")
160+
if not target_dbus_path.contains("target/gamepad"):
161+
continue
162+
self.profile_gamepad = target.get("device_type")
163+
break
164+
149165
# If no library item was set with the state, then configure the OGUI profile
150166
var profile_path: String
151167
if not self.library_item:
152168
self.profile_label.text = "Global"
153169
profile_path = settings_manager.get_value("input", "gamepad_profile", input_manager.get_default_global_profile_path()) as String
170+
# Check if we have a profile target, otherwise use the currently set one
171+
self.profile_gamepad = settings_manager.get_value("input", "gamepad_profile_target", self.profile_gamepad)
154172
else:
155173
self.profile_label.text = self.library_item.name
156174
profile_path = settings_manager.get_library_value(self.library_item, "gamepad_profile", "") as String
157-
self.profile_gamepad = settings_manager.get_library_value(self.library_item, "gamepad_profile_target", "") as String
175+
# Check if we have a profile target, otherwise use the currently set one
176+
self.profile_gamepad = settings_manager.get_library_value(self.library_item, "gamepad_profile_target", self.profile_gamepad) as String
158177

159178
self.profile = _load_profile(profile_path)
179+
logger.debug("Set profile target gamepad to " + self.profile_gamepad)
180+
160181
_update_mapping_elements()
161182

162183
# Clear focus
@@ -196,7 +217,7 @@ func populate_mappings_for(gamepad: CompositeDevice) -> void:
196217
# Sort the capabilities
197218
capabilities = InputPlumberEvent.sort_capabilities(capabilities)
198219
capabilities.reverse()
199-
logger.debug("Found capabilities for gamepad: " + str(capabilities))
220+
logger.debug("Found capabilities for " + gamepad_name + ": " + str(capabilities))
200221

201222
# Delete any old UI elements
202223
for child in container.get_children():
@@ -390,9 +411,10 @@ func _add_group_for_capability(gamepad_name: String, capability: String, parent:
390411

391412
## Syncs the UI to the given profile
392413
func _update_mapping_elements() -> void:
393-
if not profile:
414+
if not self.profile:
394415
return
395-
profile_label.text = profile.name
416+
417+
self.profile_label.text = self.profile.name
396418

397419
# Update the dropdown based on the profile's target gamepad type
398420
if not self.profile_gamepad.is_empty():
@@ -634,7 +656,7 @@ func _save_profile() -> void:
634656
logger.debug("No library item loaded to associate profile with")
635657
# Save the profile
636658
@warning_ignore("confusable_local_declaration")
637-
var path := GLOBAL_PROFILE_PATH
659+
var path := input_manager.get_default_global_profile_path()
638660
if profile.save(path) != OK:
639661
logger.error("Failed to save global gamepad profile to: " + path)
640662
notify.text = "Failed to save global gamepad profile"
@@ -646,8 +668,8 @@ func _save_profile() -> void:
646668
settings_manager.set_value("input", "gamepad_profile", path)
647669
settings_manager.set_value("input", "gamepad_profile_target", self.profile_gamepad)
648670

649-
for gamepad in input_plumber.get_composite_devices():
650-
_set_gamepad_profile(gamepad, path)
671+
for device: CompositeDevice in input_plumber.get_composite_devices():
672+
_set_gamepad_profile(device, path)
651673

652674
logger.debug("Saved global gamepad profile to: " + path)
653675
notify.text = "Global gamepad profile saved"

‎core/ui/card_ui_overlay_mode/card_ui_overlay_mode.tscn‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ grow_vertical = 2
2727
theme = ExtResource("1_0qmlq")
2828
script = ExtResource("2_3ptao")
2929

30+
[node name="InputManager" parent="." instance=ExtResource("3_klhmb")]
31+
3032
[node name="InputIconProcessor" type="Node" parent="."]
3133
script = ExtResource("4_6rltg")
3234

@@ -94,5 +96,3 @@ anchor_right = 0.5
9496
anchor_bottom = 0.5
9597
grow_horizontal = 2
9698
grow_vertical = 2
97-
98-
[node name="InputManager" parent="." instance=ExtResource("3_klhmb")]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
pub mod composite_device;
22
pub mod dbus_device;
33
pub mod event_device;
4+
pub mod gamepad;
45
pub mod input_manager;
56
pub mod keyboard;
67
pub mod mouse;
8+
pub mod target;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//! # D-Bus interface proxy for: `org.shadowblip.Input.Gamepad`
2+
//!
3+
//! This code was generated by `zbus-xmlgen` `4.1.0` from D-Bus introspection data.
4+
//! Source: `Interface '/org/shadowblip/InputPlumber/devices/target/gamepad0' from service 'org.shadowblip.InputPlumber' on system bus`.
5+
//!
6+
//! You may prefer to adapt it, instead of using it verbatim.
7+
//!
8+
//! More information can be found in the [Writing a client proxy] section of the zbus
9+
//! documentation.
10+
//!
11+
//! This type implements the [D-Bus standard interfaces], (`org.freedesktop.DBus.*`) for which the
12+
//! following zbus API can be used:
13+
//!
14+
//! * [`zbus::fdo::PeerProxy`]
15+
//! * [`zbus::fdo::PropertiesProxy`]
16+
//! * [`zbus::fdo::IntrospectableProxy`]
17+
//!
18+
//! Consequently `zbus-xmlgen` did not generate code for the above interfaces.
19+
//!
20+
//! [Writing a client proxy]: https://dbus2.github.io/zbus/client.html
21+
//! [D-Bus standard interfaces]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces,
22+
use zbus::proxy;
23+
#[proxy(
24+
interface = "org.shadowblip.Input.Target",
25+
default_service = "org.shadowblip.InputPlumber",
26+
default_path = "/org/shadowblip/InputPlumber/devices/target/gamepad0"
27+
)]
28+
pub trait Target {
29+
/// Name property
30+
#[zbus(property)]
31+
fn name(&self) -> zbus::Result<String>;
32+
33+
/// Name property
34+
#[zbus(property)]
35+
fn device_type(&self) -> zbus::Result<String>;
36+
}

‎extensions/core/src/input/inputplumber.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod composite_device;
22
pub mod dbus_device;
33
pub mod event_device;
4+
pub mod gamepad_device;
45
pub mod keyboard_device;
56
pub mod mouse_device;
67

‎extensions/core/src/input/inputplumber/composite_device.rs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use godot::classes::{ProjectSettings, Resource, ResourceLoader};
55
use crate::dbus::inputplumber::composite_device::CompositeDeviceProxyBlocking;
66
use crate::dbus::DBusVariant;
77
use crate::get_dbus_system_blocking;
8+
use crate::input::inputplumber::gamepad_device::GamepadDevice;
89

910
use super::dbus_device::DBusDevice;
1011
use super::keyboard_device::KeyboardDevice;
@@ -237,7 +238,8 @@ impl CompositeDevice {
237238
// Build the Godot object based on the path
238239
for path in values {
239240
if path.contains("gamepad") {
240-
// TODO
241+
let device = GamepadDevice::new(path.as_str());
242+
target_devices.push(&device.to_variant());
241243
continue;
242244
}
243245
if path.contains("keyboard") {

0 commit comments

Comments
 (0)