electrobun 0.5.0-beta.0 → 0.6.0-beta.0

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.
Files changed (78) hide show
  1. package/{templates/multitab-browser/bun.lock → bun.lock} +20 -13
  2. package/dist/api/bun/proc/native.ts +84 -16
  3. package/package.json +14 -16
  4. package/BETA_RELEASE.md +0 -67
  5. package/BUILD.md +0 -90
  6. package/LICENSE +0 -21
  7. package/README.md +0 -102
  8. package/debug.js +0 -5
  9. package/templates/hello-world/README.md +0 -57
  10. package/templates/hello-world/bun.lock +0 -225
  11. package/templates/hello-world/electrobun.config.ts +0 -28
  12. package/templates/hello-world/package.json +0 -16
  13. package/templates/hello-world/src/bun/index.ts +0 -15
  14. package/templates/hello-world/src/mainview/index.css +0 -124
  15. package/templates/hello-world/src/mainview/index.html +0 -46
  16. package/templates/hello-world/src/mainview/index.ts +0 -1
  17. package/templates/interactive-playground/README.md +0 -26
  18. package/templates/interactive-playground/assets/tray-icon.png +0 -0
  19. package/templates/interactive-playground/electrobun.config.ts +0 -36
  20. package/templates/interactive-playground/package-lock.json +0 -1112
  21. package/templates/interactive-playground/package.json +0 -15
  22. package/templates/interactive-playground/src/bun/demos/files.ts +0 -70
  23. package/templates/interactive-playground/src/bun/demos/menus.ts +0 -139
  24. package/templates/interactive-playground/src/bun/demos/rpc.ts +0 -83
  25. package/templates/interactive-playground/src/bun/demos/system.ts +0 -72
  26. package/templates/interactive-playground/src/bun/demos/updates.ts +0 -105
  27. package/templates/interactive-playground/src/bun/demos/windows.ts +0 -90
  28. package/templates/interactive-playground/src/bun/index.ts +0 -124
  29. package/templates/interactive-playground/src/bun/types/rpc.ts +0 -109
  30. package/templates/interactive-playground/src/mainview/components/EventLog.ts +0 -107
  31. package/templates/interactive-playground/src/mainview/components/Sidebar.ts +0 -65
  32. package/templates/interactive-playground/src/mainview/components/Toast.ts +0 -57
  33. package/templates/interactive-playground/src/mainview/demos/FileDemo.ts +0 -211
  34. package/templates/interactive-playground/src/mainview/demos/MenuDemo.ts +0 -102
  35. package/templates/interactive-playground/src/mainview/demos/RPCDemo.ts +0 -229
  36. package/templates/interactive-playground/src/mainview/demos/TrayDemo.ts +0 -132
  37. package/templates/interactive-playground/src/mainview/demos/WebViewDemo.ts +0 -465
  38. package/templates/interactive-playground/src/mainview/demos/WindowDemo.ts +0 -207
  39. package/templates/interactive-playground/src/mainview/index.css +0 -538
  40. package/templates/interactive-playground/src/mainview/index.html +0 -103
  41. package/templates/interactive-playground/src/mainview/index.ts +0 -238
  42. package/templates/multitab-browser/README.md +0 -34
  43. package/templates/multitab-browser/electrobun.config.ts +0 -32
  44. package/templates/multitab-browser/package-lock.json +0 -20
  45. package/templates/multitab-browser/package.json +0 -12
  46. package/templates/multitab-browser/src/bun/index.ts +0 -144
  47. package/templates/multitab-browser/src/bun/tabManager.ts +0 -200
  48. package/templates/multitab-browser/src/bun/types/rpc.ts +0 -78
  49. package/templates/multitab-browser/src/mainview/index.css +0 -487
  50. package/templates/multitab-browser/src/mainview/index.html +0 -94
  51. package/templates/multitab-browser/src/mainview/index.ts +0 -634
  52. package/templates/photo-booth/README.md +0 -108
  53. package/templates/photo-booth/bun.lock +0 -239
  54. package/templates/photo-booth/electrobun.config.ts +0 -32
  55. package/templates/photo-booth/package.json +0 -17
  56. package/templates/photo-booth/src/bun/index.ts +0 -92
  57. package/templates/photo-booth/src/mainview/index.css +0 -465
  58. package/templates/photo-booth/src/mainview/index.html +0 -124
  59. package/templates/photo-booth/src/mainview/index.ts +0 -499
  60. package/test-new-window-events.ts +0 -26
  61. package/test-new-window.html +0 -75
  62. package/test-npm-install.sh +0 -34
  63. package/tests/bun.lock +0 -14
  64. package/tests/electrobun.config.ts +0 -45
  65. package/tests/package-lock.json +0 -36
  66. package/tests/package.json +0 -13
  67. package/tests/src/bun/index.ts +0 -100
  68. package/tests/src/bun/test-runner.ts +0 -508
  69. package/tests/src/mainview/index.html +0 -110
  70. package/tests/src/mainview/index.ts +0 -458
  71. package/tests/src/mainview/styles/main.css +0 -451
  72. package/tests/src/testviews/tray-test.html +0 -57
  73. package/tests/src/testviews/webview-mask.html +0 -114
  74. package/tests/src/testviews/webview-navigation.html +0 -36
  75. package/tests/src/testviews/window-create.html +0 -17
  76. package/tests/src/testviews/window-events.html +0 -29
  77. package/tests/src/testviews/window-focus.html +0 -37
  78. package/tests/src/webviewtag/index.ts +0 -11
