style: cargo fmt --all (rustfmt 1.96.0 drift across the re-arch branch)
`cargo fmt --all --check` (ci.yml) was red on main: the client re-architecture
commits and origin's windows-shortcut commit landed with rustfmt violations
(e.g. a 104-char .with_context line in hyprland.rs, an unsorted mod block in
vdisplay.rs, the input.rs `{`-placement CI flagged). Reformat the tree so the
fmt gate passes; no functional changes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -66,36 +66,37 @@ pub fn run(target: &str) -> u8 {
|
||||
overlay: Some(Box::new(overlay)),
|
||||
};
|
||||
|
||||
let result = pf_presenter::run_browse(opts, |action, gamepad, native, force_software, vulkan| {
|
||||
match action {
|
||||
OverlayAction::Launch { id, title } => {
|
||||
// The carousel only renders for a paired host, so the pin exists; the
|
||||
// guard keeps a logic slip from turning into a pinless connect.
|
||||
let Some(pin) = pin else {
|
||||
tracing::warn!("launch without a stored pin — refusing");
|
||||
return ActionOutcome::Handled;
|
||||
};
|
||||
tracing::info!(%id, %title, "launching from the library");
|
||||
ActionOutcome::Start(Box::new(session_params(
|
||||
&settings,
|
||||
addr.clone(),
|
||||
port,
|
||||
pin,
|
||||
identity.clone(),
|
||||
Some(id),
|
||||
gamepad,
|
||||
native,
|
||||
force_software,
|
||||
vulkan,
|
||||
)))
|
||||
let result =
|
||||
pf_presenter::run_browse(opts, |action, gamepad, native, force_software, vulkan| {
|
||||
match action {
|
||||
OverlayAction::Launch { id, title } => {
|
||||
// The carousel only renders for a paired host, so the pin exists; the
|
||||
// guard keeps a logic slip from turning into a pinless connect.
|
||||
let Some(pin) = pin else {
|
||||
tracing::warn!("launch without a stored pin — refusing");
|
||||
return ActionOutcome::Handled;
|
||||
};
|
||||
tracing::info!(%id, %title, "launching from the library");
|
||||
ActionOutcome::Start(Box::new(session_params(
|
||||
&settings,
|
||||
addr.clone(),
|
||||
port,
|
||||
pin,
|
||||
identity.clone(),
|
||||
Some(id),
|
||||
gamepad,
|
||||
native,
|
||||
force_software,
|
||||
vulkan,
|
||||
)))
|
||||
}
|
||||
OverlayAction::Retry => {
|
||||
spawn_fetch(shared.clone(), addr.clone(), mgmt, identity.clone(), pin);
|
||||
ActionOutcome::Handled
|
||||
}
|
||||
OverlayAction::Quit => ActionOutcome::Quit,
|
||||
}
|
||||
OverlayAction::Retry => {
|
||||
spawn_fetch(shared.clone(), addr.clone(), mgmt, identity.clone(), pin);
|
||||
ActionOutcome::Handled
|
||||
}
|
||||
OverlayAction::Quit => ActionOutcome::Quit,
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(()) => 0,
|
||||
|
||||
@@ -217,7 +217,10 @@ mod session_main {
|
||||
// connects silently; an unknown host is REFUSED — there is no dialog here, and a
|
||||
// silent TOFU would defeat the pinning model. Pair via the desktop client.
|
||||
let known = trust::KnownHosts::load();
|
||||
let known_host = known.hosts.iter().find(|h| h.addr == addr && h.port == port);
|
||||
let known_host = known
|
||||
.hosts
|
||||
.iter()
|
||||
.find(|h| h.addr == addr && h.port == port);
|
||||
let pin = arg_value("--fp")
|
||||
.as_deref()
|
||||
.and_then(trust::parse_hex32)
|
||||
@@ -285,7 +288,10 @@ mod session_main {
|
||||
json_line("ended", &reason, None);
|
||||
0
|
||||
}
|
||||
Ok(pf_presenter::Outcome::ConnectFailed { msg, trust_rejected }) => {
|
||||
Ok(pf_presenter::Outcome::ConnectFailed {
|
||||
msg,
|
||||
trust_rejected,
|
||||
}) => {
|
||||
json_line("error", &msg, Some(trust_rejected));
|
||||
if trust_rejected {
|
||||
EXIT_TRUST_REJECTED
|
||||
@@ -299,7 +305,6 @@ mod session_main {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
|
||||
+43
-24
@@ -162,15 +162,16 @@ impl SimpleComponent for AppModel {
|
||||
}
|
||||
}
|
||||
|
||||
let hosts = HostsPage::builder()
|
||||
.launch(settings.clone())
|
||||
.forward(sender.input_sender(), |out| match out {
|
||||
HostsOutput::Connect(req) => AppMsg::Connect(req),
|
||||
HostsOutput::WakeConnect(req) => AppMsg::WakeConnect(req),
|
||||
HostsOutput::Pair(req) => AppMsg::Pair(req),
|
||||
HostsOutput::SpeedTest(req) => AppMsg::SpeedTest(req),
|
||||
HostsOutput::Library(req, mgmt) => AppMsg::OpenLibrary(req, mgmt),
|
||||
});
|
||||
let hosts =
|
||||
HostsPage::builder()
|
||||
.launch(settings.clone())
|
||||
.forward(sender.input_sender(), |out| match out {
|
||||
HostsOutput::Connect(req) => AppMsg::Connect(req),
|
||||
HostsOutput::WakeConnect(req) => AppMsg::WakeConnect(req),
|
||||
HostsOutput::Pair(req) => AppMsg::Pair(req),
|
||||
HostsOutput::SpeedTest(req) => AppMsg::SpeedTest(req),
|
||||
HostsOutput::Library(req, mgmt) => AppMsg::OpenLibrary(req, mgmt),
|
||||
});
|
||||
|
||||
let nav = adw::NavigationView::new();
|
||||
nav.add(hosts.widget());
|
||||
@@ -250,7 +251,12 @@ impl SimpleComponent for AppModel {
|
||||
});
|
||||
} else if known.find_by_addr(&req.addr, req.port).is_some() {
|
||||
self.toast("Host fingerprint changed — re-pair with a PIN to continue");
|
||||
crate::ui_trust::pin_dialog(&self.window, &sender, self.identity.clone(), req);
|
||||
crate::ui_trust::pin_dialog(
|
||||
&self.window,
|
||||
&sender,
|
||||
self.identity.clone(),
|
||||
req,
|
||||
);
|
||||
} else if req.pair_optional {
|
||||
crate::ui_trust::tofu_dialog(&self.window, &sender, req);
|
||||
} else {
|
||||
@@ -265,7 +271,10 @@ impl SimpleComponent for AppModel {
|
||||
None => {
|
||||
// Manual entry: a known address connects on its stored pin;
|
||||
// an unknown one must pair — never silent TOFU.
|
||||
match known.find_by_addr(&req.addr, req.port).map(|k| k.fp_hex.clone()) {
|
||||
match known
|
||||
.find_by_addr(&req.addr, req.port)
|
||||
.map(|k| k.fp_hex.clone())
|
||||
{
|
||||
Some(fp_hex) => sender.input(AppMsg::StartSession {
|
||||
req,
|
||||
fp_hex,
|
||||
@@ -307,7 +316,8 @@ impl SimpleComponent for AppModel {
|
||||
return;
|
||||
}
|
||||
self.hosts.emit(HostsMsg::ClearError);
|
||||
self.hosts.emit(HostsMsg::SetConnecting(Some(req.card_key())));
|
||||
self.hosts
|
||||
.emit(HostsMsg::SetConnecting(Some(req.card_key())));
|
||||
let fullscreen = self.settings.borrow().fullscreen_on_stream;
|
||||
if let Err(e) = spawn::spawn_session(
|
||||
sender.input_sender().clone(),
|
||||
@@ -361,7 +371,12 @@ impl SimpleComponent for AppModel {
|
||||
(_, Some((_, true)), _) if !tofu => {
|
||||
// The stored pin no longer matches (rotated cert or impostor).
|
||||
self.toast("Host fingerprint changed — re-pair with a PIN to continue");
|
||||
crate::ui_trust::pin_dialog(&self.window, &sender, self.identity.clone(), req);
|
||||
crate::ui_trust::pin_dialog(
|
||||
&self.window,
|
||||
&sender,
|
||||
self.identity.clone(),
|
||||
req,
|
||||
);
|
||||
}
|
||||
(_, Some((msg, _)), _) => self
|
||||
.hosts
|
||||
@@ -380,10 +395,15 @@ impl SimpleComponent for AppModel {
|
||||
}
|
||||
AppMsg::ShowPreferences => {
|
||||
let hosts = self.hosts.sender().clone();
|
||||
crate::ui_settings::show(&self.window, self.settings.clone(), &self.gamepad, move || {
|
||||
// The library toggle changes the saved cards' menu — re-render.
|
||||
let _ = hosts.send(HostsMsg::Refresh);
|
||||
});
|
||||
crate::ui_settings::show(
|
||||
&self.window,
|
||||
self.settings.clone(),
|
||||
&self.gamepad,
|
||||
move || {
|
||||
// The library toggle changes the saved cards' menu — re-render.
|
||||
let _ = hosts.send(HostsMsg::Refresh);
|
||||
},
|
||||
);
|
||||
}
|
||||
AppMsg::ShowShortcuts => shortcuts_window(&self.window).present(),
|
||||
AppMsg::ShowAbout => crate::ui_settings::show_about(&self.window),
|
||||
@@ -435,12 +455,12 @@ impl AppModel {
|
||||
},
|
||||
CompositorPref::Auto,
|
||||
GamepadPref::Auto,
|
||||
0, // bitrate_kbps (host default)
|
||||
0, // video_caps: probe connect, nothing presents
|
||||
2, // audio_channels: stereo
|
||||
0, // bitrate_kbps (host default)
|
||||
0, // video_caps: probe connect, nothing presents
|
||||
2, // audio_channels: stereo
|
||||
crate::video::decodable_codecs(), // codecs (unused by the probe, but honest)
|
||||
0, // preferred_codec: no preference
|
||||
None, // launch: probe connect, no game
|
||||
0, // preferred_codec: no preference
|
||||
None, // launch: probe connect, no game
|
||||
pin,
|
||||
Some(identity),
|
||||
std::time::Duration::from_secs(15),
|
||||
@@ -530,8 +550,7 @@ pub fn run() -> glib::ExitCode {
|
||||
// Streams and the console library live in the session binary now — exec it,
|
||||
// forwarding the relevant argv (the Decky wrapper keeps working through the shell
|
||||
// until it's repointed).
|
||||
if crate::cli::arg_value("--connect").is_some() || crate::cli::arg_value("--browse").is_some()
|
||||
{
|
||||
if crate::cli::arg_value("--connect").is_some() || crate::cli::arg_value("--browse").is_some() {
|
||||
return crate::cli::exec_session();
|
||||
}
|
||||
|
||||
|
||||
@@ -273,7 +273,14 @@ pub fn run_shot(ctx: &ShotCtx, scene: &str) {
|
||||
// no-art placeholders, and one solid-color texture standing in for a poster.
|
||||
"library" | "08-library" => {
|
||||
let (games, art) = mock_library();
|
||||
crate::ui_library::open_mock(&ctx.nav, ctx.identity.clone(), sender, mock_req(), games, art);
|
||||
crate::ui_library::open_mock(
|
||||
&ctx.nav,
|
||||
ctx.identity.clone(),
|
||||
sender,
|
||||
mock_req(),
|
||||
games,
|
||||
art,
|
||||
);
|
||||
}
|
||||
other => tracing::warn!("unknown PUNKTFUNK_SHOT_SCENE={other:?}; showing hosts only"),
|
||||
}
|
||||
|
||||
@@ -115,10 +115,7 @@ pub fn spawn_session(
|
||||
let stdout = child.stdout.take().expect("piped stdout");
|
||||
// Park the child where the cancel handle (and the reader, for the final reap) can
|
||||
// reach it.
|
||||
let slot = opts
|
||||
.cancel
|
||||
.clone()
|
||||
.unwrap_or_default();
|
||||
let slot = opts.cancel.clone().unwrap_or_default();
|
||||
*slot.0.lock().unwrap() = Some(child);
|
||||
|
||||
let persist_paired = opts.persist_paired;
|
||||
@@ -138,7 +135,10 @@ pub fn spawn_session(
|
||||
persist_paired,
|
||||
});
|
||||
}
|
||||
Some(ChildEvent::Error { msg, trust_rejected }) => {
|
||||
Some(ChildEvent::Error {
|
||||
msg,
|
||||
trust_rejected,
|
||||
}) => {
|
||||
error = Some((msg, trust_rejected));
|
||||
}
|
||||
Some(ChildEvent::Ended(msg)) => ended = Some(msg),
|
||||
@@ -173,9 +173,15 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parses_the_stdout_contract() {
|
||||
assert!(matches!(parse_line("{\"ready\":true}"), Some(ChildEvent::Ready)));
|
||||
assert!(matches!(
|
||||
parse_line("{\"ready\":true}"),
|
||||
Some(ChildEvent::Ready)
|
||||
));
|
||||
match parse_line("{\"error\":\"no route\",\"trust_rejected\":false}") {
|
||||
Some(ChildEvent::Error { msg, trust_rejected }) => {
|
||||
Some(ChildEvent::Error {
|
||||
msg,
|
||||
trust_rejected,
|
||||
}) => {
|
||||
assert_eq!(msg, "no route");
|
||||
assert!(!trust_rejected);
|
||||
}
|
||||
|
||||
@@ -170,7 +170,9 @@ impl relm4::factory::FactoryComponent for HostCard {
|
||||
l
|
||||
};
|
||||
match &self.kind {
|
||||
CardKind::Saved { host: k, online, .. } => {
|
||||
CardKind::Saved {
|
||||
host: k, online, ..
|
||||
} => {
|
||||
// Presence pip + spelled-out state, then the trust pill.
|
||||
let pip = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
||||
pip.add_css_class("pf-pip");
|
||||
@@ -232,11 +234,17 @@ impl relm4::factory::FactoryComponent for HostCard {
|
||||
}
|
||||
{
|
||||
let req = req.clone();
|
||||
add("speed", Box::new(move || CardOutput::SpeedTest(req.clone())));
|
||||
add(
|
||||
"speed",
|
||||
Box::new(move || CardOutput::SpeedTest(req.clone())),
|
||||
);
|
||||
}
|
||||
{
|
||||
let req = req.clone();
|
||||
add("library", Box::new(move || CardOutput::Library(req.clone())));
|
||||
add(
|
||||
"library",
|
||||
Box::new(move || CardOutput::Library(req.clone())),
|
||||
);
|
||||
}
|
||||
{
|
||||
let (fp, name) = (k.fp_hex.clone(), k.name.clone());
|
||||
@@ -344,7 +352,9 @@ struct PageWidgets {
|
||||
pub enum HostsMsg {
|
||||
/// A resolved mDNS advert (also the CI scenes' injection path).
|
||||
Advert(DiscoveredHost),
|
||||
AdvertRemoved { fullname: String },
|
||||
AdvertRemoved {
|
||||
fullname: String,
|
||||
},
|
||||
/// Reload the disk store and re-render (fresh pairings, renames, the library gate).
|
||||
Refresh,
|
||||
/// Mark the card matching `ConnectRequest::card_key` as connecting; `None` restores.
|
||||
@@ -453,7 +463,10 @@ impl SimpleComponent for HostsPage {
|
||||
content.append(&searching);
|
||||
content.append(discovered.widget());
|
||||
|
||||
let clamp = adw::Clamp::builder().maximum_size(1100).child(&content).build();
|
||||
let clamp = adw::Clamp::builder()
|
||||
.maximum_size(1100)
|
||||
.child(&content)
|
||||
.build();
|
||||
let scrolled = gtk::ScrolledWindow::builder()
|
||||
.hscrollbar_policy(gtk::PolicyType::Never)
|
||||
.child(&clamp)
|
||||
@@ -545,10 +558,7 @@ impl SimpleComponent for HostsPage {
|
||||
};
|
||||
model.rebuild();
|
||||
|
||||
ComponentParts {
|
||||
model,
|
||||
widgets: (),
|
||||
}
|
||||
ComponentParts { model, widgets: () }
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: HostsMsg, sender: ComponentSender<Self>) {
|
||||
@@ -606,8 +616,7 @@ impl HostsPage {
|
||||
// A saved host is ONLINE iff a live advert matches it (fingerprint, or address
|
||||
// when the advert carries no fp).
|
||||
let matches = |k: &KnownHost, a: &DiscoveredHost| {
|
||||
(!a.fp_hex.is_empty() && a.fp_hex == k.fp_hex)
|
||||
|| (a.addr == k.addr && a.port == k.port)
|
||||
(!a.fp_hex.is_empty() && a.fp_hex == k.fp_hex) || (a.addr == k.addr && a.port == k.port)
|
||||
};
|
||||
let most_recent = known
|
||||
.hosts
|
||||
@@ -851,6 +860,10 @@ mod tests {
|
||||
|
||||
flow.emit_by_name::<()>("child-activated", &[&child]);
|
||||
|
||||
assert_eq!(fired.get(), 1, "the per-card handler should fire exactly once");
|
||||
assert_eq!(
|
||||
fired.get(),
|
||||
1,
|
||||
"the per-card handler should fire exactly once"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,7 +277,8 @@ fn toggle_fullscreen(hwnd: isize) {
|
||||
..Default::default()
|
||||
};
|
||||
let mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
|
||||
if GetWindowPlacement(hwnd, &mut wp).is_ok() && GetMonitorInfoW(mon, &mut mi).as_bool() {
|
||||
if GetWindowPlacement(hwnd, &mut wp).is_ok() && GetMonitorInfoW(mon, &mut mi).as_bool()
|
||||
{
|
||||
*SAVED.lock().unwrap() = Some(wp);
|
||||
SetWindowLongPtrW(hwnd, GWL_STYLE, style & !overlapped);
|
||||
let r = mi.rcMonitor;
|
||||
|
||||
Reference in New Issue
Block a user