interactive: Host/View entry menu, clipboard copy, player picker
Bare `pixelpass` now opens a dialoguer-driven Host/View menu instead of going straight to host mode. Host path copies the ticket to the system clipboard via arboard with silent print-only fallback. View path prompts for the ticket, then after the local listener binds prompts mpv-vs-VLC and spawns it detached (setsid + null stdio) so the player survives pixelpass exiting. Headless invocations (`pixelpass <ticket>`, `pixelpass --repair`) unchanged. Per spec at ~/Documents/pixelpass-interactive-mode-spec.md.
This commit is contained in:
+25
-3
@@ -30,7 +30,8 @@ pub async fn run(opts: HostOpts) -> Result<()> {
|
||||
|
||||
let addr = endpoint.addr();
|
||||
let ticket = EndpointTicket::new(addr);
|
||||
print_host_banner(&ticket, display, &opts);
|
||||
let clipboard_ok = opts.interactive && copy_to_clipboard(&ticket.to_string());
|
||||
print_host_banner(&ticket, display, &opts, clipboard_ok);
|
||||
|
||||
let result = accept_loop(&endpoint, display, &opts, cancel.clone()).await;
|
||||
|
||||
@@ -93,7 +94,12 @@ async fn handle_peer(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_host_banner(ticket: &EndpointTicket, display: DisplayServer, opts: &HostOpts) {
|
||||
fn print_host_banner(
|
||||
ticket: &EndpointTicket,
|
||||
display: DisplayServer,
|
||||
opts: &HostOpts,
|
||||
clipboard_ok: bool,
|
||||
) {
|
||||
eprintln!();
|
||||
eprintln!("┌─ PixelPass · host ─────────────────────────────────────────");
|
||||
eprintln!("│ display server : {display:?}");
|
||||
@@ -101,7 +107,13 @@ fn print_host_banner(ticket: &EndpointTicket, display: DisplayServer, opts: &Hos
|
||||
eprintln!("│ bitrate / fps : {} kbps @ {} fps", opts.bitrate, opts.framerate);
|
||||
eprintln!("│ hw encode : {}", if opts.no_hwencode { "off" } else { "auto (VAAPI if available)" });
|
||||
eprintln!("│");
|
||||
eprintln!("│ Share this ticket with your viewer:");
|
||||
if clipboard_ok {
|
||||
eprintln!("│ Your share code has been copied to your clipboard.");
|
||||
eprintln!("│ Send it to your viewer. (If clipboard didn't work, the");
|
||||
eprintln!("│ code is also shown below for manual copy.)");
|
||||
} else {
|
||||
eprintln!("│ Share this ticket with your viewer:");
|
||||
}
|
||||
eprintln!("│");
|
||||
eprintln!("│ pixelpass {ticket}");
|
||||
eprintln!("│");
|
||||
@@ -111,6 +123,16 @@ fn print_host_banner(ticket: &EndpointTicket, display: DisplayServer, opts: &Hos
|
||||
eprintln!();
|
||||
}
|
||||
|
||||
fn copy_to_clipboard(text: &str) -> bool {
|
||||
match arboard::Clipboard::new().and_then(|mut cb| cb.set_text(text.to_owned())) {
|
||||
Ok(()) => true,
|
||||
Err(e) => {
|
||||
tracing::warn!("clipboard copy failed: {e}");
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn capture_summary(opts: &HostOpts) -> String {
|
||||
let mut bits = vec![if opts.window { "window" } else { "fullscreen" }.to_string()];
|
||||
if let Some(app) = &opts.app {
|
||||
|
||||
Reference in New Issue
Block a user