Webview_desktop.MenuThe native menu bar.
The system's own menu bar — the strip at the top of the screen on macOS, the one under the title bar on Linux and Windows — described as an ordinary OCaml value and installed in one call:
let quit () = Webview.terminate w in
Webview_desktop.Menu.set w
[
("MyApp", [ Menu.item "Quit" ~key:'q' ~modifiers:[ Cmd ] quit ]);
( "File",
[
Menu.item "Open…" ~key:'o' ~modifiers:[ Cmd ] pick_file;
Menu.separator;
Menu.submenu "Recent" [ Menu.item "example.txt" reopen ];
] );
]set must run on the UI thread — the thread running Webview.run — and on macOS only once the application is active, which it becomes after Webview.run has started. The reliable place is therefore a Webview.dispatch callback, the same pattern Icon.set_app_icon needs:
Webview.dispatch w (fun w -> Menu.set w menus);
Webview.run wItem callbacks are invoked on the UI thread too, so they may drive the webview directly — Webview.eval, Webview.terminate — with no Webview.dispatch in between. An exception escaping a callback is dropped: there is no OCaml handler on the native stack below it.
Webview.t argument is ignored. Note the platform convention: the first menu is the application menu, and the system draws it with the application's own name whatever title you give it. Put your Quit item there, as in the example above, and give the remaining menus their real names.GtkBox. Calling set again replaces the bar rather than stacking a second one. GTK 4 is not supported — it replaced GtkMenuBar with the GMenu model — and set is a no-op there.WM_COMMAND. Accelerators take two routes, because WebView2 runs the page in a separate browser process whose input window never feeds this process's message loop. While the page has the focus, set listens to the controller's AcceleratorKeyPressed event. While the host window has it, it installs a WH_GETMESSAGE hook on the calling thread that runs TranslateAccelerator, which webview's own loop does not call. Two consequences. Both belong to the thread that called set, so call it from the UI thread like everything else here. And a menu shortcut takes precedence over the page: a keystroke it claims is swallowed, so a page listening for Ctrl-O will not also see it. This is also why owebview.desktop needs the WebView2 SDK header to build on Windows, just as owebview does.item label on_click is a clickable entry that calls on_click () on the UI thread when chosen.
?key and ?modifiers give it a keyboard shortcut: ~key:'o' ~modifiers:[ Cmd ] is Command-O on macOS and Control-O elsewhere. Use a lowercase letter; with no ?key the item has no shortcut, and ?modifiers is then ignored.
val separator : itemA horizontal rule between groups of items.
submenu label items nests a menu inside another one.