diff --git a/client/build.rs b/client/build.rs index b7469d1..188a143 100644 --- a/client/build.rs +++ b/client/build.rs @@ -1,3 +1,28 @@ +use std::process::Command; + fn main() { println!("cargo:rustc-check-cfg=cfg(coverage)"); + println!("cargo:rerun-if-changed=../.git/HEAD"); + println!("cargo:rerun-if-changed=../.git/index"); + println!( + "cargo:rustc-env=LESAVKA_GIT_SHA={}", + git_sha().unwrap_or_else(|| "nogit".to_string()) + ); +} + +fn git_sha() -> Option { + let output = Command::new("git") + .args(["-C", "..", "rev-parse", "--short", "HEAD"]) + .output() + .ok()?; + if !output.status.success() { + return None; + } + let sha = String::from_utf8(output.stdout).ok()?; + let trimmed = sha.trim(); + if trimmed.is_empty() { + None + } else { + Some(trimmed.to_string()) + } } diff --git a/client/src/launcher/ui_components.rs b/client/src/launcher/ui_components.rs index be5a322..2cab311 100644 --- a/client/src/launcher/ui_components.rs +++ b/client/src/launcher/ui_components.rs @@ -147,7 +147,7 @@ pub fn build_launcher_view( build_status_chip_with_light("Inputs", "Local"); let (gpio_chip, gpio_light, gpio_value) = build_status_chip_with_light("GPIO", "Unknown"); let (shortcut_chip, shortcut_value) = build_status_chip("Swap Key", "Pause"); - stabilize_chip(&relay_chip, 104); + stabilize_chip(&relay_chip, 136); stabilize_chip(&routing_chip, 84); stabilize_chip(&gpio_chip, 84); stabilize_chip(&shortcut_chip, 88); diff --git a/client/src/lib.rs b/client/src/lib.rs index b06c3ea..0e7dffe 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -2,7 +2,7 @@ #![forbid(unsafe_code)] -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); +pub const VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), "+", env!("LESAVKA_GIT_SHA")); pub mod app; mod app_support; diff --git a/server/build.rs b/server/build.rs index b7469d1..188a143 100644 --- a/server/build.rs +++ b/server/build.rs @@ -1,3 +1,28 @@ +use std::process::Command; + fn main() { println!("cargo:rustc-check-cfg=cfg(coverage)"); + println!("cargo:rerun-if-changed=../.git/HEAD"); + println!("cargo:rerun-if-changed=../.git/index"); + println!( + "cargo:rustc-env=LESAVKA_GIT_SHA={}", + git_sha().unwrap_or_else(|| "nogit".to_string()) + ); +} + +fn git_sha() -> Option { + let output = Command::new("git") + .args(["-C", "..", "rev-parse", "--short", "HEAD"]) + .output() + .ok()?; + if !output.status.success() { + return None; + } + let sha = String::from_utf8(output.stdout).ok()?; + let trimmed = sha.trim(); + if trimmed.is_empty() { + None + } else { + Some(trimmed.to_string()) + } } diff --git a/server/src/lib.rs b/server/src/lib.rs index 1f461a2..5ce9f1b 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1,6 +1,6 @@ // server/src/lib.rs -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); +pub const VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), "+", env!("LESAVKA_GIT_SHA")); pub mod audio; pub mod camera; diff --git a/server/src/main.rs b/server/src/main.rs index 797b107..bd210e8 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -4,7 +4,7 @@ #[forbid(unsafe_code)] use futures_util::{Stream, StreamExt}; use std::sync::atomic::AtomicBool; -use std::{backtrace::Backtrace, panic, pin::Pin, sync::Arc}; +use std::{backtrace::Backtrace, panic, pin::Pin, sync::Arc, time::Duration}; use tokio::sync::Mutex; use tokio_stream::wrappers::ReceiverStream; use tonic::transport::Server; @@ -25,7 +25,6 @@ use lesavka_server::{ }; /*──────────────── constants ────────────────*/ -const VERSION: &str = env!("CARGO_PKG_VERSION"); const PKG_NAME: &str = env!("CARGO_PKG_NAME"); type VideoStream = Pin> + Send>>; @@ -37,6 +36,14 @@ fn hid_endpoint(index: u8) -> String { .unwrap_or_else(|_| format!("/dev/hidg{index}")) } +fn live_keyboard_report_delay() -> Duration { + std::env::var("LESAVKA_LIVE_KEYBOARD_REPORT_DELAY_MS") + .ok() + .and_then(|value| value.parse::().ok()) + .map(Duration::from_millis) + .unwrap_or_else(|| Duration::from_millis(8)) +} + /*──────────────── Handler ───────────────────*/ struct Handler { kb: Arc>, @@ -238,6 +245,7 @@ impl Relay for Handler { let gadget = self.gadget.clone(); let did_cycle = self.did_cycle.clone(); let session_lease = self.capture_power.acquire_session().await; + let report_delay = live_keyboard_report_delay(); tokio::spawn(async move { let _session_lease = session_lease; @@ -259,6 +267,9 @@ impl Relay for Handler { } } tx.send(Ok(pkt)).await.ok(); + if !report_delay.is_zero() { + tokio::time::sleep(report_delay).await; + } } info!(rpc_id, "⌨️ stream_keyboard closed"); Ok::<(), Status>(()) @@ -451,12 +462,16 @@ impl Relay for Handler { ) -> Result, Status> { let (tx, rx) = tokio::sync::mpsc::channel(32); let kb = self.kb.clone(); + let report_delay = live_keyboard_report_delay(); tokio::spawn(async move { let mut s = req.into_inner(); while let Some(pkt) = s.next().await.transpose()? { let _ = runtime_support::write_hid_report(&kb, &pkt.data).await; tx.send(Ok(pkt)).await.ok(); + if !report_delay.is_zero() { + tokio::time::sleep(report_delay).await; + } } Ok::<(), Status>(()) }); @@ -545,7 +560,7 @@ impl Relay for Handler { #[tokio::main(worker_threads = 4)] async fn main() -> anyhow::Result<()> { let _guard = init_tracing()?; - info!("🚀 {} v{} starting up", PKG_NAME, VERSION); + info!("🚀 {} v{} starting up", PKG_NAME, lesavka_server::VERSION); panic::set_hook(Box::new(|p| { let bt = Backtrace::force_capture();