electrobun 1.18.1 → 1.18.4-beta.3

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.
@@ -3,7 +3,7 @@ import electrobunEventEmitter from "../events/eventEmitter";
3
3
  import ElectrobunEvent from "../events/event";
4
4
  import { BrowserView } from "../core/BrowserView";
5
5
  import { WGPUView } from "../core/WGPUView";
6
- import { Tray } from "../core/Tray";
6
+ import { rpcPort } from "../core/Socket";
7
7
  import {
8
8
  preloadScript,
9
9
  preloadScriptSandboxed,
@@ -70,142 +70,485 @@ import {
70
70
  toArrayBuffer,
71
71
  type Pointer,
72
72
  } from "bun:ffi";
73
- import { BrowserWindow } from "../core/BrowserWindow";
74
- import { GpuWindow } from "../core/GpuWindow";
75
73
 
76
74
  function getWindowPtr(winId: number) {
77
- return (
78
- BrowserWindow.getById(winId)?.ptr ?? GpuWindow.getById(winId)?.ptr ?? null
75
+ return core?.symbols.getWindowPointer(winId) || null;
76
+ }
77
+
78
+ function getCoreLastError(): string | null {
79
+ const error = core?.symbols.electrobun_core_last_error();
80
+ if (!error) {
81
+ return null;
82
+ }
83
+
84
+ const message = error.toString();
85
+ return message.length > 0 ? message : null;
86
+ }
87
+
88
+ let webviewRuntimeConfigured = false;
89
+
90
+ function ensureWebviewRuntimeConfigured() {
91
+ if (webviewRuntimeConfigured) {
92
+ return;
93
+ }
94
+
95
+ const configured = core?.symbols.configureWebviewRuntime(
96
+ rpcPort,
97
+ toCString(preloadScript),
98
+ toCString(preloadScriptSandboxed),
79
99
  );
100
+
101
+ if (!configured) {
102
+ throw getCoreLastError() || "Failed to configure webview runtime";
103
+ }
104
+
105
+ webviewRuntimeConfigured = true;
80
106
  }
81
107
 
82
- export const native = (() => {
108
+ const core = (() => {
83
109
  try {
84
- // Use absolute path to native wrapper DLL to avoid working directory issues
85
- // On Windows shortcuts, the working directory may not be set correctly
86
- const nativeWrapperPath = join(process.cwd(), `libNativeWrapper.${suffix}`);
87
- return dlopen(nativeWrapperPath, {
88
- // window
89
- createWindowWithFrameAndStyleFromWorker: {
90
- // Pass each parameter individually
91
- args: [
92
- FFIType.u32, // windowId
93
- FFIType.f64,
94
- FFIType.f64, // x, y
95
- FFIType.f64,
96
- FFIType.f64, // width, height
97
- FFIType.u32, // styleMask
98
- FFIType.cstring, // titleBarStyle
99
- FFIType.bool, // transparent
100
- FFIType.f64, // trafficLightOffsetX
101
- FFIType.f64, // trafficLightOffsetY
102
- FFIType.function, // closeHandler
103
- FFIType.function, // moveHandler
104
- FFIType.function, // resizeHandler
105
- FFIType.function, // focusHandler
106
- FFIType.function, // blurHandler
107
- FFIType.function, // keyHandler
108
- ],
109
- returns: FFIType.ptr,
110
- },
111
- setWindowTitle: {
112
- args: [
113
- FFIType.ptr, // window ptr
114
- FFIType.cstring, // title
115
- ],
116
- returns: FFIType.void,
110
+ const corePath = join(
111
+ process.cwd(),
112
+ process.platform === "win32"
113
+ ? "ElectrobunCore.dll"
114
+ : `libElectrobunCore.${suffix}`,
115
+ );
116
+ return dlopen(corePath, {
117
+ electrobun_core_last_error: {
118
+ args: [],
119
+ returns: FFIType.cstring,
117
120
  },
118
- showWindow: {
121
+ getWindowStyle: {
119
122
  args: [
120
- FFIType.ptr, // window ptr
121
- FFIType.bool, // activate
123
+ FFIType.bool,
124
+ FFIType.bool,
125
+ FFIType.bool,
126
+ FFIType.bool,
127
+ FFIType.bool,
128
+ FFIType.bool,
129
+ FFIType.bool,
130
+ FFIType.bool,
131
+ FFIType.bool,
132
+ FFIType.bool,
133
+ FFIType.bool,
134
+ FFIType.bool,
122
135
  ],
123
- returns: FFIType.void,
136
+ returns: FFIType.u32,
124
137
  },
125
- activateWindow: {
138
+ createWindow: {
126
139
  args: [
127
- FFIType.ptr, // window ptr
140
+ FFIType.f64,
141
+ FFIType.f64,
142
+ FFIType.f64,
143
+ FFIType.f64,
144
+ FFIType.u32,
145
+ FFIType.cstring,
146
+ FFIType.bool,
147
+ FFIType.cstring,
148
+ FFIType.bool,
149
+ FFIType.bool,
150
+ FFIType.f64,
151
+ FFIType.f64,
152
+ FFIType.function,
153
+ FFIType.function,
154
+ FFIType.function,
155
+ FFIType.function,
156
+ FFIType.function,
157
+ FFIType.function,
128
158
  ],
129
- returns: FFIType.void,
159
+ returns: FFIType.u32,
130
160
  },
131
- hideWindow: {
132
- args: [FFIType.ptr],
133
- returns: FFIType.void,
161
+ getWindowPointer: {
162
+ args: [FFIType.u32],
163
+ returns: FFIType.ptr,
134
164
  },
135
- closeWindow: {
136
- args: [
137
- FFIType.ptr, // window ptr
138
- ],
165
+ setWindowTitle: {
166
+ args: [FFIType.u32, FFIType.cstring],
139
167
  returns: FFIType.void,
140
168
  },
141
169
  minimizeWindow: {
142
- args: [FFIType.ptr],
170
+ args: [FFIType.u32],
143
171
  returns: FFIType.void,
144
172
  },
145
173
  restoreWindow: {
146
- args: [FFIType.ptr],
174
+ args: [FFIType.u32],
147
175
  returns: FFIType.void,
148
176
  },
149
177
  isWindowMinimized: {
150
- args: [FFIType.ptr],
178
+ args: [FFIType.u32],
151
179
  returns: FFIType.bool,
152
180
  },
153
181
  maximizeWindow: {
154
- args: [FFIType.ptr],
182
+ args: [FFIType.u32],
155
183
  returns: FFIType.void,
156
184
  },
157
185
  unmaximizeWindow: {
158
- args: [FFIType.ptr],
186
+ args: [FFIType.u32],
159
187
  returns: FFIType.void,
160
188
  },
161
189
  isWindowMaximized: {
162
- args: [FFIType.ptr],
190
+ args: [FFIType.u32],
163
191
  returns: FFIType.bool,
164
192
  },
193
+ showWindow: {
194
+ args: [FFIType.u32, FFIType.bool],
195
+ returns: FFIType.void,
196
+ },
197
+ activateWindow: {
198
+ args: [FFIType.u32],
199
+ returns: FFIType.void,
200
+ },
201
+ hideWindow: {
202
+ args: [FFIType.u32],
203
+ returns: FFIType.void,
204
+ },
205
+ closeWindow: {
206
+ args: [FFIType.u32],
207
+ returns: FFIType.void,
208
+ },
165
209
  setWindowFullScreen: {
166
- args: [FFIType.ptr, FFIType.bool],
210
+ args: [FFIType.u32, FFIType.bool],
167
211
  returns: FFIType.void,
168
212
  },
169
213
  isWindowFullScreen: {
170
- args: [FFIType.ptr],
214
+ args: [FFIType.u32],
171
215
  returns: FFIType.bool,
172
216
  },
173
217
  setWindowAlwaysOnTop: {
174
- args: [FFIType.ptr, FFIType.bool],
218
+ args: [FFIType.u32, FFIType.bool],
175
219
  returns: FFIType.void,
176
220
  },
177
221
  isWindowAlwaysOnTop: {
178
- args: [FFIType.ptr],
222
+ args: [FFIType.u32],
179
223
  returns: FFIType.bool,
180
224
  },
181
225
  setWindowVisibleOnAllWorkspaces: {
182
- args: [FFIType.ptr, FFIType.bool],
226
+ args: [FFIType.u32, FFIType.bool],
183
227
  returns: FFIType.void,
184
228
  },
185
229
  isWindowVisibleOnAllWorkspaces: {
186
- args: [FFIType.ptr],
230
+ args: [FFIType.u32],
187
231
  returns: FFIType.bool,
188
232
  },
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
- },
233
+ setWindowPosition: {
234
+ args: [FFIType.u32, FFIType.f64, FFIType.f64],
235
+ returns: FFIType.void,
236
+ },
237
+ setWindowButtonPosition: {
238
+ args: [FFIType.u32, FFIType.f64, FFIType.f64],
239
+ returns: FFIType.void,
240
+ },
241
+ setWindowSize: {
242
+ args: [FFIType.u32, FFIType.f64, FFIType.f64],
243
+ returns: FFIType.void,
244
+ },
201
245
  setWindowFrame: {
202
- args: [FFIType.ptr, FFIType.f64, FFIType.f64, FFIType.f64, FFIType.f64],
246
+ args: [FFIType.u32, FFIType.f64, FFIType.f64, FFIType.f64, FFIType.f64],
203
247
  returns: FFIType.void,
204
248
  },
205
249
  getWindowFrame: {
206
- args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr],
250
+ args: [FFIType.u32, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr],
251
+ returns: FFIType.void,
252
+ },
253
+ configureWebviewRuntime: {
254
+ args: [
255
+ FFIType.u32,
256
+ FFIType.cstring,
257
+ FFIType.cstring,
258
+ ],
259
+ returns: FFIType.bool,
260
+ },
261
+ createWebview: {
262
+ args: [
263
+ FFIType.u32,
264
+ FFIType.u32,
265
+ FFIType.cstring,
266
+ FFIType.cstring,
267
+ FFIType.f64,
268
+ FFIType.f64,
269
+ FFIType.f64,
270
+ FFIType.f64,
271
+ FFIType.bool,
272
+ FFIType.cstring,
273
+ FFIType.function,
274
+ FFIType.function,
275
+ FFIType.function,
276
+ FFIType.function,
277
+ FFIType.function,
278
+ FFIType.cstring,
279
+ FFIType.cstring,
280
+ FFIType.cstring,
281
+ FFIType.bool,
282
+ FFIType.bool,
283
+ FFIType.bool,
284
+ ],
285
+ returns: FFIType.u32,
286
+ },
287
+ getWebviewPointer: {
288
+ args: [FFIType.u32],
289
+ returns: FFIType.ptr,
290
+ },
291
+ resizeWebview: {
292
+ args: [
293
+ FFIType.u32,
294
+ FFIType.f64,
295
+ FFIType.f64,
296
+ FFIType.f64,
297
+ FFIType.f64,
298
+ FFIType.cstring,
299
+ ],
300
+ returns: FFIType.void,
301
+ },
302
+ loadURLInWebView: {
303
+ args: [FFIType.u32, FFIType.cstring],
304
+ returns: FFIType.void,
305
+ },
306
+ loadHTMLInWebView: {
307
+ args: [FFIType.u32, FFIType.cstring],
308
+ returns: FFIType.void,
309
+ },
310
+ updatePreloadScriptToWebView: {
311
+ args: [FFIType.u32, FFIType.cstring, FFIType.cstring, FFIType.bool],
312
+ returns: FFIType.void,
313
+ },
314
+ webviewCanGoBack: {
315
+ args: [FFIType.u32],
316
+ returns: FFIType.bool,
317
+ },
318
+ webviewCanGoForward: {
319
+ args: [FFIType.u32],
320
+ returns: FFIType.bool,
321
+ },
322
+ webviewGoBack: {
323
+ args: [FFIType.u32],
324
+ returns: FFIType.void,
325
+ },
326
+ webviewGoForward: {
327
+ args: [FFIType.u32],
328
+ returns: FFIType.void,
329
+ },
330
+ webviewReload: {
331
+ args: [FFIType.u32],
332
+ returns: FFIType.void,
333
+ },
334
+ webviewRemove: {
335
+ args: [FFIType.u32],
336
+ returns: FFIType.void,
337
+ },
338
+ setWebviewHTMLContent: {
339
+ args: [FFIType.u32, FFIType.cstring],
340
+ returns: FFIType.void,
341
+ },
342
+ webviewSetTransparent: {
343
+ args: [FFIType.u32, FFIType.bool],
344
+ returns: FFIType.void,
345
+ },
346
+ webviewSetPassthrough: {
347
+ args: [FFIType.u32, FFIType.bool],
348
+ returns: FFIType.void,
349
+ },
350
+ webviewSetHidden: {
351
+ args: [FFIType.u32, FFIType.bool],
352
+ returns: FFIType.void,
353
+ },
354
+ setWebviewNavigationRules: {
355
+ args: [FFIType.u32, FFIType.cstring],
356
+ returns: FFIType.void,
357
+ },
358
+ webviewFindInPage: {
359
+ args: [FFIType.u32, FFIType.cstring, FFIType.bool, FFIType.bool],
360
+ returns: FFIType.void,
361
+ },
362
+ webviewStopFind: {
363
+ args: [FFIType.u32],
364
+ returns: FFIType.void,
365
+ },
366
+ evaluateJavaScriptWithNoCompletion: {
367
+ args: [FFIType.u32, FFIType.cstring],
368
+ returns: FFIType.void,
369
+ },
370
+ dispatchHostWebviewEvent: {
371
+ args: [FFIType.u32, FFIType.cstring, FFIType.cstring],
372
+ returns: FFIType.bool,
373
+ },
374
+ sendInternalMessageToWebview: {
375
+ args: [FFIType.u32, FFIType.cstring],
376
+ returns: FFIType.bool,
377
+ },
378
+ webviewOpenDevTools: {
379
+ args: [FFIType.u32],
380
+ returns: FFIType.void,
381
+ },
382
+ webviewCloseDevTools: {
383
+ args: [FFIType.u32],
384
+ returns: FFIType.void,
385
+ },
386
+ webviewToggleDevTools: {
387
+ args: [FFIType.u32],
388
+ returns: FFIType.void,
389
+ },
390
+ webviewSetPageZoom: {
391
+ args: [FFIType.u32, FFIType.f64],
392
+ returns: FFIType.void,
393
+ },
394
+ webviewGetPageZoom: {
395
+ args: [FFIType.u32],
396
+ returns: FFIType.f64,
397
+ },
398
+ createTray: {
399
+ args: [
400
+ FFIType.cstring,
401
+ FFIType.cstring,
402
+ FFIType.bool,
403
+ FFIType.u32,
404
+ FFIType.u32,
405
+ FFIType.function,
406
+ ],
407
+ returns: FFIType.u32,
408
+ },
409
+ showTray: {
410
+ args: [FFIType.u32],
411
+ returns: FFIType.bool,
412
+ },
413
+ hideTray: {
414
+ args: [FFIType.u32],
415
+ returns: FFIType.void,
416
+ },
417
+ setTrayTitle: {
418
+ args: [FFIType.u32, FFIType.cstring],
419
+ returns: FFIType.void,
420
+ },
421
+ setTrayImage: {
422
+ args: [FFIType.u32, FFIType.cstring],
423
+ returns: FFIType.void,
424
+ },
425
+ setTrayMenu: {
426
+ args: [FFIType.u32, FFIType.cstring],
427
+ returns: FFIType.void,
428
+ },
429
+ removeTray: {
430
+ args: [FFIType.u32],
431
+ returns: FFIType.void,
432
+ },
433
+ getTrayBounds: {
434
+ args: [FFIType.u32],
435
+ returns: FFIType.cstring,
436
+ },
437
+ setApplicationMenu: {
438
+ args: [FFIType.cstring, FFIType.function],
439
+ returns: FFIType.void,
440
+ },
441
+ showContextMenu: {
442
+ args: [FFIType.cstring, FFIType.function],
443
+ returns: FFIType.void,
444
+ },
445
+ moveToTrash: {
446
+ args: [FFIType.cstring],
447
+ returns: FFIType.bool,
448
+ },
449
+ showItemInFolder: {
450
+ args: [FFIType.cstring],
451
+ returns: FFIType.void,
452
+ },
453
+ openExternal: {
454
+ args: [FFIType.cstring],
455
+ returns: FFIType.bool,
456
+ },
457
+ openPath: {
458
+ args: [FFIType.cstring],
459
+ returns: FFIType.bool,
460
+ },
461
+ showNotification: {
462
+ args: [
463
+ FFIType.cstring,
464
+ FFIType.cstring,
465
+ FFIType.cstring,
466
+ FFIType.bool,
467
+ ],
207
468
  returns: FFIType.void,
208
469
  },
470
+ getAllDisplays: {
471
+ args: [],
472
+ returns: FFIType.cstring,
473
+ },
474
+ getPrimaryDisplay: {
475
+ args: [],
476
+ returns: FFIType.cstring,
477
+ },
478
+ getCursorScreenPoint: {
479
+ args: [],
480
+ returns: FFIType.cstring,
481
+ },
482
+ getMouseButtons: {
483
+ args: [],
484
+ returns: FFIType.u64,
485
+ },
486
+ openFileDialog: {
487
+ args: [
488
+ FFIType.cstring,
489
+ FFIType.cstring,
490
+ FFIType.int,
491
+ FFIType.int,
492
+ FFIType.int,
493
+ ],
494
+ returns: FFIType.cstring,
495
+ },
496
+ showMessageBox: {
497
+ args: [
498
+ FFIType.cstring,
499
+ FFIType.cstring,
500
+ FFIType.cstring,
501
+ FFIType.cstring,
502
+ FFIType.cstring,
503
+ FFIType.int,
504
+ FFIType.int,
505
+ ],
506
+ returns: FFIType.int,
507
+ },
508
+ clipboardReadText: {
509
+ args: [],
510
+ returns: FFIType.cstring,
511
+ },
512
+ clipboardWriteText: {
513
+ args: [FFIType.cstring],
514
+ returns: FFIType.void,
515
+ },
516
+ clipboardReadImage: {
517
+ args: [FFIType.ptr],
518
+ returns: FFIType.ptr,
519
+ },
520
+ clipboardWriteImage: {
521
+ args: [FFIType.ptr, FFIType.u64],
522
+ returns: FFIType.void,
523
+ },
524
+ clipboardClear: {
525
+ args: [],
526
+ returns: FFIType.void,
527
+ },
528
+ clipboardAvailableFormats: {
529
+ args: [],
530
+ returns: FFIType.cstring,
531
+ },
532
+ setDockIconVisible: {
533
+ args: [FFIType.bool],
534
+ returns: FFIType.void,
535
+ },
536
+ isDockIconVisible: {
537
+ args: [],
538
+ returns: FFIType.bool,
539
+ },
540
+ });
541
+ } catch {
542
+ return null;
543
+ }
544
+ })();
545
+
546
+ export const native = (() => {
547
+ try {
548
+ // Use absolute path to native wrapper DLL to avoid working directory issues
549
+ // On Windows shortcuts, the working directory may not be set correctly
550
+ const nativeWrapperPath = join(process.cwd(), `libNativeWrapper.${suffix}`);
551
+ return dlopen(nativeWrapperPath, {
209
552
  // webview
210
553
  initWebview: {
211
554
  args: [
@@ -463,73 +806,6 @@ export const native = (() => {
463
806
  args: [FFIType.ptr, FFIType.ptr],
464
807
  returns: FFIType.ptr,
465
808
  },
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
809
  // Global keyboard shortcuts
534
810
  setGlobalShortcutCallback: {
535
811
  args: [FFIType.function],
@@ -540,83 +816,16 @@ export const native = (() => {
540
816
  returns: FFIType.bool,
541
817
  },
542
818
  unregisterGlobalShortcut: {
543
- args: [FFIType.cstring],
544
- returns: FFIType.bool,
545
- },
546
- unregisterAllGlobalShortcuts: {
547
- args: [],
548
- returns: FFIType.void,
549
- },
550
- isGlobalShortcutRegistered: {
551
- args: [FFIType.cstring],
552
- returns: FFIType.bool,
553
- },
554
-
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,
819
+ args: [FFIType.cstring],
820
+ returns: FFIType.bool,
612
821
  },
613
- clipboardClear: {
822
+ unregisterAllGlobalShortcuts: {
614
823
  args: [],
615
824
  returns: FFIType.void,
616
825
  },
617
- clipboardAvailableFormats: {
618
- args: [],
619
- returns: FFIType.cstring,
826
+ isGlobalShortcutRegistered: {
827
+ args: [FFIType.cstring],
828
+ returns: FFIType.bool,
620
829
  },
621
830
 
622
831
  // Session/Cookie API
@@ -650,33 +859,7 @@ export const native = (() => {
650
859
  args: [FFIType.function],
651
860
  returns: FFIType.void,
652
861
  },
653
- setDockIconVisible: {
654
- args: [FFIType.bool],
655
- returns: FFIType.void,
656
- },
657
- isDockIconVisible: {
658
- args: [],
659
- returns: FFIType.bool,
660
- },
661
862
 
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
863
  // JSCallback utils for native code to use
681
864
  setJSUtils: {
682
865
  args: [
@@ -727,7 +910,7 @@ export const native = (() => {
727
910
  }
728
911
  })();
729
912
 
730
- export const hasFFI = native !== null;
913
+ export const hasFFI = native !== null && core !== null;
731
914
 
732
915
  // PostMessage bridge for carrot workers (inter-carrot communication, host events).
733
916
  // Created when __bunnyCarrotBootstrap exists, regardless of FFI availability.
@@ -821,12 +1004,12 @@ function createFfiRequestProxy(ffiRequest: Record<string, Function>): Record<str
821
1004
  // a zig bug I ran into last year. So check number of args in a signature when alignment issues occur.
822
1005
 
823
1006
  // Non-null accessor for use inside _ffiImpl — these methods are only called when hasFFI is true.
1007
+ const core_ = core!;
824
1008
  const native_ = native!;
825
1009
 
826
1010
  const _ffiImpl = {
827
1011
  request: {
828
1012
  createWindow: (params: {
829
- id: number;
830
1013
  url: string | null;
831
1014
  title: string;
832
1015
  frame: {
@@ -857,9 +1040,8 @@ const _ffiImpl = {
857
1040
  x: number;
858
1041
  y: number;
859
1042
  };
860
- }): FFIType.ptr => {
1043
+ }): number => {
861
1044
  const {
862
- id,
863
1045
  url: _url,
864
1046
  title,
865
1047
  frame: { x, y, width, height },
@@ -884,7 +1066,7 @@ const _ffiImpl = {
884
1066
  trafficLightOffset = { x: 0, y: 0 },
885
1067
  } = params;
886
1068
 
887
- const styleMask = native_.symbols.getWindowStyle(
1069
+ const styleMask = core_.symbols.getWindowStyle(
888
1070
  Borderless,
889
1071
  Titled,
890
1072
  Closable,
@@ -899,8 +1081,7 @@ const _ffiImpl = {
899
1081
  HUDWindow,
900
1082
  );
901
1083
 
902
- const windowPtr = native_.symbols.createWindowWithFrameAndStyleFromWorker(
903
- id,
1084
+ const windowId = core_.symbols.createWindow(
904
1085
  // frame
905
1086
  x,
906
1087
  y,
@@ -910,6 +1091,9 @@ const _ffiImpl = {
910
1091
  // style
911
1092
  toCString(titleBarStyle),
912
1093
  transparent,
1094
+ toCString(title),
1095
+ hidden,
1096
+ activate,
913
1097
  trafficLightOffset.x,
914
1098
  trafficLightOffset.y,
915
1099
  // callbacks
@@ -921,26 +1105,24 @@ const _ffiImpl = {
921
1105
  windowKeyCallback,
922
1106
  );
923
1107
 
924
- if (!windowPtr) {
925
- throw "Failed to create window";
926
- }
927
-
928
- native_.symbols.setWindowTitle(windowPtr, toCString(title));
929
- if (!hidden) {
930
- native_.symbols.showWindow(windowPtr, activate);
1108
+ if (!windowId) {
1109
+ throw getCoreLastError() || "Failed to create window";
931
1110
  }
932
1111
 
933
- return windowPtr;
1112
+ return windowId;
1113
+ },
1114
+ getWindowPointer: (params: { winId: number }): Pointer | null => {
1115
+ return getWindowPtr(params.winId);
934
1116
  },
935
1117
  setTitle: (params: { winId: number; title: string }) => {
936
1118
  const { winId, title } = params;
937
1119
  const windowPtr = getWindowPtr(winId);
938
1120
 
939
1121
  if (!windowPtr) {
940
- throw `Can't add webview to window. window no longer exists`;
1122
+ throw `Can't set window title. Window no longer exists`;
941
1123
  }
942
1124
 
943
- native_.symbols.setWindowTitle(windowPtr, toCString(title));
1125
+ core_.symbols.setWindowTitle(winId, toCString(title));
944
1126
  },
945
1127
 
946
1128
  closeWindow: (params: { winId: number }) => {
@@ -952,7 +1134,7 @@ const _ffiImpl = {
952
1134
  return;
953
1135
  }
954
1136
 
955
- native_.symbols.closeWindow(windowPtr);
1137
+ core_.symbols.closeWindow(winId);
956
1138
  // Note: Cleanup of BrowserWindowMap happens in the windowCloseCallback
957
1139
  },
958
1140
 
@@ -964,7 +1146,7 @@ const _ffiImpl = {
964
1146
  throw `Can't show window. Window no longer exists`;
965
1147
  }
966
1148
 
967
- native_.symbols.showWindow(windowPtr, params.activate ?? true);
1149
+ core_.symbols.showWindow(winId, params.activate ?? true);
968
1150
  },
969
1151
 
970
1152
  activateWindow: (params: { winId: number }) => {
@@ -975,7 +1157,7 @@ const _ffiImpl = {
975
1157
  throw `Can't activate window. Window no longer exists`;
976
1158
  }
977
1159
 
978
- native_.symbols.activateWindow(windowPtr);
1160
+ core_.symbols.activateWindow(winId);
979
1161
  },
980
1162
 
981
1163
  hideWindow: (params: { winId: number }) => {
@@ -986,7 +1168,7 @@ const _ffiImpl = {
986
1168
  throw `Can't hide window. Window no longer exists`;
987
1169
  }
988
1170
 
989
- native_.symbols.hideWindow(windowPtr);
1171
+ core_.symbols.hideWindow(winId);
990
1172
  },
991
1173
 
992
1174
  minimizeWindow: (params: { winId: number }) => {
@@ -997,7 +1179,7 @@ const _ffiImpl = {
997
1179
  throw `Can't minimize window. Window no longer exists`;
998
1180
  }
999
1181
 
1000
- native_.symbols.minimizeWindow(windowPtr);
1182
+ core_.symbols.minimizeWindow(winId);
1001
1183
  },
1002
1184
 
1003
1185
  restoreWindow: (params: { winId: number }) => {
@@ -1008,7 +1190,7 @@ const _ffiImpl = {
1008
1190
  throw `Can't restore window. Window no longer exists`;
1009
1191
  }
1010
1192
 
1011
- native_.symbols.restoreWindow(windowPtr);
1193
+ core_.symbols.restoreWindow(winId);
1012
1194
  },
1013
1195
 
1014
1196
  isWindowMinimized: (params: { winId: number }): boolean => {
@@ -1019,7 +1201,7 @@ const _ffiImpl = {
1019
1201
  return false;
1020
1202
  }
1021
1203
 
1022
- return native_.symbols.isWindowMinimized(windowPtr);
1204
+ return core_.symbols.isWindowMinimized(winId);
1023
1205
  },
1024
1206
 
1025
1207
  maximizeWindow: (params: { winId: number }) => {
@@ -1030,7 +1212,7 @@ const _ffiImpl = {
1030
1212
  throw `Can't maximize window. Window no longer exists`;
1031
1213
  }
1032
1214
 
1033
- native_.symbols.maximizeWindow(windowPtr);
1215
+ core_.symbols.maximizeWindow(winId);
1034
1216
  },
1035
1217
 
1036
1218
  unmaximizeWindow: (params: { winId: number }) => {
@@ -1041,7 +1223,7 @@ const _ffiImpl = {
1041
1223
  throw `Can't unmaximize window. Window no longer exists`;
1042
1224
  }
1043
1225
 
1044
- native_.symbols.unmaximizeWindow(windowPtr);
1226
+ core_.symbols.unmaximizeWindow(winId);
1045
1227
  },
1046
1228
 
1047
1229
  isWindowMaximized: (params: { winId: number }): boolean => {
@@ -1052,7 +1234,7 @@ const _ffiImpl = {
1052
1234
  return false;
1053
1235
  }
1054
1236
 
1055
- return native_.symbols.isWindowMaximized(windowPtr);
1237
+ return core_.symbols.isWindowMaximized(winId);
1056
1238
  },
1057
1239
 
1058
1240
  setWindowFullScreen: (params: { winId: number; fullScreen: boolean }) => {
@@ -1063,7 +1245,7 @@ const _ffiImpl = {
1063
1245
  throw `Can't set fullscreen. Window no longer exists`;
1064
1246
  }
1065
1247
 
1066
- native_.symbols.setWindowFullScreen(windowPtr, fullScreen);
1248
+ core_.symbols.setWindowFullScreen(winId, fullScreen);
1067
1249
  },
1068
1250
 
1069
1251
  isWindowFullScreen: (params: { winId: number }): boolean => {
@@ -1074,7 +1256,7 @@ const _ffiImpl = {
1074
1256
  return false;
1075
1257
  }
1076
1258
 
1077
- return native_.symbols.isWindowFullScreen(windowPtr);
1259
+ return core_.symbols.isWindowFullScreen(winId);
1078
1260
  },
1079
1261
 
1080
1262
  setWindowAlwaysOnTop: (params: { winId: number; alwaysOnTop: boolean }) => {
@@ -1085,7 +1267,7 @@ const _ffiImpl = {
1085
1267
  throw `Can't set always on top. Window no longer exists`;
1086
1268
  }
1087
1269
 
1088
- native_.symbols.setWindowAlwaysOnTop(windowPtr, alwaysOnTop);
1270
+ core_.symbols.setWindowAlwaysOnTop(winId, alwaysOnTop);
1089
1271
  },
1090
1272
 
1091
1273
  isWindowAlwaysOnTop: (params: { winId: number }): boolean => {
@@ -1096,7 +1278,7 @@ const _ffiImpl = {
1096
1278
  return false;
1097
1279
  }
1098
1280
 
1099
- return native_.symbols.isWindowAlwaysOnTop(windowPtr);
1281
+ return core_.symbols.isWindowAlwaysOnTop(winId);
1100
1282
  },
1101
1283
 
1102
1284
  setWindowVisibleOnAllWorkspaces: (params: {
@@ -1104,55 +1286,55 @@ const _ffiImpl = {
1104
1286
  visibleOnAllWorkspaces: boolean;
1105
1287
  }) => {
1106
1288
  const { winId, visibleOnAllWorkspaces } = params;
1107
- const windowPtr = BrowserWindow.getById(winId)?.ptr;
1289
+ const windowPtr = getWindowPtr(winId);
1108
1290
 
1109
1291
  if (!windowPtr) {
1110
1292
  throw `Can't set visible on all workspaces. Window no longer exists`;
1111
1293
  }
1112
1294
 
1113
- native_.symbols.setWindowVisibleOnAllWorkspaces(
1114
- windowPtr,
1295
+ core_.symbols.setWindowVisibleOnAllWorkspaces(
1296
+ winId,
1115
1297
  visibleOnAllWorkspaces,
1116
1298
  );
1117
1299
  },
1118
1300
 
1119
1301
  isWindowVisibleOnAllWorkspaces: (params: { winId: number }): boolean => {
1120
1302
  const { winId } = params;
1121
- const windowPtr = BrowserWindow.getById(winId)?.ptr;
1303
+ const windowPtr = getWindowPtr(winId);
1122
1304
 
1123
1305
  if (!windowPtr) {
1124
1306
  return false;
1125
1307
  }
1126
1308
 
1127
- return native_.symbols.isWindowVisibleOnAllWorkspaces(windowPtr);
1309
+ return core_.symbols.isWindowVisibleOnAllWorkspaces(winId);
1128
1310
  },
1129
1311
 
1130
- setWindowPosition: (params: { winId: number; x: number; y: number }) => {
1131
- const { winId, x, y } = params;
1132
- const windowPtr = getWindowPtr(winId);
1312
+ setWindowPosition: (params: { winId: number; x: number; y: number }) => {
1313
+ const { winId, x, y } = params;
1314
+ const windowPtr = getWindowPtr(winId);
1133
1315
 
1134
- if (!windowPtr) {
1135
- throw `Can't set window position. Window no longer exists`;
1136
- }
1316
+ if (!windowPtr) {
1317
+ throw `Can't set window position. Window no longer exists`;
1318
+ }
1137
1319
 
1138
- native_.symbols.setWindowPosition(windowPtr, x, y);
1139
- },
1320
+ core_.symbols.setWindowPosition(winId, x, y);
1321
+ },
1140
1322
 
1141
- setWindowButtonPosition: (params: { winId: number; x: number; y: number }) => {
1142
- const { winId, x, y } = params;
1143
- const windowPtr = getWindowPtr(winId);
1323
+ setWindowButtonPosition: (params: { winId: number; x: number; y: number }) => {
1324
+ const { winId, x, y } = params;
1325
+ const windowPtr = getWindowPtr(winId);
1144
1326
 
1145
- if (!windowPtr) {
1146
- throw `Can't set window button position. Window no longer exists`;
1147
- }
1327
+ if (!windowPtr) {
1328
+ throw `Can't set window button position. Window no longer exists`;
1329
+ }
1148
1330
 
1149
- native_.symbols.setWindowButtonPosition(windowPtr, x, y);
1150
- },
1331
+ core_.symbols.setWindowButtonPosition(winId, x, y);
1332
+ },
1151
1333
 
1152
- setWindowSize: (params: {
1153
- winId: number;
1154
- width: number;
1155
- height: number;
1334
+ setWindowSize: (params: {
1335
+ winId: number;
1336
+ width: number;
1337
+ height: number;
1156
1338
  }) => {
1157
1339
  const { winId, width, height } = params;
1158
1340
  const windowPtr = getWindowPtr(winId);
@@ -1161,7 +1343,7 @@ const _ffiImpl = {
1161
1343
  throw `Can't set window size. Window no longer exists`;
1162
1344
  }
1163
1345
 
1164
- native_.symbols.setWindowSize(windowPtr, width, height);
1346
+ core_.symbols.setWindowSize(winId, width, height);
1165
1347
  },
1166
1348
 
1167
1349
  setWindowFrame: (params: {
@@ -1178,7 +1360,7 @@ const _ffiImpl = {
1178
1360
  throw `Can't set window frame. Window no longer exists`;
1179
1361
  }
1180
1362
 
1181
- native_.symbols.setWindowFrame(windowPtr, x, y, width, height);
1363
+ core_.symbols.setWindowFrame(winId, x, y, width, height);
1182
1364
  },
1183
1365
 
1184
1366
  getWindowFrame: (params: {
@@ -1197,8 +1379,8 @@ const _ffiImpl = {
1197
1379
  const widthBuf = new Float64Array(1);
1198
1380
  const heightBuf = new Float64Array(1);
1199
1381
 
1200
- native_.symbols.getWindowFrame(
1201
- windowPtr,
1382
+ core_.symbols.getWindowFrame(
1383
+ winId,
1202
1384
  ptr(xBuf),
1203
1385
  ptr(yBuf),
1204
1386
  ptr(widthBuf),
@@ -1212,17 +1394,12 @@ const _ffiImpl = {
1212
1394
  height: heightBuf[0]!,
1213
1395
  };
1214
1396
  },
1215
-
1216
1397
  createWebview: (params: {
1217
- id: number;
1218
1398
  windowId: number;
1399
+ hostWebviewId: number | null;
1219
1400
  renderer: "cef" | "native";
1220
- rpcPort: number;
1221
1401
  secretKey: string;
1222
- hostWebviewId: number | null;
1223
- pipePrefix: string;
1224
1402
  url: string | null;
1225
- html: string | null;
1226
1403
  partition: string | null;
1227
1404
  preload: string | null;
1228
1405
  viewsRoot: string | null;
@@ -1237,17 +1414,13 @@ const _ffiImpl = {
1237
1414
  sandbox: boolean;
1238
1415
  startTransparent: boolean;
1239
1416
  startPassthrough: boolean;
1240
- }): FFIType.ptr => {
1417
+ }): number => {
1241
1418
  const {
1242
- id,
1243
1419
  windowId,
1420
+ hostWebviewId,
1244
1421
  renderer,
1245
- rpcPort,
1246
1422
  secretKey,
1247
- // hostWebviewId: number | null;
1248
- // pipePrefix: string;
1249
1423
  url,
1250
- // html: string | null;
1251
1424
  partition,
1252
1425
  preload,
1253
1426
  viewsRoot,
@@ -1257,62 +1430,11 @@ const _ffiImpl = {
1257
1430
  startTransparent,
1258
1431
  startPassthrough,
1259
1432
  } = params;
1433
+ ensureWebviewRuntimeConfigured();
1260
1434
 
1261
- const parentWindow = BrowserWindow.getById(windowId);
1262
- const windowPtr = parentWindow?.ptr;
1263
- // Get transparent flag from parent window
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,
1435
+ const webviewId = core_.symbols.createWebview(
1436
+ windowId,
1437
+ hostWebviewId || 0,
1316
1438
  toCString(renderer),
1317
1439
  toCString(url || ""),
1318
1440
  x,
@@ -1323,21 +1445,101 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1323
1445
  toCString(partition || "persist:default"),
1324
1446
  webviewDecideNavigation,
1325
1447
  webviewEventJSCallback,
1326
- eventBridgeHandler, // Event-only bridge (always active, for dom-ready, navigation, etc.)
1327
- bunBridgePostmessageHandler, // User RPC bridge (disabled in sandbox mode)
1328
- internalBridgeHandler, // Internal RPC bridge (disabled in sandbox mode)
1329
- toCString(electrobunPreload),
1330
- toCString(customPreload || ""),
1448
+ eventBridgeHandler,
1449
+ bunBridgePostmessageHandler,
1450
+ internalBridgeHandler,
1451
+ toCString(secretKey),
1452
+ toCString(preload || ""),
1331
1453
  toCString(viewsRoot || ""),
1332
- transparent,
1333
1454
  sandbox, // When true, bunBridge and internalBridge are not set up in native code
1455
+ startTransparent,
1456
+ startPassthrough,
1334
1457
  );
1335
1458
 
1336
- if (!webviewPtr) {
1337
- throw "Failed to create webview";
1459
+ if (!webviewId) {
1460
+ throw getCoreLastError() || "Failed to create webview";
1338
1461
  }
1339
1462
 
1340
- return webviewPtr;
1463
+ return webviewId;
1464
+ },
1465
+ getWebviewPointer: (params: { id: number }): Pointer | null => {
1466
+ return core_.symbols.getWebviewPointer(params.id) || null;
1467
+ },
1468
+ resizeWebview: (params: {
1469
+ id: number;
1470
+ frame: { x: number; y: number; width: number; height: number };
1471
+ masks?: string;
1472
+ }) => {
1473
+ const { id, frame: { x, y, width, height }, masks = "[]" } = params;
1474
+ core_.symbols.resizeWebview(id, x, y, width, height, toCString(masks));
1475
+ },
1476
+ loadURLInWebView: (params: { id: number; url: string }) => {
1477
+ core_.symbols.loadURLInWebView(params.id, toCString(params.url));
1478
+ },
1479
+ loadHTMLInWebView: (params: { id: number; html: string }) => {
1480
+ core_.symbols.loadHTMLInWebView(params.id, toCString(params.html));
1481
+ },
1482
+ updatePreloadScriptToWebView: (params: {
1483
+ id: number;
1484
+ scriptIdentifier: string;
1485
+ script: string;
1486
+ allFrames: boolean;
1487
+ }) => {
1488
+ core_.symbols.updatePreloadScriptToWebView(
1489
+ params.id,
1490
+ toCString(params.scriptIdentifier),
1491
+ toCString(params.script),
1492
+ params.allFrames,
1493
+ );
1494
+ },
1495
+ webviewCanGoBack: (params: { id: number }) => {
1496
+ return core_.symbols.webviewCanGoBack(params.id);
1497
+ },
1498
+ webviewCanGoForward: (params: { id: number }) => {
1499
+ return core_.symbols.webviewCanGoForward(params.id);
1500
+ },
1501
+ webviewGoBack: (params: { id: number }) => {
1502
+ core_.symbols.webviewGoBack(params.id);
1503
+ },
1504
+ webviewGoForward: (params: { id: number }) => {
1505
+ core_.symbols.webviewGoForward(params.id);
1506
+ },
1507
+ webviewReload: (params: { id: number }) => {
1508
+ core_.symbols.webviewReload(params.id);
1509
+ },
1510
+ webviewRemove: (params: { id: number }) => {
1511
+ core_.symbols.webviewRemove(params.id);
1512
+ },
1513
+ setWebviewHTMLContent: (params: { id: number; html: string }) => {
1514
+ core_.symbols.setWebviewHTMLContent(params.id, toCString(params.html));
1515
+ },
1516
+ webviewSetTransparent: (params: { id: number; transparent: boolean }) => {
1517
+ core_.symbols.webviewSetTransparent(params.id, params.transparent);
1518
+ },
1519
+ webviewSetPassthrough: (params: { id: number; passthrough: boolean }) => {
1520
+ core_.symbols.webviewSetPassthrough(params.id, params.passthrough);
1521
+ },
1522
+ webviewSetHidden: (params: { id: number; hidden: boolean }) => {
1523
+ core_.symbols.webviewSetHidden(params.id, params.hidden);
1524
+ },
1525
+ setWebviewNavigationRules: (params: { id: number; rulesJson: string }) => {
1526
+ core_.symbols.setWebviewNavigationRules(params.id, toCString(params.rulesJson));
1527
+ },
1528
+ webviewFindInPage: (params: {
1529
+ id: number;
1530
+ searchText: string;
1531
+ forward: boolean;
1532
+ matchCase: boolean;
1533
+ }) => {
1534
+ core_.symbols.webviewFindInPage(
1535
+ params.id,
1536
+ toCString(params.searchText),
1537
+ params.forward,
1538
+ params.matchCase,
1539
+ );
1540
+ },
1541
+ webviewStopFind: (params: { id: number }) => {
1542
+ core_.symbols.webviewStopFind(params.id);
1341
1543
  },
1342
1544
 
1343
1545
  createWGPUView: (params: {
@@ -1477,31 +1679,37 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1477
1679
  id: number;
1478
1680
  js: string;
1479
1681
  }) => {
1480
- const { id, js } = params;
1481
- const webview = BrowserView.getById(id);
1482
-
1483
- if (!webview?.ptr) {
1484
- return;
1485
- }
1486
-
1487
- native_.symbols.evaluateJavaScriptWithNoCompletion(
1488
- webview.ptr,
1489
- toCString(js),
1682
+ core_.symbols.evaluateJavaScriptWithNoCompletion(
1683
+ params.id,
1684
+ toCString(params.js),
1490
1685
  );
1491
1686
  },
1687
+ webviewOpenDevTools: (params: { id: number }) => {
1688
+ core_.symbols.webviewOpenDevTools(params.id);
1689
+ },
1690
+ webviewCloseDevTools: (params: { id: number }) => {
1691
+ core_.symbols.webviewCloseDevTools(params.id);
1692
+ },
1693
+ webviewToggleDevTools: (params: { id: number }) => {
1694
+ core_.symbols.webviewToggleDevTools(params.id);
1695
+ },
1696
+ webviewSetPageZoom: (params: { id: number; zoomLevel: number }) => {
1697
+ core_.symbols.webviewSetPageZoom(params.id, params.zoomLevel);
1698
+ },
1699
+ webviewGetPageZoom: (params: { id: number }): number => {
1700
+ return core_.symbols.webviewGetPageZoom(params.id);
1701
+ },
1492
1702
 
1493
1703
  createTray: (params: {
1494
- id: number;
1495
1704
  title: string;
1496
1705
  image: string;
1497
1706
  template: boolean;
1498
1707
  width: number;
1499
1708
  height: number;
1500
- }): FFIType.ptr => {
1501
- const { id, title, image, template, width, height } = params;
1709
+ }): number => {
1710
+ const { title, image, template, width, height } = params;
1502
1711
 
1503
- const trayPtr = native_.symbols.createTray(
1504
- id,
1712
+ const trayId = core_.symbols.createTray(
1505
1713
  toCString(title),
1506
1714
  toCString(image),
1507
1715
  template,
@@ -1510,27 +1718,25 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1510
1718
  trayItemHandler,
1511
1719
  );
1512
1720
 
1513
- if (!trayPtr) {
1721
+ if (!trayId) {
1514
1722
  throw "Failed to create tray";
1515
1723
  }
1516
1724
 
1517
- return trayPtr;
1725
+ return trayId;
1726
+ },
1727
+ showTray: (params: { id: number }): boolean => {
1728
+ return core_.symbols.showTray(params.id);
1729
+ },
1730
+ hideTray: (params: { id: number }): void => {
1731
+ core_.symbols.hideTray(params.id);
1518
1732
  },
1519
1733
  setTrayTitle: (params: { id: number; title: string }): void => {
1520
1734
  const { id, title } = params;
1521
-
1522
- const tray = Tray.getById(id);
1523
- if (!tray) return;
1524
-
1525
- native_.symbols.setTrayTitle(tray.ptr, toCString(title));
1735
+ core_.symbols.setTrayTitle(id, toCString(title));
1526
1736
  },
1527
1737
  setTrayImage: (params: { id: number; image: string }): void => {
1528
1738
  const { id, image } = params;
1529
-
1530
- const tray = Tray.getById(id);
1531
- if (!tray) return;
1532
-
1533
- native_.symbols.setTrayImage(tray.ptr, toCString(image));
1739
+ core_.symbols.setTrayImage(id, toCString(image));
1534
1740
  },
1535
1741
  setTrayMenu: (params: {
1536
1742
  id: number;
@@ -1538,31 +1744,14 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1538
1744
  menuConfig: string;
1539
1745
  }): void => {
1540
1746
  const { id, menuConfig } = params;
1541
-
1542
- const tray = Tray.getById(id);
1543
- if (!tray) return;
1544
-
1545
- native_.symbols.setTrayMenu(tray.ptr, toCString(menuConfig));
1747
+ core_.symbols.setTrayMenu(id, toCString(menuConfig));
1546
1748
  },
1547
1749
 
1548
1750
  removeTray: (params: { id: number }): void => {
1549
- const { id } = params;
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
1751
+ core_.symbols.removeTray(params.id);
1558
1752
  },
1559
1753
  getTrayBounds: (params: { id: number }): Rectangle => {
1560
- const tray = Tray.getById(params.id);
1561
- if (!tray?.ptr) {
1562
- return { x: 0, y: 0, width: 0, height: 0 };
1563
- }
1564
-
1565
- const jsonStr = native_.symbols.getTrayBounds(tray.ptr);
1754
+ const jsonStr = core_.symbols.getTrayBounds(params.id);
1566
1755
  if (!jsonStr) {
1567
1756
  return { x: 0, y: 0, width: 0, height: 0 };
1568
1757
  }
@@ -1576,7 +1765,7 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1576
1765
  setApplicationMenu: (params: { menuConfig: string }): void => {
1577
1766
  const { menuConfig } = params;
1578
1767
 
1579
- native_.symbols.setApplicationMenu(
1768
+ core_.symbols.setApplicationMenu(
1580
1769
  toCString(menuConfig),
1581
1770
  applicationMenuHandler,
1582
1771
  );
@@ -1584,25 +1773,25 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1584
1773
  showContextMenu: (params: { menuConfig: string }): void => {
1585
1774
  const { menuConfig } = params;
1586
1775
 
1587
- native_.symbols.showContextMenu(toCString(menuConfig), contextMenuHandler);
1776
+ core_.symbols.showContextMenu(toCString(menuConfig), contextMenuHandler);
1588
1777
  },
1589
1778
  moveToTrash: (params: { path: string }): boolean => {
1590
1779
  const { path } = params;
1591
1780
 
1592
- return native_.symbols.moveToTrash(toCString(path));
1781
+ return core_.symbols.moveToTrash(toCString(path));
1593
1782
  },
1594
1783
  showItemInFolder: (params: { path: string }): void => {
1595
1784
  const { path } = params;
1596
1785
 
1597
- native_.symbols.showItemInFolder(toCString(path));
1786
+ core_.symbols.showItemInFolder(toCString(path));
1598
1787
  },
1599
1788
  openExternal: (params: { url: string }): boolean => {
1600
1789
  const { url } = params;
1601
- return native_.symbols.openExternal(toCString(url));
1790
+ return core_.symbols.openExternal(toCString(url));
1602
1791
  },
1603
1792
  openPath: (params: { path: string }): boolean => {
1604
1793
  const { path } = params;
1605
- return native_.symbols.openPath(toCString(path));
1794
+ return core_.symbols.openPath(toCString(path));
1606
1795
  },
1607
1796
  showNotification: (params: {
1608
1797
  title: string;
@@ -1611,7 +1800,7 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1611
1800
  silent?: boolean;
1612
1801
  }): void => {
1613
1802
  const { title, body = "", subtitle = "", silent = false } = params;
1614
- native_.symbols.showNotification(
1803
+ core_.symbols.showNotification(
1615
1804
  toCString(title),
1616
1805
  toCString(body),
1617
1806
  toCString(subtitle),
@@ -1619,10 +1808,10 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1619
1808
  );
1620
1809
  },
1621
1810
  setDockIconVisible: (params: { visible: boolean }): void => {
1622
- native_.symbols.setDockIconVisible(params.visible);
1811
+ core_.symbols.setDockIconVisible(params.visible);
1623
1812
  },
1624
1813
  isDockIconVisible: (): boolean => {
1625
- return native_.symbols.isDockIconVisible();
1814
+ return core_.symbols.isDockIconVisible();
1626
1815
  },
1627
1816
  openFileDialog: (params: {
1628
1817
  startingFolder: string;
@@ -1638,7 +1827,7 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1638
1827
  canChooseDirectory,
1639
1828
  allowsMultipleSelection,
1640
1829
  } = params;
1641
- const filePath = native_.symbols.openFileDialog(
1830
+ const filePath = core_.symbols.openFileDialog(
1642
1831
  toCString(startingFolder),
1643
1832
  toCString(allowedFileTypes),
1644
1833
  canChooseFiles ? 1 : 0,
@@ -1668,7 +1857,7 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1668
1857
  } = params;
1669
1858
  // Convert buttons array to comma-separated string
1670
1859
  const buttonsStr = buttons.join(",");
1671
- return native_.symbols.showMessageBox(
1860
+ return core_.symbols.showMessageBox(
1672
1861
  toCString(type),
1673
1862
  toCString(title),
1674
1863
  toCString(message),
@@ -1681,17 +1870,17 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1681
1870
 
1682
1871
  // Clipboard API
1683
1872
  clipboardReadText: (): string | null => {
1684
- const result = native_.symbols.clipboardReadText();
1873
+ const result = core_.symbols.clipboardReadText();
1685
1874
  if (!result) return null;
1686
1875
  return result.toString();
1687
1876
  },
1688
1877
  clipboardWriteText: (params: { text: string }): void => {
1689
- native_.symbols.clipboardWriteText(toCString(params.text));
1878
+ core_.symbols.clipboardWriteText(toCString(params.text));
1690
1879
  },
1691
1880
  clipboardReadImage: (): Uint8Array | null => {
1692
1881
  // Allocate a buffer for the size output
1693
1882
  const sizeBuffer = new BigUint64Array(1);
1694
- const dataPtr = native_.symbols.clipboardReadImage(ptr(sizeBuffer));
1883
+ const dataPtr = core_.symbols.clipboardReadImage(ptr(sizeBuffer));
1695
1884
 
1696
1885
  if (!dataPtr) return null;
1697
1886
 
@@ -1711,13 +1900,13 @@ window.__electrobunBunBridge = window.__electrobunBunBridge || window.webkit?.me
1711
1900
  },
1712
1901
  clipboardWriteImage: (params: { pngData: Uint8Array }): void => {
1713
1902
  const { pngData } = params;
1714
- native_.symbols.clipboardWriteImage(ptr(pngData), BigInt(pngData.length));
1903
+ core_.symbols.clipboardWriteImage(ptr(pngData), BigInt(pngData.length));
1715
1904
  },
1716
1905
  clipboardClear: (): void => {
1717
- native_.symbols.clipboardClear();
1906
+ core_.symbols.clipboardClear();
1718
1907
  },
1719
1908
  clipboardAvailableFormats: (): string[] => {
1720
- const result = native_.symbols.clipboardAvailableFormats();
1909
+ const result = core_.symbols.clipboardAvailableFormats();
1721
1910
  if (!result) return [];
1722
1911
  const formatsStr = result.toString();
1723
1912
  if (!formatsStr) return [];
@@ -2088,7 +2277,7 @@ if (native) {
2088
2277
  const appReopenCallback = new JSCallback(
2089
2278
  () => {
2090
2279
  if (process.platform === "darwin") {
2091
- native_.symbols.setDockIconVisible(true);
2280
+ core_.symbols.setDockIconVisible(true);
2092
2281
  }
2093
2282
  const handler = electrobunEventEmitter.events.app.reopen;
2094
2283
  const event = handler({});
@@ -2178,7 +2367,7 @@ export const Screen = {
2178
2367
  * @returns Display object for the primary monitor
2179
2368
  */
2180
2369
  getPrimaryDisplay: (): Display => {
2181
- const jsonStr = native ? native_.symbols.getPrimaryDisplay() : null;
2370
+ const jsonStr = hasFFI ? core_.symbols.getPrimaryDisplay() : null;
2182
2371
  if (!jsonStr) {
2183
2372
  return {
2184
2373
  id: 0,
@@ -2206,7 +2395,7 @@ export const Screen = {
2206
2395
  * @returns Array of Display objects
2207
2396
  */
2208
2397
  getAllDisplays: (): Display[] => {
2209
- const jsonStr = native ? native_.symbols.getAllDisplays() : null;
2398
+ const jsonStr = hasFFI ? core_.symbols.getAllDisplays() : null;
2210
2399
  if (!jsonStr) {
2211
2400
  return [];
2212
2401
  }
@@ -2222,7 +2411,7 @@ export const Screen = {
2222
2411
  * @returns Point with x and y coordinates
2223
2412
  */
2224
2413
  getCursorScreenPoint: (): Point => {
2225
- const jsonStr = native ? native_.symbols.getCursorScreenPoint() : null;
2414
+ const jsonStr = hasFFI ? core_.symbols.getCursorScreenPoint() : null;
2226
2415
  if (!jsonStr) {
2227
2416
  return { x: 0, y: 0 };
2228
2417
  }
@@ -2238,7 +2427,7 @@ export const Screen = {
2238
2427
  */
2239
2428
  getMouseButtons: (): bigint => {
2240
2429
  try {
2241
- return native ? native_.symbols.getMouseButtons() : BigInt(0);
2430
+ return hasFFI ? core_.symbols.getMouseButtons() : BigInt(0);
2242
2431
  } catch {
2243
2432
  return 0n;
2244
2433
  }
@@ -2403,35 +2592,11 @@ const webviewDecideNavigation = new JSCallback(
2403
2592
  );
2404
2593
 
2405
2594
  const webviewEventHandler = (id: number, eventName: string, detail: string) => {
2406
- const webview = BrowserView.getById(id);
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
- }
2419
-
2420
- // This is a webviewtag so we should send the event into the parent as well
2421
- // NOTE: for new-window-open and host-message the detail is a json string that needs to be parsed
2422
- let js;
2423
- if (eventName === "new-window-open" || eventName === "host-message") {
2424
- // detail is already a JSON string that will be parsed as a JS object
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
- }
2595
+ core_.symbols.dispatchHostWebviewEvent(
2596
+ id,
2597
+ toCString(eventName),
2598
+ toCString(detail),
2599
+ );
2435
2600
 
2436
2601
  const eventMap: Record<string, string> = {
2437
2602
  "will-navigate": "willNavigate",
@@ -2620,8 +2785,6 @@ const internalBridgeHandler = new JSCallback(
2620
2785
  )[msgJson.id];
2621
2786
  handler?.(msgJson.payload);
2622
2787
  } else if (msgJson.type === "request") {
2623
- const hostWebview = BrowserView.getById(msgJson.hostWebviewId);
2624
- // const targetWebview = BrowserView.getById(msgJson.params.params.hostWebviewId);
2625
2788
  const handler = (
2626
2789
  internalRpcHandlers.request as Record<
2627
2790
  string,
@@ -2637,15 +2800,10 @@ const internalBridgeHandler = new JSCallback(
2637
2800
  success: true,
2638
2801
  payload,
2639
2802
  };
2640
-
2641
- if (!hostWebview) {
2642
- console.log(
2643
- "--->>> internal request in bun: NO HOST WEBVIEW FOUND",
2644
- );
2645
- return;
2646
- }
2647
-
2648
- hostWebview.sendInternalMessageViaExecute(resultObj);
2803
+ core_.symbols.sendInternalMessageToWebview(
2804
+ msgJson.hostWebviewId,
2805
+ toCString(JSON.stringify(resultObj)),
2806
+ );
2649
2807
  }
2650
2808
  });
2651
2809
  } catch (err) {
@@ -2826,24 +2984,10 @@ export const internalRpcHandlers = {
2826
2984
  return viewForTag.id;
2827
2985
  },
2828
2986
  webviewTagCanGoBack: (params: { id: number }) => {
2829
- const { id } = params;
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);
2987
+ return core_.symbols.webviewCanGoBack(params.id);
2837
2988
  },
2838
2989
  webviewTagCanGoForward: (params: { id: number }) => {
2839
- const { id } = params;
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);
2990
+ return core_.symbols.webviewCanGoForward(params.id);
2847
2991
  },
2848
2992
  },
2849
2993
  message: {
@@ -2852,25 +2996,14 @@ export const internalRpcHandlers = {
2852
2996
  frame: { x: number; y: number; width: number; height: number };
2853
2997
  masks: string;
2854
2998
  }) => {
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
2999
  const { x, y, width, height } = params.frame;
2867
- native_.symbols.resizeWebview(
2868
- webviewPtr,
3000
+ core_.symbols.resizeWebview(
3001
+ params.id,
2869
3002
  x,
2870
3003
  y,
2871
3004
  width,
2872
3005
  height,
2873
- toCString(params.masks),
3006
+ toCString(params.masks ?? "[]"),
2874
3007
  );
2875
3008
  },
2876
3009
  wgpuTagResize: (params: {
@@ -2898,80 +3031,46 @@ export const internalRpcHandlers = {
2898
3031
  },
2899
3032
  webviewTagUpdateSrc: (params: { id: number; url: string }) => {
2900
3033
  const webview = BrowserView.getById(params.id);
2901
- if (!webview || !webview.ptr) {
2902
- console.error(
2903
- `webviewTagUpdateSrc: BrowserView not found or has no ptr for id ${params.id}`,
2904
- );
2905
- return;
3034
+ if (webview) {
3035
+ webview.url = params.url;
2906
3036
  }
2907
- native_.symbols.loadURLInWebView(webview.ptr, toCString(params.url));
3037
+ core_.symbols.loadURLInWebView(params.id, toCString(params.url));
2908
3038
  },
2909
3039
  webviewTagUpdateHtml: (params: { id: number; html: string }) => {
2910
3040
  const webview = BrowserView.getById(params.id);
2911
- if (!webview || !webview.ptr) {
2912
- console.error(
2913
- `webviewTagUpdateHtml: BrowserView not found or has no ptr for id ${params.id}`,
2914
- );
3041
+ if (!webview) {
3042
+ console.error(`webviewTagUpdateHtml: BrowserView not found for id ${params.id}`);
2915
3043
  return;
2916
3044
  }
2917
3045
 
2918
- // Store HTML content in native map for scheme handlers
2919
- native_.symbols.setWebviewHTMLContent(webview.id, toCString(params.html));
2920
-
2921
3046
  webview.loadHTML(params.html);
2922
3047
  webview.html = params.html;
2923
3048
  },
2924
3049
  webviewTagUpdatePreload: (params: { id: number; preload: string }) => {
2925
3050
  const webview = BrowserView.getById(params.id);
2926
- if (!webview || !webview.ptr) {
2927
- console.error(
2928
- `webviewTagUpdatePreload: BrowserView not found or has no ptr for id ${params.id}`,
2929
- );
2930
- return;
3051
+ if (webview) {
3052
+ webview.preload = params.preload;
2931
3053
  }
2932
- native_.symbols.updatePreloadScriptToWebView(
2933
- webview.ptr,
3054
+ core_.symbols.updatePreloadScriptToWebView(
3055
+ params.id,
2934
3056
  toCString("electrobun_custom_preload_script"),
2935
3057
  toCString(params.preload),
2936
3058
  true,
2937
3059
  );
2938
3060
  },
2939
3061
  webviewTagGoBack: (params: { id: number }) => {
2940
- const webview = BrowserView.getById(params.id);
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);
3062
+ core_.symbols.webviewGoBack(params.id);
2948
3063
  },
2949
3064
  webviewTagGoForward: (params: { id: number }) => {
2950
- const webview = BrowserView.getById(params.id);
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);
3065
+ core_.symbols.webviewGoForward(params.id);
2958
3066
  },
2959
3067
  webviewTagReload: (params: { id: number }) => {
2960
- const webview = BrowserView.getById(params.id);
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);
3068
+ core_.symbols.webviewReload(params.id);
2968
3069
  },
2969
3070
  webviewTagRemove: (params: { id: number }) => {
2970
3071
  const webview = BrowserView.getById(params.id);
2971
- if (!webview || !webview.ptr) {
2972
- console.error(
2973
- `webviewTagRemove: BrowserView not found or has no ptr for id ${params.id}`,
2974
- );
3072
+ if (!webview) {
3073
+ console.error(`webviewTagRemove: BrowserView not found for id ${params.id}`);
2975
3074
  return;
2976
3075
  }
2977
3076
  webview.remove();
@@ -2988,14 +3087,7 @@ export const internalRpcHandlers = {
2988
3087
  id: number;
2989
3088
  transparent: boolean;
2990
3089
  }) => {
2991
- const webview = BrowserView.getById(params.id);
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);
3090
+ core_.symbols.webviewSetTransparent(params.id, params.transparent);
2999
3091
  },
3000
3092
  wgpuTagSetTransparent: (params: {
3001
3093
  id: number;
@@ -3014,17 +3106,7 @@ export const internalRpcHandlers = {
3014
3106
  id: number;
3015
3107
  enablePassthrough: boolean;
3016
3108
  }) => {
3017
- const webview = BrowserView.getById(params.id);
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
- );
3109
+ core_.symbols.webviewSetPassthrough(params.id, params.enablePassthrough);
3028
3110
  },
3029
3111
  wgpuTagSetPassthrough: (params: { id: number; passthrough: boolean }) => {
3030
3112
  const view = WGPUView.getById(params.id);
@@ -3037,14 +3119,7 @@ export const internalRpcHandlers = {
3037
3119
  native_.symbols.wgpuViewSetPassthrough(view.ptr, params.passthrough);
3038
3120
  },
3039
3121
  webviewTagSetHidden: (params: { id: number; hidden: boolean }) => {
3040
- const webview = BrowserView.getById(params.id);
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);
3122
+ core_.symbols.webviewSetHidden(params.id, params.hidden);
3048
3123
  },
3049
3124
  wgpuTagSetHidden: (params: { id: number; hidden: boolean }) => {
3050
3125
  const view = WGPUView.getById(params.id);
@@ -3081,18 +3156,12 @@ export const internalRpcHandlers = {
3081
3156
  native_.symbols.wgpuRunGPUTest(view.ptr);
3082
3157
  },
3083
3158
  webviewTagSetNavigationRules: (params: { id: number; rules: string[] }) => {
3159
+ const rulesJson = JSON.stringify(params.rules);
3084
3160
  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;
3161
+ if (webview) {
3162
+ webview.navigationRules = rulesJson;
3090
3163
  }
3091
- const rulesJson = JSON.stringify(params.rules);
3092
- native_.symbols.setWebviewNavigationRules(
3093
- webview.ptr,
3094
- toCString(rulesJson),
3095
- );
3164
+ core_.symbols.setWebviewNavigationRules(params.id, toCString(rulesJson));
3096
3165
  },
3097
3166
  webviewTagFindInPage: (params: {
3098
3167
  id: number;
@@ -3100,70 +3169,28 @@ export const internalRpcHandlers = {
3100
3169
  forward: boolean;
3101
3170
  matchCase: boolean;
3102
3171
  }) => {
3103
- const webview = BrowserView.getById(params.id);
3104
- if (!webview || !webview.ptr) {
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,
3172
+ core_.symbols.webviewFindInPage(
3173
+ params.id,
3112
3174
  toCString(params.searchText),
3113
3175
  params.forward,
3114
3176
  params.matchCase,
3115
3177
  );
3116
3178
  },
3117
3179
  webviewTagStopFind: (params: { id: number }) => {
3118
- const webview = BrowserView.getById(params.id);
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);
3180
+ core_.symbols.webviewStopFind(params.id);
3126
3181
  },
3127
3182
  webviewTagOpenDevTools: (params: { id: number }) => {
3128
- const webview = BrowserView.getById(params.id);
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);
3183
+ core_.symbols.webviewOpenDevTools(params.id);
3136
3184
  },
3137
3185
  webviewTagCloseDevTools: (params: { id: number }) => {
3138
- const webview = BrowserView.getById(params.id);
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);
3186
+ core_.symbols.webviewCloseDevTools(params.id);
3146
3187
  },
3147
3188
  webviewTagToggleDevTools: (params: { id: number }) => {
3148
- const webview = BrowserView.getById(params.id);
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);
3189
+ core_.symbols.webviewToggleDevTools(params.id);
3156
3190
  },
3157
3191
  webviewTagExecuteJavascript: (params: { id: number; js: string }) => {
3158
- const webview = BrowserView.getById(params.id);
3159
- if (!webview || !webview.ptr) {
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,
3192
+ core_.symbols.evaluateJavaScriptWithNoCompletion(
3193
+ params.id,
3167
3194
  toCString(params.js),
3168
3195
  );
3169
3196
  },