Skip to content

Commit 316c973

Browse files
committed
fix: prevent browser webview from stealing keyboard shortcuts
Move the before-input-event handler from webview-focus IPC (which registered on webview webContents) to the tab's setWebContents handler in emain-tabview.ts. This ensures keyboard shortcuts like Cmd+Number tab switching work even when a browser webview has focus.
1 parent e4e77e7 commit 316c973

3 files changed

Lines changed: 28 additions & 43 deletions

File tree

emain/emain-ipc.ts

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { PNG } from "pngjs";
1010
import { Readable } from "stream";
1111
import { RpcApi } from "../frontend/app/store/wshclientapi";
1212
import { getWebServerEndpoint } from "../frontend/util/endpoints";
13-
import * as keyutil from "../frontend/util/keyutil";
1413
import { fireAndForget, parseDataUrl } from "../frontend/util/util";
1514
import {
1615
incrementTermCommandsDurable,
@@ -22,16 +21,13 @@ import {
2221
import { createBuilderWindow, getAllBuilderWindows, getBuilderWindowByWebContentsId } from "./emain-builder";
2322
import { callWithOriginalXdgCurrentDesktopAsync, unamePlatform } from "./emain-platform";
2423
import { getWaveTabViewByWebContentsId } from "./emain-tabview";
25-
import { handleCtrlShiftState } from "./emain-util";
24+
import { setWebviewKeys } from "./emain-util";
2625
import { getWaveVersion } from "./emain-wavesrv";
2726
import { createNewWaveWindow, getWaveWindowByWebContentsId } from "./emain-window";
2827
import { ElectronWshClient } from "./emain-wsh";
2928

3029
const electronApp = electron.app;
3130

32-
let webviewFocusId: number = null;
33-
let webviewKeys: string[] = [];
34-
3531
export function openBuilderWindow(appId?: string) {
3632
const normalizedAppId = appId || "";
3733
const existingBuilderWindows = getAllBuilderWindows();
@@ -280,48 +276,12 @@ export function initIpcHandlers() {
280276
event.returnValue = event.sender.getZoomFactor();
281277
});
282278

283-
const hasBeforeInputRegisteredMap = new Map<number, boolean>();
284-
285-
electron.ipcMain.on("webview-focus", (event: Electron.IpcMainEvent, focusedId: number) => {
286-
webviewFocusId = focusedId;
279+
electron.ipcMain.on("webview-focus", (_event: Electron.IpcMainEvent, focusedId: number) => {
287280
console.log("webview-focus", focusedId);
288-
if (focusedId == null) {
289-
return;
290-
}
291-
const parentWc = event.sender;
292-
const webviewWc = electron.webContents.fromId(focusedId);
293-
if (webviewWc == null) {
294-
webviewFocusId = null;
295-
return;
296-
}
297-
if (!hasBeforeInputRegisteredMap.get(focusedId)) {
298-
hasBeforeInputRegisteredMap.set(focusedId, true);
299-
webviewWc.on("before-input-event", (e, input) => {
300-
let waveEvent = keyutil.adaptFromElectronKeyEvent(input);
301-
handleCtrlShiftState(parentWc, waveEvent);
302-
if (webviewFocusId != focusedId) {
303-
return;
304-
}
305-
if (input.type != "keyDown") {
306-
return;
307-
}
308-
for (let keyDesc of webviewKeys) {
309-
if (keyutil.checkKeyPressed(waveEvent, keyDesc)) {
310-
e.preventDefault();
311-
parentWc.send("reinject-key", waveEvent);
312-
console.log("webview reinject-key", keyDesc);
313-
return;
314-
}
315-
}
316-
});
317-
webviewWc.on("destroyed", () => {
318-
hasBeforeInputRegisteredMap.delete(focusedId);
319-
});
320-
}
321281
});
322282

323283
electron.ipcMain.on("register-global-webview-keys", (event, keys: string[]) => {
324-
webviewKeys = keys ?? [];
284+
setWebviewKeys(keys);
325285
});
326286

327287
electron.ipcMain.on("set-keyboard-chord-mode", (event) => {

emain/emain-tabview.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { setWasActive } from "./emain-activity";
1212
import { getElectronAppBasePath, isDevVite, unamePlatform } from "./emain-platform";
1313
import {
1414
decreaseZoomLevel,
15+
getWebviewKeys,
1516
handleCtrlShiftFocus,
1617
handleCtrlShiftState,
1718
increaseZoomLevel,
@@ -322,6 +323,20 @@ export async function getOrCreateWebViewForTab(waveWindowId: string, tabId: stri
322323
tabView.webContents.send("webview-new-window", wc.id, details);
323324
return { action: "deny" };
324325
});
326+
wc.on("before-input-event", (e, input) => {
327+
if (input.type != "keyDown") {
328+
return;
329+
}
330+
const waveEvent = adaptFromElectronKeyEvent(input);
331+
handleCtrlShiftState(tabView.webContents, waveEvent);
332+
for (const keyDesc of getWebviewKeys()) {
333+
if (checkKeyPressed(waveEvent, keyDesc)) {
334+
e.preventDefault();
335+
tabView.webContents.send("reinject-key", waveEvent);
336+
return;
337+
}
338+
}
339+
});
325340
});
326341
tabView.webContents.on("before-input-event", (e, input) => {
327342
const waveEvent = adaptFromElectronKeyEvent(input);

emain/emain-util.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ export const WaveAppPathVarName = "WAVETERM_APP_PATH";
88
export const WaveAppResourcesPathVarName = "WAVETERM_RESOURCES_PATH";
99
export const WaveAppElectronExecPath = "WAVETERM_ELECTRONEXECPATH";
1010

11+
let webviewKeys: string[] = [];
12+
13+
export function getWebviewKeys(): string[] {
14+
return webviewKeys;
15+
}
16+
17+
export function setWebviewKeys(keys: string[]) {
18+
webviewKeys = keys ?? [];
19+
}
20+
1121
const MinZoomLevel = 0.4;
1222
const MaxZoomLevel = 2.6;
1323
const ZoomDelta = 0.2;

0 commit comments

Comments
 (0)