mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-06-27 10:44:48 +03:00
Adds a one-shot Hello message to the lan-mouse wire protocol so each
peer can display the other end's build commit hash and warn on
version mismatch. Soft-warn only — mismatched versions never refuse
traffic.
Wire change (lan-mouse-proto)
* `ProtoEvent::Hello { commit: [u8; 8] }` carries the 8-byte ASCII
short commit from shadow_rs's `SHORT_COMMIT`. Encoded/decoded
alongside the existing event variants.
* `EventType::Hello` is appended to the enum so existing IDs are
untouched. Old peers receive the event, hit `InvalidEventId`, and
silently skip it via the forward-compat handler in
`connect.rs::receive_loop` — the connection is unaffected.
Daemon
* Connect side sends one Hello immediately after the DTLS handshake
authenticates and before the ping_pong loop starts. Best-effort,
fire-and-forget — `log::debug!` on send error.
* Listen side mirrors the peer's Hello with its own (same shape as
the existing Ping → Pong reply), so the peer's connect-side
receive_loop populates `ClientState::peer_commit` for that
handle.
* The disconnect path clears `peer_commit` so a stale hash isn't
shown after the connection drops.
IPC
* `ClientState::peer_commit: Option<[u8; 8]>`. `None` means the
peer hasn't sent Hello yet — either fresh connection or older
build that predates the event.
GTK
* `ClientObject` exposes `peer-commit` as an `Option<String>`
property; `peer_commit_to_string` converts the wire `[u8; 8]` to
the displayable hex.
* `lan_mouse_gtk::run` now takes the local commit and stashes it in
a `OnceLock` so per-row UI can compare against each peer's hash.
* `ClientRow::refresh_version_status` re-renders the collapsed
subtitle with Pango markup whenever the property changes:
- matched → green "peer version: <hex> · matched"
- mismatch → orange "peer version: <hex> · ours: <hex>"
- unknown → orange "peer version: unknown · ours: <hex>"
* Window invokes `refresh_version_status` from
`update_client_state` after writing the new property, and
`bind` calls it once on row construction so the initial
subtitle isn't blank.
Known limitation: state-change broadcasts from the network side
(set_alive / set_active_addr / set_peer_commit) don't currently
trigger a `FrontendEvent::State` directly; the UI picks up the
latest values on the next user-driven broadcast. Same pre-existing
behavior as the alive/active_addr fields.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
57 lines
1.7 KiB
Rust
57 lines
1.7 KiB
Rust
mod imp;
|
|
|
|
use adw::subclass::prelude::*;
|
|
use gtk::glib::{self, Object};
|
|
|
|
use lan_mouse_ipc::{ClientConfig, ClientHandle, ClientState};
|
|
|
|
glib::wrapper! {
|
|
pub struct ClientObject(ObjectSubclass<imp::ClientObject>);
|
|
}
|
|
|
|
impl ClientObject {
|
|
pub fn new(handle: ClientHandle, client: ClientConfig, state: ClientState) -> Self {
|
|
Object::builder()
|
|
.property("handle", handle)
|
|
.property("hostname", client.hostname)
|
|
.property("port", client.port as u32)
|
|
.property("position", client.pos.to_string())
|
|
.property("active", state.active)
|
|
.property(
|
|
"ips",
|
|
state
|
|
.ips
|
|
.iter()
|
|
.map(|ip| ip.to_string())
|
|
.collect::<Vec<_>>(),
|
|
)
|
|
.property("resolving", state.resolving)
|
|
.property("peer-commit", peer_commit_to_string(state.peer_commit))
|
|
.build()
|
|
}
|
|
|
|
pub fn get_data(&self) -> ClientData {
|
|
self.imp().data.borrow().clone()
|
|
}
|
|
}
|
|
|
|
/// Render the 8-byte ASCII commit hash carried in
|
|
/// [`lan_mouse_ipc::ClientState::peer_commit`] as a `String`. `None`
|
|
/// in → `None` out (peer hasn't sent a Hello yet, or speaks an older
|
|
/// proto).
|
|
pub fn peer_commit_to_string(commit: Option<[u8; 8]>) -> Option<String> {
|
|
commit.and_then(|c| std::str::from_utf8(&c).ok().map(str::to_string))
|
|
}
|
|
|
|
#[derive(Default, Clone)]
|
|
pub struct ClientData {
|
|
pub handle: ClientHandle,
|
|
pub hostname: Option<String>,
|
|
pub port: u32,
|
|
pub active: bool,
|
|
pub position: String,
|
|
pub resolving: bool,
|
|
pub ips: Vec<String>,
|
|
pub peer_commit: Option<String>,
|
|
}
|