Merge pull request #327 from uriva/fix/linux-wayland-hud-drag

fix(linux): allow dragging HUD overlay on Wayland
This commit is contained in:
webadderall
2026-04-24 00:18:56 +10:00
committed by GitHub
2 changed files with 33 additions and 1 deletions
+22
View File
@@ -301,6 +301,16 @@ let hudDragFixedSize: { width: number; height: number } | null = null;
ipcMain.on("hud-overlay-drag", (_event, phase: string, screenX: number, screenY: number) => {
if (!hudOverlayWindow || hudOverlayWindow.isDestroyed()) return;
// On Linux the compositor (especially Wayland) refuses programmatic window
// placement, so BrowserWindow.setBounds() with x/y is silently ignored and
// the HUD appears "stuck". The renderer marks the drag handle as
// -webkit-app-region: drag on Linux, letting the OS move the window for us.
// The resulting position is captured by the win.on("moved", ...) listener
// below so `hudUserPosition` stays in sync for in-place resize.
if (process.platform === "linux") {
return;
}
if (phase === "start") {
const bounds = hudOverlayWindow.getBounds();
hudDragOffset = { x: screenX - bounds.x, y: screenY - bounds.y };
@@ -511,6 +521,18 @@ export function createHudOverlayWindow(): BrowserWindow {
hudOverlayWindow = win;
// On Linux the HUD is dragged by the OS via -webkit-app-region (Wayland
// forbids client-side positioning). Mirror the resulting bounds into
// hudUserPosition so subsequent expand/collapse resizes stay in place
// instead of snapping back to the default centered spot.
if (process.platform === "linux") {
win.on("moved", () => {
if (win.isDestroyed()) return;
const { x, y } = win.getBounds();
hudUserPosition = { x, y };
});
}
// Reset the user's saved HUD position when displays change so the bar
// doesn't end up stranded off-screen after a monitor is disconnected.
const screen = getScreen();
+11 -1
View File
@@ -1587,7 +1587,17 @@ export function LaunchWindow() {
className={`${styles.bar} mb-2`}
>
<div
className="flex items-center px-0.5 cursor-grab active:cursor-grabbing"
// On Linux (especially Wayland) the compositor owns window
// placement, so BrowserWindow.setBounds() is silently ignored.
// Fall back to a native OS drag via -webkit-app-region on the
// handle. We still need JS pointer handlers in webcam-preview
// mode (which translates via CSS inside the window), so only
// mark the handle as a native drag region for the IPC path.
className={`flex items-center px-0.5 cursor-grab active:cursor-grabbing ${
platform === "linux" && !showRecordingWebcamPreview
? styles.electronDrag
: ""
}`}
onPointerDown={handleHudBarPointerDown}
onPointerMove={handleHudBarPointerMove}
onPointerUp={handleHudBarPointerUp}