Menus
laufey supports three kinds of menus: an application menu bar, per-window
context menus, and the developer tools. A menu is described by a slice of
MenuItem values, which can be regular items, submenus, separators, or standard
roles such as quit, copy, and paste. Items may carry a keyboard accelerator.
When the user clicks an item that has an identifier, your callback is invoked
with that identifier.
Regular items also support a few visual properties, mirroring Electron’s
MenuItem: checked (a checkmark, all platforms), icon (a file path to a PNG
image — macOS and Windows, unsupported on Linux; on macOS a monochrome
black+alpha PNG is treated as a template and tints to white on selection, while
Windows renders it as-is), and tooltip (hover text — macOS only).
#![allow(unused)]
fn main() {
use laufey::MenuItem;
let menu = [MenuItem::Submenu {
label: "File".into(),
items: vec![
MenuItem::Item {
label: "Open".into(),
id: Some("open".into()),
accelerator: Some("CmdOrCtrl+O".into()),
enabled: true,
checked: false,
icon: Some("icons/open.png".into()), // file path to a template PNG
tooltip: Some("Open a file".into()),
},
MenuItem::Separator,
MenuItem::Role { role: "quit".into() },
],
}];
win.set_menu(&menu, |id| println!("menu: {id}"));
win.show_context_menu(x, y, &menu, |id| println!("context: {id}"));
win.open_devtools();
}
On macOS the application menu is the global menu bar at the top of the screen, and laufey swaps it as windows take focus. On Windows and Linux the menu is attached to the individual window. A context menu is a pop-up shown at a point you specify, in window coordinates.
The application menu does not work under the CEF and Winit backends on Linux. A
GtkMenuBar must be packed into a GtkWindow placed above the browser, and
reparenting CEF into a client-owned GtkWindow through
CefWindowInfo::SetAsChild breaks on XWayland, where cross-client X11 child
windows are not supported natively. Context menus work everywhere, because a
GtkMenu pop-up does not need a containing window.