Skip to content

Commit ac0b03e

Browse files
authored
feat: add window menu
* adds menu and fix high cpu usage * attempt to fix Windows and Ubuntu CI errors * add libxdo feature to muda to make Ubuntu arm tests to pass * on android libxdo does not exists, so we are gating the menu feature for Android systems
1 parent 0a8f2b6 commit ac0b03e

9 files changed

Lines changed: 1246 additions & 84 deletions

File tree

.github/workflows/CI.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ jobs:
6565
# Linux x86_64
6666
- os: ubuntu-latest
6767
target: x86_64-unknown-linux-gnu
68-
sys_deps: pkg-config libwebkit2gtk-4.1-dev libsoup-3.0-dev libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev libgdk-pixbuf2.0-dev libgtk-3-dev
68+
sys_deps: pkg-config libwebkit2gtk-4.1-dev libsoup-3.0-dev libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev libgdk-pixbuf2.0-dev libgtk-3-dev libxdo-dev
6969

7070
# Linux ARM64
7171
- os: ubuntu-latest
7272
target: aarch64-unknown-linux-gnu
7373
cross_arch: arm64
74-
cross_sys_deps: libglib2.0-dev:arm64 libwebkit2gtk-4.1-dev:arm64 libsoup-3.0-dev:arm64 libcairo2-dev:arm64 libpango1.0-dev:arm64 libatk1.0-dev:arm64 libgdk-pixbuf2.0-dev:arm64 libgtk-3-dev:arm64
74+
cross_sys_deps: libglib2.0-dev:arm64 libwebkit2gtk-4.1-dev:arm64 libsoup-3.0-dev:arm64 libcairo2-dev:arm64 libpango1.0-dev:arm64 libatk1.0-dev:arm64 libgdk-pixbuf2.0-dev:arm64 libgtk-3-dev:arm64 libxdo-dev:arm64
7575
cross_gcc: gcc-aarch64-linux-gnu
7676
cross_gpp: g++-aarch64-linux-gnu
7777
cross_triplet: aarch64-linux-gnu
@@ -91,7 +91,7 @@ jobs:
9191
- os: ubuntu-latest
9292
target: armv7-unknown-linux-gnueabihf
9393
cross_arch: armhf
94-
cross_sys_deps: libglib2.0-dev:armhf libwebkit2gtk-4.1-dev:armhf libsoup-3.0-dev:armhf libcairo2-dev:armhf libpango1.0-dev:armhf libatk1.0-dev:armhf libgdk-pixbuf2.0-dev:armhf libgtk-3-dev:armhf
94+
cross_sys_deps: libglib2.0-dev:armhf libwebkit2gtk-4.1-dev:armhf libsoup-3.0-dev:armhf libcairo2-dev:armhf libpango1.0-dev:armhf libatk1.0-dev:armhf libgdk-pixbuf2.0-dev:armhf libgtk-3-dev:armhf libxdo-dev:armhf
9595
cross_gcc: gcc-arm-linux-gnueabihf
9696
cross_gpp: g++-arm-linux-gnueabihf
9797
cross_triplet: arm-linux-gnueabihf

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ napi-derive = "3.5.1"
1515
tao = { version = "0.34.5", features = ["rwh_06"] }
1616
wry = { version = "0.53.5", features = ["devtools", "fullscreen"] }
1717

18+
[target.'cfg(not(target_os = "android"))'.dependencies]
19+
muda = { version = "0.17", features = ["libxdo"] }
20+
1821
[target.'cfg(target_os = "linux")'.dependencies]
1922
gtk = "0.18"
2023
glib = "0.18"

README.md

Lines changed: 147 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,20 @@ npm install @webviewjs/webview
1717

1818
# Supported platforms
1919

20-
| Platform | Supported |
21-
| ----------------------- | --------- |
22-
| x86_64-apple-darwin ||
23-
| x86_64-pc-windows-msvc ||
24-
| i686-pc-windows-msvc ||
25-
| aarch64-apple-darwin ||
26-
| aarch64-linux-android ||
27-
| armv7-linux-androideabi ||
28-
| aarch64-pc-windows-msvc ||
20+
| Platform | Supported |
21+
| ---------------------------- | --------- |
22+
| x86_64-pc-windows-msvc ||
23+
| i686-pc-windows-msvc ||
24+
| aarch64-pc-windows-msvc ||
25+
| x86_64-apple-darwin ||
26+
| aarch64-apple-darwin ||
27+
| x86_64-unknown-linux-gnu ||
28+
| i686-unknown-linux-gnu ||
29+
| aarch64-unknown-linux-gnu ||
30+
| armv7-unknown-linux-gnueabihf||
31+
| aarch64-linux-android ||
32+
| armv7-linux-androideabi ||
33+
| x86_64-unknown-freebsd ||
2934

3035
# Examples
3136

