electrobun 1.18.1 → 1.18.4-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -14
- package/dash.config.ts +28 -0
- package/dist/api/browser/global.d.ts +6 -0
- package/dist/api/browser/index.ts +162 -44
- package/dist/api/{bun → config}/ElectrobunConfig.ts +109 -40
- package/dist/api/config/validate.test.ts +31 -0
- package/dist/api/config/validate.ts +19 -0
- package/dist/api/preload/.generated/compiled.ts +8 -0
- package/dist/api/{bun/preload → preload}/build.ts +6 -6
- package/dist/api/{bun/preload → preload}/encryption.ts +11 -5
- package/dist/api/{bun/preload → preload}/globals.d.ts +8 -0
- package/dist/api/{bun/preload → preload}/index.ts +18 -8
- package/dist/api/{bun/preload → preload}/webviewTag.ts +32 -3
- package/dist/api/{bun/preload → preload}/wgpuTag.ts +33 -2
- package/dist/api/{bun → sdks/bun}/__tests__/ffi-contract.test.ts +6 -9
- package/dist/api/{bun → sdks/bun}/core/BrowserView.ts +96 -55
- package/dist/api/{bun → sdks/bun}/core/BrowserWindow.ts +20 -30
- package/dist/api/{bun → sdks/bun}/core/BuildConfig.ts +32 -5
- package/dist/api/{bun → sdks/bun}/core/GpuWindow.ts +20 -7
- package/dist/api/sdks/bun/core/Socket.ts +22 -0
- package/dist/api/{bun → sdks/bun}/core/Tray.ts +33 -32
- package/dist/api/{bun → sdks/bun}/core/Updater.ts +10 -10
- package/dist/api/{bun → sdks/bun}/core/Utils.ts +3 -5
- package/dist/api/{bun → sdks/bun}/core/WGPUView.ts +43 -13
- package/dist/api/{bun → sdks/bun}/index.ts +39 -10
- package/dist/api/{bun → sdks/bun}/proc/native.ts +942 -746
- package/dist/api/{bun → sdks/bun}/webGPU.ts +1 -1
- package/dist/api/{bun → sdks/bun}/webgpuAdapter.ts +40 -33
- package/dist/api/shared/build-dependencies.test.ts +48 -0
- package/dist/api/shared/build-dependencies.ts +46 -0
- package/dist/api/shared/go-version.ts +3 -0
- package/dist/api/shared/odin-version.ts +6 -0
- package/dist/api/shared/rust-version.ts +3 -0
- package/dist/go-sdk/callbacks.go +260 -0
- package/dist/go-sdk/electrobun.go +2021 -0
- package/dist/main.js +35 -28
- package/dist/odin-sdk/electrobun/electrobun.odin +2337 -0
- package/dist/preload-full.js +948 -0
- package/dist/preload-sandboxed.js +111 -0
- package/dist/rust-sdk/electrobun.rs +2396 -0
- package/dist/zig-sdk/electrobun.zig +2005 -0
- package/package.json +5 -29
- package/src/cli/index.ts +868 -654
- package/bin/electrobun.cjs +0 -169
- package/dist/api/bun/core/Socket.ts +0 -205
- package/dist/api/bun/core/windowIds.ts +0 -5
- package/dist/api/bun/preload/.generated/compiled.ts +0 -8
- package/dist/api/shared/bun-version.ts +0 -3
- /package/dist/api/{bun/preload → preload}/dragRegions.ts +0 -0
- /package/dist/api/{bun/preload → preload}/events.ts +0 -0
- /package/dist/api/{bun/preload → preload}/index-sandboxed.ts +0 -0
- /package/dist/api/{bun/preload → preload}/internalRpc.ts +0 -0
- /package/dist/api/{bun/preload → preload}/overlaySync.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/core/ApplicationMenu.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/core/ContextMenu.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/core/Paths.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/core/menuRoles.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/ApplicationEvents.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/event.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/eventEmitter.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/trayEvents.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/webviewEvents.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/windowEvents.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/proc/linux.md +0 -0
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import { join } from "path";
|
|
1
|
+
import { dirname, join } from "path";
|
|
2
|
+
import { createReadStream } from "node:fs";
|
|
2
3
|
import electrobunEventEmitter from "../events/eventEmitter";
|
|
3
4
|
import ElectrobunEvent from "../events/event";
|
|
4
5
|
import { BrowserView } from "../core/BrowserView";
|
|
5
6
|
import { WGPUView } from "../core/WGPUView";
|
|
6
|
-
import { Tray } from "../core/Tray";
|
|
7
7
|
import {
|
|
8
8
|
preloadScript,
|
|
9
9
|
preloadScriptSandboxed,
|
|
10
|
-
} from "
|
|
10
|
+
} from "../../../preload/.generated/compiled";
|
|
11
11
|
|
|
12
12
|
// Menu data reference system to avoid serialization overhead
|
|
13
13
|
const menuDataRegistry = new Map<string, any>();
|
|
14
14
|
let menuDataCounter = 0;
|
|
15
|
-
|
|
16
15
|
function storeMenuData(data: any): string {
|
|
17
16
|
const id = `menuData_${++menuDataCounter}`;
|
|
18
17
|
menuDataRegistry.set(id, data);
|
|
@@ -70,142 +69,586 @@ import {
|
|
|
70
69
|
toArrayBuffer,
|
|
71
70
|
type Pointer,
|
|
72
71
|
} from "bun:ffi";
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
|
|
73
|
+
function getElectrobunLibraryPathCandidates(fileName: string) {
|
|
74
|
+
const candidates = new Set<string>();
|
|
75
|
+
candidates.add(join(process.cwd(), fileName));
|
|
76
|
+
if (process.argv0) {
|
|
77
|
+
candidates.add(join(dirname(process.argv0), fileName));
|
|
78
|
+
}
|
|
79
|
+
return Array.from(candidates);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function tryDlopenCandidates<T extends Record<string, { args: FFIType[]; returns: FFIType }>>(
|
|
83
|
+
fileName: string,
|
|
84
|
+
symbols: T,
|
|
85
|
+
) {
|
|
86
|
+
let lastError: unknown = null;
|
|
87
|
+
for (const candidatePath of getElectrobunLibraryPathCandidates(fileName)) {
|
|
88
|
+
try {
|
|
89
|
+
return dlopen(candidatePath, symbols);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
lastError = error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
throw lastError ?? new Error(`Failed to load ${fileName}`);
|
|
95
|
+
}
|
|
75
96
|
|
|
76
97
|
function getWindowPtr(winId: number) {
|
|
77
|
-
return (
|
|
78
|
-
|
|
98
|
+
return core?.symbols.getWindowPointer(winId) || null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getCoreLastError(): string | null {
|
|
102
|
+
const error = core?.symbols.electrobun_core_last_error();
|
|
103
|
+
if (!error) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const message = error.toString();
|
|
108
|
+
return message.length > 0 ? message : null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let webviewRuntimeConfigured = false;
|
|
112
|
+
|
|
113
|
+
function ensureWebviewRuntimeConfigured() {
|
|
114
|
+
if (webviewRuntimeConfigured) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const configured = core?.symbols.configureWebviewRuntime(
|
|
119
|
+
0,
|
|
120
|
+
toCString(preloadScript),
|
|
121
|
+
toCString(preloadScriptSandboxed),
|
|
79
122
|
);
|
|
123
|
+
|
|
124
|
+
if (!configured) {
|
|
125
|
+
throw getCoreLastError() || "Failed to configure webview runtime";
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
webviewRuntimeConfigured = true;
|
|
80
129
|
}
|
|
81
130
|
|
|
82
|
-
|
|
131
|
+
const core = (() => {
|
|
83
132
|
try {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
133
|
+
const coreFileName =
|
|
134
|
+
process.platform === "win32"
|
|
135
|
+
? "ElectrobunCore.dll"
|
|
136
|
+
: `libElectrobunCore.${suffix}`;
|
|
137
|
+
return tryDlopenCandidates(coreFileName, {
|
|
138
|
+
electrobun_core_last_error: {
|
|
139
|
+
args: [],
|
|
140
|
+
returns: FFIType.cstring,
|
|
141
|
+
},
|
|
142
|
+
getWindowStyle: {
|
|
143
|
+
args: [
|
|
144
|
+
FFIType.bool,
|
|
145
|
+
FFIType.bool,
|
|
146
|
+
FFIType.bool,
|
|
147
|
+
FFIType.bool,
|
|
148
|
+
FFIType.bool,
|
|
149
|
+
FFIType.bool,
|
|
150
|
+
FFIType.bool,
|
|
151
|
+
FFIType.bool,
|
|
152
|
+
FFIType.bool,
|
|
153
|
+
FFIType.bool,
|
|
154
|
+
FFIType.bool,
|
|
155
|
+
FFIType.bool,
|
|
156
|
+
],
|
|
157
|
+
returns: FFIType.u32,
|
|
158
|
+
},
|
|
159
|
+
createWindow: {
|
|
91
160
|
args: [
|
|
92
|
-
FFIType.u32, // windowId
|
|
93
161
|
FFIType.f64,
|
|
94
|
-
FFIType.f64, // x, y
|
|
95
162
|
FFIType.f64,
|
|
96
|
-
FFIType.f64,
|
|
97
|
-
FFIType.
|
|
98
|
-
FFIType.
|
|
99
|
-
FFIType.
|
|
100
|
-
FFIType.
|
|
101
|
-
FFIType.
|
|
102
|
-
FFIType.
|
|
103
|
-
FFIType.
|
|
104
|
-
FFIType.
|
|
105
|
-
FFIType.
|
|
106
|
-
FFIType.function,
|
|
107
|
-
FFIType.function,
|
|
163
|
+
FFIType.f64,
|
|
164
|
+
FFIType.f64,
|
|
165
|
+
FFIType.u32,
|
|
166
|
+
FFIType.cstring,
|
|
167
|
+
FFIType.bool,
|
|
168
|
+
FFIType.cstring,
|
|
169
|
+
FFIType.bool,
|
|
170
|
+
FFIType.bool,
|
|
171
|
+
FFIType.f64,
|
|
172
|
+
FFIType.f64,
|
|
173
|
+
FFIType.function,
|
|
174
|
+
FFIType.function,
|
|
175
|
+
FFIType.function,
|
|
176
|
+
FFIType.function,
|
|
177
|
+
FFIType.function,
|
|
178
|
+
FFIType.function,
|
|
108
179
|
],
|
|
180
|
+
returns: FFIType.u32,
|
|
181
|
+
},
|
|
182
|
+
getWindowPointer: {
|
|
183
|
+
args: [FFIType.u32],
|
|
109
184
|
returns: FFIType.ptr,
|
|
110
185
|
},
|
|
111
186
|
setWindowTitle: {
|
|
187
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
188
|
+
returns: FFIType.void,
|
|
189
|
+
},
|
|
190
|
+
minimizeWindow: {
|
|
191
|
+
args: [FFIType.u32],
|
|
192
|
+
returns: FFIType.void,
|
|
193
|
+
},
|
|
194
|
+
restoreWindow: {
|
|
195
|
+
args: [FFIType.u32],
|
|
196
|
+
returns: FFIType.void,
|
|
197
|
+
},
|
|
198
|
+
isWindowMinimized: {
|
|
199
|
+
args: [FFIType.u32],
|
|
200
|
+
returns: FFIType.bool,
|
|
201
|
+
},
|
|
202
|
+
maximizeWindow: {
|
|
203
|
+
args: [FFIType.u32],
|
|
204
|
+
returns: FFIType.void,
|
|
205
|
+
},
|
|
206
|
+
unmaximizeWindow: {
|
|
207
|
+
args: [FFIType.u32],
|
|
208
|
+
returns: FFIType.void,
|
|
209
|
+
},
|
|
210
|
+
isWindowMaximized: {
|
|
211
|
+
args: [FFIType.u32],
|
|
212
|
+
returns: FFIType.bool,
|
|
213
|
+
},
|
|
214
|
+
showWindow: {
|
|
215
|
+
args: [FFIType.u32, FFIType.bool],
|
|
216
|
+
returns: FFIType.void,
|
|
217
|
+
},
|
|
218
|
+
activateWindow: {
|
|
219
|
+
args: [FFIType.u32],
|
|
220
|
+
returns: FFIType.void,
|
|
221
|
+
},
|
|
222
|
+
hideWindow: {
|
|
223
|
+
args: [FFIType.u32],
|
|
224
|
+
returns: FFIType.void,
|
|
225
|
+
},
|
|
226
|
+
closeWindow: {
|
|
227
|
+
args: [FFIType.u32],
|
|
228
|
+
returns: FFIType.void,
|
|
229
|
+
},
|
|
230
|
+
setWindowFullScreen: {
|
|
231
|
+
args: [FFIType.u32, FFIType.bool],
|
|
232
|
+
returns: FFIType.void,
|
|
233
|
+
},
|
|
234
|
+
isWindowFullScreen: {
|
|
235
|
+
args: [FFIType.u32],
|
|
236
|
+
returns: FFIType.bool,
|
|
237
|
+
},
|
|
238
|
+
setWindowAlwaysOnTop: {
|
|
239
|
+
args: [FFIType.u32, FFIType.bool],
|
|
240
|
+
returns: FFIType.void,
|
|
241
|
+
},
|
|
242
|
+
isWindowAlwaysOnTop: {
|
|
243
|
+
args: [FFIType.u32],
|
|
244
|
+
returns: FFIType.bool,
|
|
245
|
+
},
|
|
246
|
+
setWindowVisibleOnAllWorkspaces: {
|
|
247
|
+
args: [FFIType.u32, FFIType.bool],
|
|
248
|
+
returns: FFIType.void,
|
|
249
|
+
},
|
|
250
|
+
isWindowVisibleOnAllWorkspaces: {
|
|
251
|
+
args: [FFIType.u32],
|
|
252
|
+
returns: FFIType.bool,
|
|
253
|
+
},
|
|
254
|
+
setWindowPosition: {
|
|
255
|
+
args: [FFIType.u32, FFIType.f64, FFIType.f64],
|
|
256
|
+
returns: FFIType.void,
|
|
257
|
+
},
|
|
258
|
+
setWindowButtonPosition: {
|
|
259
|
+
args: [FFIType.u32, FFIType.f64, FFIType.f64],
|
|
260
|
+
returns: FFIType.void,
|
|
261
|
+
},
|
|
262
|
+
setWindowSize: {
|
|
263
|
+
args: [FFIType.u32, FFIType.f64, FFIType.f64],
|
|
264
|
+
returns: FFIType.void,
|
|
265
|
+
},
|
|
266
|
+
setWindowFrame: {
|
|
267
|
+
args: [FFIType.u32, FFIType.f64, FFIType.f64, FFIType.f64, FFIType.f64],
|
|
268
|
+
returns: FFIType.void,
|
|
269
|
+
},
|
|
270
|
+
getWindowFrame: {
|
|
271
|
+
args: [FFIType.u32, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr],
|
|
272
|
+
returns: FFIType.void,
|
|
273
|
+
},
|
|
274
|
+
configureWebviewRuntime: {
|
|
275
|
+
args: [
|
|
276
|
+
FFIType.u32,
|
|
277
|
+
FFIType.cstring,
|
|
278
|
+
FFIType.cstring,
|
|
279
|
+
],
|
|
280
|
+
returns: FFIType.bool,
|
|
281
|
+
},
|
|
282
|
+
createWebview: {
|
|
283
|
+
args: [
|
|
284
|
+
FFIType.u32,
|
|
285
|
+
FFIType.u32,
|
|
286
|
+
FFIType.cstring,
|
|
287
|
+
FFIType.cstring,
|
|
288
|
+
FFIType.f64,
|
|
289
|
+
FFIType.f64,
|
|
290
|
+
FFIType.f64,
|
|
291
|
+
FFIType.f64,
|
|
292
|
+
FFIType.bool,
|
|
293
|
+
FFIType.cstring,
|
|
294
|
+
FFIType.function,
|
|
295
|
+
FFIType.function,
|
|
296
|
+
FFIType.function,
|
|
297
|
+
FFIType.function,
|
|
298
|
+
FFIType.function,
|
|
299
|
+
FFIType.cstring,
|
|
300
|
+
FFIType.cstring,
|
|
301
|
+
FFIType.cstring,
|
|
302
|
+
FFIType.bool,
|
|
303
|
+
FFIType.bool,
|
|
304
|
+
FFIType.bool,
|
|
305
|
+
],
|
|
306
|
+
returns: FFIType.u32,
|
|
307
|
+
},
|
|
308
|
+
getWebviewPointer: {
|
|
309
|
+
args: [FFIType.u32],
|
|
310
|
+
returns: FFIType.ptr,
|
|
311
|
+
},
|
|
312
|
+
resizeWebview: {
|
|
112
313
|
args: [
|
|
113
|
-
FFIType.
|
|
114
|
-
FFIType.
|
|
314
|
+
FFIType.u32,
|
|
315
|
+
FFIType.f64,
|
|
316
|
+
FFIType.f64,
|
|
317
|
+
FFIType.f64,
|
|
318
|
+
FFIType.f64,
|
|
319
|
+
FFIType.cstring,
|
|
115
320
|
],
|
|
116
321
|
returns: FFIType.void,
|
|
117
322
|
},
|
|
118
|
-
|
|
323
|
+
loadURLInWebView: {
|
|
324
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
325
|
+
returns: FFIType.void,
|
|
326
|
+
},
|
|
327
|
+
loadHTMLInWebView: {
|
|
328
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
329
|
+
returns: FFIType.void,
|
|
330
|
+
},
|
|
331
|
+
updatePreloadScriptToWebView: {
|
|
332
|
+
args: [FFIType.u32, FFIType.cstring, FFIType.cstring, FFIType.bool],
|
|
333
|
+
returns: FFIType.void,
|
|
334
|
+
},
|
|
335
|
+
webviewCanGoBack: {
|
|
336
|
+
args: [FFIType.u32],
|
|
337
|
+
returns: FFIType.bool,
|
|
338
|
+
},
|
|
339
|
+
webviewCanGoForward: {
|
|
340
|
+
args: [FFIType.u32],
|
|
341
|
+
returns: FFIType.bool,
|
|
342
|
+
},
|
|
343
|
+
webviewGoBack: {
|
|
344
|
+
args: [FFIType.u32],
|
|
345
|
+
returns: FFIType.void,
|
|
346
|
+
},
|
|
347
|
+
webviewGoForward: {
|
|
348
|
+
args: [FFIType.u32],
|
|
349
|
+
returns: FFIType.void,
|
|
350
|
+
},
|
|
351
|
+
webviewReload: {
|
|
352
|
+
args: [FFIType.u32],
|
|
353
|
+
returns: FFIType.void,
|
|
354
|
+
},
|
|
355
|
+
webviewRemove: {
|
|
356
|
+
args: [FFIType.u32],
|
|
357
|
+
returns: FFIType.void,
|
|
358
|
+
},
|
|
359
|
+
setWebviewHTMLContent: {
|
|
360
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
361
|
+
returns: FFIType.void,
|
|
362
|
+
},
|
|
363
|
+
webviewSetTransparent: {
|
|
364
|
+
args: [FFIType.u32, FFIType.bool],
|
|
365
|
+
returns: FFIType.void,
|
|
366
|
+
},
|
|
367
|
+
webviewSetPassthrough: {
|
|
368
|
+
args: [FFIType.u32, FFIType.bool],
|
|
369
|
+
returns: FFIType.void,
|
|
370
|
+
},
|
|
371
|
+
webviewSetHidden: {
|
|
372
|
+
args: [FFIType.u32, FFIType.bool],
|
|
373
|
+
returns: FFIType.void,
|
|
374
|
+
},
|
|
375
|
+
setWebviewNavigationRules: {
|
|
376
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
377
|
+
returns: FFIType.void,
|
|
378
|
+
},
|
|
379
|
+
webviewFindInPage: {
|
|
380
|
+
args: [FFIType.u32, FFIType.cstring, FFIType.bool, FFIType.bool],
|
|
381
|
+
returns: FFIType.void,
|
|
382
|
+
},
|
|
383
|
+
webviewStopFind: {
|
|
384
|
+
args: [FFIType.u32],
|
|
385
|
+
returns: FFIType.void,
|
|
386
|
+
},
|
|
387
|
+
evaluateJavaScriptWithNoCompletion: {
|
|
388
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
389
|
+
returns: FFIType.void,
|
|
390
|
+
},
|
|
391
|
+
sendHostMessageToWebviewViaTransport: {
|
|
392
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
393
|
+
returns: FFIType.bool,
|
|
394
|
+
},
|
|
395
|
+
popNextQueuedHostMessage: {
|
|
396
|
+
args: [FFIType.ptr],
|
|
397
|
+
returns: FFIType.ptr,
|
|
398
|
+
},
|
|
399
|
+
getHostMessageWakeupReadFD: {
|
|
400
|
+
args: [],
|
|
401
|
+
returns: FFIType.int,
|
|
402
|
+
},
|
|
403
|
+
freeCoreString: {
|
|
404
|
+
args: [FFIType.ptr],
|
|
405
|
+
returns: FFIType.void,
|
|
406
|
+
},
|
|
407
|
+
clearWebviewHostTransport: {
|
|
408
|
+
args: [FFIType.u32],
|
|
409
|
+
returns: FFIType.void,
|
|
410
|
+
},
|
|
411
|
+
dispatchHostWebviewEvent: {
|
|
412
|
+
args: [FFIType.u32, FFIType.cstring, FFIType.cstring],
|
|
413
|
+
returns: FFIType.bool,
|
|
414
|
+
},
|
|
415
|
+
sendInternalMessageToWebview: {
|
|
416
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
417
|
+
returns: FFIType.bool,
|
|
418
|
+
},
|
|
419
|
+
webviewOpenDevTools: {
|
|
420
|
+
args: [FFIType.u32],
|
|
421
|
+
returns: FFIType.void,
|
|
422
|
+
},
|
|
423
|
+
webviewCloseDevTools: {
|
|
424
|
+
args: [FFIType.u32],
|
|
425
|
+
returns: FFIType.void,
|
|
426
|
+
},
|
|
427
|
+
webviewToggleDevTools: {
|
|
428
|
+
args: [FFIType.u32],
|
|
429
|
+
returns: FFIType.void,
|
|
430
|
+
},
|
|
431
|
+
webviewSetPageZoom: {
|
|
432
|
+
args: [FFIType.u32, FFIType.f64],
|
|
433
|
+
returns: FFIType.void,
|
|
434
|
+
},
|
|
435
|
+
webviewGetPageZoom: {
|
|
436
|
+
args: [FFIType.u32],
|
|
437
|
+
returns: FFIType.f64,
|
|
438
|
+
},
|
|
439
|
+
createWGPUView: {
|
|
119
440
|
args: [
|
|
120
|
-
FFIType.
|
|
121
|
-
FFIType.
|
|
441
|
+
FFIType.u32,
|
|
442
|
+
FFIType.f64,
|
|
443
|
+
FFIType.f64,
|
|
444
|
+
FFIType.f64,
|
|
445
|
+
FFIType.f64,
|
|
446
|
+
FFIType.bool,
|
|
447
|
+
FFIType.bool,
|
|
448
|
+
FFIType.bool,
|
|
122
449
|
],
|
|
450
|
+
returns: FFIType.u32,
|
|
451
|
+
},
|
|
452
|
+
getWGPUViewPointer: {
|
|
453
|
+
args: [FFIType.u32],
|
|
454
|
+
returns: FFIType.ptr,
|
|
455
|
+
},
|
|
456
|
+
setWGPUViewFrame: {
|
|
457
|
+
args: [FFIType.u32, FFIType.f64, FFIType.f64, FFIType.f64, FFIType.f64],
|
|
123
458
|
returns: FFIType.void,
|
|
124
459
|
},
|
|
125
|
-
|
|
460
|
+
resizeWGPUView: {
|
|
461
|
+
args: [FFIType.u32, FFIType.f64, FFIType.f64, FFIType.f64, FFIType.f64, FFIType.cstring],
|
|
462
|
+
returns: FFIType.void,
|
|
463
|
+
},
|
|
464
|
+
setWGPUViewTransparent: {
|
|
465
|
+
args: [FFIType.u32, FFIType.bool],
|
|
466
|
+
returns: FFIType.void,
|
|
467
|
+
},
|
|
468
|
+
setWGPUViewPassthrough: {
|
|
469
|
+
args: [FFIType.u32, FFIType.bool],
|
|
470
|
+
returns: FFIType.void,
|
|
471
|
+
},
|
|
472
|
+
setWGPUViewHidden: {
|
|
473
|
+
args: [FFIType.u32, FFIType.bool],
|
|
474
|
+
returns: FFIType.void,
|
|
475
|
+
},
|
|
476
|
+
removeWGPUView: {
|
|
477
|
+
args: [FFIType.u32],
|
|
478
|
+
returns: FFIType.void,
|
|
479
|
+
},
|
|
480
|
+
getWGPUViewNativeHandle: {
|
|
481
|
+
args: [FFIType.u32],
|
|
482
|
+
returns: FFIType.ptr,
|
|
483
|
+
},
|
|
484
|
+
runWGPUViewTest: {
|
|
485
|
+
args: [FFIType.u32],
|
|
486
|
+
returns: FFIType.void,
|
|
487
|
+
},
|
|
488
|
+
createTray: {
|
|
489
|
+
args: [
|
|
490
|
+
FFIType.cstring,
|
|
491
|
+
FFIType.cstring,
|
|
492
|
+
FFIType.bool,
|
|
493
|
+
FFIType.u32,
|
|
494
|
+
FFIType.u32,
|
|
495
|
+
FFIType.function,
|
|
496
|
+
],
|
|
497
|
+
returns: FFIType.u32,
|
|
498
|
+
},
|
|
499
|
+
showTray: {
|
|
500
|
+
args: [FFIType.u32],
|
|
501
|
+
returns: FFIType.bool,
|
|
502
|
+
},
|
|
503
|
+
hideTray: {
|
|
504
|
+
args: [FFIType.u32],
|
|
505
|
+
returns: FFIType.void,
|
|
506
|
+
},
|
|
507
|
+
setTrayTitle: {
|
|
508
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
509
|
+
returns: FFIType.void,
|
|
510
|
+
},
|
|
511
|
+
setTrayImage: {
|
|
512
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
513
|
+
returns: FFIType.void,
|
|
514
|
+
},
|
|
515
|
+
setTrayMenu: {
|
|
516
|
+
args: [FFIType.u32, FFIType.cstring],
|
|
517
|
+
returns: FFIType.void,
|
|
518
|
+
},
|
|
519
|
+
removeTray: {
|
|
520
|
+
args: [FFIType.u32],
|
|
521
|
+
returns: FFIType.void,
|
|
522
|
+
},
|
|
523
|
+
getTrayBounds: {
|
|
524
|
+
args: [FFIType.u32],
|
|
525
|
+
returns: FFIType.cstring,
|
|
526
|
+
},
|
|
527
|
+
setApplicationMenu: {
|
|
528
|
+
args: [FFIType.cstring, FFIType.function],
|
|
529
|
+
returns: FFIType.void,
|
|
530
|
+
},
|
|
531
|
+
showContextMenu: {
|
|
532
|
+
args: [FFIType.cstring, FFIType.function],
|
|
533
|
+
returns: FFIType.void,
|
|
534
|
+
},
|
|
535
|
+
moveToTrash: {
|
|
536
|
+
args: [FFIType.cstring],
|
|
537
|
+
returns: FFIType.bool,
|
|
538
|
+
},
|
|
539
|
+
showItemInFolder: {
|
|
540
|
+
args: [FFIType.cstring],
|
|
541
|
+
returns: FFIType.void,
|
|
542
|
+
},
|
|
543
|
+
openExternal: {
|
|
544
|
+
args: [FFIType.cstring],
|
|
545
|
+
returns: FFIType.bool,
|
|
546
|
+
},
|
|
547
|
+
openPath: {
|
|
548
|
+
args: [FFIType.cstring],
|
|
549
|
+
returns: FFIType.bool,
|
|
550
|
+
},
|
|
551
|
+
showNotification: {
|
|
552
|
+
args: [
|
|
553
|
+
FFIType.cstring,
|
|
554
|
+
FFIType.cstring,
|
|
555
|
+
FFIType.cstring,
|
|
556
|
+
FFIType.bool,
|
|
557
|
+
],
|
|
558
|
+
returns: FFIType.void,
|
|
559
|
+
},
|
|
560
|
+
getAllDisplays: {
|
|
561
|
+
args: [],
|
|
562
|
+
returns: FFIType.cstring,
|
|
563
|
+
},
|
|
564
|
+
getPrimaryDisplay: {
|
|
565
|
+
args: [],
|
|
566
|
+
returns: FFIType.cstring,
|
|
567
|
+
},
|
|
568
|
+
getCursorScreenPoint: {
|
|
569
|
+
args: [],
|
|
570
|
+
returns: FFIType.cstring,
|
|
571
|
+
},
|
|
572
|
+
getMouseButtons: {
|
|
573
|
+
args: [],
|
|
574
|
+
returns: FFIType.u64,
|
|
575
|
+
},
|
|
576
|
+
openFileDialog: {
|
|
126
577
|
args: [
|
|
127
|
-
FFIType.
|
|
578
|
+
FFIType.cstring,
|
|
579
|
+
FFIType.cstring,
|
|
580
|
+
FFIType.int,
|
|
581
|
+
FFIType.int,
|
|
582
|
+
FFIType.int,
|
|
128
583
|
],
|
|
129
|
-
returns: FFIType.
|
|
130
|
-
},
|
|
131
|
-
hideWindow: {
|
|
132
|
-
args: [FFIType.ptr],
|
|
133
|
-
returns: FFIType.void,
|
|
584
|
+
returns: FFIType.cstring,
|
|
134
585
|
},
|
|
135
|
-
|
|
586
|
+
showMessageBox: {
|
|
136
587
|
args: [
|
|
137
|
-
FFIType.
|
|
588
|
+
FFIType.cstring,
|
|
589
|
+
FFIType.cstring,
|
|
590
|
+
FFIType.cstring,
|
|
591
|
+
FFIType.cstring,
|
|
592
|
+
FFIType.cstring,
|
|
593
|
+
FFIType.int,
|
|
594
|
+
FFIType.int,
|
|
138
595
|
],
|
|
139
|
-
returns: FFIType.
|
|
596
|
+
returns: FFIType.int,
|
|
140
597
|
},
|
|
141
|
-
|
|
142
|
-
args: [
|
|
143
|
-
returns: FFIType.
|
|
598
|
+
clipboardReadText: {
|
|
599
|
+
args: [],
|
|
600
|
+
returns: FFIType.cstring,
|
|
144
601
|
},
|
|
145
|
-
|
|
146
|
-
args: [FFIType.
|
|
602
|
+
clipboardWriteText: {
|
|
603
|
+
args: [FFIType.cstring],
|
|
147
604
|
returns: FFIType.void,
|
|
148
605
|
},
|
|
149
|
-
|
|
150
|
-
args: [FFIType.ptr],
|
|
151
|
-
returns: FFIType.bool,
|
|
152
|
-
},
|
|
153
|
-
maximizeWindow: {
|
|
606
|
+
clipboardReadImage: {
|
|
154
607
|
args: [FFIType.ptr],
|
|
155
|
-
returns: FFIType.
|
|
608
|
+
returns: FFIType.ptr,
|
|
156
609
|
},
|
|
157
|
-
|
|
158
|
-
args: [FFIType.ptr],
|
|
610
|
+
clipboardWriteImage: {
|
|
611
|
+
args: [FFIType.ptr, FFIType.u64],
|
|
159
612
|
returns: FFIType.void,
|
|
160
613
|
},
|
|
161
|
-
|
|
162
|
-
args: [
|
|
163
|
-
returns: FFIType.bool,
|
|
164
|
-
},
|
|
165
|
-
setWindowFullScreen: {
|
|
166
|
-
args: [FFIType.ptr, FFIType.bool],
|
|
614
|
+
clipboardClear: {
|
|
615
|
+
args: [],
|
|
167
616
|
returns: FFIType.void,
|
|
168
617
|
},
|
|
169
|
-
|
|
170
|
-
args: [
|
|
171
|
-
returns: FFIType.
|
|
618
|
+
clipboardAvailableFormats: {
|
|
619
|
+
args: [],
|
|
620
|
+
returns: FFIType.cstring,
|
|
172
621
|
},
|
|
173
|
-
|
|
174
|
-
args: [FFIType.
|
|
622
|
+
setDockIconVisible: {
|
|
623
|
+
args: [FFIType.bool],
|
|
175
624
|
returns: FFIType.void,
|
|
176
625
|
},
|
|
177
|
-
|
|
178
|
-
args: [
|
|
626
|
+
isDockIconVisible: {
|
|
627
|
+
args: [],
|
|
179
628
|
returns: FFIType.bool,
|
|
180
629
|
},
|
|
181
|
-
|
|
182
|
-
args: [FFIType.
|
|
630
|
+
setExitOnLastWindowClosed: {
|
|
631
|
+
args: [FFIType.bool],
|
|
183
632
|
returns: FFIType.void,
|
|
184
633
|
},
|
|
185
|
-
|
|
186
|
-
args: [FFIType.
|
|
187
|
-
returns: FFIType.bool,
|
|
188
|
-
},
|
|
189
|
-
setWindowPosition: {
|
|
190
|
-
args: [FFIType.ptr, FFIType.f64, FFIType.f64],
|
|
191
|
-
returns: FFIType.void,
|
|
192
|
-
},
|
|
193
|
-
setWindowButtonPosition: {
|
|
194
|
-
args: [FFIType.ptr, FFIType.f64, FFIType.f64],
|
|
195
|
-
returns: FFIType.void,
|
|
196
|
-
},
|
|
197
|
-
setWindowSize: {
|
|
198
|
-
args: [FFIType.ptr, FFIType.f64, FFIType.f64],
|
|
199
|
-
returns: FFIType.void,
|
|
200
|
-
},
|
|
201
|
-
setWindowFrame: {
|
|
202
|
-
args: [FFIType.ptr, FFIType.f64, FFIType.f64, FFIType.f64, FFIType.f64],
|
|
634
|
+
setQuitRequestedHandler: {
|
|
635
|
+
args: [FFIType.function],
|
|
203
636
|
returns: FFIType.void,
|
|
204
637
|
},
|
|
205
|
-
|
|
206
|
-
args: [FFIType.
|
|
638
|
+
quitGracefully: {
|
|
639
|
+
args: [FFIType.i32, FFIType.i32],
|
|
207
640
|
returns: FFIType.void,
|
|
208
641
|
},
|
|
642
|
+
});
|
|
643
|
+
} catch {
|
|
644
|
+
return null;
|
|
645
|
+
}
|
|
646
|
+
})();
|
|
647
|
+
|
|
648
|
+
export const native = (() => {
|
|
649
|
+
try {
|
|
650
|
+
const nativeWrapperFileName = `libNativeWrapper.${suffix}`;
|
|
651
|
+
return tryDlopenCandidates(nativeWrapperFileName, {
|
|
209
652
|
// webview
|
|
210
653
|
initWebview: {
|
|
211
654
|
args: [
|
|
@@ -222,13 +665,13 @@ export const native = (() => {
|
|
|
222
665
|
FFIType.function, // decideNavigation: *const fn (u32, [*:0]const u8) callconv(.C) bool,
|
|
223
666
|
FFIType.function, // webviewEventHandler: *const fn (u32, [*:0]const u8, [*:0]const u8) callconv(.C) void,
|
|
224
667
|
FFIType.function, // eventBridgeHandler: *const fn (u32, [*:0]const u8) callconv(.C) void (events only, always active)
|
|
225
|
-
FFIType.function, //
|
|
668
|
+
FFIType.function, // hostBridgePostmessageHandler: *const fn (u32, [*:0]const u8) callconv(.C) void (user RPC, disabled in sandbox)
|
|
226
669
|
FFIType.function, // internalBridgeHandler: *const fn (u32, [*:0]const u8) callconv(.C) void (internal RPC, disabled in sandbox)
|
|
227
670
|
FFIType.cstring, // electrobunPreloadScript
|
|
228
671
|
FFIType.cstring, // customPreloadScript
|
|
229
672
|
FFIType.cstring, // viewsRoot
|
|
230
673
|
FFIType.bool, // transparent
|
|
231
|
-
FFIType.bool, // sandbox - when true,
|
|
674
|
+
FFIType.bool, // sandbox - when true, hostBridge and internalBridge are not set up
|
|
232
675
|
],
|
|
233
676
|
returns: FFIType.ptr,
|
|
234
677
|
},
|
|
@@ -463,73 +906,6 @@ export const native = (() => {
|
|
|
463
906
|
args: [FFIType.ptr, FFIType.ptr],
|
|
464
907
|
returns: FFIType.ptr,
|
|
465
908
|
},
|
|
466
|
-
// Tray
|
|
467
|
-
createTray: {
|
|
468
|
-
args: [
|
|
469
|
-
FFIType.u32, // id
|
|
470
|
-
FFIType.cstring, // title
|
|
471
|
-
FFIType.cstring, // pathToImage
|
|
472
|
-
FFIType.bool, // isTemplate
|
|
473
|
-
FFIType.u32, // width
|
|
474
|
-
FFIType.u32, //height
|
|
475
|
-
FFIType.function, // trayItemHandler
|
|
476
|
-
],
|
|
477
|
-
returns: FFIType.ptr,
|
|
478
|
-
},
|
|
479
|
-
setTrayTitle: {
|
|
480
|
-
args: [FFIType.ptr, FFIType.cstring],
|
|
481
|
-
returns: FFIType.void,
|
|
482
|
-
},
|
|
483
|
-
setTrayImage: {
|
|
484
|
-
args: [FFIType.ptr, FFIType.cstring],
|
|
485
|
-
returns: FFIType.void,
|
|
486
|
-
},
|
|
487
|
-
setTrayMenu: {
|
|
488
|
-
args: [FFIType.ptr, FFIType.cstring],
|
|
489
|
-
returns: FFIType.void,
|
|
490
|
-
},
|
|
491
|
-
removeTray: {
|
|
492
|
-
args: [FFIType.ptr],
|
|
493
|
-
returns: FFIType.void,
|
|
494
|
-
},
|
|
495
|
-
getTrayBounds: {
|
|
496
|
-
args: [FFIType.ptr],
|
|
497
|
-
returns: FFIType.cstring,
|
|
498
|
-
},
|
|
499
|
-
setApplicationMenu: {
|
|
500
|
-
args: [FFIType.cstring, FFIType.function],
|
|
501
|
-
returns: FFIType.void,
|
|
502
|
-
},
|
|
503
|
-
showContextMenu: {
|
|
504
|
-
args: [FFIType.cstring, FFIType.function],
|
|
505
|
-
returns: FFIType.void,
|
|
506
|
-
},
|
|
507
|
-
moveToTrash: {
|
|
508
|
-
args: [FFIType.cstring],
|
|
509
|
-
returns: FFIType.bool,
|
|
510
|
-
},
|
|
511
|
-
showItemInFolder: {
|
|
512
|
-
args: [FFIType.cstring],
|
|
513
|
-
returns: FFIType.void,
|
|
514
|
-
},
|
|
515
|
-
openExternal: {
|
|
516
|
-
args: [FFIType.cstring],
|
|
517
|
-
returns: FFIType.bool,
|
|
518
|
-
},
|
|
519
|
-
openPath: {
|
|
520
|
-
args: [FFIType.cstring],
|
|
521
|
-
returns: FFIType.bool,
|
|
522
|
-
},
|
|
523
|
-
showNotification: {
|
|
524
|
-
args: [
|
|
525
|
-
FFIType.cstring, // title
|
|
526
|
-
FFIType.cstring, // body
|
|
527
|
-
FFIType.cstring, // subtitle
|
|
528
|
-
FFIType.bool, // silent
|
|
529
|
-
],
|
|
530
|
-
returns: FFIType.void,
|
|
531
|
-
},
|
|
532
|
-
|
|
533
909
|
// Global keyboard shortcuts
|
|
534
910
|
setGlobalShortcutCallback: {
|
|
535
911
|
args: [FFIType.function],
|
|
@@ -552,73 +928,6 @@ export const native = (() => {
|
|
|
552
928
|
returns: FFIType.bool,
|
|
553
929
|
},
|
|
554
930
|
|
|
555
|
-
// Screen API
|
|
556
|
-
getAllDisplays: {
|
|
557
|
-
args: [],
|
|
558
|
-
returns: FFIType.cstring,
|
|
559
|
-
},
|
|
560
|
-
getPrimaryDisplay: {
|
|
561
|
-
args: [],
|
|
562
|
-
returns: FFIType.cstring,
|
|
563
|
-
},
|
|
564
|
-
getCursorScreenPoint: {
|
|
565
|
-
args: [],
|
|
566
|
-
returns: FFIType.cstring,
|
|
567
|
-
},
|
|
568
|
-
getMouseButtons: {
|
|
569
|
-
args: [],
|
|
570
|
-
returns: FFIType.u64,
|
|
571
|
-
},
|
|
572
|
-
|
|
573
|
-
openFileDialog: {
|
|
574
|
-
args: [
|
|
575
|
-
FFIType.cstring,
|
|
576
|
-
FFIType.cstring,
|
|
577
|
-
FFIType.int,
|
|
578
|
-
FFIType.int,
|
|
579
|
-
FFIType.int,
|
|
580
|
-
],
|
|
581
|
-
returns: FFIType.cstring,
|
|
582
|
-
},
|
|
583
|
-
showMessageBox: {
|
|
584
|
-
args: [
|
|
585
|
-
FFIType.cstring, // type
|
|
586
|
-
FFIType.cstring, // title
|
|
587
|
-
FFIType.cstring, // message
|
|
588
|
-
FFIType.cstring, // detail
|
|
589
|
-
FFIType.cstring, // buttons (comma-separated)
|
|
590
|
-
FFIType.int, // defaultId
|
|
591
|
-
FFIType.int, // cancelId
|
|
592
|
-
],
|
|
593
|
-
returns: FFIType.int,
|
|
594
|
-
},
|
|
595
|
-
|
|
596
|
-
// Clipboard API
|
|
597
|
-
clipboardReadText: {
|
|
598
|
-
args: [],
|
|
599
|
-
returns: FFIType.cstring,
|
|
600
|
-
},
|
|
601
|
-
clipboardWriteText: {
|
|
602
|
-
args: [FFIType.cstring],
|
|
603
|
-
returns: FFIType.void,
|
|
604
|
-
},
|
|
605
|
-
clipboardReadImage: {
|
|
606
|
-
args: [FFIType.ptr], // pointer to size_t for output size
|
|
607
|
-
returns: FFIType.ptr, // pointer to PNG data
|
|
608
|
-
},
|
|
609
|
-
clipboardWriteImage: {
|
|
610
|
-
args: [FFIType.ptr, FFIType.u64], // PNG data pointer, size
|
|
611
|
-
returns: FFIType.void,
|
|
612
|
-
},
|
|
613
|
-
clipboardClear: {
|
|
614
|
-
args: [],
|
|
615
|
-
returns: FFIType.void,
|
|
616
|
-
},
|
|
617
|
-
clipboardAvailableFormats: {
|
|
618
|
-
args: [],
|
|
619
|
-
returns: FFIType.cstring,
|
|
620
|
-
},
|
|
621
|
-
|
|
622
931
|
// Session/Cookie API
|
|
623
932
|
sessionGetCookies: {
|
|
624
933
|
args: [FFIType.cstring, FFIType.cstring],
|
|
@@ -650,33 +959,7 @@ export const native = (() => {
|
|
|
650
959
|
args: [FFIType.function],
|
|
651
960
|
returns: FFIType.void,
|
|
652
961
|
},
|
|
653
|
-
setDockIconVisible: {
|
|
654
|
-
args: [FFIType.bool],
|
|
655
|
-
returns: FFIType.void,
|
|
656
|
-
},
|
|
657
|
-
isDockIconVisible: {
|
|
658
|
-
args: [],
|
|
659
|
-
returns: FFIType.bool,
|
|
660
|
-
},
|
|
661
962
|
|
|
662
|
-
// Window style utilities
|
|
663
|
-
getWindowStyle: {
|
|
664
|
-
args: [
|
|
665
|
-
FFIType.bool,
|
|
666
|
-
FFIType.bool,
|
|
667
|
-
FFIType.bool,
|
|
668
|
-
FFIType.bool,
|
|
669
|
-
FFIType.bool,
|
|
670
|
-
FFIType.bool,
|
|
671
|
-
FFIType.bool,
|
|
672
|
-
FFIType.bool,
|
|
673
|
-
FFIType.bool,
|
|
674
|
-
FFIType.bool,
|
|
675
|
-
FFIType.bool,
|
|
676
|
-
FFIType.bool,
|
|
677
|
-
],
|
|
678
|
-
returns: FFIType.u32,
|
|
679
|
-
},
|
|
680
963
|
// JSCallback utils for native code to use
|
|
681
964
|
setJSUtils: {
|
|
682
965
|
args: [
|
|
@@ -727,7 +1010,7 @@ export const native = (() => {
|
|
|
727
1010
|
}
|
|
728
1011
|
})();
|
|
729
1012
|
|
|
730
|
-
export const hasFFI = native !== null;
|
|
1013
|
+
export const hasFFI = native !== null && core !== null;
|
|
731
1014
|
|
|
732
1015
|
// PostMessage bridge for carrot workers (inter-carrot communication, host events).
|
|
733
1016
|
// Created when __bunnyCarrotBootstrap exists, regardless of FFI availability.
|
|
@@ -809,7 +1092,14 @@ function createFfiRequestProxy(ffiRequest: Record<string, Function>): Record<str
|
|
|
809
1092
|
return new Proxy(ffiRequest, {
|
|
810
1093
|
get(target, method: string) {
|
|
811
1094
|
if (typeof method !== "string") return target[method];
|
|
812
|
-
return (params?: unknown) =>
|
|
1095
|
+
return (params?: unknown) => {
|
|
1096
|
+
if (!bridge) {
|
|
1097
|
+
throw new Error(
|
|
1098
|
+
`Electrobun FFI is unavailable and no host bridge exists for request ${method}`,
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
return bridge.requestHost(method, params);
|
|
1102
|
+
};
|
|
813
1103
|
},
|
|
814
1104
|
});
|
|
815
1105
|
}
|
|
@@ -821,12 +1111,103 @@ function createFfiRequestProxy(ffiRequest: Record<string, Function>): Record<str
|
|
|
821
1111
|
// a zig bug I ran into last year. So check number of args in a signature when alignment issues occur.
|
|
822
1112
|
|
|
823
1113
|
// Non-null accessor for use inside _ffiImpl — these methods are only called when hasFFI is true.
|
|
1114
|
+
const core_ = core!;
|
|
824
1115
|
const native_ = native!;
|
|
1116
|
+
const queuedHostMessageWebviewIdBuf = new Uint32Array(1);
|
|
1117
|
+
|
|
1118
|
+
const drainQueuedHostMessages = () => {
|
|
1119
|
+
if (!core) {
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
for (;;) {
|
|
1124
|
+
let rawMessage = "";
|
|
1125
|
+
let webviewId = 0;
|
|
1126
|
+
const messagePtr = core_.symbols.popNextQueuedHostMessage(
|
|
1127
|
+
ptr(queuedHostMessageWebviewIdBuf),
|
|
1128
|
+
) as Pointer | null;
|
|
1129
|
+
|
|
1130
|
+
if (!messagePtr) {
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
try {
|
|
1135
|
+
webviewId = queuedHostMessageWebviewIdBuf[0]!;
|
|
1136
|
+
rawMessage = new CString(messagePtr).toString();
|
|
1137
|
+
if (!rawMessage) {
|
|
1138
|
+
continue;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
const webview = BrowserView.ensureWrapped(webviewId);
|
|
1142
|
+
if (!webview) {
|
|
1143
|
+
continue;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
webview.rpcHandler?.(JSON.parse(rawMessage));
|
|
1147
|
+
} catch (err) {
|
|
1148
|
+
console.error("error draining queued host message:", {
|
|
1149
|
+
webviewId,
|
|
1150
|
+
messagePreview: rawMessage.slice(0, 500),
|
|
1151
|
+
error:
|
|
1152
|
+
err instanceof Error
|
|
1153
|
+
? { name: err.name, message: err.message, stack: err.stack }
|
|
1154
|
+
: err,
|
|
1155
|
+
});
|
|
1156
|
+
} finally {
|
|
1157
|
+
core_.symbols.freeCoreString(messagePtr);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
};
|
|
1161
|
+
|
|
1162
|
+
let hostMessagePollingStarted = false;
|
|
1163
|
+
const startHostMessagePolling = (error?: unknown) => {
|
|
1164
|
+
if (hostMessagePollingStarted) {
|
|
1165
|
+
return;
|
|
1166
|
+
}
|
|
1167
|
+
hostMessagePollingStarted = true;
|
|
1168
|
+
const code =
|
|
1169
|
+
error && typeof error === "object" && "code" in error
|
|
1170
|
+
? String((error as { code?: unknown }).code)
|
|
1171
|
+
: "";
|
|
1172
|
+
if (error && code !== "EAGAIN") {
|
|
1173
|
+
console.error("host message wakeup stream failed, falling back to polling:", error);
|
|
1174
|
+
}
|
|
1175
|
+
setInterval(drainQueuedHostMessages, 16);
|
|
1176
|
+
drainQueuedHostMessages();
|
|
1177
|
+
};
|
|
1178
|
+
|
|
1179
|
+
if (core) {
|
|
1180
|
+
const wakeupReadFd = core_.symbols.getHostMessageWakeupReadFD();
|
|
1181
|
+
const isRealBunRuntime = typeof process.versions?.bun === "string";
|
|
1182
|
+
|
|
1183
|
+
if (isRealBunRuntime) {
|
|
1184
|
+
startHostMessagePolling();
|
|
1185
|
+
} else if (typeof wakeupReadFd === "number" && wakeupReadFd >= 0) {
|
|
1186
|
+
try {
|
|
1187
|
+
const wakeupStream = createReadStream("/dev/null", {
|
|
1188
|
+
fd: wakeupReadFd,
|
|
1189
|
+
autoClose: false,
|
|
1190
|
+
});
|
|
1191
|
+
wakeupStream.on("data", () => {
|
|
1192
|
+
drainQueuedHostMessages();
|
|
1193
|
+
});
|
|
1194
|
+
wakeupStream.on("error", (error) => {
|
|
1195
|
+
wakeupStream.destroy();
|
|
1196
|
+
startHostMessagePolling(error);
|
|
1197
|
+
});
|
|
1198
|
+
} catch (error) {
|
|
1199
|
+
startHostMessagePolling(error);
|
|
1200
|
+
}
|
|
1201
|
+
} else {
|
|
1202
|
+
startHostMessagePolling();
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
drainQueuedHostMessages();
|
|
1206
|
+
}
|
|
825
1207
|
|
|
826
1208
|
const _ffiImpl = {
|
|
827
1209
|
request: {
|
|
828
1210
|
createWindow: (params: {
|
|
829
|
-
id: number;
|
|
830
1211
|
url: string | null;
|
|
831
1212
|
title: string;
|
|
832
1213
|
frame: {
|
|
@@ -857,9 +1238,8 @@ const _ffiImpl = {
|
|
|
857
1238
|
x: number;
|
|
858
1239
|
y: number;
|
|
859
1240
|
};
|
|
860
|
-
}):
|
|
1241
|
+
}): number => {
|
|
861
1242
|
const {
|
|
862
|
-
id,
|
|
863
1243
|
url: _url,
|
|
864
1244
|
title,
|
|
865
1245
|
frame: { x, y, width, height },
|
|
@@ -884,7 +1264,7 @@ const _ffiImpl = {
|
|
|
884
1264
|
trafficLightOffset = { x: 0, y: 0 },
|
|
885
1265
|
} = params;
|
|
886
1266
|
|
|
887
|
-
const styleMask =
|
|
1267
|
+
const styleMask = core_.symbols.getWindowStyle(
|
|
888
1268
|
Borderless,
|
|
889
1269
|
Titled,
|
|
890
1270
|
Closable,
|
|
@@ -899,8 +1279,7 @@ const _ffiImpl = {
|
|
|
899
1279
|
HUDWindow,
|
|
900
1280
|
);
|
|
901
1281
|
|
|
902
|
-
const
|
|
903
|
-
id,
|
|
1282
|
+
const windowId = core_.symbols.createWindow(
|
|
904
1283
|
// frame
|
|
905
1284
|
x,
|
|
906
1285
|
y,
|
|
@@ -910,6 +1289,9 @@ const _ffiImpl = {
|
|
|
910
1289
|
// style
|
|
911
1290
|
toCString(titleBarStyle),
|
|
912
1291
|
transparent,
|
|
1292
|
+
toCString(title),
|
|
1293
|
+
hidden,
|
|
1294
|
+
activate,
|
|
913
1295
|
trafficLightOffset.x,
|
|
914
1296
|
trafficLightOffset.y,
|
|
915
1297
|
// callbacks
|
|
@@ -921,26 +1303,24 @@ const _ffiImpl = {
|
|
|
921
1303
|
windowKeyCallback,
|
|
922
1304
|
);
|
|
923
1305
|
|
|
924
|
-
if (!
|
|
925
|
-
throw "Failed to create window";
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
native_.symbols.setWindowTitle(windowPtr, toCString(title));
|
|
929
|
-
if (!hidden) {
|
|
930
|
-
native_.symbols.showWindow(windowPtr, activate);
|
|
1306
|
+
if (!windowId) {
|
|
1307
|
+
throw getCoreLastError() || "Failed to create window";
|
|
931
1308
|
}
|
|
932
1309
|
|
|
933
|
-
return
|
|
1310
|
+
return windowId;
|
|
1311
|
+
},
|
|
1312
|
+
getWindowPointer: (params: { winId: number }): Pointer | null => {
|
|
1313
|
+
return getWindowPtr(params.winId);
|
|
934
1314
|
},
|
|
935
1315
|
setTitle: (params: { winId: number; title: string }) => {
|
|
936
1316
|
const { winId, title } = params;
|
|
937
1317
|
const windowPtr = getWindowPtr(winId);
|
|
938
1318
|
|
|
939
1319
|
if (!windowPtr) {
|
|
940
|
-
throw `Can't
|
|
1320
|
+
throw `Can't set window title. Window no longer exists`;
|
|
941
1321
|
}
|
|
942
1322
|
|
|
943
|
-
|
|
1323
|
+
core_.symbols.setWindowTitle(winId, toCString(title));
|
|
944
1324
|
},
|
|
945
1325
|
|
|
946
1326
|
closeWindow: (params: { winId: number }) => {
|
|
@@ -952,7 +1332,7 @@ const _ffiImpl = {
|
|
|
952
1332
|
return;
|
|
953
1333
|
}
|
|
954
1334
|
|
|
955
|
-
|
|
1335
|
+
core_.symbols.closeWindow(winId);
|
|
956
1336
|
// Note: Cleanup of BrowserWindowMap happens in the windowCloseCallback
|
|
957
1337
|
},
|
|
958
1338
|
|
|
@@ -964,7 +1344,7 @@ const _ffiImpl = {
|
|
|
964
1344
|
throw `Can't show window. Window no longer exists`;
|
|
965
1345
|
}
|
|
966
1346
|
|
|
967
|
-
|
|
1347
|
+
core_.symbols.showWindow(winId, params.activate ?? true);
|
|
968
1348
|
},
|
|
969
1349
|
|
|
970
1350
|
activateWindow: (params: { winId: number }) => {
|
|
@@ -975,7 +1355,7 @@ const _ffiImpl = {
|
|
|
975
1355
|
throw `Can't activate window. Window no longer exists`;
|
|
976
1356
|
}
|
|
977
1357
|
|
|
978
|
-
|
|
1358
|
+
core_.symbols.activateWindow(winId);
|
|
979
1359
|
},
|
|
980
1360
|
|
|
981
1361
|
hideWindow: (params: { winId: number }) => {
|
|
@@ -986,7 +1366,7 @@ const _ffiImpl = {
|
|
|
986
1366
|
throw `Can't hide window. Window no longer exists`;
|
|
987
1367
|
}
|
|
988
1368
|
|
|
989
|
-
|
|
1369
|
+
core_.symbols.hideWindow(winId);
|
|
990
1370
|
},
|
|
991
1371
|
|
|
992
1372
|
minimizeWindow: (params: { winId: number }) => {
|
|
@@ -997,7 +1377,7 @@ const _ffiImpl = {
|
|
|
997
1377
|
throw `Can't minimize window. Window no longer exists`;
|
|
998
1378
|
}
|
|
999
1379
|
|
|
1000
|
-
|
|
1380
|
+
core_.symbols.minimizeWindow(winId);
|
|
1001
1381
|
},
|
|
1002
1382
|
|
|
1003
1383
|
restoreWindow: (params: { winId: number }) => {
|
|
@@ -1008,7 +1388,7 @@ const _ffiImpl = {
|
|
|
1008
1388
|
throw `Can't restore window. Window no longer exists`;
|
|
1009
1389
|
}
|
|
1010
1390
|
|
|
1011
|
-
|
|
1391
|
+
core_.symbols.restoreWindow(winId);
|
|
1012
1392
|
},
|
|
1013
1393
|
|
|
1014
1394
|
isWindowMinimized: (params: { winId: number }): boolean => {
|
|
@@ -1019,7 +1399,7 @@ const _ffiImpl = {
|
|
|
1019
1399
|
return false;
|
|
1020
1400
|
}
|
|
1021
1401
|
|
|
1022
|
-
return
|
|
1402
|
+
return core_.symbols.isWindowMinimized(winId);
|
|
1023
1403
|
},
|
|
1024
1404
|
|
|
1025
1405
|
maximizeWindow: (params: { winId: number }) => {
|
|
@@ -1030,7 +1410,7 @@ const _ffiImpl = {
|
|
|
1030
1410
|
throw `Can't maximize window. Window no longer exists`;
|
|
1031
1411
|
}
|
|
1032
1412
|
|
|
1033
|
-
|
|
1413
|
+
core_.symbols.maximizeWindow(winId);
|
|
1034
1414
|
},
|
|
1035
1415
|
|
|
1036
1416
|
unmaximizeWindow: (params: { winId: number }) => {
|
|
@@ -1041,7 +1421,7 @@ const _ffiImpl = {
|
|
|
1041
1421
|
throw `Can't unmaximize window. Window no longer exists`;
|
|
1042
1422
|
}
|
|
1043
1423
|
|
|
1044
|
-
|
|
1424
|
+
core_.symbols.unmaximizeWindow(winId);
|
|
1045
1425
|
},
|
|
1046
1426
|
|
|
1047
1427
|
isWindowMaximized: (params: { winId: number }): boolean => {
|
|
@@ -1052,7 +1432,7 @@ const _ffiImpl = {
|
|
|
1052
1432
|
return false;
|
|
1053
1433
|
}
|
|
1054
1434
|
|
|
1055
|
-
return
|
|
1435
|
+
return core_.symbols.isWindowMaximized(winId);
|
|
1056
1436
|
},
|
|
1057
1437
|
|
|
1058
1438
|
setWindowFullScreen: (params: { winId: number; fullScreen: boolean }) => {
|
|
@@ -1063,7 +1443,7 @@ const _ffiImpl = {
|
|
|
1063
1443
|
throw `Can't set fullscreen. Window no longer exists`;
|
|
1064
1444
|
}
|
|
1065
1445
|
|
|
1066
|
-
|
|
1446
|
+
core_.symbols.setWindowFullScreen(winId, fullScreen);
|
|
1067
1447
|
},
|
|
1068
1448
|
|
|
1069
1449
|
isWindowFullScreen: (params: { winId: number }): boolean => {
|
|
@@ -1074,7 +1454,7 @@ const _ffiImpl = {
|
|
|
1074
1454
|
return false;
|
|
1075
1455
|
}
|
|
1076
1456
|
|
|
1077
|
-
return
|
|
1457
|
+
return core_.symbols.isWindowFullScreen(winId);
|
|
1078
1458
|
},
|
|
1079
1459
|
|
|
1080
1460
|
setWindowAlwaysOnTop: (params: { winId: number; alwaysOnTop: boolean }) => {
|
|
@@ -1085,7 +1465,7 @@ const _ffiImpl = {
|
|
|
1085
1465
|
throw `Can't set always on top. Window no longer exists`;
|
|
1086
1466
|
}
|
|
1087
1467
|
|
|
1088
|
-
|
|
1468
|
+
core_.symbols.setWindowAlwaysOnTop(winId, alwaysOnTop);
|
|
1089
1469
|
},
|
|
1090
1470
|
|
|
1091
1471
|
isWindowAlwaysOnTop: (params: { winId: number }): boolean => {
|
|
@@ -1096,7 +1476,7 @@ const _ffiImpl = {
|
|
|
1096
1476
|
return false;
|
|
1097
1477
|
}
|
|
1098
1478
|
|
|
1099
|
-
return
|
|
1479
|
+
return core_.symbols.isWindowAlwaysOnTop(winId);
|
|
1100
1480
|
},
|
|
1101
1481
|
|
|
1102
1482
|
setWindowVisibleOnAllWorkspaces: (params: {
|
|
@@ -1104,55 +1484,55 @@ const _ffiImpl = {
|
|
|
1104
1484
|
visibleOnAllWorkspaces: boolean;
|
|
1105
1485
|
}) => {
|
|
1106
1486
|
const { winId, visibleOnAllWorkspaces } = params;
|
|
1107
|
-
const windowPtr =
|
|
1487
|
+
const windowPtr = getWindowPtr(winId);
|
|
1108
1488
|
|
|
1109
1489
|
if (!windowPtr) {
|
|
1110
1490
|
throw `Can't set visible on all workspaces. Window no longer exists`;
|
|
1111
1491
|
}
|
|
1112
1492
|
|
|
1113
|
-
|
|
1114
|
-
|
|
1493
|
+
core_.symbols.setWindowVisibleOnAllWorkspaces(
|
|
1494
|
+
winId,
|
|
1115
1495
|
visibleOnAllWorkspaces,
|
|
1116
1496
|
);
|
|
1117
1497
|
},
|
|
1118
1498
|
|
|
1119
1499
|
isWindowVisibleOnAllWorkspaces: (params: { winId: number }): boolean => {
|
|
1120
1500
|
const { winId } = params;
|
|
1121
|
-
const windowPtr =
|
|
1501
|
+
const windowPtr = getWindowPtr(winId);
|
|
1122
1502
|
|
|
1123
1503
|
if (!windowPtr) {
|
|
1124
1504
|
return false;
|
|
1125
1505
|
}
|
|
1126
1506
|
|
|
1127
|
-
return
|
|
1507
|
+
return core_.symbols.isWindowVisibleOnAllWorkspaces(winId);
|
|
1128
1508
|
},
|
|
1129
1509
|
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1510
|
+
setWindowPosition: (params: { winId: number; x: number; y: number }) => {
|
|
1511
|
+
const { winId, x, y } = params;
|
|
1512
|
+
const windowPtr = getWindowPtr(winId);
|
|
1133
1513
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1514
|
+
if (!windowPtr) {
|
|
1515
|
+
throw `Can't set window position. Window no longer exists`;
|
|
1516
|
+
}
|
|
1137
1517
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1518
|
+
core_.symbols.setWindowPosition(winId, x, y);
|
|
1519
|
+
},
|
|
1140
1520
|
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1521
|
+
setWindowButtonPosition: (params: { winId: number; x: number; y: number }) => {
|
|
1522
|
+
const { winId, x, y } = params;
|
|
1523
|
+
const windowPtr = getWindowPtr(winId);
|
|
1144
1524
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1525
|
+
if (!windowPtr) {
|
|
1526
|
+
throw `Can't set window button position. Window no longer exists`;
|
|
1527
|
+
}
|
|
1148
1528
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1529
|
+
core_.symbols.setWindowButtonPosition(winId, x, y);
|
|
1530
|
+
},
|
|
1151
1531
|
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1532
|
+
setWindowSize: (params: {
|
|
1533
|
+
winId: number;
|
|
1534
|
+
width: number;
|
|
1535
|
+
height: number;
|
|
1156
1536
|
}) => {
|
|
1157
1537
|
const { winId, width, height } = params;
|
|
1158
1538
|
const windowPtr = getWindowPtr(winId);
|
|
@@ -1161,7 +1541,7 @@ const _ffiImpl = {
|
|
|
1161
1541
|
throw `Can't set window size. Window no longer exists`;
|
|
1162
1542
|
}
|
|
1163
1543
|
|
|
1164
|
-
|
|
1544
|
+
core_.symbols.setWindowSize(winId, width, height);
|
|
1165
1545
|
},
|
|
1166
1546
|
|
|
1167
1547
|
setWindowFrame: (params: {
|
|
@@ -1178,7 +1558,7 @@ const _ffiImpl = {
|
|
|
1178
1558
|
throw `Can't set window frame. Window no longer exists`;
|
|
1179
1559
|
}
|
|
1180
1560
|
|
|
1181
|
-
|
|
1561
|
+
core_.symbols.setWindowFrame(winId, x, y, width, height);
|
|
1182
1562
|
},
|
|
1183
1563
|
|
|
1184
1564
|
getWindowFrame: (params: {
|
|
@@ -1197,8 +1577,8 @@ const _ffiImpl = {
|
|
|
1197
1577
|
const widthBuf = new Float64Array(1);
|
|
1198
1578
|
const heightBuf = new Float64Array(1);
|
|
1199
1579
|
|
|
1200
|
-
|
|
1201
|
-
|
|
1580
|
+
core_.symbols.getWindowFrame(
|
|
1581
|
+
winId,
|
|
1202
1582
|
ptr(xBuf),
|
|
1203
1583
|
ptr(yBuf),
|
|
1204
1584
|
ptr(widthBuf),
|
|
@@ -1212,17 +1592,12 @@ const _ffiImpl = {
|
|
|
1212
1592
|
height: heightBuf[0]!,
|
|
1213
1593
|
};
|
|
1214
1594
|
},
|
|
1215
|
-
|
|
1216
1595
|
createWebview: (params: {
|
|
1217
|
-
id: number;
|
|
1218
1596
|
windowId: number;
|
|
1597
|
+
hostWebviewId: number | null;
|
|
1219
1598
|
renderer: "cef" | "native";
|
|
1220
|
-
rpcPort: number;
|
|
1221
1599
|
secretKey: string;
|
|
1222
|
-
hostWebviewId: number | null;
|
|
1223
|
-
pipePrefix: string;
|
|
1224
1600
|
url: string | null;
|
|
1225
|
-
html: string | null;
|
|
1226
1601
|
partition: string | null;
|
|
1227
1602
|
preload: string | null;
|
|
1228
1603
|
viewsRoot: string | null;
|
|
@@ -1237,17 +1612,13 @@ const _ffiImpl = {
|
|
|
1237
1612
|
sandbox: boolean;
|
|
1238
1613
|
startTransparent: boolean;
|
|
1239
1614
|
startPassthrough: boolean;
|
|
1240
|
-
}):
|
|
1615
|
+
}): number => {
|
|
1241
1616
|
const {
|
|
1242
|
-
id,
|
|
1243
1617
|
windowId,
|
|
1618
|
+
hostWebviewId,
|
|
1244
1619
|
renderer,
|
|
1245
|
-
rpcPort,
|
|
1246
1620
|
secretKey,
|
|
1247
|
-
// hostWebviewId: number | null;
|
|
1248
|
-
// pipePrefix: string;
|
|
1249
1621
|
url,
|
|
1250
|
-
// html: string | null;
|
|
1251
1622
|
partition,
|
|
1252
1623
|
preload,
|
|
1253
1624
|
viewsRoot,
|
|
@@ -1257,62 +1628,11 @@ const _ffiImpl = {
|
|
|
1257
1628
|
startTransparent,
|
|
1258
1629
|
startPassthrough,
|
|
1259
1630
|
} = params;
|
|
1631
|
+
ensureWebviewRuntimeConfigured();
|
|
1260
1632
|
|
|
1261
|
-
const
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
const transparent = parentWindow?.transparent ?? false;
|
|
1265
|
-
|
|
1266
|
-
if (!windowPtr) {
|
|
1267
|
-
throw `Can't add webview to window. window no longer exists`;
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
// Dynamic setup per-webview (variables that change for each webview)
|
|
1271
|
-
// EventBridge is available for ALL webviews (including sandboxed) for event emission
|
|
1272
|
-
// InternalBridge and BunBridge are only available for trusted (non-sandboxed) webviews
|
|
1273
|
-
let dynamicPreload: string;
|
|
1274
|
-
let selectedPreloadScript: string;
|
|
1275
|
-
|
|
1276
|
-
if (sandbox) {
|
|
1277
|
-
// Sandboxed webview: minimal preload with only event emission capability
|
|
1278
|
-
// Note: We set up internalBridge for event emission fallback (until native code
|
|
1279
|
-
// adds dedicated eventBridge handler). The security is enforced because:
|
|
1280
|
-
// 1. Sandboxed preload has NO RPC code - it can only emit events
|
|
1281
|
-
// 2. No bunBridge is set up - no user RPC communication
|
|
1282
|
-
// 3. No secretKey/rpcPort - no encrypted socket RPC
|
|
1283
|
-
// 4. No webview tag support - can't create OOPIFs
|
|
1284
|
-
// Note: Check existing value first to preserve bridges already set by CEF's OnContextCreated
|
|
1285
|
-
dynamicPreload = `
|
|
1286
|
-
window.__electrobunWebviewId = ${id};
|
|
1287
|
-
window.__electrobunWindowId = ${windowId};
|
|
1288
|
-
window.__electrobunEventBridge = window.__electrobunEventBridge || window.webkit?.messageHandlers?.eventBridge || window.eventBridge || window.chrome?.webview?.hostObjects?.eventBridge;
|
|
1289
|
-
window.__electrobunInternalBridge = window.__electrobunInternalBridge || window.webkit?.messageHandlers?.internalBridge || window.internalBridge || window.chrome?.webview?.hostObjects?.internalBridge;
|
|
1290
|
-
`;
|
|
1291
|
-
selectedPreloadScript = preloadScriptSandboxed;
|
|
1292
|
-
} else {
|
|
1293
|
-
// Trusted webview: all bridges, full preload
|
|
1294
|
-
// Note: Check existing value first to preserve bridges already set by CEF's OnContextCreated
|
|
1295
|
-
dynamicPreload = `
|
|
1296
|
-
window.__electrobunWebviewId = ${id};
|
|
1297
|
-
window.__electrobunWindowId = ${windowId};
|
|
1298
|
-
window.__electrobunRpcSocketPort = ${rpcPort};
|
|
1299
|
-
window.__electrobunSecretKeyBytes = [${secretKey}];
|
|
1300
|
-
window.__electrobunEventBridge = window.__electrobunEventBridge || window.webkit?.messageHandlers?.eventBridge || window.eventBridge || window.chrome?.webview?.hostObjects?.eventBridge;
|
|
1301
|
-
window.__electrobunInternalBridge = window.__electrobunInternalBridge || window.webkit?.messageHandlers?.internalBridge || window.internalBridge || window.chrome?.webview?.hostObjects?.internalBridge;
|
|
1302
|
-
window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.messageHandlers?.bunBridge || window.bunBridge || window.chrome?.webview?.hostObjects?.bunBridge;
|
|
1303
|
-
`;
|
|
1304
|
-
selectedPreloadScript = preloadScript;
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
const electrobunPreload = dynamicPreload + selectedPreloadScript;
|
|
1308
|
-
|
|
1309
|
-
const customPreload = preload;
|
|
1310
|
-
|
|
1311
|
-
// Pre-set flags before initWebview (workaround for FFI param count limits)
|
|
1312
|
-
native_.symbols.setNextWebviewFlags(startTransparent, startPassthrough);
|
|
1313
|
-
const webviewPtr = native_.symbols.initWebview(
|
|
1314
|
-
id,
|
|
1315
|
-
windowPtr,
|
|
1633
|
+
const webviewId = core_.symbols.createWebview(
|
|
1634
|
+
windowId,
|
|
1635
|
+
hostWebviewId || 0,
|
|
1316
1636
|
toCString(renderer),
|
|
1317
1637
|
toCString(url || ""),
|
|
1318
1638
|
x,
|
|
@@ -1323,25 +1643,104 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1323
1643
|
toCString(partition || "persist:default"),
|
|
1324
1644
|
webviewDecideNavigation,
|
|
1325
1645
|
webviewEventJSCallback,
|
|
1326
|
-
eventBridgeHandler,
|
|
1327
|
-
|
|
1328
|
-
internalBridgeHandler,
|
|
1329
|
-
toCString(
|
|
1330
|
-
toCString(
|
|
1646
|
+
eventBridgeHandler,
|
|
1647
|
+
hostBridgePostmessageHandler,
|
|
1648
|
+
internalBridgeHandler,
|
|
1649
|
+
toCString(secretKey),
|
|
1650
|
+
toCString(preload || ""),
|
|
1331
1651
|
toCString(viewsRoot || ""),
|
|
1332
|
-
|
|
1333
|
-
|
|
1652
|
+
sandbox, // When true, hostBridge and internalBridge are not set up in native code
|
|
1653
|
+
startTransparent,
|
|
1654
|
+
startPassthrough,
|
|
1334
1655
|
);
|
|
1335
1656
|
|
|
1336
|
-
if (!
|
|
1337
|
-
throw "Failed to create webview";
|
|
1657
|
+
if (!webviewId) {
|
|
1658
|
+
throw getCoreLastError() || "Failed to create webview";
|
|
1338
1659
|
}
|
|
1339
1660
|
|
|
1340
|
-
return
|
|
1661
|
+
return webviewId;
|
|
1662
|
+
},
|
|
1663
|
+
getWebviewPointer: (params: { id: number }): Pointer | null => {
|
|
1664
|
+
return core_.symbols.getWebviewPointer(params.id) || null;
|
|
1665
|
+
},
|
|
1666
|
+
resizeWebview: (params: {
|
|
1667
|
+
id: number;
|
|
1668
|
+
frame: { x: number; y: number; width: number; height: number };
|
|
1669
|
+
masks?: string;
|
|
1670
|
+
}) => {
|
|
1671
|
+
const { id, frame: { x, y, width, height }, masks = "[]" } = params;
|
|
1672
|
+
core_.symbols.resizeWebview(id, x, y, width, height, toCString(masks));
|
|
1673
|
+
},
|
|
1674
|
+
loadURLInWebView: (params: { id: number; url: string }) => {
|
|
1675
|
+
core_.symbols.loadURLInWebView(params.id, toCString(params.url));
|
|
1676
|
+
},
|
|
1677
|
+
loadHTMLInWebView: (params: { id: number; html: string }) => {
|
|
1678
|
+
core_.symbols.loadHTMLInWebView(params.id, toCString(params.html));
|
|
1679
|
+
},
|
|
1680
|
+
updatePreloadScriptToWebView: (params: {
|
|
1681
|
+
id: number;
|
|
1682
|
+
scriptIdentifier: string;
|
|
1683
|
+
script: string;
|
|
1684
|
+
allFrames: boolean;
|
|
1685
|
+
}) => {
|
|
1686
|
+
core_.symbols.updatePreloadScriptToWebView(
|
|
1687
|
+
params.id,
|
|
1688
|
+
toCString(params.scriptIdentifier),
|
|
1689
|
+
toCString(params.script),
|
|
1690
|
+
params.allFrames,
|
|
1691
|
+
);
|
|
1692
|
+
},
|
|
1693
|
+
webviewCanGoBack: (params: { id: number }) => {
|
|
1694
|
+
return core_.symbols.webviewCanGoBack(params.id);
|
|
1695
|
+
},
|
|
1696
|
+
webviewCanGoForward: (params: { id: number }) => {
|
|
1697
|
+
return core_.symbols.webviewCanGoForward(params.id);
|
|
1698
|
+
},
|
|
1699
|
+
webviewGoBack: (params: { id: number }) => {
|
|
1700
|
+
core_.symbols.webviewGoBack(params.id);
|
|
1701
|
+
},
|
|
1702
|
+
webviewGoForward: (params: { id: number }) => {
|
|
1703
|
+
core_.symbols.webviewGoForward(params.id);
|
|
1704
|
+
},
|
|
1705
|
+
webviewReload: (params: { id: number }) => {
|
|
1706
|
+
core_.symbols.webviewReload(params.id);
|
|
1707
|
+
},
|
|
1708
|
+
webviewRemove: (params: { id: number }) => {
|
|
1709
|
+
core_.symbols.webviewRemove(params.id);
|
|
1710
|
+
},
|
|
1711
|
+
setWebviewHTMLContent: (params: { id: number; html: string }) => {
|
|
1712
|
+
core_.symbols.setWebviewHTMLContent(params.id, toCString(params.html));
|
|
1713
|
+
},
|
|
1714
|
+
webviewSetTransparent: (params: { id: number; transparent: boolean }) => {
|
|
1715
|
+
core_.symbols.webviewSetTransparent(params.id, params.transparent);
|
|
1716
|
+
},
|
|
1717
|
+
webviewSetPassthrough: (params: { id: number; passthrough: boolean }) => {
|
|
1718
|
+
core_.symbols.webviewSetPassthrough(params.id, params.passthrough);
|
|
1719
|
+
},
|
|
1720
|
+
webviewSetHidden: (params: { id: number; hidden: boolean }) => {
|
|
1721
|
+
core_.symbols.webviewSetHidden(params.id, params.hidden);
|
|
1722
|
+
},
|
|
1723
|
+
setWebviewNavigationRules: (params: { id: number; rulesJson: string }) => {
|
|
1724
|
+
core_.symbols.setWebviewNavigationRules(params.id, toCString(params.rulesJson));
|
|
1725
|
+
},
|
|
1726
|
+
webviewFindInPage: (params: {
|
|
1727
|
+
id: number;
|
|
1728
|
+
searchText: string;
|
|
1729
|
+
forward: boolean;
|
|
1730
|
+
matchCase: boolean;
|
|
1731
|
+
}) => {
|
|
1732
|
+
core_.symbols.webviewFindInPage(
|
|
1733
|
+
params.id,
|
|
1734
|
+
toCString(params.searchText),
|
|
1735
|
+
params.forward,
|
|
1736
|
+
params.matchCase,
|
|
1737
|
+
);
|
|
1738
|
+
},
|
|
1739
|
+
webviewStopFind: (params: { id: number }) => {
|
|
1740
|
+
core_.symbols.webviewStopFind(params.id);
|
|
1341
1741
|
},
|
|
1342
1742
|
|
|
1343
1743
|
createWGPUView: (params: {
|
|
1344
|
-
id: number;
|
|
1345
1744
|
windowId: number;
|
|
1346
1745
|
frame: {
|
|
1347
1746
|
x: number;
|
|
@@ -1352,9 +1751,8 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1352
1751
|
autoResize: boolean;
|
|
1353
1752
|
startTransparent: boolean;
|
|
1354
1753
|
startPassthrough: boolean;
|
|
1355
|
-
}):
|
|
1754
|
+
}): number => {
|
|
1356
1755
|
const {
|
|
1357
|
-
id,
|
|
1358
1756
|
windowId,
|
|
1359
1757
|
frame: { x, y, width, height },
|
|
1360
1758
|
autoResize,
|
|
@@ -1362,14 +1760,8 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1362
1760
|
startPassthrough,
|
|
1363
1761
|
} = params;
|
|
1364
1762
|
|
|
1365
|
-
const
|
|
1366
|
-
|
|
1367
|
-
throw `Can't add WGPUView to window. window no longer exists`;
|
|
1368
|
-
}
|
|
1369
|
-
|
|
1370
|
-
const viewPtr = native_.symbols.initWGPUView(
|
|
1371
|
-
id,
|
|
1372
|
-
windowPtr,
|
|
1763
|
+
const viewId = core_.symbols.createWGPUView(
|
|
1764
|
+
windowId,
|
|
1373
1765
|
x,
|
|
1374
1766
|
y,
|
|
1375
1767
|
width,
|
|
@@ -1379,11 +1771,14 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1379
1771
|
startPassthrough,
|
|
1380
1772
|
);
|
|
1381
1773
|
|
|
1382
|
-
if (!
|
|
1774
|
+
if (!viewId) {
|
|
1383
1775
|
throw "Failed to create WGPUView";
|
|
1384
1776
|
}
|
|
1385
1777
|
|
|
1386
|
-
return
|
|
1778
|
+
return viewId;
|
|
1779
|
+
},
|
|
1780
|
+
getWGPUViewPointer: (params: { id: number }): Pointer | null => {
|
|
1781
|
+
return core_.symbols.getWGPUViewPointer(params.id) || null;
|
|
1387
1782
|
},
|
|
1388
1783
|
|
|
1389
1784
|
wgpuViewSetFrame: (params: {
|
|
@@ -1393,16 +1788,8 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1393
1788
|
width: number;
|
|
1394
1789
|
height: number;
|
|
1395
1790
|
}) => {
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
console.error(
|
|
1399
|
-
`wgpuViewSetFrame: WGPUView not found or has no ptr for id ${params.id}`,
|
|
1400
|
-
);
|
|
1401
|
-
return;
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
native_.symbols.wgpuViewSetFrame(
|
|
1405
|
-
view.ptr,
|
|
1791
|
+
core_.symbols.setWGPUViewFrame(
|
|
1792
|
+
params.id,
|
|
1406
1793
|
params.x,
|
|
1407
1794
|
params.y,
|
|
1408
1795
|
params.width,
|
|
@@ -1411,97 +1798,83 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1411
1798
|
},
|
|
1412
1799
|
|
|
1413
1800
|
wgpuViewSetTransparent: (params: { id: number; transparent: boolean }) => {
|
|
1414
|
-
|
|
1415
|
-
if (!view?.ptr) {
|
|
1416
|
-
console.error(
|
|
1417
|
-
`wgpuViewSetTransparent: WGPUView not found or has no ptr for id ${params.id}`,
|
|
1418
|
-
);
|
|
1419
|
-
return;
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
native_.symbols.wgpuViewSetTransparent(view.ptr, params.transparent);
|
|
1801
|
+
core_.symbols.setWGPUViewTransparent(params.id, params.transparent);
|
|
1423
1802
|
},
|
|
1424
1803
|
|
|
1425
1804
|
wgpuViewSetPassthrough: (params: {
|
|
1426
1805
|
id: number;
|
|
1427
1806
|
passthrough: boolean;
|
|
1428
1807
|
}) => {
|
|
1429
|
-
|
|
1430
|
-
if (!view?.ptr) {
|
|
1431
|
-
console.error(
|
|
1432
|
-
`wgpuViewSetPassthrough: WGPUView not found or has no ptr for id ${params.id}`,
|
|
1433
|
-
);
|
|
1434
|
-
return;
|
|
1435
|
-
}
|
|
1436
|
-
|
|
1437
|
-
native_.symbols.wgpuViewSetPassthrough(view.ptr, params.passthrough);
|
|
1808
|
+
core_.symbols.setWGPUViewPassthrough(params.id, params.passthrough);
|
|
1438
1809
|
},
|
|
1439
1810
|
|
|
1440
1811
|
wgpuViewSetHidden: (params: { id: number; hidden: boolean }) => {
|
|
1441
|
-
|
|
1442
|
-
if (!view?.ptr) {
|
|
1443
|
-
console.error(
|
|
1444
|
-
`wgpuViewSetHidden: WGPUView not found or has no ptr for id ${params.id}`,
|
|
1445
|
-
);
|
|
1446
|
-
return;
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
native_.symbols.wgpuViewSetHidden(view.ptr, params.hidden);
|
|
1812
|
+
core_.symbols.setWGPUViewHidden(params.id, params.hidden);
|
|
1450
1813
|
},
|
|
1451
1814
|
|
|
1452
1815
|
wgpuViewRemove: (params: { id: number }) => {
|
|
1453
|
-
|
|
1454
|
-
if (!view?.ptr) {
|
|
1455
|
-
console.error(
|
|
1456
|
-
`wgpuViewRemove: WGPUView not found or has no ptr for id ${params.id}`,
|
|
1457
|
-
);
|
|
1458
|
-
return;
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
native_.symbols.wgpuViewRemove(view.ptr);
|
|
1816
|
+
core_.symbols.removeWGPUView(params.id);
|
|
1462
1817
|
},
|
|
1463
1818
|
wgpuViewGetNativeHandle: (params: { id: number }): Pointer | null => {
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
);
|
|
1469
|
-
return null;
|
|
1470
|
-
}
|
|
1471
|
-
|
|
1472
|
-
const handle = native_.symbols.wgpuViewGetNativeHandle(view.ptr);
|
|
1473
|
-
return handle || null;
|
|
1819
|
+
return core_.symbols.getWGPUViewNativeHandle(params.id) || null;
|
|
1820
|
+
},
|
|
1821
|
+
runWGPUViewTest: (params: { id: number }) => {
|
|
1822
|
+
core_.symbols.runWGPUViewTest(params.id);
|
|
1474
1823
|
},
|
|
1475
1824
|
|
|
1476
1825
|
evaluateJavascriptWithNoCompletion: (params: {
|
|
1477
1826
|
id: number;
|
|
1478
1827
|
js: string;
|
|
1479
1828
|
}) => {
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1829
|
+
core_.symbols.evaluateJavaScriptWithNoCompletion(
|
|
1830
|
+
params.id,
|
|
1831
|
+
toCString(params.js),
|
|
1832
|
+
);
|
|
1833
|
+
},
|
|
1834
|
+
sendHostMessageToWebviewViaTransport: (params: {
|
|
1835
|
+
id: number;
|
|
1836
|
+
messageJson: string;
|
|
1837
|
+
}): boolean => {
|
|
1838
|
+
return core_.symbols.sendHostMessageToWebviewViaTransport(
|
|
1839
|
+
params.id,
|
|
1840
|
+
toCString(params.messageJson),
|
|
1490
1841
|
);
|
|
1491
1842
|
},
|
|
1843
|
+
clearWebviewHostTransport: (params: { id: number }) => {
|
|
1844
|
+
core_.symbols.clearWebviewHostTransport(params.id);
|
|
1845
|
+
},
|
|
1846
|
+
webviewOpenDevTools: (params: { id: number }) => {
|
|
1847
|
+
core_.symbols.webviewOpenDevTools(params.id);
|
|
1848
|
+
},
|
|
1849
|
+
webviewCloseDevTools: (params: { id: number }) => {
|
|
1850
|
+
core_.symbols.webviewCloseDevTools(params.id);
|
|
1851
|
+
},
|
|
1852
|
+
webviewToggleDevTools: (params: { id: number }) => {
|
|
1853
|
+
core_.symbols.webviewToggleDevTools(params.id);
|
|
1854
|
+
},
|
|
1855
|
+
webviewSetPageZoom: (params: { id: number; zoomLevel: number }) => {
|
|
1856
|
+
core_.symbols.webviewSetPageZoom(params.id, params.zoomLevel);
|
|
1857
|
+
},
|
|
1858
|
+
webviewGetPageZoom: (params: { id: number }): number => {
|
|
1859
|
+
return core_.symbols.webviewGetPageZoom(params.id);
|
|
1860
|
+
},
|
|
1861
|
+
setExitOnLastWindowClosed: (params: { enabled: boolean }) => {
|
|
1862
|
+
core_.symbols.setExitOnLastWindowClosed(params.enabled);
|
|
1863
|
+
},
|
|
1864
|
+
quitGracefully: (params: { code: number; timeoutMs: number }) => {
|
|
1865
|
+
core_.symbols.quitGracefully(params.code, params.timeoutMs);
|
|
1866
|
+
},
|
|
1492
1867
|
|
|
1493
1868
|
createTray: (params: {
|
|
1494
|
-
id: number;
|
|
1495
1869
|
title: string;
|
|
1496
1870
|
image: string;
|
|
1497
1871
|
template: boolean;
|
|
1498
1872
|
width: number;
|
|
1499
1873
|
height: number;
|
|
1500
|
-
}):
|
|
1501
|
-
const {
|
|
1874
|
+
}): number => {
|
|
1875
|
+
const { title, image, template, width, height } = params;
|
|
1502
1876
|
|
|
1503
|
-
const
|
|
1504
|
-
id,
|
|
1877
|
+
const trayId = core_.symbols.createTray(
|
|
1505
1878
|
toCString(title),
|
|
1506
1879
|
toCString(image),
|
|
1507
1880
|
template,
|
|
@@ -1510,27 +1883,25 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1510
1883
|
trayItemHandler,
|
|
1511
1884
|
);
|
|
1512
1885
|
|
|
1513
|
-
if (!
|
|
1886
|
+
if (!trayId) {
|
|
1514
1887
|
throw "Failed to create tray";
|
|
1515
1888
|
}
|
|
1516
1889
|
|
|
1517
|
-
return
|
|
1890
|
+
return trayId;
|
|
1891
|
+
},
|
|
1892
|
+
showTray: (params: { id: number }): boolean => {
|
|
1893
|
+
return core_.symbols.showTray(params.id);
|
|
1894
|
+
},
|
|
1895
|
+
hideTray: (params: { id: number }): void => {
|
|
1896
|
+
core_.symbols.hideTray(params.id);
|
|
1518
1897
|
},
|
|
1519
1898
|
setTrayTitle: (params: { id: number; title: string }): void => {
|
|
1520
1899
|
const { id, title } = params;
|
|
1521
|
-
|
|
1522
|
-
const tray = Tray.getById(id);
|
|
1523
|
-
if (!tray) return;
|
|
1524
|
-
|
|
1525
|
-
native_.symbols.setTrayTitle(tray.ptr, toCString(title));
|
|
1900
|
+
core_.symbols.setTrayTitle(id, toCString(title));
|
|
1526
1901
|
},
|
|
1527
1902
|
setTrayImage: (params: { id: number; image: string }): void => {
|
|
1528
1903
|
const { id, image } = params;
|
|
1529
|
-
|
|
1530
|
-
const tray = Tray.getById(id);
|
|
1531
|
-
if (!tray) return;
|
|
1532
|
-
|
|
1533
|
-
native_.symbols.setTrayImage(tray.ptr, toCString(image));
|
|
1904
|
+
core_.symbols.setTrayImage(id, toCString(image));
|
|
1534
1905
|
},
|
|
1535
1906
|
setTrayMenu: (params: {
|
|
1536
1907
|
id: number;
|
|
@@ -1538,31 +1909,14 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1538
1909
|
menuConfig: string;
|
|
1539
1910
|
}): void => {
|
|
1540
1911
|
const { id, menuConfig } = params;
|
|
1541
|
-
|
|
1542
|
-
const tray = Tray.getById(id);
|
|
1543
|
-
if (!tray) return;
|
|
1544
|
-
|
|
1545
|
-
native_.symbols.setTrayMenu(tray.ptr, toCString(menuConfig));
|
|
1912
|
+
core_.symbols.setTrayMenu(id, toCString(menuConfig));
|
|
1546
1913
|
},
|
|
1547
1914
|
|
|
1548
1915
|
removeTray: (params: { id: number }): void => {
|
|
1549
|
-
|
|
1550
|
-
const tray = Tray.getById(id);
|
|
1551
|
-
|
|
1552
|
-
if (!tray) {
|
|
1553
|
-
throw `Can't remove tray. Tray no longer exists`;
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1556
|
-
native_.symbols.removeTray(tray.ptr);
|
|
1557
|
-
// The Tray class will handle removing from TrayMap
|
|
1916
|
+
core_.symbols.removeTray(params.id);
|
|
1558
1917
|
},
|
|
1559
1918
|
getTrayBounds: (params: { id: number }): Rectangle => {
|
|
1560
|
-
const
|
|
1561
|
-
if (!tray?.ptr) {
|
|
1562
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
|
-
const jsonStr = native_.symbols.getTrayBounds(tray.ptr);
|
|
1919
|
+
const jsonStr = core_.symbols.getTrayBounds(params.id);
|
|
1566
1920
|
if (!jsonStr) {
|
|
1567
1921
|
return { x: 0, y: 0, width: 0, height: 0 };
|
|
1568
1922
|
}
|
|
@@ -1576,7 +1930,7 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1576
1930
|
setApplicationMenu: (params: { menuConfig: string }): void => {
|
|
1577
1931
|
const { menuConfig } = params;
|
|
1578
1932
|
|
|
1579
|
-
|
|
1933
|
+
core_.symbols.setApplicationMenu(
|
|
1580
1934
|
toCString(menuConfig),
|
|
1581
1935
|
applicationMenuHandler,
|
|
1582
1936
|
);
|
|
@@ -1584,25 +1938,25 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1584
1938
|
showContextMenu: (params: { menuConfig: string }): void => {
|
|
1585
1939
|
const { menuConfig } = params;
|
|
1586
1940
|
|
|
1587
|
-
|
|
1941
|
+
core_.symbols.showContextMenu(toCString(menuConfig), contextMenuHandler);
|
|
1588
1942
|
},
|
|
1589
1943
|
moveToTrash: (params: { path: string }): boolean => {
|
|
1590
1944
|
const { path } = params;
|
|
1591
1945
|
|
|
1592
|
-
return
|
|
1946
|
+
return core_.symbols.moveToTrash(toCString(path));
|
|
1593
1947
|
},
|
|
1594
1948
|
showItemInFolder: (params: { path: string }): void => {
|
|
1595
1949
|
const { path } = params;
|
|
1596
1950
|
|
|
1597
|
-
|
|
1951
|
+
core_.symbols.showItemInFolder(toCString(path));
|
|
1598
1952
|
},
|
|
1599
1953
|
openExternal: (params: { url: string }): boolean => {
|
|
1600
1954
|
const { url } = params;
|
|
1601
|
-
return
|
|
1955
|
+
return core_.symbols.openExternal(toCString(url));
|
|
1602
1956
|
},
|
|
1603
1957
|
openPath: (params: { path: string }): boolean => {
|
|
1604
1958
|
const { path } = params;
|
|
1605
|
-
return
|
|
1959
|
+
return core_.symbols.openPath(toCString(path));
|
|
1606
1960
|
},
|
|
1607
1961
|
showNotification: (params: {
|
|
1608
1962
|
title: string;
|
|
@@ -1611,7 +1965,7 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1611
1965
|
silent?: boolean;
|
|
1612
1966
|
}): void => {
|
|
1613
1967
|
const { title, body = "", subtitle = "", silent = false } = params;
|
|
1614
|
-
|
|
1968
|
+
core_.symbols.showNotification(
|
|
1615
1969
|
toCString(title),
|
|
1616
1970
|
toCString(body),
|
|
1617
1971
|
toCString(subtitle),
|
|
@@ -1619,10 +1973,10 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1619
1973
|
);
|
|
1620
1974
|
},
|
|
1621
1975
|
setDockIconVisible: (params: { visible: boolean }): void => {
|
|
1622
|
-
|
|
1976
|
+
core_.symbols.setDockIconVisible(params.visible);
|
|
1623
1977
|
},
|
|
1624
1978
|
isDockIconVisible: (): boolean => {
|
|
1625
|
-
return
|
|
1979
|
+
return core_.symbols.isDockIconVisible();
|
|
1626
1980
|
},
|
|
1627
1981
|
openFileDialog: (params: {
|
|
1628
1982
|
startingFolder: string;
|
|
@@ -1638,7 +1992,7 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1638
1992
|
canChooseDirectory,
|
|
1639
1993
|
allowsMultipleSelection,
|
|
1640
1994
|
} = params;
|
|
1641
|
-
const filePath =
|
|
1995
|
+
const filePath = core_.symbols.openFileDialog(
|
|
1642
1996
|
toCString(startingFolder),
|
|
1643
1997
|
toCString(allowedFileTypes),
|
|
1644
1998
|
canChooseFiles ? 1 : 0,
|
|
@@ -1668,7 +2022,7 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1668
2022
|
} = params;
|
|
1669
2023
|
// Convert buttons array to comma-separated string
|
|
1670
2024
|
const buttonsStr = buttons.join(",");
|
|
1671
|
-
return
|
|
2025
|
+
return core_.symbols.showMessageBox(
|
|
1672
2026
|
toCString(type),
|
|
1673
2027
|
toCString(title),
|
|
1674
2028
|
toCString(message),
|
|
@@ -1681,17 +2035,17 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1681
2035
|
|
|
1682
2036
|
// Clipboard API
|
|
1683
2037
|
clipboardReadText: (): string | null => {
|
|
1684
|
-
const result =
|
|
2038
|
+
const result = core_.symbols.clipboardReadText();
|
|
1685
2039
|
if (!result) return null;
|
|
1686
2040
|
return result.toString();
|
|
1687
2041
|
},
|
|
1688
2042
|
clipboardWriteText: (params: { text: string }): void => {
|
|
1689
|
-
|
|
2043
|
+
core_.symbols.clipboardWriteText(toCString(params.text));
|
|
1690
2044
|
},
|
|
1691
2045
|
clipboardReadImage: (): Uint8Array | null => {
|
|
1692
2046
|
// Allocate a buffer for the size output
|
|
1693
2047
|
const sizeBuffer = new BigUint64Array(1);
|
|
1694
|
-
const dataPtr =
|
|
2048
|
+
const dataPtr = core_.symbols.clipboardReadImage(ptr(sizeBuffer));
|
|
1695
2049
|
|
|
1696
2050
|
if (!dataPtr) return null;
|
|
1697
2051
|
|
|
@@ -1711,13 +2065,13 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
|
|
|
1711
2065
|
},
|
|
1712
2066
|
clipboardWriteImage: (params: { pngData: Uint8Array }): void => {
|
|
1713
2067
|
const { pngData } = params;
|
|
1714
|
-
|
|
2068
|
+
core_.symbols.clipboardWriteImage(ptr(pngData), BigInt(pngData.length));
|
|
1715
2069
|
},
|
|
1716
2070
|
clipboardClear: (): void => {
|
|
1717
|
-
|
|
2071
|
+
core_.symbols.clipboardClear();
|
|
1718
2072
|
},
|
|
1719
2073
|
clipboardAvailableFormats: (): string[] => {
|
|
1720
|
-
const result =
|
|
2074
|
+
const result = core_.symbols.clipboardAvailableFormats();
|
|
1721
2075
|
if (!result) return [];
|
|
1722
2076
|
const formatsStr = result.toString();
|
|
1723
2077
|
if (!formatsStr) return [];
|
|
@@ -2054,7 +2408,7 @@ const getMimeType = new JSCallback(
|
|
|
2054
2408
|
|
|
2055
2409
|
const getHTMLForWebviewSync = new JSCallback(
|
|
2056
2410
|
(webviewId) => {
|
|
2057
|
-
const webview = BrowserView.
|
|
2411
|
+
const webview = BrowserView.ensureWrapped(webviewId);
|
|
2058
2412
|
|
|
2059
2413
|
return toCString(webview?.html || "");
|
|
2060
2414
|
},
|
|
@@ -2088,7 +2442,7 @@ if (native) {
|
|
|
2088
2442
|
const appReopenCallback = new JSCallback(
|
|
2089
2443
|
() => {
|
|
2090
2444
|
if (process.platform === "darwin") {
|
|
2091
|
-
|
|
2445
|
+
core_.symbols.setDockIconVisible(true);
|
|
2092
2446
|
}
|
|
2093
2447
|
const handler = electrobunEventEmitter.events.app.reopen;
|
|
2094
2448
|
const event = handler({});
|
|
@@ -2107,7 +2461,7 @@ if (native) {
|
|
|
2107
2461
|
},
|
|
2108
2462
|
{ args: [], returns: "void", threadsafe: true },
|
|
2109
2463
|
);
|
|
2110
|
-
|
|
2464
|
+
core_.symbols.setQuitRequestedHandler(quitRequestedCallback);
|
|
2111
2465
|
|
|
2112
2466
|
const globalShortcutCallback = new JSCallback(
|
|
2113
2467
|
(acceleratorPtr) => {
|
|
@@ -2178,7 +2532,7 @@ export const Screen = {
|
|
|
2178
2532
|
* @returns Display object for the primary monitor
|
|
2179
2533
|
*/
|
|
2180
2534
|
getPrimaryDisplay: (): Display => {
|
|
2181
|
-
const jsonStr =
|
|
2535
|
+
const jsonStr = hasFFI ? core_.symbols.getPrimaryDisplay() : null;
|
|
2182
2536
|
if (!jsonStr) {
|
|
2183
2537
|
return {
|
|
2184
2538
|
id: 0,
|
|
@@ -2206,7 +2560,7 @@ export const Screen = {
|
|
|
2206
2560
|
* @returns Array of Display objects
|
|
2207
2561
|
*/
|
|
2208
2562
|
getAllDisplays: (): Display[] => {
|
|
2209
|
-
const jsonStr =
|
|
2563
|
+
const jsonStr = hasFFI ? core_.symbols.getAllDisplays() : null;
|
|
2210
2564
|
if (!jsonStr) {
|
|
2211
2565
|
return [];
|
|
2212
2566
|
}
|
|
@@ -2222,7 +2576,7 @@ export const Screen = {
|
|
|
2222
2576
|
* @returns Point with x and y coordinates
|
|
2223
2577
|
*/
|
|
2224
2578
|
getCursorScreenPoint: (): Point => {
|
|
2225
|
-
const jsonStr =
|
|
2579
|
+
const jsonStr = hasFFI ? core_.symbols.getCursorScreenPoint() : null;
|
|
2226
2580
|
if (!jsonStr) {
|
|
2227
2581
|
return { x: 0, y: 0 };
|
|
2228
2582
|
}
|
|
@@ -2238,7 +2592,7 @@ export const Screen = {
|
|
|
2238
2592
|
*/
|
|
2239
2593
|
getMouseButtons: (): bigint => {
|
|
2240
2594
|
try {
|
|
2241
|
-
return
|
|
2595
|
+
return hasFFI ? core_.symbols.getMouseButtons() : BigInt(0);
|
|
2242
2596
|
} catch {
|
|
2243
2597
|
return 0n;
|
|
2244
2598
|
}
|
|
@@ -2403,35 +2757,13 @@ const webviewDecideNavigation = new JSCallback(
|
|
|
2403
2757
|
);
|
|
2404
2758
|
|
|
2405
2759
|
const webviewEventHandler = (id: number, eventName: string, detail: string) => {
|
|
2406
|
-
|
|
2407
|
-
if (!webview) {
|
|
2408
|
-
console.error("[webviewEventHandler] No webview found for id:", id);
|
|
2409
|
-
return;
|
|
2410
|
-
}
|
|
2411
|
-
|
|
2412
|
-
if (webview.hostWebviewId) {
|
|
2413
|
-
const hostWebview = BrowserView.getById(webview.hostWebviewId);
|
|
2414
|
-
|
|
2415
|
-
if (!hostWebview) {
|
|
2416
|
-
console.error("[webviewEventHandler] No webview found for id:", id);
|
|
2417
|
-
return;
|
|
2418
|
-
}
|
|
2760
|
+
BrowserView.ensureWrapped(id);
|
|
2419
2761
|
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
js = `document.querySelector('#electrobun-webview-${id}').emit(${JSON.stringify(eventName)}, ${detail});`;
|
|
2426
|
-
} else {
|
|
2427
|
-
js = `document.querySelector('#electrobun-webview-${id}').emit(${JSON.stringify(eventName)}, ${JSON.stringify(detail)});`;
|
|
2428
|
-
}
|
|
2429
|
-
|
|
2430
|
-
native_.symbols.evaluateJavaScriptWithNoCompletion(
|
|
2431
|
-
hostWebview.ptr,
|
|
2432
|
-
toCString(js),
|
|
2433
|
-
);
|
|
2434
|
-
}
|
|
2762
|
+
core_.symbols.dispatchHostWebviewEvent(
|
|
2763
|
+
id,
|
|
2764
|
+
toCString(eventName),
|
|
2765
|
+
toCString(detail),
|
|
2766
|
+
);
|
|
2435
2767
|
|
|
2436
2768
|
const eventMap: Record<string, string> = {
|
|
2437
2769
|
"will-navigate": "willNavigate",
|
|
@@ -2525,7 +2857,7 @@ const webviewEventJSCallback = new JSCallback(
|
|
|
2525
2857
|
},
|
|
2526
2858
|
);
|
|
2527
2859
|
|
|
2528
|
-
const
|
|
2860
|
+
const hostBridgePostmessageHandler = new JSCallback(
|
|
2529
2861
|
(id, msg) => {
|
|
2530
2862
|
try {
|
|
2531
2863
|
const msgStr = new CString(msg);
|
|
@@ -2539,12 +2871,14 @@ const bunBridgePostmessageHandler = new JSCallback(
|
|
|
2539
2871
|
}
|
|
2540
2872
|
const msgJson = JSON.parse(rawMessage);
|
|
2541
2873
|
|
|
2542
|
-
const webview = BrowserView.
|
|
2543
|
-
if (!webview)
|
|
2874
|
+
const webview = BrowserView.ensureWrapped(id);
|
|
2875
|
+
if (!webview) {
|
|
2876
|
+
return;
|
|
2877
|
+
}
|
|
2544
2878
|
|
|
2545
2879
|
webview.rpcHandler?.(msgJson);
|
|
2546
2880
|
} catch (err) {
|
|
2547
|
-
console.error("error sending message to
|
|
2881
|
+
console.error("error sending message to host: ", err);
|
|
2548
2882
|
}
|
|
2549
2883
|
},
|
|
2550
2884
|
{
|
|
@@ -2620,8 +2954,6 @@ const internalBridgeHandler = new JSCallback(
|
|
|
2620
2954
|
)[msgJson.id];
|
|
2621
2955
|
handler?.(msgJson.payload);
|
|
2622
2956
|
} else if (msgJson.type === "request") {
|
|
2623
|
-
const hostWebview = BrowserView.getById(msgJson.hostWebviewId);
|
|
2624
|
-
// const targetWebview = BrowserView.getById(msgJson.params.params.hostWebviewId);
|
|
2625
2957
|
const handler = (
|
|
2626
2958
|
internalRpcHandlers.request as Record<
|
|
2627
2959
|
string,
|
|
@@ -2637,15 +2969,10 @@ const internalBridgeHandler = new JSCallback(
|
|
|
2637
2969
|
success: true,
|
|
2638
2970
|
payload,
|
|
2639
2971
|
};
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
);
|
|
2645
|
-
return;
|
|
2646
|
-
}
|
|
2647
|
-
|
|
2648
|
-
hostWebview.sendInternalMessageViaExecute(resultObj);
|
|
2972
|
+
core_.symbols.sendInternalMessageToWebview(
|
|
2973
|
+
msgJson.hostWebviewId,
|
|
2974
|
+
toCString(JSON.stringify(resultObj)),
|
|
2975
|
+
);
|
|
2649
2976
|
}
|
|
2650
2977
|
});
|
|
2651
2978
|
} catch (err) {
|
|
@@ -2826,24 +3153,10 @@ export const internalRpcHandlers = {
|
|
|
2826
3153
|
return viewForTag.id;
|
|
2827
3154
|
},
|
|
2828
3155
|
webviewTagCanGoBack: (params: { id: number }) => {
|
|
2829
|
-
|
|
2830
|
-
const webviewPtr = BrowserView.getById(id)?.ptr;
|
|
2831
|
-
if (!webviewPtr) {
|
|
2832
|
-
console.error("no webview ptr");
|
|
2833
|
-
return false;
|
|
2834
|
-
}
|
|
2835
|
-
|
|
2836
|
-
return native_.symbols.webviewCanGoBack(webviewPtr);
|
|
3156
|
+
return core_.symbols.webviewCanGoBack(params.id);
|
|
2837
3157
|
},
|
|
2838
3158
|
webviewTagCanGoForward: (params: { id: number }) => {
|
|
2839
|
-
|
|
2840
|
-
const webviewPtr = BrowserView.getById(id)?.ptr;
|
|
2841
|
-
if (!webviewPtr) {
|
|
2842
|
-
console.error("no webview ptr");
|
|
2843
|
-
return false;
|
|
2844
|
-
}
|
|
2845
|
-
|
|
2846
|
-
return native_.symbols.webviewCanGoForward(webviewPtr);
|
|
3159
|
+
return core_.symbols.webviewCanGoForward(params.id);
|
|
2847
3160
|
},
|
|
2848
3161
|
},
|
|
2849
3162
|
message: {
|
|
@@ -2852,25 +3165,14 @@ export const internalRpcHandlers = {
|
|
|
2852
3165
|
frame: { x: number; y: number; width: number; height: number };
|
|
2853
3166
|
masks: string;
|
|
2854
3167
|
}) => {
|
|
2855
|
-
const browserView = BrowserView.getById(params.id);
|
|
2856
|
-
const webviewPtr = browserView?.ptr;
|
|
2857
|
-
|
|
2858
|
-
if (!webviewPtr) {
|
|
2859
|
-
console.log(
|
|
2860
|
-
"[Bun] ERROR: webviewTagResize - no webview ptr found for id:",
|
|
2861
|
-
params.id,
|
|
2862
|
-
);
|
|
2863
|
-
return;
|
|
2864
|
-
}
|
|
2865
|
-
|
|
2866
3168
|
const { x, y, width, height } = params.frame;
|
|
2867
|
-
|
|
2868
|
-
|
|
3169
|
+
core_.symbols.resizeWebview(
|
|
3170
|
+
params.id,
|
|
2869
3171
|
x,
|
|
2870
3172
|
y,
|
|
2871
3173
|
width,
|
|
2872
3174
|
height,
|
|
2873
|
-
toCString(params.masks),
|
|
3175
|
+
toCString(params.masks ?? "[]"),
|
|
2874
3176
|
);
|
|
2875
3177
|
},
|
|
2876
3178
|
wgpuTagResize: (params: {
|
|
@@ -2897,81 +3199,47 @@ export const internalRpcHandlers = {
|
|
|
2897
3199
|
);
|
|
2898
3200
|
},
|
|
2899
3201
|
webviewTagUpdateSrc: (params: { id: number; url: string }) => {
|
|
2900
|
-
const webview = BrowserView.
|
|
2901
|
-
if (
|
|
2902
|
-
|
|
2903
|
-
`webviewTagUpdateSrc: BrowserView not found or has no ptr for id ${params.id}`,
|
|
2904
|
-
);
|
|
2905
|
-
return;
|
|
3202
|
+
const webview = BrowserView.ensureWrapped(params.id);
|
|
3203
|
+
if (webview) {
|
|
3204
|
+
webview.url = params.url;
|
|
2906
3205
|
}
|
|
2907
|
-
|
|
3206
|
+
core_.symbols.loadURLInWebView(params.id, toCString(params.url));
|
|
2908
3207
|
},
|
|
2909
3208
|
webviewTagUpdateHtml: (params: { id: number; html: string }) => {
|
|
2910
|
-
const webview = BrowserView.
|
|
2911
|
-
if (!webview
|
|
2912
|
-
console.error(
|
|
2913
|
-
`webviewTagUpdateHtml: BrowserView not found or has no ptr for id ${params.id}`,
|
|
2914
|
-
);
|
|
3209
|
+
const webview = BrowserView.ensureWrapped(params.id);
|
|
3210
|
+
if (!webview) {
|
|
3211
|
+
console.error(`webviewTagUpdateHtml: BrowserView not found for id ${params.id}`);
|
|
2915
3212
|
return;
|
|
2916
3213
|
}
|
|
2917
3214
|
|
|
2918
|
-
// Store HTML content in native map for scheme handlers
|
|
2919
|
-
native_.symbols.setWebviewHTMLContent(webview.id, toCString(params.html));
|
|
2920
|
-
|
|
2921
3215
|
webview.loadHTML(params.html);
|
|
2922
3216
|
webview.html = params.html;
|
|
2923
3217
|
},
|
|
2924
3218
|
webviewTagUpdatePreload: (params: { id: number; preload: string }) => {
|
|
2925
|
-
const webview = BrowserView.
|
|
2926
|
-
if (
|
|
2927
|
-
|
|
2928
|
-
`webviewTagUpdatePreload: BrowserView not found or has no ptr for id ${params.id}`,
|
|
2929
|
-
);
|
|
2930
|
-
return;
|
|
3219
|
+
const webview = BrowserView.ensureWrapped(params.id);
|
|
3220
|
+
if (webview) {
|
|
3221
|
+
webview.preload = params.preload;
|
|
2931
3222
|
}
|
|
2932
|
-
|
|
2933
|
-
|
|
3223
|
+
core_.symbols.updatePreloadScriptToWebView(
|
|
3224
|
+
params.id,
|
|
2934
3225
|
toCString("electrobun_custom_preload_script"),
|
|
2935
3226
|
toCString(params.preload),
|
|
2936
3227
|
true,
|
|
2937
3228
|
);
|
|
2938
3229
|
},
|
|
2939
3230
|
webviewTagGoBack: (params: { id: number }) => {
|
|
2940
|
-
|
|
2941
|
-
if (!webview || !webview.ptr) {
|
|
2942
|
-
console.error(
|
|
2943
|
-
`webviewTagGoBack: BrowserView not found or has no ptr for id ${params.id}`,
|
|
2944
|
-
);
|
|
2945
|
-
return;
|
|
2946
|
-
}
|
|
2947
|
-
native_.symbols.webviewGoBack(webview.ptr);
|
|
3231
|
+
core_.symbols.webviewGoBack(params.id);
|
|
2948
3232
|
},
|
|
2949
3233
|
webviewTagGoForward: (params: { id: number }) => {
|
|
2950
|
-
|
|
2951
|
-
if (!webview || !webview.ptr) {
|
|
2952
|
-
console.error(
|
|
2953
|
-
`webviewTagGoForward: BrowserView not found or has no ptr for id ${params.id}`,
|
|
2954
|
-
);
|
|
2955
|
-
return;
|
|
2956
|
-
}
|
|
2957
|
-
native_.symbols.webviewGoForward(webview.ptr);
|
|
3234
|
+
core_.symbols.webviewGoForward(params.id);
|
|
2958
3235
|
},
|
|
2959
3236
|
webviewTagReload: (params: { id: number }) => {
|
|
2960
|
-
|
|
2961
|
-
if (!webview || !webview.ptr) {
|
|
2962
|
-
console.error(
|
|
2963
|
-
`webviewTagReload: BrowserView not found or has no ptr for id ${params.id}`,
|
|
2964
|
-
);
|
|
2965
|
-
return;
|
|
2966
|
-
}
|
|
2967
|
-
native_.symbols.webviewReload(webview.ptr);
|
|
3237
|
+
core_.symbols.webviewReload(params.id);
|
|
2968
3238
|
},
|
|
2969
3239
|
webviewTagRemove: (params: { id: number }) => {
|
|
2970
|
-
const webview = BrowserView.
|
|
2971
|
-
if (!webview
|
|
2972
|
-
console.error(
|
|
2973
|
-
`webviewTagRemove: BrowserView not found or has no ptr for id ${params.id}`,
|
|
2974
|
-
);
|
|
3240
|
+
const webview = BrowserView.ensureWrapped(params.id);
|
|
3241
|
+
if (!webview) {
|
|
3242
|
+
console.error(`webviewTagRemove: BrowserView not found for id ${params.id}`);
|
|
2975
3243
|
return;
|
|
2976
3244
|
}
|
|
2977
3245
|
webview.remove();
|
|
@@ -2988,14 +3256,7 @@ export const internalRpcHandlers = {
|
|
|
2988
3256
|
id: number;
|
|
2989
3257
|
transparent: boolean;
|
|
2990
3258
|
}) => {
|
|
2991
|
-
|
|
2992
|
-
if (!webview || !webview.ptr) {
|
|
2993
|
-
console.error(
|
|
2994
|
-
`webviewTagSetTransparent: BrowserView not found or has no ptr for id ${params.id}`,
|
|
2995
|
-
);
|
|
2996
|
-
return;
|
|
2997
|
-
}
|
|
2998
|
-
native_.symbols.webviewSetTransparent(webview.ptr, params.transparent);
|
|
3259
|
+
core_.symbols.webviewSetTransparent(params.id, params.transparent);
|
|
2999
3260
|
},
|
|
3000
3261
|
wgpuTagSetTransparent: (params: {
|
|
3001
3262
|
id: number;
|
|
@@ -3014,17 +3275,7 @@ export const internalRpcHandlers = {
|
|
|
3014
3275
|
id: number;
|
|
3015
3276
|
enablePassthrough: boolean;
|
|
3016
3277
|
}) => {
|
|
3017
|
-
|
|
3018
|
-
if (!webview || !webview.ptr) {
|
|
3019
|
-
console.error(
|
|
3020
|
-
`webviewTagSetPassthrough: BrowserView not found or has no ptr for id ${params.id}`,
|
|
3021
|
-
);
|
|
3022
|
-
return;
|
|
3023
|
-
}
|
|
3024
|
-
native_.symbols.webviewSetPassthrough(
|
|
3025
|
-
webview.ptr,
|
|
3026
|
-
params.enablePassthrough,
|
|
3027
|
-
);
|
|
3278
|
+
core_.symbols.webviewSetPassthrough(params.id, params.enablePassthrough);
|
|
3028
3279
|
},
|
|
3029
3280
|
wgpuTagSetPassthrough: (params: { id: number; passthrough: boolean }) => {
|
|
3030
3281
|
const view = WGPUView.getById(params.id);
|
|
@@ -3037,14 +3288,7 @@ export const internalRpcHandlers = {
|
|
|
3037
3288
|
native_.symbols.wgpuViewSetPassthrough(view.ptr, params.passthrough);
|
|
3038
3289
|
},
|
|
3039
3290
|
webviewTagSetHidden: (params: { id: number; hidden: boolean }) => {
|
|
3040
|
-
|
|
3041
|
-
if (!webview || !webview.ptr) {
|
|
3042
|
-
console.error(
|
|
3043
|
-
`webviewTagSetHidden: BrowserView not found or has no ptr for id ${params.id}`,
|
|
3044
|
-
);
|
|
3045
|
-
return;
|
|
3046
|
-
}
|
|
3047
|
-
native_.symbols.webviewSetHidden(webview.ptr, params.hidden);
|
|
3291
|
+
core_.symbols.webviewSetHidden(params.id, params.hidden);
|
|
3048
3292
|
},
|
|
3049
3293
|
wgpuTagSetHidden: (params: { id: number; hidden: boolean }) => {
|
|
3050
3294
|
const view = WGPUView.getById(params.id);
|
|
@@ -3081,18 +3325,12 @@ export const internalRpcHandlers = {
|
|
|
3081
3325
|
native_.symbols.wgpuRunGPUTest(view.ptr);
|
|
3082
3326
|
},
|
|
3083
3327
|
webviewTagSetNavigationRules: (params: { id: number; rules: string[] }) => {
|
|
3084
|
-
const webview = BrowserView.getById(params.id);
|
|
3085
|
-
if (!webview || !webview.ptr) {
|
|
3086
|
-
console.error(
|
|
3087
|
-
`webviewTagSetNavigationRules: BrowserView not found or has no ptr for id ${params.id}`,
|
|
3088
|
-
);
|
|
3089
|
-
return;
|
|
3090
|
-
}
|
|
3091
3328
|
const rulesJson = JSON.stringify(params.rules);
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3329
|
+
const webview = BrowserView.ensureWrapped(params.id);
|
|
3330
|
+
if (webview) {
|
|
3331
|
+
webview.navigationRules = rulesJson;
|
|
3332
|
+
}
|
|
3333
|
+
core_.symbols.setWebviewNavigationRules(params.id, toCString(rulesJson));
|
|
3096
3334
|
},
|
|
3097
3335
|
webviewTagFindInPage: (params: {
|
|
3098
3336
|
id: number;
|
|
@@ -3100,70 +3338,28 @@ export const internalRpcHandlers = {
|
|
|
3100
3338
|
forward: boolean;
|
|
3101
3339
|
matchCase: boolean;
|
|
3102
3340
|
}) => {
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
console.error(
|
|
3106
|
-
`webviewTagFindInPage: BrowserView not found or has no ptr for id ${params.id}`,
|
|
3107
|
-
);
|
|
3108
|
-
return;
|
|
3109
|
-
}
|
|
3110
|
-
native_.symbols.webviewFindInPage(
|
|
3111
|
-
webview.ptr,
|
|
3341
|
+
core_.symbols.webviewFindInPage(
|
|
3342
|
+
params.id,
|
|
3112
3343
|
toCString(params.searchText),
|
|
3113
3344
|
params.forward,
|
|
3114
3345
|
params.matchCase,
|
|
3115
3346
|
);
|
|
3116
3347
|
},
|
|
3117
3348
|
webviewTagStopFind: (params: { id: number }) => {
|
|
3118
|
-
|
|
3119
|
-
if (!webview || !webview.ptr) {
|
|
3120
|
-
console.error(
|
|
3121
|
-
`webviewTagStopFind: BrowserView not found or has no ptr for id ${params.id}`,
|
|
3122
|
-
);
|
|
3123
|
-
return;
|
|
3124
|
-
}
|
|
3125
|
-
native_.symbols.webviewStopFind(webview.ptr);
|
|
3349
|
+
core_.symbols.webviewStopFind(params.id);
|
|
3126
3350
|
},
|
|
3127
3351
|
webviewTagOpenDevTools: (params: { id: number }) => {
|
|
3128
|
-
|
|
3129
|
-
if (!webview || !webview.ptr) {
|
|
3130
|
-
console.error(
|
|
3131
|
-
`webviewTagOpenDevTools: BrowserView not found or has no ptr for id ${params.id}`,
|
|
3132
|
-
);
|
|
3133
|
-
return;
|
|
3134
|
-
}
|
|
3135
|
-
native_.symbols.webviewOpenDevTools(webview.ptr);
|
|
3352
|
+
core_.symbols.webviewOpenDevTools(params.id);
|
|
3136
3353
|
},
|
|
3137
3354
|
webviewTagCloseDevTools: (params: { id: number }) => {
|
|
3138
|
-
|
|
3139
|
-
if (!webview || !webview.ptr) {
|
|
3140
|
-
console.error(
|
|
3141
|
-
`webviewTagCloseDevTools: BrowserView not found or has no ptr for id ${params.id}`,
|
|
3142
|
-
);
|
|
3143
|
-
return;
|
|
3144
|
-
}
|
|
3145
|
-
native_.symbols.webviewCloseDevTools(webview.ptr);
|
|
3355
|
+
core_.symbols.webviewCloseDevTools(params.id);
|
|
3146
3356
|
},
|
|
3147
3357
|
webviewTagToggleDevTools: (params: { id: number }) => {
|
|
3148
|
-
|
|
3149
|
-
if (!webview || !webview.ptr) {
|
|
3150
|
-
console.error(
|
|
3151
|
-
`webviewTagToggleDevTools: BrowserView not found or has no ptr for id ${params.id}`,
|
|
3152
|
-
);
|
|
3153
|
-
return;
|
|
3154
|
-
}
|
|
3155
|
-
native_.symbols.webviewToggleDevTools(webview.ptr);
|
|
3358
|
+
core_.symbols.webviewToggleDevTools(params.id);
|
|
3156
3359
|
},
|
|
3157
3360
|
webviewTagExecuteJavascript: (params: { id: number; js: string }) => {
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
console.error(
|
|
3161
|
-
`webviewTagExecuteJavascript: BrowserView not found or has no ptr for id ${params.id}`,
|
|
3162
|
-
);
|
|
3163
|
-
return;
|
|
3164
|
-
}
|
|
3165
|
-
native_.symbols.evaluateJavaScriptWithNoCompletion(
|
|
3166
|
-
webview.ptr,
|
|
3361
|
+
core_.symbols.evaluateJavaScriptWithNoCompletion(
|
|
3362
|
+
params.id,
|
|
3167
3363
|
toCString(params.js),
|
|
3168
3364
|
);
|
|
3169
3365
|
},
|