@@ -1,15 +0,0 @@
1
- {
2
- "name": "electrobun-interactive-playground",
3
- "version": "0.0.1",
4
- "description": "Interactive playground for exploring Electrobun features",
5
- "type": "module",
6
- "scripts": {
7
- "build:dev": "electrobun build",
8
- "build:canary": "electrobun build --canary",
9
- "start": "electrobun build && electrobun dev",
10
- "start:canary": "electrobun build --canary && electrobun dev --canary"
11
- },
12
- "dependencies": {
13
- "electrobun": "latest"
14
- }
15
- }
@@ -1,70 +0,0 @@
1
- import { Utils } from "electrobun/bun";
2
- import { join } from "path";
3
- import { homedir } from "os";
4
-
5
- class FileManager {
6
- async openFileDialog(options: {
7
- multiple?: boolean;
8
- fileTypes?: string[];
9
- startingFolder?: string;
10
- }) {
11
- try {
12
- const result = await Utils.openFileDialog({
13
- startingFolder: options.startingFolder || join(homedir(), "Desktop"),
14
- allowedFileTypes: options.fileTypes?.join(",") || "*",
15
- canChooseFiles: true,
16
- canChooseDirectory: false,
17
- allowsMultipleSelection: options.multiple || false,
18
- });
19
-
20
- // Filter out empty strings
21
- const filteredResult = result.filter(path => path.trim() !== "");
22
- this.onFileSelected?.(filteredResult);
23
-
24
- return filteredResult;
25
- } catch (error) {
26
- console.error("File dialog error:", error);
27
- return [];
28
- }
29
- }
30
-
31
- async moveToTrash(path: string) {
32
- try {
33
- await Utils.moveToTrash(path);
34
- this.onSystemEvent?.({
35
- type: 'file-trashed',
36
- details: { path, success: true }
37
- });
38
- } catch (error) {
39
- console.error("Move to trash error:", error);
40
- this.onSystemEvent?.({
41
- type: 'file-trashed',
42
- details: { path, success: false, error: error.message }
43
- });
44
- throw error;
45
- }
46
- }
47
-
48
- async showInFinder(path: string) {
49
- try {
50
- await Utils.showItemInFolder(path);
51
- this.onSystemEvent?.({
52
- type: 'show-in-finder',
53
- details: { path, success: true }
54
- });
55
- } catch (error) {
56
- console.error("Show in finder error:", error);
57
- this.onSystemEvent?.({
58
- type: 'show-in-finder',
59
- details: { path, success: false, error: error.message }
60
- });
61
- throw error;
62
- }
63
- }
64
-
65
- // Event callbacks
66
- onFileSelected?: (paths: string[]) => void;
67
- onSystemEvent?: (event: { type: string; details: any }) => void;
68
- }
69
-
70
- export const fileManager = new FileManager();
@@ -1,139 +0,0 @@
1
- import { ApplicationMenu, ContextMenu, Tray } from "electrobun/bun";
2
-
3
- class MenuManager {
4
- private trays = new Map<number, Tray>();
5
- private nextTrayId = 1;
6
-
7
- constructor() {
8
- this.setupApplicationMenu();
9
- }
10
-
11
- private setupApplicationMenu() {
12
- ApplicationMenu.setApplicationMenu([
13
- {
14
- submenu: [
15
- { label: "About", role: "about" },
16
- { type: "separator" },
17
- { label: "Quit", role: "quit", accelerator: "q" }
18
- ],
19
- },
20
- {
21
- label: "Edit",
22
- submenu: [
23
- { role: "undo" },
24
- { role: "redo" },
25
- { type: "separator" },
26
- {
27
- label: "Custom Demo Action",
28
- action: "demo-action",
29
- tooltip: "This is a demo menu item",
30
- },
31
- { type: "separator" },
32
- { role: "cut" },
33
- { role: "copy" },
34
- { role: "paste" },
35
- { role: "selectAll" },
36
- ],
37
- },
38
- {
39
- label: "View",
40
- submenu: [
41
- { role: "reload" },
42
- { role: "forceReload" },
43
- { role: "toggleDevTools" },
44
- { type: "separator" },
45
- { role: "resetZoom" },
46
- { role: "zoomIn" },
47
- { role: "zoomOut" },
48
- { type: "separator" },
49
- { role: "togglefullscreen" }
50
- ],
51
- },
52
- {
53
- label: "Window",
54
- submenu: [
55
- { role: "minimize" },
56
- { role: "close" }
57
- ],
58
- }
59
- ]);
60
- }
61
-
62
- async createTray(options: { title: string; image?: string }) {
63
- const id = this.nextTrayId++;
64
-
65
- const tray = new Tray({
66
- title: options.title,
67
- image: options.image || "views://assets/tray-icon.png",
68
- template: true,
69
- width: 32,
70
- height: 32,
71
- });
72
-
73
- // Set up tray menu
74
- tray.setMenu([
75
- {
76
- type: "normal",
77
- label: "Show Playground",
78
- action: "show-playground",
79
- },
80
- {
81
- type: "separator",
82
- },
83
- {
84
- type: "normal",
85
- label: "Demo Action",
86
- action: "demo-tray-action",
87
- tooltip: "This is a demo tray action",
88
- },
89
- {
90
- type: "normal",
91
- label: "Quit",
92
- action: "quit-app",
93
- },
94
- ]);
95
-
96
- tray.on("tray-clicked", (e) => {
97
- this.onTrayClicked?.(id, e.data.action);
98
- });
99
-
100
- this.trays.set(id, tray);
101
- return { id };
102
- }
103
-
104
- async removeTray(id: number) {
105
- const tray = this.trays.get(id);
106
- if (tray) {
107
- tray.remove();
108
- this.trays.delete(id);
109
- }
110
- }
111
-
112
- async showContextMenu(params: { x: number; y: number }) {
113
- ContextMenu.showContextMenu([
114
- { role: "undo" },
115
- { role: "redo" },
116
- { type: "separator" },
117
- {
118
- label: "Demo Context Action",
119
- action: "demo-context-action",
120
- tooltip: "This is a demo context menu item",
121
- },
122
- {
123
- label: "Disabled Action",
124
- action: "disabled-action",
125
- enabled: false,
126
- },
127
- { type: "separator" },
128
- { role: "cut" },
129
- { role: "copy" },
130
- { role: "paste" },
131
- ]);
132
- }
133
-
134
- // Event callbacks
135
- onTrayClicked?: (id: number, action: string) => void;
136
- onMenuClicked?: (action: string) => void;
137
- }
138
-
139
- export const menuManager = new MenuManager();
@@ -1,83 +0,0 @@
1
- class RPCTester {
2
- async doMath(data: { a: number; b: number; operation: string }): Promise<number> {
3
- const startTime = Date.now();
4
- let result: number;
5
-
6
- switch (data.operation) {
7
- case 'add':
8
- result = data.a + data.b;
9
- break;
10
- case 'subtract':
11
- result = data.a - data.b;
12
- break;
13
- case 'multiply':
14
- result = data.a * data.b;
15
- break;
16
- case 'divide':
17
- if (data.b === 0) throw new Error("Division by zero");
18
- result = data.a / data.b;
19
- break;
20
- case 'power':
21
- result = Math.pow(data.a, data.b);
22
- break;
23
- default:
24
- throw new Error(`Unknown operation: ${data.operation}`);
25
- }
26
-
27
- const duration = Date.now() - startTime;
28
-
29
- // Don't send notification here - let the frontend handle timing and display
30
- // to avoid duplicate entries
31
-
32
- return result;
33
- }
34
-
35
- async echoBigData(data: string): Promise<string> {
36
- const startTime = Date.now();
37
-
38
- // Simulate some processing time
39
- await new Promise(resolve => setTimeout(resolve, 100));
40
-
41
- const response = `Echo: ${data.slice(0, 100)}... (${data.length} chars)`;
42
- const duration = Date.now() - startTime;
43
-
44
- // Don't send notification here - let the frontend handle timing and display
45
- // to avoid duplicate entries
46
-
47
- return response;
48
- }
49
-
50
- async performanceTest(messageSize: number, messageCount: number): Promise<{
51
- totalTime: number;
52
- averageTime: number;
53
- messagesPerSecond: number;
54
- }> {
55
- const testData = "x".repeat(messageSize);
56
- const results: number[] = [];
57
-
58
- const startTime = Date.now();
59
-
60
- for (let i = 0; i < messageCount; i++) {
61
- const messageStart = Date.now();
62
- await this.echoBigData(testData);
63
- results.push(Date.now() - messageStart);
64
- }
65
-
66
- const totalTime = Date.now() - startTime;
67
- const averageTime = results.reduce((a, b) => a + b, 0) / results.length;
68
- const messagesPerSecond = (messageCount / totalTime) * 1000;
69
-
70
- // Don't send notification here - let the frontend handle timing and display
71
-
72
- return {
73
- totalTime,
74
- averageTime,
75
- messagesPerSecond
76
- };
77
- }
78
-
79
- // Event callbacks
80
- onRpcTestResult?: (data: { operation: string; result: any; duration: number }) => void;
81
- }
82
-
83
- export const rpcTester = new RPCTester();
@@ -1,72 +0,0 @@
1
- import Electrobun from "electrobun/bun";
2
- import { platform, arch, release } from "os";
3
-
4
- class SystemManager {
5
- async getPlatformInfo() {
6
- return {
7
- platform: platform(),
8
- arch: arch(),
9
- version: release(),
10
- electrobunVersion: "0.0.19-beta.118", // This should come from the actual API
11
- };
12
- }
13
-
14
- async showNotification(options: {
15
- title: string;
16
- body: string;
17
- icon?: string;
18
- }) {
19
- // Note: Notification API needs to be implemented in Electrobun
20
- // For now, we'll simulate it
21
- console.log("Notification:", options);
22
-
23
- this.onSystemEvent?.({
24
- type: 'notification-shown',
25
- details: {
26
- title: options.title,
27
- body: options.body,
28
- timestamp: new Date().toISOString()
29
- }
30
- });
31
-
32
- // In a real implementation, this would use the native notification system
33
- return Promise.resolve();
34
- }
35
-
36
- async getClipboardText(): Promise<string> {
37
- // Note: Clipboard API needs to be implemented in Electrobun
38
- // This is a placeholder
39
- return "Clipboard API not yet implemented";
40
- }
41
-
42
- async setClipboardText(text: string): Promise<void> {
43
- // Note: Clipboard API needs to be implemented in Electrobun
44
- console.log("Setting clipboard text:", text);
45
-
46
- this.onSystemEvent?.({
47
- type: 'clipboard-set',
48
- details: { text, timestamp: new Date().toISOString() }
49
- });
50
- }
51
-
52
- async getScreenInfo() {
53
- // Note: Screen API needs to be implemented in Electrobun
54
- // This is a placeholder
55
- return {
56
- displays: [
57
- {
58
- id: 1,
59
- width: 1920,
60
- height: 1080,
61
- scaleFactor: 1,
62
- primary: true
63
- }
64
- ]
65
- };
66
- }
67
-
68
- // Event callbacks
69
- onSystemEvent?: (event: { type: string; details: any }) => void;
70
- }
71
-
72
- export const systemManager = new SystemManager();
@@ -1,105 +0,0 @@
1
- import Electrobun from "electrobun/bun";
2
-
3
- class UpdateManager {
4
- async checkForUpdates() {
5
- try {
6
- const updateInfo = await Electrobun.Updater.checkForUpdate();
7
-
8
- this.onUpdateStatus?.({
9
- status: 'checked',
10
- progress: 100
11
- });
12
-
13
- return {
14
- updateAvailable: updateInfo.updateAvailable,
15
- currentVersion: Electrobun.Updater.getLocalVersion?.() || "0.0.19-beta.118",
16
- latestVersion: updateInfo.latestVersion,
17
- };
18
- } catch (error) {
19
- console.error("Update check error:", error);
20
-
21
- this.onUpdateStatus?.({
22
- status: 'error',
23
- progress: 0
24
- });
25
-
26
- return {
27
- updateAvailable: false,
28
- currentVersion: "0.0.19-beta.118",
29
- error: error.message
30
- };
31
- }
32
- }
33
-
34
- async downloadUpdate() {
35
- try {
36
- this.onUpdateStatus?.({
37
- status: 'downloading',
38
- progress: 0
39
- });
40
-
41
- // Simulate download progress
42
- for (let i = 0; i <= 100; i += 10) {
43
- await new Promise(resolve => setTimeout(resolve, 200));
44
- this.onUpdateStatus?.({
45
- status: 'downloading',
46
- progress: i
47
- });
48
- }
49
-
50
- await Electrobun.Updater.downloadUpdate();
51
-
52
- this.onUpdateStatus?.({
53
- status: 'downloaded',
54
- progress: 100
55
- });
56
-
57
- return { success: true };
58
- } catch (error) {
59
- console.error("Update download error:", error);
60
-
61
- this.onUpdateStatus?.({
62
- status: 'error',
63
- progress: 0
64
- });
65
-
66
- return { success: false, error: error.message };
67
- }
68
- }
69
-
70
- async applyUpdate() {
71
- try {
72
- this.onUpdateStatus?.({
73
- status: 'applying',
74
- progress: 50
75
- });
76
-
77
- await Electrobun.Updater.applyUpdate();
78
-
79
- this.onUpdateStatus?.({
80
- status: 'applied',
81
- progress: 100
82
- });
83
-
84
- return { success: true };
85
- } catch (error) {
86
- console.error("Update apply error:", error);
87
-
88
- this.onUpdateStatus?.({
89
- status: 'error',
90
- progress: 0
91
- });
92
-
93
- return { success: false, error: error.message };
94
- }
95
- }
96
-
97
- getUpdateInfo() {
98
- return Electrobun.Updater.updateInfo?.() || null;
99
- }
100
-
101
- // Event callbacks
102
- onUpdateStatus?: (data: { status: string; progress?: number }) => void;
103
- }
104
-
105
- export const updateManager = new UpdateManager();
@@ -1,90 +0,0 @@
1
- import { BrowserWindow } from "electrobun/bun";
2
-
3
- class WindowManager {
4
- private windows = new Map<number, BrowserWindow>();
5
- private nextId = 1;
6
-
7
- async createWindow(options: {
8
- width: number;
9
- height: number;
10
- x: number;
11
- y: number;
12
- frameless?: boolean;
13
- transparent?: boolean;
14
- alwaysOnTop?: boolean;
15
- }) {
16
- const id = this.nextId++;
17
-
18
- const window = new BrowserWindow({
19
- title: `Demo Window ${id}`,
20
- url: "views://mainview/index.html",
21
- renderer: "cef",
22
- frame: {
23
- width: options.width,
24
- height: options.height,
25
- x: options.x,
26
- y: options.y,
27
- },
28
- titleBarStyle: options.frameless ? "hiddenInset" : "default",
29
- // For completely frameless, we need to set styleMask
30
- styleMask: options.frameless ? {
31
- Borderless: true,
32
- Titled: false,
33
- Closable: true,
34
- Miniaturizable: true,
35
- Resizable: true,
36
- } : undefined,
37
- });
38
-
39
- this.windows.set(id, window);
40
-
41
- // Listen for window events
42
- window.on("close", () => {
43
- this.windows.delete(id);
44
- this.onWindowClosed?.(id);
45
- });
46
-
47
- window.on("resize", (event) => {
48
- this.onWindowEvent?.({ type: 'resize', id, data: event.data });
49
- });
50
-
51
- window.on("move", (event) => {
52
- this.onWindowEvent?.({ type: 'move', id, data: event.data });
53
- });
54
-
55
- this.onWindowCreated?.(id, `Demo Window ${id}`);
56
-
57
- return { id };
58
- }
59
-
60
- async closeWindow(id: number) {
61
- const window = this.windows.get(id);
62
- if (window) {
63
- window.close();
64
- this.windows.delete(id);
65
- }
66
- }
67
-
68
- async focusWindow(id: number) {
69
- const window = this.windows.get(id);
70
- if (window) {
71
- window.focus();
72
- this.onWindowFocused?.(id);
73
- }
74
- }
75
-
76
- async getWindowList() {
77
- return Array.from(this.windows.entries()).map(([id, window]) => ({
78
- id,
79
- title: window.getTitle() || `Window ${id}`,
80
- }));
81
- }
82
-
83
- // Event callbacks
84
- onWindowCreated?: (id: number, title: string) => void;
85
- onWindowClosed?: (id: number) => void;
86
- onWindowFocused?: (id: number) => void;
87
- onWindowEvent?: (event: { type: string; id: number; data: any }) => void;
88
- }
89
-
90
- export const windowManager = new WindowManager();
@@ -1,124 +0,0 @@
1
- import Electrobun, { BrowserWindow, BrowserView } from "electrobun/bun";
2
- import { type PlaygroundRPC } from "./types/rpc";
3
-
4
- // Import demo modules
5
- import { windowManager } from "./demos/windows";
6
- import { menuManager } from "./demos/menus";
7
- import { fileManager } from "./demos/files";
8
- import { rpcTester } from "./demos/rpc";
9
-
10
- console.log("🚀 Electrobun Interactive Playground starting...");
11
-
12
- // Set up RPC communication
13
- const rpc = BrowserView.defineRPC<PlaygroundRPC>({
14
- maxRequestTime: 10000,
15
- handlers: {
16
- requests: {
17
- // Window Management
18
- createWindow: windowManager.createWindow.bind(windowManager),
19
- closeWindow: windowManager.closeWindow.bind(windowManager),
20
- focusWindow: windowManager.focusWindow.bind(windowManager),
21
- getWindowList: windowManager.getWindowList.bind(windowManager),
22
-
23
- // RPC Testing
24
- doMath: rpcTester.doMath.bind(rpcTester),
25
- echoBigData: rpcTester.echoBigData.bind(rpcTester),
26
-
27
- // Menu Operations
28
- createTray: menuManager.createTray.bind(menuManager),
29
- removeTray: menuManager.removeTray.bind(menuManager),
30
- showContextMenu: menuManager.showContextMenu.bind(menuManager),
31
-
32
- // File Operations
33
- openFileDialog: fileManager.openFileDialog.bind(fileManager),
34
- moveToTrash: fileManager.moveToTrash.bind(fileManager),
35
- showInFinder: fileManager.showInFinder.bind(fileManager),
36
-
37
- // WebView Operations (placeholder)
38
- createWebView: async (url: string) => ({ id: 1 }),
39
- executeJSInWebView: async (params: { id: number; script: string }) => null,
40
-
41
-
42
- },
43
- messages: {
44
- "*": (messageName, payload) => {
45
- console.log(`📨 Message received: ${messageName}`, payload);
46
- },
47
- },
48
- },
49
- });
50
-
51
- // Create main playground window
52
- const mainWindow = new BrowserWindow({
53
- title: "Electrobun Interactive Playground",
54
- url: "views://mainview/index.html",
55
- renderer: "cef",
56
- frame: {
57
- width: 1400,
58
- height: 900,
59
- x: 100,
60
- y: 100,
61
- },
62
- titleBarStyle: "default",
63
- rpc,
64
- });
65
-
66
- // Set up event forwarding from demo modules to the UI
67
- windowManager.onWindowCreated = (id, title) => {
68
- rpc.send.windowCreated({ id, title });
69
- };
70
-
71
- windowManager.onWindowClosed = (id) => {
72
- rpc.send.windowClosed({ id });
73
- };
74
-
75
- windowManager.onWindowFocused = (id) => {
76
- rpc.send.windowFocused({ id });
77
- };
78
-
79
- menuManager.onTrayClicked = (id, action) => {
80
- rpc.send.trayClicked({ id, action });
81
- console.log(`🔔 Tray ${id} clicked: ${action}`);
82
- };
83
-
84
- menuManager.onMenuClicked = (action) => {
85
- rpc.send.menuClicked({ action });
86
- console.log(`🎛️ Menu clicked: ${action}`);
87
- };
88
-
89
- fileManager.onFileSelected = (paths) => {
90
- rpc.send.fileSelected({ paths });
91
- console.log(`📁 Files selected:`, paths);
92
- };
93
-
94
- fileManager.onSystemEvent = (event) => {
95
- rpc.send.systemEvent(event);
96
- console.log(`⚙️ System event:`, event);
97
- };
98
-
99
- rpcTester.onRpcTestResult = (data) => {
100
- rpc.send.rpcTestResult(data);
101
- console.log(`📡 RPC test result:`, data);
102
- };
103
-
104
-
105
-
106
- // Listen for global events
107
- Electrobun.events.on("application-menu-clicked", (e) => {
108
- menuManager.onMenuClicked?.(e.data.action);
109
- });
110
-
111
- Electrobun.events.on("context-menu-clicked", (e) => {
112
- menuManager.onMenuClicked?.(e.data.action);
113
- });
114
-
115
- // Send initial status
116
- mainWindow.webview.on("dom-ready", () => {
117
- console.log("✅ Main window DOM ready");
118
- rpc.send.logMessage({
119
- level: 'info',
120
- message: 'Electrobun Interactive Playground loaded successfully!'
121
- });
122
- });
123
-
124
- console.log("🎮 Playground initialized successfully");