@@ -45,6 +50,129 @@ webview.loadUrl('https://nodejs.org');
4550
app.run();
4651
```
4752

53+
## Menu System
54+
55+
WebviewJS provides a cross-platform menu system that works on macOS, Windows, and Linux.
56+
57+
### Basic Menu Setup
58+
59+
```js
60+
import { Application, initMenuSystem } from '@webviewjs/webview';
61+
62+
// Initialize menu system (recommended, especially for macOS)
63+
initMenuSystem();
64+
65+
const app = new Application();
66+
67+
// Set global application menu
68+
app.setMenu({
69+
items: [
70+
{
71+
label: "File",
72+
submenu: {
73+
items: [
74+
{ id: "new", label: "New", accelerator: "CmdOrCtrl+N" },
75+
{ id: "open", label: "Open", accelerator: "CmdOrCtrl+O" },
76+
{ role: "separator" },
77+
{ id: "quit", label: "Quit", accelerator: "CmdOrCtrl+Q" }
78+
]
79+
}
80+
},
81+
{
82+
label: "Edit",
83+
submenu: {
84+
items: [
85+
{ role: "copy" },
86+
{ role: "paste" },
87+
{ role: "cut" },
88+
{ role: "selectall" }
89+
]
90+
}
91+
}
92+
]
93+
});
94+
95+
const window = app.createBrowserWindow();
96+
const webview = window.createWebview({ url: 'https://nodejs.org' });
97+
98+
app.run();
99+
```
100+
101+
### Menu Event Handling
102+
103+
```js
104+
import { Application, WebviewApplicationEvent } from '@webviewjs/webview';
105+
106+
const app = new Application();
107+
108+
// Handle menu events
109+
app.bind((event) => {
110+
if (event.event === WebviewApplicationEvent.CustomMenuClick) {
111+
const menuEvent = event.customMenuEvent;
112+
console.log(`Menu item clicked: ${menuEvent.id}`);
113+
console.log(`From window: ${menuEvent.windowId}`);
114+
115+
// Handle specific menu items
116+
switch (menuEvent.id) {
117+
case 'new':
118+
console.log('Creating new document...');
119+
break;
120+
case 'open':
121+
console.log('Opening file...');
122+
break;
123+
case 'quit':
124+
app.exit();
125+
break;
126+
}
127+
}
128+
});
129+
130+
// Set up menu...
131+
app.setMenu({ /* ... */ });
132+
```
133+
134+
### Window-Specific Menus
135+
136+
```js
137+
const app = new Application();
138+
139+
// Create window with custom menu
140+
const window = app.createBrowserWindow({
141+
title: "Custom Window",
142+
menu: {
143+
items: [
144+
{
145+
id: "window-action",
146+
label: "Window Action",
147+
accelerator: "Ctrl+W"
148+
}
149+
]
150+
}
151+
});
152+
153+
// Or check if window has a menu
154+
if (window.hasMenu()) {
155+
console.log('This window has a menu');
156+
}
157+
```
158+
159+
### Menu Item Options
160+
161+
- **`id`**: Unique identifier for the menu item (used in events)
162+
- **`label`**: Display text for the menu item
163+
- **`enabled`**: Whether the item is clickable (default: true)
164+
- **`accelerator`**: Keyboard shortcut (e.g., "CmdOrCtrl+N", "Alt+F4")
165+
- **`submenu`**: Nested menu items
166+
- **`role`**: Predefined menu items with built-in behavior
167+
168+
### Predefined Menu Roles
169+
170+
- **`"copy"`**: Standard copy action
171+
- **`"paste"`**: Standard paste action
172+
- **`"cut"`**: Standard cut action
173+
- **`"selectall"`**: Select all text action
174+
- **`"separator"`**: Visual separator line
175+
48176
## IPC
49177

50178
```js
@@ -120,7 +248,15 @@ webview.reload();
120248

121249
For more details on closing applications and cleaning up resources, see the [Closing Guide](./docs/CLOSING_GUIDE.md).
122250

123-
Check out [examples](./examples) directory for more examples, such as serving contents from a web server to webview, etc.
251+
Check out [examples](./examples) directory for more examples:
252+
253+
- **[menu-system.mjs](./examples/menu-system.mjs)** - Comprehensive menu system demonstration with all features
254+
- **[window-menus.mjs](./examples/window-menus.mjs)** - Window-specific vs global menu examples
255+
- **[http/](./examples/http/)** - Serving content from a web server to webview
256+
- **[transparent.mjs](./examples/transparent.mjs)** - Transparent window example
257+
- **[close-example.mjs](./examples/close-example.mjs)** - Graceful application closing
258+
259+
Run any example with: `node examples/menu-system.mjs` (after building the project)
124260

125261
# Building executables
126262

@@ -141,7 +277,7 @@ You can pass `--resources ./my-resource.json` to include additional resources in
141277

142278
- [Bun](https://bun.sh/) >= 1.3.0
143279
- [Rust](https://www.rust-lang.org/) stable toolchain
144-
- [Node.js](https://nodejs.org/) >= 18 (for testing)
280+
- [Node.js](https://nodejs.org/) >= 24 (for testing)
145281

146282
## Setup
147283

0 commit comments

Comments
 (0)