Events
The default main-process export exposes the global event emitter. Window, webview, menu, and tray objects also expose scoped listeners. In the native SDKs there is no emitter: window and webview events are C callbacks registered at creation time.
import Electrobun, { BrowserWindow } from "electrobun/main";
const win = new BrowserWindow({ title: "Events", url: "views://mainview/index.html",});
Electrobun.events.on("will-navigate", (event) => { console.log("Any view will navigate", event);});
win.webview.on("will-navigate", (event: unknown) => { console.log("This view will navigate", event);});import Electrobun, { BrowserWindow } from "electrobun/main";
const win = new BrowserWindow({ title: "Events", url: "views://mainview/index.html",});
Electrobun.events.on("will-navigate", (event) => { console.log("Any view will navigate", event);});
win.webview.on("will-navigate", (event: unknown) => { console.log("This view will navigate", event);});fn onResize(window_id: u32, x: f64, y: f64, width: f64, height: f64) callconv(.C) void { std.debug.print("window {d} resized to {d}x{d} at ({d},{d})\n", .{ window_id, width, height, x, y });}
fn onWebviewEvent(webview_id: u32, event_name: [*:0]const u8, payload: [*:0]const u8) callconv(.C) void { std.debug.print("webview {d}: {s} {s}\n", .{ webview_id, event_name, payload });}
const window_id = try core.createWindow(.{ .title = "Events", .callbacks = .{ .resize = onResize },});
_ = try core.createWebview(.{ .window_id = window_id, .url = "views://mainview/index.html", .callbacks = .{ .decide_navigation = electrobun.allowAllNavigation, .event = onWebviewEvent, },});extern "C" fn on_resize(window_id: u32, x: f64, y: f64, width: f64, height: f64) { println!("window {window_id} resized to {width}x{height} at ({x},{y})");}
extern "C" fn on_webview_event(webview_id: u32, event_name: *const c_char, detail: *const c_char) { let name = electrobun::c_string_to_string(event_name); let detail = electrobun::c_string_to_string(detail); println!("webview {webview_id}: {name} {detail}");}
let mut window_options = WindowOptions::new("Events", Rect::new(160.0, 100.0, 960.0, 640.0));window_options.callbacks = WindowCallbacks { resize: Some(on_resize), ..WindowCallbacks::default()};let window_id = core.create_window(window_options)?;
let mut webview_options = WebviewOptions::new( window_id, "views://mainview/index.html", Rect::new(0.0, 0.0, 960.0, 640.0),);webview_options.callbacks = WebviewCallbacks { decide_navigation: Some(electrobun::allow_all_navigation), event: Some(on_webview_event), ..WebviewCallbacks::default()};core.create_webview(webview_options)?;windowOptions := electrobun.NewWindowOptions( "Events", electrobun.NewRect(160, 100, 960, 640),)windowOptions.Callbacks = electrobun.WindowCallbacks{ Resize: func(windowID uint32, x, y, width, height float64) { fmt.Printf("window %d resized to %.0fx%.0f\n", windowID, width, height) },}windowID, err := core.CreateWindow(windowOptions)
webviewOptions := electrobun.NewWebviewOptions( windowID, "views://mainview/index.html", electrobun.NewRect(0, 0, 960, 640),)webviewOptions.Callbacks = electrobun.WebviewCallbacks{ DecideNavigation: electrobun.AllowAllNavigation, Event: func(webviewID uint32, eventName, detail string) { fmt.Printf("webview %d: %s %s\n", webviewID, eventName, detail) },}webviewID, err := core.CreateWebview(webviewOptions)import "base:runtime"
on_window_resize :: proc "c" (window_id: u32, x: f64, y: f64, width: f64, height: f64) { context = runtime.default_context() fmt.printfln("window %d resized to %.0fx%.0f", window_id, width, height)}
on_webview_event :: proc "c" (webview_id: u32, event_name: cstring, detail: cstring) { context = runtime.default_context() fmt.printfln("webview %d: %s %s", webview_id, event_name, detail)}
window_options := electrobun.defaultWindowOptions("Events")window_options.callbacks.resize = on_window_resizewindow_id, window_err := electrobun.createWindow(core, window_options)
webview_options := electrobun.defaultWebviewOptions(window_id)webview_options.url = "views://mainview/index.html"webview_options.callbacks = { decide_navigation = electrobun.allowAllNavigation, event = on_webview_event,}webview_id, webview_err := electrobun.createWebview(core, webview_options)The rest of this page documents the TypeScript emitter surface used by Cottontail and Bun.
Event objects
Electrobun events expose:
name: emitted event name.data: event-specific payload.response: optional response consumed by a cancellable native action.responseWasSet: whether a handler assigned a response.clearResponse(): remove a response set by an earlier handler.
Handlers run synchronously in registration order. A cancellable action reads
the response after emission, so assign event.response before returning from
the callback.
Application events
Current application event names are application-menu-clicked,
context-menu-clicked, open-url, reopen, and before-quit.
import Electrobun from "electrobun/main";
Electrobun.events.on("open-url", (event) => { const data = event.data as { url: string }; const url = new URL(data.url); console.log(url.protocol, url.pathname);});
Electrobun.events.on("before-quit", (event) => { const shouldCancel = false; if (shouldCancel) { event.response = { allow: false }; }});On macOS, custom schemes and associated files arrive through open-url; files
use file:// URLs. Configure them with app.urlSchemes and
app.fileAssociations.
Window events
Current window event names are close, will-close, resize, move,
focus, blur, keyDown, and keyUp. Per-window close handlers run before
the internal last-window shutdown logic.
Webview events
Current webview event names are will-navigate, did-navigate,
did-navigate-in-page, did-commit-navigation, dom-ready,
new-window-open, host-message, download-started, download-progress,
download-completed, and download-failed.
The BrowserView.on() typed surface currently includes navigation, readiness,
and download events. <electrobun-webview> exposes its browser-side event
surface documented on the webview tag page.
Shutdown
Use before-quit to synchronously save in-memory state, initiate already
prepared cleanup, or cancel shutdown. The current event emitter does not
await a returned promise.
import Electrobun from "electrobun/main";
Electrobun.events.on("before-quit", (event) => { const canQuit = true; if (!canQuit) { event.response = { allow: false }; return; }
console.log("Application is quitting");});
process.on("exit", (code) => { console.log("Process exited with code", code);});