Compare commits

..

12 Commits

Author SHA1 Message Date
Ferdinand Schober
4821cd11ac bundle vc_redist.x64.exe 2026-06-14 23:26:24 +02:00
Ferdinand Schober
67c0ff0045 fix icons 2026-06-14 23:26:24 +02:00
Ferdinand Schober
f4c9563a62 add application icon 2026-06-14 23:26:24 +02:00
Ferdinand Schober
51601d68c7 add startmenu entry 2026-06-14 23:26:24 +02:00
Ferdinand Schober
5501ed0c50 embed .cab file 2026-06-14 23:26:24 +02:00
Ferdinand Schober
f54a472e34 start working on an installer 2026-06-14 23:26:24 +02:00
Ferdinand Schober
d68df35409 use proper css styling for the font colors 2026-06-14 22:59:26 +02:00
Jon Kinney
c2f6e172bb chore: cargo fmt for peer-version code 2026-06-14 22:59:26 +02:00
Jon Kinney
32b6683cda fix(version-exchange): also store peer commit on the listen side
Previously the Hello handler in `ListenTask` echoed our local commit
back but deliberately threw away the peer's, on the assumption that
the outgoing connect-side path (`connect.rs:278-279` →
`set_peer_commit`) would always populate the visible state for any
bidirectionally-configured peer.

That assumption breaks any time the *outgoing* TCP/DTLS direction is
broken even though the inbound direction is fine — happened just now
when the peer Mac's daemon stopped listening on 4242 (DHCP-renewed
IP, daemon crashed, asymmetric NAT, …). Mac was still happily
connecting in the other direction and sending events, including the
initial Hello, but Linux silently displayed "peer version unknown"
because the listen side dropped Mac's commit on the floor.

Add a `PeerHello { addr, commit }` EmulationEvent variant fired from
the listen-side Hello handler. The service maps `addr → ClientHandle`
via `client_manager.get_client(addr)` and calls `set_peer_commit` +
`broadcast_client` exactly like the connect path does. The connect
path remains the primary source for symmetric setups; this is the
defensive fallback so version visibility doesn't depend on outbound
reachability.

Skips silently when no outgoing client is configured for the peer's
addr (incoming-only setup) — there's no UI row to update in that
case anyway.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-14 22:59:26 +02:00
Jon Kinney
62b22e1764 ui(client_row): sentence-case "Peer version" and "Ours" labels
These are user-visible labels in the version-status subtitle, so
sentence-case reads better than the lowercase first-pass. "matched"
stays lowercase since it's a status descriptor, not a label.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-14 22:59:26 +02:00
Jon Kinney
72c86c0d83 feat: peer version exchange with soft-warn UI indicator
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>
2026-06-14 22:59:26 +02:00
Jon Kinney
82766cdc87 fix(proto): tolerate undecodable peer datagrams instead of disconnecting
The DTLS recv loops in src/listen.rs and src/connect.rs each read
one full datagram per call. A failed `try_into::<ProtoEvent>()`
means the datagram's leading EventType byte didn't match any
known variant — a misalignment is impossible because DTLS is
message-framed, not stream-framed.

Previously, src/listen.rs would `break` out of the loop on parse
failure (tearing down the connection) and src/connect.rs would
silently swallow the error with no log. Both are wrong as
forward-compat behavior: any future protocol addition (e.g. a
new event variant) would force every existing peer to disconnect
rather than gracefully ignoring the unknown event.

Skip-and-continue on both sides, with a debug-level log so the
behavior is observable. Pre-requisite for any future ProtoEvent
variant to land without forcing a coordinated upgrade across
every peer in a deployment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-14 22:59:26 +02:00
10 changed files with 169 additions and 0 deletions

3
wix/bundle/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
/bin
/obj
icon.ico

16
wix/bundle/Bundle.wixproj Normal file
View File

@@ -0,0 +1,16 @@
<Project Sdk="WixToolset.Sdk/5.0.0">
<PropertyGroup>
<OutputType>Bundle</OutputType>
<TargetExt>.exe</TargetExt>
<Platforms>x64</Platforms>
<InstallerPlatform>x64</InstallerPlatform>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="WixToolset.Heat">
<Version>5.0.2</Version>
</PackageReference>
<PackageReference Include="WixToolset.Bal.wixext">
<Version>5.0.2</Version>
</PackageReference>
</ItemGroup>
</Project>

42
wix/bundle/Bundle.wxs Normal file
View File

