diff --git a/client/src/app.rs b/client/src/app.rs index 0dcef32..f34361b 100644 --- a/client/src/app.rs +++ b/client/src/app.rs @@ -149,7 +149,7 @@ impl LesavkaClientApp { /*──────────────── keyboard stream ───────────────*/ async fn stream_loop_keyboard(&self, ep: Channel) { loop { - info!("⌨️ dial {}", self.server_addr); // LESAVKA-client + info!("⌨️🤙 dial {}", self.server_addr); // LESAVKA-client let mut cli = RelayClient::new(ep.clone()); // ✅ use kbd_tx here - fixes E0271 @@ -171,7 +171,7 @@ impl LesavkaClientApp { /*──────────────── mouse stream ──────────────────*/ async fn stream_loop_mouse(&self, ep: Channel) { loop { - info!("🖱️ dial {}", self.server_addr); + info!("🖱️🤙 dial {}", self.server_addr); let mut cli = RelayClient::new(ep.clone()); let outbound = BroadcastStream::new(self.mou_tx.subscribe()) diff --git a/client/src/input/inputs.rs b/client/src/input/inputs.rs index 9aa2574..31e1aac 100644 --- a/client/src/input/inputs.rs +++ b/client/src/input/inputs.rs @@ -64,7 +64,7 @@ impl InputAggregator { match classify_device(&dev) { DeviceKind::Keyboard => { dev.grab().with_context(|| format!("grabbing keyboard {path:?}"))?; - info!("Grabbed keyboard {:?}", dev.name().unwrap_or("UNKNOWN")); + info!("🤏🖱️ Grabbed keyboard {:?}", dev.name().unwrap_or("UNKNOWN")); // pass dev_mode to aggregator // let kbd_agg = KeyboardAggregator::new(dev, self.dev_mode); @@ -75,7 +75,7 @@ impl InputAggregator { } DeviceKind::Mouse => { dev.grab().with_context(|| format!("grabbing mouse {path:?}"))?; - info!("Grabbed mouse {:?}", dev.name().unwrap_or("UNKNOWN")); + info!("🤏⌨️ Grabbed mouse {:?}", dev.name().unwrap_or("UNKNOWN")); // let mouse_agg = MouseAggregator::new(dev); let mouse_agg = MouseAggregator::new(dev, self.dev_mode, self.mou_tx.clone()); diff --git a/client/src/layout.rs b/client/src/layout.rs index 1a3ec60..c4fa5f7 100644 --- a/client/src/layout.rs +++ b/client/src/layout.rs @@ -1,4 +1,4 @@ -// client/src/layout.rs – Wayland-only window placement utilities +// client/src/layout.rs - Wayland-only window placement utilities #![forbid(unsafe_code)] use std::process::Command; diff --git a/client/src/main.rs b/client/src/main.rs index 2c7cbe0..fe485e7 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -69,7 +69,7 @@ async fn main() -> Result<()> { .with(file_layer) .init(); - tracing::info!("lesavka-client running in DEV mode → {}", log_path.display()); + tracing::info!("📜 lesavka-client running in DEV mode → {}", log_path.display()); } else { tracing_subscriber::registry() .with(env_filter) diff --git a/client/src/output/audio.rs b/client/src/output/audio.rs index 9ada77c..e045ef8 100644 --- a/client/src/output/audio.rs +++ b/client/src/output/audio.rs @@ -4,6 +4,7 @@ use anyhow::{Context, Result}; use gstreamer as gst; use gstreamer_app as gst_app; use gst::prelude::*; +use gst::MessageView::*; use tracing::{error, info, warn, debug}; use lesavka_common::lesavka::AudioPacket; @@ -69,7 +70,6 @@ impl AudioOut { // ── 4. Log *all* warnings/errors from the bus ────────────────────── let bus = pipeline.bus().unwrap(); std::thread::spawn(move || { - use gst::MessageView::*; for msg in bus.iter_timed(gst::ClockTime::NONE) { match msg.view() { Error(e) => error!("💥 gst error from {:?}: {} ({})", @@ -82,8 +82,18 @@ impl AudioOut { .structure() .map(|s| s.to_string()) .unwrap_or_default()), - StateChanged(s) if s.current() == gst::State::Playing => - info!("🔊 audio pipeline PLAYING (sink='{}')", sink), + StateChanged(s) if s.current() == gst::State::Playing => { + if msg + .src() + .map(|s| s.is::()) + .unwrap_or(false) + { + info!("🔊 audio pipeline PLAYING (sink='{}')", sink); + } else { + debug!("🔊 element {} now PLAYING", + msg.src().map(|s| s.name()).unwrap_or_default()); + } + }, _ => {} } } @@ -116,12 +126,11 @@ impl Drop for AudioOut { fn pick_sink_element() -> Result { // 1. Operator override if let Ok(s) = std::env::var("LESAVKA_AUDIO_SINK") { - info!("🎛️ sink overridden via LESAVKA_AUDIO_SINK={}", s); + info!("💪 sink overridden via LESAVKA_AUDIO_SINK={}", s); return Ok(s); } // 2. Query PipeWire for default & running sinks - // (works even if PulseAudio is present because PipeWire mimics it) let sinks = list_pw_sinks(); // Vec<(name,state)> for (n, st) in &sinks { if *st == "RUNNING" { @@ -132,45 +141,23 @@ fn pick_sink_element() -> Result { // 3. First RUNNING sink if let Some((n, _)) = sinks.iter().find(|(_, st)| *st == "RUNNING") { - warn!("🪄 picking first RUNNING sink '{}'", n); - return Ok(format!("pulsesink device={}", n)); - } - // 4. Anything - if let Some((n, _)) = sinks.first() { - warn!("🪄 picking first sink '{}'", n); + warn!("🏃 picking first RUNNING sink '{}'", n); return Ok(format!("pulsesink device={}", n)); } - // Fallback – let autoaudiosink try its luck - warn!("😬 no PipeWire sinks readable – falling back to autoaudiosink"); + // 4. Anything + if let Some((n, _)) = sinks.first() { + warn!("🎲 picking first sink '{}'", n); + return Ok(format!("pulsesink device={}", n)); + } + + // Fallback - let autoaudiosink try its luck + warn!("🫣 no PipeWire sinks readable - falling back to autoaudiosink"); Ok("autoaudiosink".to_string()) } -/// Minimal PipeWire sink enumerator (no extra crate required). fn list_pw_sinks() -> Vec<(String, String)> { let mut out = Vec::new(); - // if let Ok(lines) = std::process::Command::new("pw-cli") - // .args(["ls", "Node"]) - // .output() - // .map(|o| String::from_utf8_lossy(&o.stdout).to_string()) - // { - // for l in lines.lines() { - // // Example: " 36 │ node.alive = true │ alsa_output.pci-0000_2f_00.4.iec958-stereo │ state: SUSPENDED ..." - // if let Some(pos) = l.find("│") { - // let parts: Vec<_> = l[pos..].split('│').map(|s| s.trim()).collect(); - // if parts.len() >= 3 && parts[2].starts_with("alsa_output.") { - // let name = parts[2].to_string(); - // // try to parse state, else UNKNOWN - // let state = parts.get(3) - // .and_then(|s| s.split_whitespace().nth(1)) - // .unwrap_or("UNKNOWN") - // .to_string(); - // out.push((name, state)); - // } - // } - // } - // } - if out.is_empty() { // ── PulseAudio / pactl fallback ──────────────────────────────── if let Ok(info) = std::process::Command::new("pactl") diff --git a/client/src/output/display.rs b/client/src/output/display.rs index ac7a6c1..97e3ca0 100644 --- a/client/src/output/display.rs +++ b/client/src/output/display.rs @@ -15,7 +15,7 @@ pub struct MonitorInfo { /// Enumerate monitors sorted by our desired priority. pub fn enumerate_monitors() -> Vec { let Some(display) = gdk::Display::default() else { - tracing::warn!("⚠️ no GDK display – falling back to single-monitor 0,0"); + tracing::warn!("⚠️ no GDK display - falling back to single-monitor 0,0"); return vec![MonitorInfo { geometry: gdk::Rectangle::new(0, 0, 1920, 1080), scale_factor: 1, diff --git a/client/src/output/video.rs b/client/src/output/video.rs index 0d8f2d6..374efa0 100644 --- a/client/src/output/video.rs +++ b/client/src/output/video.rs @@ -124,7 +124,7 @@ impl MonitorWindow { y = r.y, ); - // Retry in a detached thread – avoids blocking GStreamer + // Retry in a detached thread - avoids blocking GStreamer let placename = placer.name; let runner = placer.run.clone(); thread::spawn(move || { diff --git a/scripts/daemon/lesavka-core.sh b/scripts/daemon/lesavka-core.sh index b59295a..43c051a 100644 --- a/scripts/daemon/lesavka-core.sh +++ b/scripts/daemon/lesavka-core.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# lesavka‑core.sh – one‑shot USB‑gadget bring‑up (Pi‑5 / Arch‑ARM) +# lesavka‑core.sh - one‑shot USB‑gadget bring‑up (Pi‑5 / Arch‑ARM) # Presents: • Boot‑protocol keyboard (hidg0) # • Boot‑protocol mouse (hidg1) # • Stereo UAC2 speaker + microphone @@ -98,7 +98,7 @@ printf '\x05\x01\x09\x02\xa1\x01\x09\x01\xa1\x00'\ '\x05\x01\x09\x30\x09\x31\x09\x38\x15\x81\x25\x7f\x75\x08\x95\x03\x81\x06'\ '\xc0\xc0' >"$G/functions/hid.usb1/report_desc" -# ---------- UAC2 function – speaker + mic, 2×48 kHz stereo --------- +# ---------- UAC2 function - speaker + mic, 2×48 kHz stereo --------- mkdir -p "$G/functions/uac2.usb0" U="$G/functions/uac2.usb0" # Playback (speaker) diff --git a/scripts/install/server.sh b/scripts/install/server.sh index 2b0cae3..53ef002 100755 --- a/scripts/install/server.sh +++ b/scripts/install/server.sh @@ -122,8 +122,6 @@ ExecStart=/usr/local/bin/lesavka-server Restart=always Environment=RUST_LOG=lesavka_server=info,lesavka_server::audio=info,lesavka_server::video=info,lesavka_server::gadget=info Environment=RUST_BACKTRACE=1 -Environment=GST_DEBUG=3,v4l2src:6,tsdemux:6,parsebin:5 -Environment=GST_DEBUG_DUMP_DOT_DIR=/tmp Restart=always RestartSec=5 StandardError=append:/tmp/lesavka-server.stderr diff --git a/server/src/audio.rs b/server/src/audio.rs index 0729e3c..ffbd476 100644 --- a/server/src/audio.rs +++ b/server/src/audio.rs @@ -39,7 +39,7 @@ impl Drop for AudioStream { } /*───────────────────────────────────────────────────────────────────────────*/ -/* ear() – capture from ALSA (“speaker”) and push AAC AUs via gRPC */ +/* ear() - capture from ALSA (“speaker”) and push AAC AUs via gRPC */ /*───────────────────────────────────────────────────────────────────────────*/ pub async fn ear(alsa_dev: &str, id: u32) -> anyhow::Result { @@ -151,7 +151,6 @@ fn build_pipeline_desc(dev: &str) -> anyhow::Result { }) .ok_or_else(|| anyhow!("no AAC encoder plugin available"))?; - // one long literal assembled with `concat!` so Rust sees *one* string Ok(format!( concat!( "alsasrc device=\"{dev}\" do-timestamp=true ! ", diff --git a/server/src/video.rs b/server/src/video.rs index 1986b60..1604376 100644 --- a/server/src/video.rs +++ b/server/src/video.rs @@ -32,7 +32,7 @@ impl Stream for VideoStream { impl Drop for VideoStream { fn drop(&mut self) { - // shut down nicely – avoids the “dispose element … READY/PLAYING …” spam + // shut down nicely - avoids the “dispose element … READY/PLAYING …” spam let _ = self._pipeline.set_state(gst::State::Null); } } @@ -93,7 +93,7 @@ pub async fn eye_ball( } else { warn!(target:"lesavka_server::video", eye = %eye, - "🍪 cam_{eye} not found – skipping pad-probe"); + "🍪 cam_{eye} not found - skipping pad-probe"); } let eye_clone = eye.to_owned(); @@ -191,7 +191,7 @@ pub async fn eye_ball( debug!(target:"lesavka_server::video", eye = %eye, dropped = c, - "⏳ channel full – dropping frames"); + "⏳ channel full - dropping frames"); } } Err(e) => error!("mpsc send err: {e}"),