Fix HUD overlay height sizing

This commit is contained in:
webadderall
2026-03-20 20:18:41 +11:00
parent ea4f47ada3
commit c1cb222995
4 changed files with 63 additions and 10 deletions
+1
View File
@@ -28,6 +28,7 @@ interface Window {
hudOverlayClose: () => void;
setHudOverlayExpanded: (expanded: boolean) => void;
setHudOverlayCompactWidth: (width: number) => void;
setHudOverlayMeasuredHeight: (height: number, expanded: boolean) => void;
getHudOverlayCaptureProtection: () => Promise<{ success: boolean; enabled: boolean }>;
setHudOverlayCaptureProtection: (
enabled: boolean,
+3
View File
@@ -13,6 +13,9 @@ contextBridge.exposeInMainWorld("electronAPI", {
setHudOverlayCompactWidth: (width: number) => {
ipcRenderer.send("set-hud-overlay-compact-width", width);
},
setHudOverlayMeasuredHeight: (height: number, expanded: boolean) => {
ipcRenderer.send("set-hud-overlay-measured-height", height, expanded);
},
getHudOverlayCaptureProtection: () => {
return ipcRenderer.invoke("get-hud-overlay-capture-protection");
},
+36 -3
View File
@@ -29,10 +29,12 @@ const HUD_EDGE_MARGIN_DIP = 16;
const HUD_SHADOW_BLEED_DIP = 36;
const HUD_MIN_WINDOW_WIDTH = 560;
const HUD_COMPACT_HEIGHT = 96;
const HUD_EXPANDED_HEIGHT = 520 + HUD_SHADOW_BLEED_DIP;
const HUD_MIN_EXPANDED_HEIGHT = 520 + HUD_SHADOW_BLEED_DIP;
let hudOverlayExpanded = false;
let hudOverlayCompactWidth = HUD_MIN_WINDOW_WIDTH;
let hudOverlayCompactHeight = HUD_COMPACT_HEIGHT;
let hudOverlayExpandedHeight = HUD_MIN_EXPANDED_HEIGHT;
function isHudOverlayCaptureProtectionSupported(): boolean {
return process.platform !== "linux";
@@ -86,7 +88,11 @@ function getHudOverlayBounds(expanded: boolean) {
maxWindowWidth,
Math.max(HUD_MIN_WINDOW_WIDTH, Math.round(hudOverlayCompactWidth)),
);
const windowHeight = expanded ? HUD_EXPANDED_HEIGHT : HUD_COMPACT_HEIGHT;
const maxWindowHeight = Math.max(HUD_COMPACT_HEIGHT, workArea.height - HUD_EDGE_MARGIN_DIP * 2);
const desiredHeight = expanded
? Math.max(HUD_MIN_EXPANDED_HEIGHT, Math.round(hudOverlayExpandedHeight))
: Math.max(HUD_COMPACT_HEIGHT, Math.round(hudOverlayCompactHeight));
const windowHeight = Math.min(maxWindowHeight, desiredHeight);
const bottomClearanceDip = Math.round((HUD_BOTTOM_CLEARANCE_CM / CM_PER_INCH) * DIP_PER_INCH);
const screenBottom = bounds.y + bounds.height;
const workAreaBottom = workArea.y + workArea.height;
@@ -152,6 +158,33 @@ ipcMain.on("set-hud-overlay-compact-width", (_event, width: number) => {
applyHudOverlayBounds(hudOverlayExpanded);
});
ipcMain.on("set-hud-overlay-measured-height", (_event, height: number, expanded: boolean) => {
if (!Number.isFinite(height)) {
return;
}
const primaryDisplay = getScreen().getPrimaryDisplay();
const maxWindowHeight = Math.max(
HUD_COMPACT_HEIGHT,
primaryDisplay.workArea.height - HUD_EDGE_MARGIN_DIP * 2,
);
const nextHeight = Math.min(maxWindowHeight, Math.max(HUD_COMPACT_HEIGHT, Math.round(height)));
if (expanded) {
if (nextHeight === hudOverlayExpandedHeight) {
return;
}
hudOverlayExpandedHeight = Math.max(HUD_MIN_EXPANDED_HEIGHT, nextHeight);
} else {
if (nextHeight === hudOverlayCompactHeight) {
return;
}
hudOverlayCompactHeight = nextHeight;
}
applyHudOverlayBounds(hudOverlayExpanded);
});
ipcMain.handle("get-hud-overlay-capture-protection", () => {
const enabled = loadHudOverlayCaptureProtectionSetting();
@@ -189,7 +222,7 @@ export function createHudOverlayWindow(): BrowserWindow {
height: initialBounds.height,
minWidth: HUD_MIN_WINDOW_WIDTH,
minHeight: HUD_COMPACT_HEIGHT,
maxHeight: HUD_EXPANDED_HEIGHT,
maxHeight: Math.max(HUD_COMPACT_HEIGHT, getScreen().getPrimaryDisplay().workArea.height - HUD_EDGE_MARGIN_DIP * 2),
x: initialBounds.x,
y: initialBounds.y,
frame: false,
+23 -7
View File
@@ -175,6 +175,7 @@ export function LaunchWindow() {
const [hideHudFromCapture, setHideHudFromCapture] = useState(true);
const [platform, setPlatform] = useState<string | null>(null);
const dropdownRef = useRef<HTMLDivElement>(null);
const hudContentRef = useRef<HTMLDivElement>(null);
const hudBarRef = useRef<HTMLDivElement>(null);
const webcamPreviewRef = useRef<HTMLVideoElement | null>(null);
@@ -360,32 +361,46 @@ export function LaunchWindow() {
}, [activeDropdown]);
useEffect(() => {
const hudContent = hudContentRef.current;
const hudBar = hudBarRef.current;
if (!hudBar || typeof ResizeObserver === "undefined") {
if (!hudContent || !hudBar || typeof ResizeObserver === "undefined") {
return;
}
let frameId = 0;
const reportWidth = () => {
const reportHudSize = () => {
frameId = 0;
const measuredWidth = Math.ceil(
Math.max(hudBar.getBoundingClientRect().width, hudBar.scrollWidth) + 24,
Math.max(
hudBar.getBoundingClientRect().width,
hudBar.scrollWidth,
hudContent.getBoundingClientRect().width,
hudContent.scrollWidth,
) + 24,
);
const measuredHeight = Math.ceil(
Math.max(hudContent.getBoundingClientRect().height, hudContent.scrollHeight) + 24,
);
window.electronAPI.setHudOverlayCompactWidth(measuredWidth);
window.electronAPI.setHudOverlayMeasuredHeight(
measuredHeight,
activeDropdown !== "none",
);
};
const scheduleWidthReport = () => {
const scheduleHudSizeReport = () => {
if (frameId !== 0) {
cancelAnimationFrame(frameId);
}
frameId = requestAnimationFrame(reportWidth);
frameId = requestAnimationFrame(reportHudSize);
};
scheduleWidthReport();
scheduleHudSizeReport();
const resizeObserver = new ResizeObserver(() => {
scheduleWidthReport();
scheduleHudSizeReport();
});
resizeObserver.observe(hudContent);
resizeObserver.observe(hudBar);
return () => {
@@ -633,6 +648,7 @@ export function LaunchWindow() {
ref={dropdownRef}
>
<div
ref={hudContentRef}
className="flex flex-col items-center overflow-visible"
>
{/* Only the visible HUD content should become interactive. */}