@@ -0,0 +1,42 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
<Bundle
Name="Lan Mouse"
Version="0.10.0"
UpgradeCode="{39A9744D-9D6E-4CD3-A84F-9E034786A7B1}"
Compressed="no"
SplashScreenSourceFile="icon.ico">
<BootstrapperApplication>
<bal:WixStandardBootstrapperApplication
LicenseUrl=""
Theme="hyperlinkLicense" />
</BootstrapperApplication>
<Chain>
<!-- Visual C++ 2015-2022 Redistributable (x64) - 14.40.33810 -->
<ExePackage
Id="VC_REDIST_X64"
DisplayName="Microsoft Visual C++ 2015-2022 Redistributable (x64) - 14.40.33810"
PerMachine="yes"
Permanent="yes"
Protocol="burn"
InstallCondition="VersionNT64 AND (ARCH_NAME = &quot;AMD64&quot;)"
DetectCondition="(VCRUNTIME_X64_VER &gt;= VCRUNTIME_VER) AND VersionNT64 AND (ARCH_NAME = &quot;AMD64&quot;)"
InstallArguments="/install /quiet /norestart"
RepairArguments="/repair /quiet /norestart"
UninstallArguments="/uninstall /quiet /norestart">
<ExePackagePayload
Name="VC_redist.x64.exe"
ProductName="Microsoft Visual C++ 2015-2022 Redistributable (x64) - 14.40.33810"
Description="Microsoft Visual C++ 2015-2022 Redistributable (x64) - 14.40.33810"
Hash="5935B69F5138AC3FBC33813C74DA853269BA079F910936AEFA95E230C6092B92F6225BFFB594E5DD35FF29BF260E4B35F91ADEDE90FDF5F062030D8666FD0104"
Size="25397512"
Version="14.40.33810.0"
DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/1754ea58-11a6-44ab-a262-696e194ce543/3642E3F95D50CC193E4B5A0B0FFBF7FE2C08801517758B4C8AEB7105A091208A/VC_redist.x64.exe" />
</ExePackage>
<MsiPackage SourceFile="..\lan-mouse\bin\Debug\en-US\LanMouse.msi" Compressed="yes"/>
</Chain>
</Bundle>
</Wix>

3
wix/lan-mouse/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
/bin
/obj
icon.ico

13
wix/lan-mouse/Folders.wxs Normal file
View File

@@ -0,0 +1,13 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment>
<StandardDirectory Id="ProgramFiles64Folder">
<Directory Id="INSTALLFOLDER" Name="!(bind.Property.Manufacturer) !(bind.Property.ProductName)">
<Directory Id="SHARE" Name="share"/>
<Directory Id="LIB" Name="lib"/>
</Directory>
</StandardDirectory>
<StandardDirectory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="!(bind.Property.ProductName)"/>
</StandardDirectory>
</Fragment>
</Wix>

View File

@@ -0,0 +1,34 @@
<Project Sdk="WixToolset.Sdk/5.0.2">
<PropertyGroup>
<InstallerPlatform>x64</InstallerPlatform>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="WixToolset.Heat">
<Version>5.0.2</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<HarvestDirectory Include="C:\gtk-build\gtk\x64\release\bin">
<ComponentGroupName>GTKBIN</ComponentGroupName>
<DirectoryRefId>INSTALLFOLDER</DirectoryRefId>
<SuppressRegistry>true</SuppressRegistry>
</HarvestDirectory>
<BindPath Include="C:\gtk-build\gtk\x64\release\bin" />
</ItemGroup>
<ItemGroup>
<HarvestDirectory Include="C:\gtk-build\gtk\x64\release\share\icons">
<ComponentGroupName>GTKICONS</ComponentGroupName>
<DirectoryRefId>SHARE</DirectoryRefId>
<SuppressRegistry>true</SuppressRegistry>
</HarvestDirectory>
<BindPath Include="C:\gtk-build\gtk\x64\release\share\icons" />
</ItemGroup>
<ItemGroup>
<HarvestDirectory Include="C:\gtk-build\gtk\x64\release\lib\gdk-pixbuf-2.0">
<ComponentGroupName>GTKLIBS</ComponentGroupName>
<DirectoryRefId>LIB</DirectoryRefId>
<SuppressRegistry>true</SuppressRegistry>
</HarvestDirectory>
<BindPath Include="C:\gtk-build\gtk\x64\release\lib\gdk-pixbuf-2.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,32 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment>
<ComponentGroup Id="LanMouseComponents" Directory="INSTALLFOLDER" Subdirectory="bin">
<Component Guid="{ECB52D3E-28AD-4BEC-B9DF-E01CCAB356BE}">
<!-- the main binary -->
<File Source="..\..\target\release\lan-mouse.exe"/>
<!-- visual c runtime dll -->
<!--<File Source="C:\windows\system32\VCRUNTIME140.dll"/>-->
<!--<File Source="C:\windows\system32\VCRUNTIME140_1.dll"/>-->
</Component>
<!-- start menu entry-->
<Component Id="ApplicationShortcut" Directory="ApplicationProgramsFolder">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="!(bind.Property.ProductName)"
Description ="Mouse and Keyboard sharing Software"
Target="[INSTALLFOLDER]bin\lan-mouse.exe"
WorkingDirectory="INSTALLFOLDER">
<Icon Id="LanMouse" SourceFile=".\icon.ico"/>
</Shortcut>
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue
Root="HKCU"
Key="Software\Feschber\LanMouse"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,8 @@
<!--
This file contains the declaration of all the localizable strings.
-->
<WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">
<String Id="DowngradeError" Value="A newer version of [ProductName] is already installed." />
</WixLocalization>

16
wix/lan-mouse/Package.wxs Normal file
View File

@@ -0,0 +1,16 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Package Name="Lan Mouse"
Manufacturer="Ferdinand Schober"
Version="0.10.0.0"
UpgradeCode="{a330cd60-4c35-4a54-8bb6-75b3049b46c6}">
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
<MediaTemplate EmbedCab="yes"/>
<Feature Id="Main">
<ComponentGroupRef Id="GTKBIN"/>
<ComponentGroupRef Id="GTKICONS"/>
<ComponentGroupRef Id="GTKLIBS"/>
<ComponentGroupRef Id="LanMouseComponents"/>
</Feature>
</Package>
</Wix>

2
wix/lan-mouse/build.ps1 Normal file
View File

@@ -0,0 +1,2 @@
magick -background none -density 384 ..\lan-mouse-gtk\resources\de.feschber.LanMouse.svg -trim -define icon:auto-resize icon.ico
dotnet build