From b53568c99fd6698550afbce935c92d8340d0b001 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Wed, 5 Aug 2026 23:37:18 +0200 Subject: [PATCH] fix(decky): a host saved under its own IP now shows the name it advertises MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The panel captioned most rows with an IP address. The saved records were the source: `hosts add` falls back to the address when the pairing path knew nothing better, so `name` is literally "192.168.1.21" — and `mergeHosts` took `s.name || s.addr` unconditionally. The fallback only ever fired for an EMPTY name, so a name that was already a copy of the address sailed through as if it were meaningful, and the row printed the address twice: once as its title, once as its subtitle. The friendly name was in hand the whole time. The row is built by joining the saved record to the live advert, and that advert carries the host's actual hostname — the join was already trusted for address, port, online and OS, and only the name was read from the saved side alone. So treat a name equal to the record's own address as the placeholder it is and yield to the advert. A real saved name still wins, even when stale: it may be one the user chose, and an advert must never silently overwrite it. The comparison is against the SAVED address, so a host that moved DHCP lease still recognises its old address as a placeholder rather than mistaking it for a chosen name. Checked against the Deck that reported this, over its actual store and browse: three online rows turn into home-worker-5, ENRICOS-DESKTOP and steamdeck, the four offline ones keep their address (nothing is advertising a better name for them yet), and a user-chosen name survives a conflicting advert. --- clients/decky/src/hooks.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/clients/decky/src/hooks.ts b/clients/decky/src/hooks.ts index 8f2fde12..7c7c4c7d 100644 --- a/clients/decky/src/hooks.ts +++ b/clients/decky/src/hooks.ts @@ -122,6 +122,25 @@ function advertMatchesSaved(a: DiscoveredHost, s: SavedHost): boolean { ); } +/** + * The label a saved row shows. + * + * A saved record whose name IS its own address is a PLACEHOLDER, not a choice: `hosts add` + * falls back to the address when the pairing path had nothing better, so the row ends up + * captioned with the same string it already prints underneath. When the box is on the air it + * is advertising its actual hostname — prefer that, and the row reads "home-worker-5" instead + * of "192.168.1.21". + * + * A real saved name always wins over the advert, even a stale one: it may be a name the user + * chose, and a live advert must never quietly overwrite that. Compared against the SAVED + * address, so a host that moved DHCP lease still recognises its old address as a placeholder. + */ +function hostLabel(s: SavedHost, advert?: DiscoveredHost): string { + const placeholder = !s.name || s.name === s.addr || s.name === `${s.addr}:${s.port}`; + if (!placeholder) return s.name; + return advert?.name || s.name || s.addr; +} + /** * Join the saved store and the live browse into the rows the panel draws. * @@ -134,7 +153,7 @@ export function mergeHosts(saved: SavedHost[], discovered: DiscoveredHost[]): Ho // Prefer a live advert's address: the host may have moved since it was last saved. const advert = discovered.find((a) => advertMatchesSaved(a, s)); return { - name: s.name || s.addr, + name: hostLabel(s, advert), addr: advert?.addr ?? s.addr, port: advert?.port ?? s.port, fp: s.fp_hex,