diff --git a/app.go b/app.go index ed03794..944508a 100644 --- a/app.go +++ b/app.go @@ -17774,3 +17774,29 @@ func (a *App) SetSpotTTLMinutes(min int) error { a.setSetting(keyClusterSpotTTL, strconv.Itoa(min)) return nil } + +// SetCompactHeight resizes the compact window to fit its content. +// +// The height used to be a constant "tuned so the compact entry strip fits in a +// single row". Constants tuned against a layout stop being true the moment the +// layout changes, and this one outlived a strip that had since lost a row — +// leaving a band of empty window under the fields. The frontend measures what +// it actually rendered and says so. +// +// Ignored unless compact is on, so nothing can shrink the normal window. +func (a *App) SetCompactHeight(h int) { + if a.ctx == nil || !a.compact { + return + } + // Bounded: a measurement of zero (a layout not yet painted) must not collapse + // the window to nothing, and no strip is ever 600px tall. + if h < 80 || h > 600 { + return + } + w, _ := wruntime.WindowGetSize(a.ctx) + if w <= 0 { + w = compactW + } + wruntime.WindowSetMinSize(a.ctx, 900, h) + wruntime.WindowSetSize(a.ctx, w, h) +} diff --git a/changelog.json b/changelog.json index 289be88..72679cb 100644 --- a/changelog.json +++ b/changelog.json @@ -7,14 +7,16 @@ "DX Cluster: a spot lifetime can be set — 5, 10, 15 minutes or your own value — after which spots leave the list and the band maps.", "Call lookup: QRZ.com now fills Name with the first name only, and optionally with the operator nickname instead.", "Entry form: a narrower left column, State beside the locator, and a new line with County, CQ, ITU and DXCC.", - "Station Control: the short and long path headings are repeated under the compass, at a readable size and clickable." + "Station Control: the short and long path headings are repeated under the compass, at a readable size and clickable.", + "Compact mode: the window now fits the entry strip instead of leaving a band of empty space below it." ], "fr": [ "Cluster : « Masquer les contactés » ne masque plus un spot qui est un nouveau préfixe, comté, carré ou parc dans une contrée déjà faite.", "Cluster DX : on peut fixer une durée de vie des spots — 5, 10, 15 minutes ou une valeur libre — au-delà de laquelle ils quittent la liste et les band maps.", "Recherche d indicatif : QRZ.com remplit désormais Nom avec le seul prénom, et au choix avec le surnom de l opérateur.", "Saisie : colonne de gauche plus étroite, État à côté du locator, et une nouvelle ligne Comté, CQ, ITU et DXCC.", - "Contrôle station : les azimuts court et long chemin sont repris sous la boussole, lisibles et cliquables." + "Contrôle station : les azimuts court et long chemin sont repris sous la boussole, lisibles et cliquables.", + "Mode compact : la fenêtre épouse la bande de saisie au lieu de laisser une bande vide en dessous." ] }, { diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index ae37c78..fd588f0 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -16,7 +16,7 @@ import { GetStartupStatus, CheckForUpdate, DownloadAndApplyUpdate, GetLiveStations, GetWhatsNew, GetChangelog, SMTPConfigured, SendLogToDeveloper, WorkedBefore, - SetCompactMode, + SetCompactMode, SetCompactHeight, GetCATState, SetCATFrequency, SetCATMode, SwitchCATRig, FlexApplyBandAntenna, FlexApplyBandPower, GetSecretStatus, UnlockSecrets, RefreshCtyDat, DownloadAllReferenceLists, @@ -529,6 +529,28 @@ export default function App() { setCompact(next); SetCompactMode(next); } + // Fit the compact window to what was actually rendered. + // + // The height was a constant "tuned so the compact entry strip fits in a single + // row". A constant tuned against a layout stops being true the moment the + // layout changes, and this one outlived a strip that had since lost a row — + // leaving a band of empty window under the fields. Measure instead. + const compactRootRef = useRef(null); + useEffect(() => { + if (!compact) return; + const fit = () => { + const el = compactRootRef.current; + if (!el) return; + // Rounded, so a sub-pixel reflow cannot start a resize loop. + // + the compact topbar, which is a fixed h-8 (32px), + a couple of pixels + // for the border so the strip is never clipped by one row of anti-aliasing. + SetCompactHeight(Math.round(el.getBoundingClientRect().height) + 32 + 2); + }; + const id = window.setTimeout(fit, 60); // let the strip paint first + const ro = new ResizeObserver(fit); + if (compactRootRef.current) ro.observe(compactRootRef.current); + return () => { window.clearTimeout(id); ro.disconnect(); }; + }, [compact]); // CAT — receives live rig state via Wails events. const [catState, setCatState] = useState({ enabled: false, connected: false } as any); @@ -5892,7 +5914,7 @@ export default function App() { Enter from any inside the strip logs the QSO. Radix Selects render as