From 9822fc3b1c66cd097947da07538bd2c77c82cbdb Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Mon, 13 Jul 2026 07:49:38 +0200 Subject: [PATCH] fix(windows): drop the orphaned in-process gamepad forwarding hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removing the builtin stream path (ef580825) left GamepadService's attach/detach/ active/auto_pref + the Ctl::Attach/Detach variants with no callers — the spawned punktfunk-session binary owns pad forwarding now. The client still compiled, but clippy -D warnings tripped on the dead code. Drop the forwarding hooks + the active-pad mirror; the service keeps pads() (Settings list) and set_pinned() (persist the forwarded-pad selection the session child reads). Co-Authored-By: Claude Opus 4.8 (1M context) --- clients/windows/src/gamepad.rs | 52 ++++------------------------------ 1 file changed, 6 insertions(+), 46 deletions(-) diff --git a/clients/windows/src/gamepad.rs b/clients/windows/src/gamepad.rs index 3fb1c5b6..3a957c01 100644 --- a/clients/windows/src/gamepad.rs +++ b/clients/windows/src/gamepad.rs @@ -74,30 +74,26 @@ fn pref_for_type(t: sdl3::gamepad::GamepadType) -> GamepadPref { } enum Ctl { - Attach(Arc), - Detach, Pin(Option), } #[derive(Clone)] pub struct GamepadService { pads: Arc>>, - active: Arc>>, // `Arc>` (not a bare `Sender`, which is `!Sync`) so the service is `Sync` — the - // WinUI app shares it across the UI thread and the session-pump thread (attach/detach). + // WinUI app shares it across the UI thread and the settings-pin path. ctl: Arc>>, } impl GamepadService { pub fn start() -> GamepadService { let pads = Arc::new(Mutex::new(Vec::new())); - let active = Arc::new(Mutex::new(None)); let (ctl, ctl_rx) = std::sync::mpsc::channel(); - let (p, a) = (pads.clone(), active.clone()); + let p = pads.clone(); if let Err(e) = std::thread::Builder::new() .name("punktfunk-gamepad".into()) .spawn(move || { - if let Err(e) = run(&p, &a, &ctl_rx) { + if let Err(e) = run(&p, &ctl_rx) { tracing::warn!(error = %e, "gamepad service ended — pads disabled"); } }) @@ -106,7 +102,6 @@ impl GamepadService { } GamepadService { pads, - active, ctl: Arc::new(Mutex::new(ctl)), } } @@ -116,33 +111,13 @@ impl GamepadService { self.pads.lock().unwrap().clone() } - pub fn active(&self) -> Option { - self.active.lock().unwrap().clone() - } - /// Pin the forwarded controller by stable key (`PadInfo::key`) — `None` = automatic. /// The pin survives the pad disconnecting: it re-applies the moment a matching - /// controller shows up again (same semantics as `pf-client-core`'s service). + /// controller shows up again (same semantics as `pf-client-core`'s service). The spawned + /// `punktfunk-session` binary owns the actual forwarding; this persists the selection. pub fn set_pinned(&self, key: Option) { let _ = self.ctl.lock().unwrap().send(Ctl::Pin(key)); } - - pub fn attach(&self, connector: Arc) { - let _ = self.ctl.lock().unwrap().send(Ctl::Attach(connector)); - } - - pub fn detach(&self) { - let _ = self.ctl.lock().unwrap().send(Ctl::Detach); - } - - /// What "Automatic" resolves to right now — the virtual pad matching the physical one - /// (Swift parity); no pad connected leaves the host's own default. - pub fn auto_pref(&self) -> GamepadPref { - match self.active() { - Some(p) => p.pref, - None => GamepadPref::Auto, - } - } } fn send(connector: &NativeClient, kind: InputKind, code: u32, x: i32) { @@ -404,11 +379,7 @@ impl Worker { } #[allow(clippy::too_many_lines)] -fn run( - pads_out: &Mutex>, - active_out: &Mutex>, - ctl: &Receiver, -) -> Result<(), String> { +fn run(pads_out: &Mutex>, ctl: &Receiver) -> Result<(), String> { // Off-main-thread + no video subsystem: keep SDL away from signals, poll pads on its own // thread. sdl3::hint::set("SDL_NO_SIGNAL_HANDLERS", "1"); @@ -437,23 +408,12 @@ fn run( let mut list: Vec = w.order.iter().filter_map(|&id| w.pad_info(id)).collect(); list.reverse(); // most recent first — the Settings list order *pads_out.lock().unwrap() = list; - *active_out.lock().unwrap() = w.active_id().and_then(|id| w.pad_info(id)); }; loop { // Control plane from the UI thread. loop { match ctl.try_recv() { - Ok(Ctl::Attach(c)) => { - w.attached = Some(c); - w.last_axis = [i32::MIN; 6]; - w.set_sensors(true); - } - Ok(Ctl::Detach) => { - w.flush_held(); - w.set_sensors(false); - w.attached = None; - } Ok(Ctl::Pin(key)) => { let before = w.active_id(); w.pinned = key;