mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-25 07:16:02 +00:00
fix(windows): align Win10 HUD restore with interactive fallback
This commit is contained in:
+29
-22
@@ -8,8 +8,8 @@ import {
|
||||
dialog,
|
||||
ipcMain,
|
||||
Menu,
|
||||
nativeImage,
|
||||
Notification,
|
||||
nativeImage,
|
||||
session,
|
||||
systemPreferences,
|
||||
Tray,
|
||||
@@ -22,27 +22,28 @@ import {
|
||||
killWindowsCaptureProcess,
|
||||
registerIpcHandlers,
|
||||
} from "./ipc/handlers";
|
||||
import type { UpdateToastPayload } from "./updater";
|
||||
import {
|
||||
checkForAppUpdates,
|
||||
deferUpdateReminder,
|
||||
dismissUpdateToast,
|
||||
downloadAvailableUpdate,
|
||||
deferUpdateReminder,
|
||||
getCurrentUpdateToastPayload,
|
||||
getUpdaterLogPath,
|
||||
getUpdateStatusSummary,
|
||||
installDownloadedUpdateNow,
|
||||
previewUpdateToast,
|
||||
skipAvailableUpdateVersion,
|
||||
setupAutoUpdates,
|
||||
skipAvailableUpdateVersion,
|
||||
} from "./updater";
|
||||
import type { UpdateToastPayload } from "./updater";
|
||||
import {
|
||||
createEditorWindow,
|
||||
createHudOverlayWindow,
|
||||
createSourceSelectorWindow,
|
||||
getUpdateToastWindow,
|
||||
getHudOverlayWindow,
|
||||
getUpdateToastWindow,
|
||||
hideUpdateToastWindow,
|
||||
isHudOverlayMousePassthroughSupported,
|
||||
showUpdateToastWindow,
|
||||
} from "./windows";
|
||||
|
||||
@@ -76,14 +77,8 @@ async function logSmokeExportGpuDiagnostics() {
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(
|
||||
"[smoke-export] GPU feature status",
|
||||
JSON.stringify(app.getGPUFeatureStatus()),
|
||||
);
|
||||
console.log(
|
||||
"[smoke-export] GPU info",
|
||||
JSON.stringify(await app.getGPUInfo("basic")),
|
||||
);
|
||||
console.log("[smoke-export] GPU feature status", JSON.stringify(app.getGPUFeatureStatus()));
|
||||
console.log("[smoke-export] GPU info", JSON.stringify(await app.getGPUInfo("basic")));
|
||||
} catch (error) {
|
||||
console.warn("[smoke-export] Failed to read GPU diagnostics:", error);
|
||||
}
|
||||
@@ -207,11 +202,17 @@ function focusOrCreateMainWindow() {
|
||||
return;
|
||||
}
|
||||
|
||||
// On Win32, calling show/moveTop/focus on the transparent HUD overlay
|
||||
// permanently corrupts setIgnoreMouseEvents forwarding, making it
|
||||
// click-through. Only focus the editor window; the HUD is alwaysOnTop
|
||||
// so it doesn't need explicit focus.
|
||||
if (process.platform === "win32" && !isEditorWindow(mainWindow)) {
|
||||
// On Win32 with mouse passthrough enabled (Win11+), calling
|
||||
// show/moveTop/focus on the transparent HUD overlay permanently corrupts
|
||||
// setIgnoreMouseEvents forwarding, making it click-through. Only focus
|
||||
// the editor window; the HUD is alwaysOnTop so it doesn't need explicit
|
||||
// focus. On Win10 (passthrough disabled), the HUD is always interactive
|
||||
// and can be safely shown/restored.
|
||||
if (
|
||||
process.platform === "win32" &&
|
||||
!isEditorWindow(mainWindow) &&
|
||||
isHudOverlayMousePassthroughSupported()
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -229,7 +230,7 @@ function focusOrCreateMainWindow() {
|
||||
* operation that may alter focus or z-order so that hover detection keeps working.
|
||||
*/
|
||||
function reassertHudOverlayMouseState() {
|
||||
if (process.platform !== "win32") {
|
||||
if (process.platform !== "win32" || !isHudOverlayMousePassthroughSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -448,7 +449,9 @@ function sendUpdateToastToWindows(channel: "update-toast-state", payload: unknow
|
||||
return false;
|
||||
}
|
||||
|
||||
const notificationKey = [updatePayload.phase, updatePayload.version, updatePayload.detail].join(":");
|
||||
const notificationKey = [updatePayload.phase, updatePayload.version, updatePayload.detail].join(
|
||||
":",
|
||||
);
|
||||
if (activeUpdateNotificationKey === notificationKey) {
|
||||
return true;
|
||||
}
|
||||
@@ -723,10 +726,14 @@ app.whenReady().then(async () => {
|
||||
const cameraStatus = systemPreferences.getMediaAccessStatus("camera");
|
||||
const micStatus = systemPreferences.getMediaAccessStatus("microphone");
|
||||
if (cameraStatus !== "granted") {
|
||||
console.warn(`[permissions] Camera access is "${cameraStatus}" — webcam may not work. Check Windows Settings > Privacy > Camera.`);
|
||||
console.warn(
|
||||
`[permissions] Camera access is "${cameraStatus}" — webcam may not work. Check Windows Settings > Privacy > Camera.`,
|
||||
);
|
||||
}
|
||||
if (micStatus !== "granted") {
|
||||
console.warn(`[permissions] Microphone access is "${micStatus}" — mic recording may not work. Check Windows Settings > Privacy > Microphone.`);
|
||||
console.warn(
|
||||
`[permissions] Microphone access is "${micStatus}" — mic recording may not work. Check Windows Settings > Privacy > Microphone.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+28
-6
@@ -1,5 +1,6 @@
|
||||
import fs from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { app, BrowserWindow, ipcMain } from "electron";
|
||||
@@ -96,8 +97,26 @@ function isHudOverlayCaptureProtectionSupported(): boolean {
|
||||
return process.platform !== "linux";
|
||||
}
|
||||
|
||||
function isHudOverlayMousePassthroughSupported(): boolean {
|
||||
return process.platform !== "linux";
|
||||
function getWindowsBuildNumber(): number | null {
|
||||
if (process.platform !== "win32") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const build = Number.parseInt(os.release().split(".")[2] ?? "", 10);
|
||||
return Number.isFinite(build) ? build : null;
|
||||
}
|
||||
|
||||
export function isHudOverlayMousePassthroughSupported(): boolean {
|
||||
if (process.platform === "linux") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const build = getWindowsBuildNumber();
|
||||
if (build !== null && build < 22000) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function loadHudOverlayCaptureProtectionSetting(): boolean {
|
||||
@@ -138,7 +157,9 @@ function persistHudOverlayCaptureProtectionSetting(enabled: boolean): void {
|
||||
|
||||
function getScreen() {
|
||||
if (!app.isReady()) {
|
||||
throw new Error("getScreen() called before app is ready. Ensure all screen access happens after app.whenReady().");
|
||||
throw new Error(
|
||||
"getScreen() called before app is ready. Ensure all screen access happens after app.whenReady().",
|
||||
);
|
||||
}
|
||||
return nodeRequire("electron").screen as typeof import("electron").screen;
|
||||
}
|
||||
@@ -405,12 +426,13 @@ export function createHudOverlayWindow(): BrowserWindow {
|
||||
win.setIgnoreMouseEvents(true, { forward: true });
|
||||
}
|
||||
|
||||
// On Windows 10, focus changes (e.g. showing a native notification) can break
|
||||
// On Windows 11+, focus changes (e.g. showing a native notification) can break
|
||||
// setIgnoreMouseEvents forwarding on a transparent always-on-top window, making
|
||||
// it permanently click-through without hover detection. Re-initialise the
|
||||
// pass-through-with-forwarding state whenever the window gains focus by toggling
|
||||
// the flag off then back on so the native WS_EX_TRANSPARENT flag is fully reset.
|
||||
if (process.platform === "win32") {
|
||||
// On Windows 10 (build < 22000) passthrough is disabled entirely, so skip this.
|
||||
if (process.platform === "win32" && isHudOverlayMousePassthroughSupported()) {
|
||||
win.on("focus", () => {
|
||||
if (!win.isDestroyed()) {
|
||||
win.setIgnoreMouseEvents(false);
|
||||
@@ -429,7 +451,7 @@ export function createHudOverlayWindow(): BrowserWindow {
|
||||
if (!win.isDestroyed()) {
|
||||
win.show();
|
||||
win.moveTop();
|
||||
if (process.platform === "win32") {
|
||||
if (process.platform === "win32" && isHudOverlayMousePassthroughSupported()) {
|
||||
win.setIgnoreMouseEvents(false);
|
||||
setTimeout(() => {
|
||||
if (!win.isDestroyed()) {
|
||||
|
||||
Reference in New Issue
Block a user