electrobun 1.18.1 → 1.18.4-beta.10
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.
- package/README.md +37 -14
- package/dash.config.ts +28 -0
- package/dist/api/browser/global.d.ts +6 -0
- package/dist/api/browser/index.ts +162 -44
- package/dist/api/{bun → config}/ElectrobunConfig.ts +109 -40
- package/dist/api/config/validate.test.ts +31 -0
- package/dist/api/config/validate.ts +19 -0
- package/dist/api/preload/.generated/compiled.ts +8 -0
- package/dist/api/{bun/preload → preload}/build.ts +6 -6
- package/dist/api/{bun/preload → preload}/encryption.ts +11 -5
- package/dist/api/{bun/preload → preload}/globals.d.ts +8 -0
- package/dist/api/{bun/preload → preload}/index.ts +18 -8
- package/dist/api/{bun/preload → preload}/webviewTag.ts +32 -3
- package/dist/api/{bun/preload → preload}/wgpuTag.ts +33 -2
- package/dist/api/{bun → sdks/bun}/__tests__/ffi-contract.test.ts +6 -9
- package/dist/api/{bun → sdks/bun}/core/BrowserView.ts +96 -55
- package/dist/api/{bun → sdks/bun}/core/BrowserWindow.ts +20 -30
- package/dist/api/{bun → sdks/bun}/core/BuildConfig.ts +32 -5
- package/dist/api/{bun → sdks/bun}/core/GpuWindow.ts +20 -7
- package/dist/api/sdks/bun/core/Socket.ts +22 -0
- package/dist/api/{bun → sdks/bun}/core/Tray.ts +33 -32
- package/dist/api/{bun → sdks/bun}/core/Updater.ts +10 -10
- package/dist/api/{bun → sdks/bun}/core/Utils.ts +3 -5
- package/dist/api/{bun → sdks/bun}/core/WGPUView.ts +43 -13
- package/dist/api/{bun → sdks/bun}/index.ts +39 -10
- package/dist/api/{bun → sdks/bun}/proc/native.ts +942 -746
- package/dist/api/{bun → sdks/bun}/webGPU.ts +1 -1
- package/dist/api/{bun → sdks/bun}/webgpuAdapter.ts +40 -33
- package/dist/api/shared/build-dependencies.test.ts +48 -0
- package/dist/api/shared/build-dependencies.ts +46 -0
- package/dist/api/shared/go-version.ts +3 -0
- package/dist/api/shared/odin-version.ts +6 -0
- package/dist/api/shared/rust-version.ts +3 -0
- package/dist/go-sdk/callbacks.go +260 -0
- package/dist/go-sdk/electrobun.go +2021 -0
- package/dist/main.js +35 -28
- package/dist/odin-sdk/electrobun/electrobun.odin +2337 -0
- package/dist/preload-full.js +948 -0
- package/dist/preload-sandboxed.js +111 -0
- package/dist/rust-sdk/electrobun.rs +2396 -0
- package/dist/zig-sdk/electrobun.zig +2005 -0
- package/package.json +5 -29
- package/src/cli/index.ts +868 -654
- package/bin/electrobun.cjs +0 -169
- package/dist/api/bun/core/Socket.ts +0 -205
- package/dist/api/bun/core/windowIds.ts +0 -5
- package/dist/api/bun/preload/.generated/compiled.ts +0 -8
- package/dist/api/shared/bun-version.ts +0 -3
- /package/dist/api/{bun/preload → preload}/dragRegions.ts +0 -0
- /package/dist/api/{bun/preload → preload}/events.ts +0 -0
- /package/dist/api/{bun/preload → preload}/index-sandboxed.ts +0 -0
- /package/dist/api/{bun/preload → preload}/internalRpc.ts +0 -0
- /package/dist/api/{bun/preload → preload}/overlaySync.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/core/ApplicationMenu.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/core/ContextMenu.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/core/Paths.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/core/menuRoles.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/ApplicationEvents.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/event.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/eventEmitter.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/trayEvents.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/webviewEvents.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/events/windowEvents.ts +0 -0
- /package/dist/api/{bun → sdks/bun}/proc/linux.md +0 -0
|
@@ -0,0 +1,2021 @@
|
|
|
1
|
+
package electrobun
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
#cgo linux LDFLAGS: -ldl
|
|
5
|
+
#include <stdbool.h>
|
|
6
|
+
#include <stdint.h>
|
|
7
|
+
#include <stdlib.h>
|
|
8
|
+
|
|
9
|
+
#ifdef _WIN32
|
|
10
|
+
#include <windows.h>
|
|
11
|
+
#else
|
|
12
|
+
#include <dlfcn.h>
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
extern void electrobunWindowCloseHandler(uint32_t);
|
|
16
|
+
extern void electrobunWindowMoveHandler(uint32_t, double, double);
|
|
17
|
+
extern void electrobunWindowResizeHandler(uint32_t, double, double, double, double);
|
|
18
|
+
extern void electrobunWindowFocusHandler(uint32_t);
|
|
19
|
+
extern void electrobunWindowBlurHandler(uint32_t);
|
|
20
|
+
extern void electrobunWindowKeyHandler(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
|
|
21
|
+
extern uint32_t electrobunDecideNavigationHandler(uint32_t, const char*);
|
|
22
|
+
extern void electrobunWebviewEventHandler(uint32_t, const char*, const char*);
|
|
23
|
+
extern void electrobunWebviewEventBridgeHandler(uint32_t, const char*);
|
|
24
|
+
extern void electrobunWebviewHostBridgeHandler(uint32_t, const char*);
|
|
25
|
+
extern void electrobunWebviewInternalBridgeHandler(uint32_t, const char*);
|
|
26
|
+
extern void electrobunStatusItemHandler(uint32_t, const char*);
|
|
27
|
+
extern void electrobunGlobalShortcutHandler(const char*);
|
|
28
|
+
extern void electrobunURLOpenHandler(const char*);
|
|
29
|
+
extern void electrobunAppReopenHandler(void);
|
|
30
|
+
extern void electrobunQuitRequestedHandler(void);
|
|
31
|
+
|
|
32
|
+
typedef void (*eb_window_close_cb)(uint32_t);
|
|
33
|
+
typedef void (*eb_window_move_cb)(uint32_t, double, double);
|
|
34
|
+
typedef void (*eb_window_resize_cb)(uint32_t, double, double, double, double);
|
|
35
|
+
typedef void (*eb_window_focus_cb)(uint32_t);
|
|
36
|
+
typedef void (*eb_window_blur_cb)(uint32_t);
|
|
37
|
+
typedef void (*eb_window_key_cb)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
|
|
38
|
+
typedef uint32_t (*eb_decide_navigation_cb)(uint32_t, const char*);
|
|
39
|
+
typedef void (*eb_webview_event_cb)(uint32_t, const char*, const char*);
|
|
40
|
+
typedef void (*eb_webview_post_message_cb)(uint32_t, const char*);
|
|
41
|
+
typedef void (*eb_status_item_cb)(uint32_t, const char*);
|
|
42
|
+
typedef void (*eb_global_shortcut_cb)(const char*);
|
|
43
|
+
typedef void (*eb_url_open_cb)(const char*);
|
|
44
|
+
typedef void (*eb_app_reopen_cb)(void);
|
|
45
|
+
typedef void (*eb_quit_requested_cb)(void);
|
|
46
|
+
|
|
47
|
+
static void eb_window_close(uint32_t id) { electrobunWindowCloseHandler(id); }
|
|
48
|
+
static void eb_window_move(uint32_t id, double x, double y) { electrobunWindowMoveHandler(id, x, y); }
|
|
49
|
+
static void eb_window_resize(uint32_t id, double x, double y, double w, double h) { electrobunWindowResizeHandler(id, x, y, w, h); }
|
|
50
|
+
static void eb_window_focus(uint32_t id) { electrobunWindowFocusHandler(id); }
|
|
51
|
+
static void eb_window_blur(uint32_t id) { electrobunWindowBlurHandler(id); }
|
|
52
|
+
static void eb_window_key(uint32_t id, uint32_t key, uint32_t modifiers, uint32_t event_type, uint32_t characters) { electrobunWindowKeyHandler(id, key, modifiers, event_type, characters); }
|
|
53
|
+
static uint32_t eb_decide_navigation(uint32_t id, const char* url) { return electrobunDecideNavigationHandler(id, url); }
|
|
54
|
+
static void eb_webview_event(uint32_t id, const char* event_name, const char* detail) { electrobunWebviewEventHandler(id, event_name, detail); }
|
|
55
|
+
static void eb_webview_event_bridge(uint32_t id, const char* message) { electrobunWebviewEventBridgeHandler(id, message); }
|
|
56
|
+
static void eb_webview_host_bridge(uint32_t id, const char* message) { electrobunWebviewHostBridgeHandler(id, message); }
|
|
57
|
+
static void eb_webview_internal_bridge(uint32_t id, const char* message) { electrobunWebviewInternalBridgeHandler(id, message); }
|
|
58
|
+
static void eb_status_item(uint32_t id, const char* message) { electrobunStatusItemHandler(id, message); }
|
|
59
|
+
static void eb_global_shortcut(const char* accelerator) { electrobunGlobalShortcutHandler(accelerator); }
|
|
60
|
+
static void eb_url_open(const char* url) { electrobunURLOpenHandler(url); }
|
|
61
|
+
static void eb_app_reopen(void) { electrobunAppReopenHandler(); }
|
|
62
|
+
static void eb_quit_requested(void) { electrobunQuitRequestedHandler(); }
|
|
63
|
+
|
|
64
|
+
#ifdef _WIN32
|
|
65
|
+
static void* eb_dlopen(const char* path) { return (void*)LoadLibraryA(path); }
|
|
66
|
+
static void* eb_dlsym(void* handle, const char* name) { return (void*)GetProcAddress((HMODULE)handle, name); }
|
|
67
|
+
static const char* eb_dlerror(void) {
|
|
68
|
+
static char message[512];
|
|
69
|
+
DWORD err = GetLastError();
|
|
70
|
+
if (err == 0) return "unknown dynamic loader error";
|
|
71
|
+
DWORD written = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, message, sizeof(message), NULL);
|
|
72
|
+
if (written == 0) return "unknown dynamic loader error";
|
|
73
|
+
return message;
|
|
74
|
+
}
|
|
75
|
+
#else
|
|
76
|
+
static void* eb_dlopen(const char* path) { return dlopen(path, RTLD_NOW | RTLD_LOCAL); }
|
|
77
|
+
static void* eb_dlsym(void* handle, const char* name) { return dlsym(handle, name); }
|
|
78
|
+
static const char* eb_dlerror(void) { return dlerror(); }
|
|
79
|
+
#endif
|
|
80
|
+
|
|
81
|
+
typedef const char* (*eb_last_error_fn)(void);
|
|
82
|
+
static const char* eb_call_last_error(void* fn) { return ((eb_last_error_fn)fn)(); }
|
|
83
|
+
|
|
84
|
+
typedef int (*eb_run_main_thread_fn)(const char*, const char*, const char*, int);
|
|
85
|
+
static int eb_call_run_main_thread(void* fn, const char* identifier, const char* name, const char* channel, int argc) {
|
|
86
|
+
return ((eb_run_main_thread_fn)fn)(identifier, name, channel, argc);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
typedef bool (*eb_configure_webview_runtime_fn)(uint32_t, const char*, const char*);
|
|
90
|
+
static bool eb_call_configure_webview_runtime(void* fn, uint32_t rpc_port, const char* full_preload, const char* sandboxed_preload) {
|
|
91
|
+
return ((eb_configure_webview_runtime_fn)fn)(rpc_port, full_preload, sandboxed_preload);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
typedef uint32_t (*eb_get_window_style_fn)(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool);
|
|
95
|
+
static uint32_t eb_call_get_window_style(void* fn, bool borderless, bool titled, bool closable, bool miniaturizable, bool resizable, bool unified_title_and_toolbar, bool full_screen, bool full_size_content_view, bool utility_window, bool doc_modal_window, bool nonactivating_panel, bool hud_window) {
|
|
96
|
+
return ((eb_get_window_style_fn)fn)(borderless, titled, closable, miniaturizable, resizable, unified_title_and_toolbar, full_screen, full_size_content_view, utility_window, doc_modal_window, nonactivating_panel, hud_window);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
typedef uint32_t (*eb_create_window_fn)(double, double, double, double, uint32_t, const char*, bool, const char*, bool, bool, double, double, eb_window_close_cb, eb_window_move_cb, eb_window_resize_cb, eb_window_focus_cb, eb_window_blur_cb, eb_window_key_cb);
|
|
100
|
+
static uint32_t eb_call_create_window(void* fn, double x, double y, double width, double height, uint32_t style, const char* title_bar_style, bool transparent, const char* title, bool hidden, bool activate, double traffic_x, double traffic_y, bool close_enabled, bool move_enabled, bool resize_enabled, bool focus_enabled, bool blur_enabled, bool key_enabled) {
|
|
101
|
+
return ((eb_create_window_fn)fn)(x, y, width, height, style, title_bar_style, transparent, title, hidden, activate, traffic_x, traffic_y, close_enabled ? eb_window_close : 0, move_enabled ? eb_window_move : 0, resize_enabled ? eb_window_resize : 0, focus_enabled ? eb_window_focus : 0, blur_enabled ? eb_window_blur : 0, key_enabled ? eb_window_key : 0);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
typedef uint32_t (*eb_create_webview_fn)(uint32_t, uint32_t, const char*, const char*, double, double, double, double, bool, const char*, eb_decide_navigation_cb, eb_webview_event_cb, eb_webview_post_message_cb, eb_webview_post_message_cb, eb_webview_post_message_cb, const char*, const char*, const char*, bool, bool, bool);
|
|
105
|
+
static uint32_t eb_call_create_webview(void* fn, uint32_t window_id, uint32_t host_webview_id, const char* renderer, const char* url, double x, double y, double width, double height, bool auto_resize, const char* partition, bool decide_enabled, bool event_enabled, bool event_bridge_enabled, bool host_bridge_enabled, bool internal_bridge_enabled, const char* secret_key, const char* preload, const char* views_root, bool sandbox, bool start_transparent, bool start_passthrough) {
|
|
106
|
+
return ((eb_create_webview_fn)fn)(window_id, host_webview_id, renderer, url, x, y, width, height, auto_resize, partition, decide_enabled ? eb_decide_navigation : 0, event_enabled ? eb_webview_event : 0, event_bridge_enabled ? eb_webview_event_bridge : 0, host_bridge_enabled ? eb_webview_host_bridge : 0, internal_bridge_enabled ? eb_webview_internal_bridge : 0, secret_key, preload, views_root, sandbox, start_transparent, start_passthrough);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
typedef uint32_t (*eb_create_wgpu_view_fn)(uint32_t, double, double, double, double, bool, bool, bool);
|
|
110
|
+
static uint32_t eb_call_create_wgpu_view(void* fn, uint32_t window_id, double x, double y, double width, double height, bool transparent, bool passthrough, bool hidden) {
|
|
111
|
+
return ((eb_create_wgpu_view_fn)fn)(window_id, x, y, width, height, transparent, passthrough, hidden);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
typedef void (*eb_u32_fn)(uint32_t);
|
|
115
|
+
static void eb_call_u32(void* fn, uint32_t value) { ((eb_u32_fn)fn)(value); }
|
|
116
|
+
|
|
117
|
+
typedef bool (*eb_u32_bool_ret_fn)(uint32_t);
|
|
118
|
+
static bool eb_call_u32_bool_ret(void* fn, uint32_t value) { return ((eb_u32_bool_ret_fn)fn)(value); }
|
|
119
|
+
|
|
120
|
+
typedef void (*eb_u32_bool_fn)(uint32_t, bool);
|
|
121
|
+
static void eb_call_u32_bool(void* fn, uint32_t value, bool flag) { ((eb_u32_bool_fn)fn)(value, flag); }
|
|
122
|
+
|
|
123
|
+
typedef void (*eb_bool_fn)(bool);
|
|
124
|
+
static void eb_call_bool(void* fn, bool flag) { ((eb_bool_fn)fn)(flag); }
|
|
125
|
+
|
|
126
|
+
typedef bool (*eb_bool_ret_fn)(void);
|
|
127
|
+
static bool eb_call_bool_ret(void* fn) { return ((eb_bool_ret_fn)fn)(); }
|
|
128
|
+
|
|
129
|
+
typedef void (*eb_u32_string_fn)(uint32_t, const char*);
|
|
130
|
+
static void eb_call_u32_string(void* fn, uint32_t value, const char* text) { ((eb_u32_string_fn)fn)(value, text); }
|
|
131
|
+
|
|
132
|
+
typedef void (*eb_u32_string_bool_bool_fn)(uint32_t, const char*, bool, bool);
|
|
133
|
+
static void eb_call_u32_string_bool_bool(void* fn, uint32_t value, const char* text, bool a, bool b) { ((eb_u32_string_bool_bool_fn)fn)(value, text, a, b); }
|
|
134
|
+
|
|
135
|
+
typedef void (*eb_u32_f64_f64_fn)(uint32_t, double, double);
|
|
136
|
+
static void eb_call_u32_f64_f64(void* fn, uint32_t value, double x, double y) { ((eb_u32_f64_f64_fn)fn)(value, x, y); }
|
|
137
|
+
|
|
138
|
+
typedef void (*eb_u32_f64_fn)(uint32_t, double);
|
|
139
|
+
static void eb_call_u32_f64(void* fn, uint32_t value, double number) { ((eb_u32_f64_fn)fn)(value, number); }
|
|
140
|
+
|
|
141
|
+
typedef double (*eb_u32_f64_ret_fn)(uint32_t);
|
|
142
|
+
static double eb_call_u32_f64_ret(void* fn, uint32_t value) { return ((eb_u32_f64_ret_fn)fn)(value); }
|
|
143
|
+
|
|
144
|
+
typedef void (*eb_u32_f64_f64_f64_f64_fn)(uint32_t, double, double, double, double);
|
|
145
|
+
static void eb_call_u32_f64_f64_f64_f64(void* fn, uint32_t value, double x, double y, double width, double height) { ((eb_u32_f64_f64_f64_f64_fn)fn)(value, x, y, width, height); }
|
|
146
|
+
|
|
147
|
+
typedef void (*eb_get_window_frame_fn)(uint32_t, double*, double*, double*, double*);
|
|
148
|
+
static void eb_call_get_window_frame(void* fn, uint32_t value, double* x, double* y, double* width, double* height) { ((eb_get_window_frame_fn)fn)(value, x, y, width, height); }
|
|
149
|
+
|
|
150
|
+
typedef void (*eb_resize_webview_fn)(uint32_t, double, double, double, double, const char*);
|
|
151
|
+
static void eb_call_resize_webview(void* fn, uint32_t value, double x, double y, double width, double height, const char* masks_json) { ((eb_resize_webview_fn)fn)(value, x, y, width, height, masks_json); }
|
|
152
|
+
|
|
153
|
+
typedef bool (*eb_send_host_message_fn)(uint32_t, const char*);
|
|
154
|
+
static bool eb_call_send_host_message(void* fn, uint32_t webview_id, const char* message_json) { return ((eb_send_host_message_fn)fn)(webview_id, message_json); }
|
|
155
|
+
|
|
156
|
+
typedef char* (*eb_pop_host_message_fn)(uint32_t*);
|
|
157
|
+
static char* eb_call_pop_host_message(void* fn, uint32_t* webview_id) { return ((eb_pop_host_message_fn)fn)(webview_id); }
|
|
158
|
+
|
|
159
|
+
typedef void (*eb_free_core_string_fn)(char*);
|
|
160
|
+
static void eb_call_free_core_string(void* fn, char* value) { ((eb_free_core_string_fn)fn)(value); }
|
|
161
|
+
|
|
162
|
+
typedef uint32_t (*eb_create_tray_fn)(const char*, const char*, bool, uint32_t, uint32_t, eb_status_item_cb);
|
|
163
|
+
static uint32_t eb_call_create_tray(void* fn, const char* title, const char* image, bool is_template, uint32_t width, uint32_t height, bool handler_enabled) {
|
|
164
|
+
return ((eb_create_tray_fn)fn)(title, image, is_template, width, height, handler_enabled ? eb_status_item : 0);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
typedef bool (*eb_show_tray_fn)(uint32_t);
|
|
168
|
+
static bool eb_call_show_tray(void* fn, uint32_t tray_id) { return ((eb_show_tray_fn)fn)(tray_id); }
|
|
169
|
+
|
|
170
|
+
typedef char* (*eb_string_ret_fn)(void);
|
|
171
|
+
static char* eb_call_string_ret(void* fn) { return ((eb_string_ret_fn)fn)(); }
|
|
172
|
+
|
|
173
|
+
typedef const char* (*eb_u32_const_string_ret_fn)(uint32_t);
|
|
174
|
+
static const char* eb_call_u32_const_string_ret(void* fn, uint32_t value) { return ((eb_u32_const_string_ret_fn)fn)(value); }
|
|
175
|
+
|
|
176
|
+
typedef bool (*eb_string_bool_ret_fn)(const char*);
|
|
177
|
+
static bool eb_call_string_bool_ret(void* fn, const char* value) { return ((eb_string_bool_ret_fn)fn)(value); }
|
|
178
|
+
|
|
179
|
+
typedef void (*eb_string_fn)(const char*);
|
|
180
|
+
static void eb_call_string(void* fn, const char* value) { ((eb_string_fn)fn)(value); }
|
|
181
|
+
|
|
182
|
+
typedef void (*eb_notification_fn)(const char*, const char*, const char*, bool);
|
|
183
|
+
static void eb_call_notification(void* fn, const char* title, const char* body, const char* subtitle, bool silent) { ((eb_notification_fn)fn)(title, body, subtitle, silent); }
|
|
184
|
+
|
|
185
|
+
typedef void (*eb_menu_fn)(const char*, eb_status_item_cb);
|
|
186
|
+
static void eb_call_menu(void* fn, const char* menu_json, bool handler_enabled) { ((eb_menu_fn)fn)(menu_json, handler_enabled ? eb_status_item : 0); }
|
|
187
|
+
|
|
188
|
+
typedef char* (*eb_open_file_dialog_fn)(const char*, const char*, int, int, int);
|
|
189
|
+
static char* eb_call_open_file_dialog(void* fn, const char* starting_folder, const char* allowed_file_types, int can_choose_files, int can_choose_directory, int allows_multiple_selection) {
|
|
190
|
+
return ((eb_open_file_dialog_fn)fn)(starting_folder, allowed_file_types, can_choose_files, can_choose_directory, allows_multiple_selection);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
typedef int (*eb_show_message_box_fn)(const char*, const char*, const char*, const char*, const char*, int, int);
|
|
194
|
+
static int eb_call_show_message_box(void* fn, const char* box_type, const char* title, const char* message, const char* detail, const char* buttons, int default_id, int cancel_id) {
|
|
195
|
+
return ((eb_show_message_box_fn)fn)(box_type, title, message, detail, buttons, default_id, cancel_id);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
typedef void (*eb_set_global_shortcut_callback_fn)(eb_global_shortcut_cb);
|
|
199
|
+
static void eb_call_set_global_shortcut_callback(void* fn, bool enabled) { ((eb_set_global_shortcut_callback_fn)fn)(enabled ? eb_global_shortcut : 0); }
|
|
200
|
+
|
|
201
|
+
typedef bool (*eb_string_string_bool_ret_fn)(const char*, const char*);
|
|
202
|
+
static bool eb_call_string_string_bool_ret(void* fn, const char* a, const char* b) { return ((eb_string_string_bool_ret_fn)fn)(a, b); }
|
|
203
|
+
|
|
204
|
+
typedef char* (*eb_string_string_ret_fn)(const char*, const char*);
|
|
205
|
+
static char* eb_call_string_string_ret(void* fn, const char* a, const char* b) { return ((eb_string_string_ret_fn)fn)(a, b); }
|
|
206
|
+
|
|
207
|
+
typedef bool (*eb_string_string_string_bool_ret_fn)(const char*, const char*, const char*);
|
|
208
|
+
static bool eb_call_string_string_string_bool_ret(void* fn, const char* a, const char* b, const char* c) { return ((eb_string_string_string_bool_ret_fn)fn)(a, b, c); }
|
|
209
|
+
|
|
210
|
+
typedef void (*eb_string_string_fn)(const char*, const char*);
|
|
211
|
+
static void eb_call_string_string(void* fn, const char* a, const char* b) { ((eb_string_string_fn)fn)(a, b); }
|
|
212
|
+
|
|
213
|
+
typedef void (*eb_set_url_open_handler_fn)(eb_url_open_cb);
|
|
214
|
+
static void eb_call_set_url_open_handler(void* fn, bool enabled) { ((eb_set_url_open_handler_fn)fn)(enabled ? eb_url_open : 0); }
|
|
215
|
+
|
|
216
|
+
typedef void (*eb_set_app_reopen_handler_fn)(eb_app_reopen_cb);
|
|
217
|
+
static void eb_call_set_app_reopen_handler(void* fn, bool enabled) { ((eb_set_app_reopen_handler_fn)fn)(enabled ? eb_app_reopen : 0); }
|
|
218
|
+
|
|
219
|
+
typedef void (*eb_set_quit_requested_handler_fn)(eb_quit_requested_cb);
|
|
220
|
+
static void eb_call_set_quit_requested_handler(void* fn, bool enabled) { ((eb_set_quit_requested_handler_fn)fn)(enabled ? eb_quit_requested : 0); }
|
|
221
|
+
|
|
222
|
+
typedef void (*eb_void_fn)(void);
|
|
223
|
+
static void eb_call_void(void* fn) { ((eb_void_fn)fn)(); }
|
|
224
|
+
|
|
225
|
+
typedef void (*eb_int_fn)(int);
|
|
226
|
+
static void eb_call_int(void* fn, int value) { ((eb_int_fn)fn)(value); }
|
|
227
|
+
|
|
228
|
+
typedef void* (*eb_u32_ptr_ret_fn)(uint32_t);
|
|
229
|
+
static void* eb_call_u32_ptr_ret(void* fn, uint32_t value) { return ((eb_u32_ptr_ret_fn)fn)(value); }
|
|
230
|
+
|
|
231
|
+
typedef void* (*eb_ptr_ret_fn)(void*);
|
|
232
|
+
static void* eb_call_ptr_ret(void* fn, void* value) { return ((eb_ptr_ret_fn)fn)(value); }
|
|
233
|
+
|
|
234
|
+
typedef void* (*eb_ptr_ptr_ptr_ret_fn)(void*, void*);
|
|
235
|
+
static void* eb_call_ptr_ptr_ptr_ret(void* fn, void* a, void* b) { return ((eb_ptr_ptr_ptr_ret_fn)fn)(a, b); }
|
|
236
|
+
|
|
237
|
+
typedef void (*eb_ptr_ptr_ptr_fn)(void*, void*, void*);
|
|
238
|
+
static void eb_call_ptr_ptr_ptr(void* fn, void* a, void* b, void* c) { ((eb_ptr_ptr_ptr_fn)fn)(a, b, c); }
|
|
239
|
+
|
|
240
|
+
typedef void (*eb_ptr_ptr_fn)(void*, void*);
|
|
241
|
+
static void eb_call_ptr_ptr(void* fn, void* a, void* b) { ((eb_ptr_ptr_fn)fn)(a, b); }
|
|
242
|
+
|
|
243
|
+
typedef int (*eb_ptr_int_ret_fn)(void*);
|
|
244
|
+
static int eb_call_ptr_int_ret(void* fn, void* value) { return ((eb_ptr_int_ret_fn)fn)(value); }
|
|
245
|
+
*/
|
|
246
|
+
import "C"
|
|
247
|
+
|
|
248
|
+
import (
|
|
249
|
+
"encoding/json"
|
|
250
|
+
"errors"
|
|
251
|
+
"fmt"
|
|
252
|
+
"os"
|
|
253
|
+
"path/filepath"
|
|
254
|
+
"runtime"
|
|
255
|
+
"strings"
|
|
256
|
+
"unsafe"
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
type Renderer string
|
|
260
|
+
|
|
261
|
+
const (
|
|
262
|
+
RendererNative Renderer = "native"
|
|
263
|
+
RendererCEF Renderer = "cef"
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
type AppInfo struct {
|
|
267
|
+
Identifier string
|
|
268
|
+
Name string
|
|
269
|
+
Channel string
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
type Rect struct {
|
|
273
|
+
X float64 `json:"x"`
|
|
274
|
+
Y float64 `json:"y"`
|
|
275
|
+
Width float64 `json:"width"`
|
|
276
|
+
Height float64 `json:"height"`
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
func NewRect(x, y, width, height float64) Rect {
|
|
280
|
+
return Rect{X: x, Y: y, Width: width, Height: height}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
type WindowStyle struct {
|
|
284
|
+
Borderless bool
|
|
285
|
+
Titled bool
|
|
286
|
+
Closable bool
|
|
287
|
+
Miniaturizable bool
|
|
288
|
+
Resizable bool
|
|
289
|
+
UnifiedTitleAndToolbar bool
|
|
290
|
+
FullScreen bool
|
|
291
|
+
FullSizeContentView bool
|
|
292
|
+
UtilityWindow bool
|
|
293
|
+
DocModalWindow bool
|
|
294
|
+
NonactivatingPanel bool
|
|
295
|
+
HUDWindow bool
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
func StandardWindowStyle() WindowStyle {
|
|
299
|
+
return WindowStyle{
|
|
300
|
+
Titled: true,
|
|
301
|
+
Closable: true,
|
|
302
|
+
Miniaturizable: true,
|
|
303
|
+
Resizable: true,
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
type WindowCloseHandler func(uint32)
|
|
308
|
+
type WindowMoveHandler func(uint32, float64, float64)
|
|
309
|
+
type WindowResizeHandler func(uint32, float64, float64, float64, float64)
|
|
310
|
+
type WindowFocusHandler func(uint32)
|
|
311
|
+
type WindowBlurHandler func(uint32)
|
|
312
|
+
type WindowKeyHandler func(uint32, uint32, uint32, uint32, uint32)
|
|
313
|
+
|
|
314
|
+
type WindowCallbacks struct {
|
|
315
|
+
Close WindowCloseHandler
|
|
316
|
+
Move WindowMoveHandler
|
|
317
|
+
Resize WindowResizeHandler
|
|
318
|
+
Focus WindowFocusHandler
|
|
319
|
+
Blur WindowBlurHandler
|
|
320
|
+
Key WindowKeyHandler
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
type TrafficLightOffset struct {
|
|
324
|
+
X float64
|
|
325
|
+
Y float64
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
type WindowOptions struct {
|
|
329
|
+
Title string
|
|
330
|
+
Frame Rect
|
|
331
|
+
Style WindowStyle
|
|
332
|
+
TitleBarStyle string
|
|
333
|
+
Transparent bool
|
|
334
|
+
Hidden bool
|
|
335
|
+
Activate bool
|
|
336
|
+
TrafficLightOffset TrafficLightOffset
|
|
337
|
+
Callbacks WindowCallbacks
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
func NewWindowOptions(title string, frame Rect) WindowOptions {
|
|
341
|
+
return WindowOptions{
|
|
342
|
+
Title: title,
|
|
343
|
+
Frame: frame,
|
|
344
|
+
Style: StandardWindowStyle(),
|
|
345
|
+
TitleBarStyle: "default",
|
|
346
|
+
Activate: true,
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
type DecideNavigationHandler func(uint32, string) uint32
|
|
351
|
+
type WebviewEventHandler func(uint32, string, string)
|
|
352
|
+
type WebviewPostMessageHandler func(uint32, string)
|
|
353
|
+
|
|
354
|
+
type WebviewCallbacks struct {
|
|
355
|
+
DecideNavigation DecideNavigationHandler
|
|
356
|
+
Event WebviewEventHandler
|
|
357
|
+
EventBridge WebviewPostMessageHandler
|
|
358
|
+
HostBridge WebviewPostMessageHandler
|
|
359
|
+
BunBridge WebviewPostMessageHandler
|
|
360
|
+
InternalBridge WebviewPostMessageHandler
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
type WebviewOptions struct {
|
|
364
|
+
WindowID uint32
|
|
365
|
+
HostWebviewID uint32
|
|
366
|
+
Renderer Renderer
|
|
367
|
+
URL string
|
|
368
|
+
Frame Rect
|
|
369
|
+
AutoResize bool
|
|
370
|
+
Partition string
|
|
371
|
+
SecretKey string
|
|
372
|
+
Preload string
|
|
373
|
+
ViewsRoot string
|
|
374
|
+
Sandbox bool
|
|
375
|
+
StartTransparent bool
|
|
376
|
+
StartPassthrough bool
|
|
377
|
+
Callbacks WebviewCallbacks
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
func NewWebviewOptions(windowID uint32, url string, frame Rect) WebviewOptions {
|
|
381
|
+
return WebviewOptions{
|
|
382
|
+
WindowID: windowID,
|
|
383
|
+
Renderer: RendererNative,
|
|
384
|
+
URL: url,
|
|
385
|
+
Frame: frame,
|
|
386
|
+
AutoResize: true,
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
type WGPUViewOptions struct {
|
|
391
|
+
WindowID uint32
|
|
392
|
+
Frame Rect
|
|
393
|
+
StartTransparent bool
|
|
394
|
+
StartPassthrough bool
|
|
395
|
+
Hidden bool
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
func NewWGPUViewOptions(windowID uint32, frame Rect) WGPUViewOptions {
|
|
399
|
+
return WGPUViewOptions{WindowID: windowID, Frame: frame}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
type StatusItemHandler func(uint32, string)
|
|
403
|
+
|
|
404
|
+
type TrayOptions struct {
|
|
405
|
+
Title string
|
|
406
|
+
Image string
|
|
407
|
+
IsTemplate bool
|
|
408
|
+
Width uint32
|
|
409
|
+
Height uint32
|
|
410
|
+
Handler StatusItemHandler
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
type NotificationOptions struct {
|
|
414
|
+
Title string
|
|
415
|
+
Body string
|
|
416
|
+
Subtitle string
|
|
417
|
+
Silent bool
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
type MessageBoxOptions struct {
|
|
421
|
+
BoxType string
|
|
422
|
+
Title string
|
|
423
|
+
Message string
|
|
424
|
+
Detail string
|
|
425
|
+
Buttons []string
|
|
426
|
+
DefaultID int
|
|
427
|
+
CancelID int
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
type OpenFileDialogOptions struct {
|
|
431
|
+
StartingFolder string
|
|
432
|
+
AllowedFileTypes string
|
|
433
|
+
CanChooseFiles bool
|
|
434
|
+
CanChooseDirectory bool
|
|
435
|
+
AllowsMultipleSelection bool
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
type Point struct {
|
|
439
|
+
X float64 `json:"x"`
|
|
440
|
+
Y float64 `json:"y"`
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
type Display struct {
|
|
444
|
+
ID int64 `json:"id"`
|
|
445
|
+
Bounds Rect `json:"bounds"`
|
|
446
|
+
WorkArea Rect `json:"workArea"`
|
|
447
|
+
ScaleFactor float64 `json:"scaleFactor"`
|
|
448
|
+
IsPrimary bool `json:"isPrimary"`
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
type Paths struct {
|
|
452
|
+
Home string
|
|
453
|
+
AppData string
|
|
454
|
+
Config string
|
|
455
|
+
Cache string
|
|
456
|
+
Temp string
|
|
457
|
+
Logs string
|
|
458
|
+
Documents string
|
|
459
|
+
Downloads string
|
|
460
|
+
Desktop string
|
|
461
|
+
Pictures string
|
|
462
|
+
Music string
|
|
463
|
+
Videos string
|
|
464
|
+
UserData string
|
|
465
|
+
UserCache string
|
|
466
|
+
UserLogs string
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
type BundlePaths struct {
|
|
470
|
+
ExeDir string
|
|
471
|
+
ResourcesDir string
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
type WgpuAdapterDevice struct {
|
|
475
|
+
Adapter unsafe.Pointer
|
|
476
|
+
Device unsafe.Pointer
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
type WgpuNative struct {
|
|
480
|
+
lib unsafe.Pointer
|
|
481
|
+
createInstance unsafe.Pointer
|
|
482
|
+
deviceGetQueue unsafe.Pointer
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
type WgpuContext struct {
|
|
486
|
+
View unsafe.Pointer
|
|
487
|
+
Instance unsafe.Pointer
|
|
488
|
+
Surface unsafe.Pointer
|
|
489
|
+
Adapter unsafe.Pointer
|
|
490
|
+
Device unsafe.Pointer
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
type Core struct {
|
|
494
|
+
lib unsafe.Pointer
|
|
495
|
+
symbols map[string]unsafe.Pointer
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
func LoadWgpuNative() (*WgpuNative, error) {
|
|
499
|
+
bundlePaths, err := ResolveBundlePaths()
|
|
500
|
+
if err != nil {
|
|
501
|
+
return nil, err
|
|
502
|
+
}
|
|
503
|
+
libPath := filepath.Join(bundlePaths.ExeDir, wgpuLibraryName())
|
|
504
|
+
pathCString := C.CString(libPath)
|
|
505
|
+
defer C.free(unsafe.Pointer(pathCString))
|
|
506
|
+
|
|
507
|
+
lib := C.eb_dlopen(pathCString)
|
|
508
|
+
if lib == nil {
|
|
509
|
+
return nil, fmt.Errorf("failed to open %s: %s", libPath, cConstString(C.eb_dlerror()))
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
native := &WgpuNative{lib: lib}
|
|
513
|
+
var ok bool
|
|
514
|
+
native.createInstance, ok = native.Symbol("wgpuCreateInstance")
|
|
515
|
+
if !ok {
|
|
516
|
+
return nil, errors.New("missing WGPU symbol wgpuCreateInstance")
|
|
517
|
+
}
|
|
518
|
+
native.deviceGetQueue, ok = native.Symbol("wgpuDeviceGetQueue")
|
|
519
|
+
if !ok {
|
|
520
|
+
return nil, errors.New("missing WGPU symbol wgpuDeviceGetQueue")
|
|
521
|
+
}
|
|
522
|
+
return native, nil
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
func (n *WgpuNative) Symbol(name string) (unsafe.Pointer, bool) {
|
|
526
|
+
nameCString := C.CString(name)
|
|
527
|
+
defer C.free(unsafe.Pointer(nameCString))
|
|
528
|
+
symbol := C.eb_dlsym(n.lib, nameCString)
|
|
529
|
+
return symbol, symbol != nil
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
func (n *WgpuNative) CreateInstance() (unsafe.Pointer, error) {
|
|
533
|
+
instance := C.eb_call_ptr_ret(n.createInstance, nil)
|
|
534
|
+
if instance == nil {
|
|
535
|
+
return nil, errors.New("failed to create WGPU instance")
|
|
536
|
+
}
|
|
537
|
+
return instance, nil
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
func (n *WgpuNative) DeviceGetQueue(device unsafe.Pointer) (unsafe.Pointer, error) {
|
|
541
|
+
queue := C.eb_call_ptr_ret(n.deviceGetQueue, device)
|
|
542
|
+
if queue == nil {
|
|
543
|
+
return nil, errors.New("failed to get WGPU queue")
|
|
544
|
+
}
|
|
545
|
+
return queue, nil
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
func CreateWgpuContextForView(core *Core, native *WgpuNative, view unsafe.Pointer) (WgpuContext, error) {
|
|
549
|
+
instance, err := native.CreateInstance()
|
|
550
|
+
if err != nil {
|
|
551
|
+
return WgpuContext{}, err
|
|
552
|
+
}
|
|
553
|
+
surface, err := core.WgpuCreateSurfaceForView(instance, view)
|
|
554
|
+
if err != nil {
|
|
555
|
+
return WgpuContext{}, err
|
|
556
|
+
}
|
|
557
|
+
adapterDevice, err := core.WgpuCreateAdapterDeviceMainThread(instance, surface)
|
|
558
|
+
if err != nil {
|
|
559
|
+
return WgpuContext{}, err
|
|
560
|
+
}
|
|
561
|
+
return WgpuContext{
|
|
562
|
+
View: view,
|
|
563
|
+
Instance: instance,
|
|
564
|
+
Surface: surface,
|
|
565
|
+
Adapter: adapterDevice.Adapter,
|
|
566
|
+
Device: adapterDevice.Device,
|
|
567
|
+
}, nil
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
func CreateWgpuContextForWGPUView(core *Core, native *WgpuNative, viewID uint32) (WgpuContext, error) {
|
|
571
|
+
view, err := core.GetWGPUViewPointer(viewID)
|
|
572
|
+
if err != nil {
|
|
573
|
+
return WgpuContext{}, err
|
|
574
|
+
}
|
|
575
|
+
return CreateWgpuContextForView(core, native, view)
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
func (ctx WgpuContext) GetQueue(native *WgpuNative) (unsafe.Pointer, error) {
|
|
579
|
+
return native.DeviceGetQueue(ctx.Device)
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
func LoadCore() (*Core, error) {
|
|
583
|
+
bundlePaths, err := ResolveBundlePaths()
|
|
584
|
+
if err != nil {
|
|
585
|
+
return nil, err
|
|
586
|
+
}
|
|
587
|
+
libPath := filepath.Join(bundlePaths.ExeDir, coreLibraryName())
|
|
588
|
+
pathCString := C.CString(libPath)
|
|
589
|
+
defer C.free(unsafe.Pointer(pathCString))
|
|
590
|
+
lib := C.eb_dlopen(pathCString)
|
|
591
|
+
if lib == nil {
|
|
592
|
+
return nil, fmt.Errorf("failed to open %s: %s", libPath, cConstString(C.eb_dlerror()))
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
core := &Core{lib: lib, symbols: make(map[string]unsafe.Pointer)}
|
|
596
|
+
for _, name := range requiredSymbols {
|
|
597
|
+
nameCString := C.CString(name)
|
|
598
|
+
symbol := C.eb_dlsym(lib, nameCString)
|
|
599
|
+
C.free(unsafe.Pointer(nameCString))
|
|
600
|
+
if symbol == nil {
|
|
601
|
+
return nil, fmt.Errorf("missing core symbol %s", name)
|
|
602
|
+
}
|
|
603
|
+
core.symbols[name] = symbol
|
|
604
|
+
}
|
|
605
|
+
return core, nil
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
var requiredSymbols = []string{
|
|
609
|
+
"electrobun_core_last_error",
|
|
610
|
+
"electrobun_core_run_main_thread",
|
|
611
|
+
"configureWebviewRuntime",
|
|
612
|
+
"getWindowStyle",
|
|
613
|
+
"createWindow",
|
|
614
|
+
"createWebview",
|
|
615
|
+
"createWGPUView",
|
|
616
|
+
"setWindowTitle",
|
|
617
|
+
"minimizeWindow",
|
|
618
|
+
"restoreWindow",
|
|
619
|
+
"isWindowMinimized",
|
|
620
|
+
"maximizeWindow",
|
|
621
|
+
"unmaximizeWindow",
|
|
622
|
+
"isWindowMaximized",
|
|
623
|
+
"setWindowFullScreen",
|
|
624
|
+
"isWindowFullScreen",
|
|
625
|
+
"setWindowAlwaysOnTop",
|
|
626
|
+
"isWindowAlwaysOnTop",
|
|
627
|
+
"setWindowVisibleOnAllWorkspaces",
|
|
628
|
+
"isWindowVisibleOnAllWorkspaces",
|
|
629
|
+
"showWindow",
|
|
630
|
+
"activateWindow",
|
|
631
|
+
"hideWindow",
|
|
632
|
+
"setWindowButtonPosition",
|
|
633
|
+
"setWindowPosition",
|
|
634
|
+
"setWindowSize",
|
|
635
|
+
"setWindowFrame",
|
|
636
|
+
"getWindowFrame",
|
|
637
|
+
"closeWindow",
|
|
638
|
+
"resizeWebview",
|
|
639
|
+
"loadURLInWebView",
|
|
640
|
+
"loadHTMLInWebView",
|
|
641
|
+
"webviewCanGoBack",
|
|
642
|
+
"webviewCanGoForward",
|
|
643
|
+
"webviewGoBack",
|
|
644
|
+
"webviewGoForward",
|
|
645
|
+
"webviewReload",
|
|
646
|
+
"webviewRemove",
|
|
647
|
+
"setWebviewHTMLContent",
|
|
648
|
+
"webviewSetTransparent",
|
|
649
|
+
"webviewSetPassthrough",
|
|
650
|
+
"webviewSetHidden",
|
|
651
|
+
"setWebviewNavigationRules",
|
|
652
|
+
"webviewFindInPage",
|
|
653
|
+
"webviewStopFind",
|
|
654
|
+
"webviewOpenDevTools",
|
|
655
|
+
"webviewCloseDevTools",
|
|
656
|
+
"webviewToggleDevTools",
|
|
657
|
+
"webviewSetPageZoom",
|
|
658
|
+
"webviewGetPageZoom",
|
|
659
|
+
"sendInternalMessageToWebview",
|
|
660
|
+
"setWGPUViewFrame",
|
|
661
|
+
"resizeWGPUView",
|
|
662
|
+
"setWGPUViewTransparent",
|
|
663
|
+
"setWGPUViewPassthrough",
|
|
664
|
+
"setWGPUViewHidden",
|
|
665
|
+
"removeWGPUView",
|
|
666
|
+
"getWGPUViewPointer",
|
|
667
|
+
"getWGPUViewNativeHandle",
|
|
668
|
+
"runWGPUViewTest",
|
|
669
|
+
"toggleWGPUViewTestShader",
|
|
670
|
+
"sendHostMessageToWebviewViaTransport",
|
|
671
|
+
"popNextQueuedHostMessage",
|
|
672
|
+
"freeCoreString",
|
|
673
|
+
"evaluateJavaScriptWithNoCompletion",
|
|
674
|
+
"createTray",
|
|
675
|
+
"showTray",
|
|
676
|
+
"hideTray",
|
|
677
|
+
"setTrayTitle",
|
|
678
|
+
"removeTray",
|
|
679
|
+
"getTrayBounds",
|
|
680
|
+
"setDockIconVisible",
|
|
681
|
+
"isDockIconVisible",
|
|
682
|
+
"getPrimaryDisplay",
|
|
683
|
+
"getAllDisplays",
|
|
684
|
+
"getCursorScreenPoint",
|
|
685
|
+
"moveToTrash",
|
|
686
|
+
"showItemInFolder",
|
|
687
|
+
"openExternal",
|
|
688
|
+
"openPath",
|
|
689
|
+
"showNotification",
|
|
690
|
+
"clipboardReadText",
|
|
691
|
+
"clipboardWriteText",
|
|
692
|
+
"clipboardClear",
|
|
693
|
+
"clipboardAvailableFormats",
|
|
694
|
+
"setApplicationMenu",
|
|
695
|
+
"showContextMenu",
|
|
696
|
+
"openFileDialog",
|
|
697
|
+
"showMessageBox",
|
|
698
|
+
"setGlobalShortcutCallback",
|
|
699
|
+
"registerGlobalShortcut",
|
|
700
|
+
"unregisterGlobalShortcut",
|
|
701
|
+
"unregisterAllGlobalShortcuts",
|
|
702
|
+
"isGlobalShortcutRegistered",
|
|
703
|
+
"sessionGetCookies",
|
|
704
|
+
"sessionSetCookie",
|
|
705
|
+
"sessionRemoveCookie",
|
|
706
|
+
"sessionClearCookies",
|
|
707
|
+
"sessionClearStorageData",
|
|
708
|
+
"setURLOpenHandler",
|
|
709
|
+
"setAppReopenHandler",
|
|
710
|
+
"setQuitRequestedHandler",
|
|
711
|
+
"stopEventLoop",
|
|
712
|
+
"waitForShutdownComplete",
|
|
713
|
+
"forceExit",
|
|
714
|
+
"wgpuCreateSurfaceForView",
|
|
715
|
+
"wgpuCreateAdapterDeviceMainThread",
|
|
716
|
+
"wgpuSurfaceConfigureMainThread",
|
|
717
|
+
"wgpuSurfaceGetCurrentTextureMainThread",
|
|
718
|
+
"wgpuSurfacePresentMainThread",
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
func (c *Core) symbol(name string) unsafe.Pointer {
|
|
722
|
+
return c.symbols[name]
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
func (c *Core) ConfigureWebviewRuntimeFromExecutableDir(bundlePaths BundlePaths, rpcPort uint32) error {
|
|
726
|
+
fullPreload, err := os.ReadFile(filepath.Join(bundlePaths.ResourcesDir, "preload-full.js"))
|
|
727
|
+
if err != nil {
|
|
728
|
+
return err
|
|
729
|
+
}
|
|
730
|
+
sandboxedPreload, err := os.ReadFile(filepath.Join(bundlePaths.ResourcesDir, "preload-sandboxed.js"))
|
|
731
|
+
if err != nil {
|
|
732
|
+
return err
|
|
733
|
+
}
|
|
734
|
+
fullCString, freeFull, err := cString(string(fullPreload), "preload-full.js")
|
|
735
|
+
if err != nil {
|
|
736
|
+
return err
|
|
737
|
+
}
|
|
738
|
+
defer freeFull()
|
|
739
|
+
sandboxedCString, freeSandboxed, err := cString(string(sandboxedPreload), "preload-sandboxed.js")
|
|
740
|
+
if err != nil {
|
|
741
|
+
return err
|
|
742
|
+
}
|
|
743
|
+
defer freeSandboxed()
|
|
744
|
+
ok := C.eb_call_configure_webview_runtime(
|
|
745
|
+
c.symbol("configureWebviewRuntime"),
|
|
746
|
+
C.uint32_t(rpcPort),
|
|
747
|
+
fullCString,
|
|
748
|
+
sandboxedCString,
|
|
749
|
+
)
|
|
750
|
+
if !bool(ok) {
|
|
751
|
+
return errors.New(c.LastError())
|
|
752
|
+
}
|
|
753
|
+
return nil
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
func (c *Core) CreateWindow(options WindowOptions) (uint32, error) {
|
|
757
|
+
title, freeTitle, err := cString(options.Title, "window title")
|
|
758
|
+
if err != nil {
|
|
759
|
+
return 0, err
|
|
760
|
+
}
|
|
761
|
+
defer freeTitle()
|
|
762
|
+
titleBarStyle, freeTitleBarStyle, err := cString(options.TitleBarStyle, "title bar style")
|
|
763
|
+
if err != nil {
|
|
764
|
+
return 0, err
|
|
765
|
+
}
|
|
766
|
+
defer freeTitleBarStyle()
|
|
767
|
+
|
|
768
|
+
style := options.Style
|
|
769
|
+
styleMask := C.eb_call_get_window_style(
|
|
770
|
+
c.symbol("getWindowStyle"),
|
|
771
|
+
cbool(style.Borderless),
|
|
772
|
+
cbool(style.Titled),
|
|
773
|
+
cbool(style.Closable),
|
|
774
|
+
cbool(style.Miniaturizable),
|
|
775
|
+
cbool(style.Resizable),
|
|
776
|
+
cbool(style.UnifiedTitleAndToolbar),
|
|
777
|
+
cbool(style.FullScreen),
|
|
778
|
+
cbool(style.FullSizeContentView),
|
|
779
|
+
cbool(style.UtilityWindow),
|
|
780
|
+
cbool(style.DocModalWindow),
|
|
781
|
+
cbool(style.NonactivatingPanel),
|
|
782
|
+
cbool(style.HUDWindow),
|
|
783
|
+
)
|
|
784
|
+
|
|
785
|
+
windowID := C.eb_call_create_window(
|
|
786
|
+
c.symbol("createWindow"),
|
|
787
|
+
C.double(options.Frame.X),
|
|
788
|
+
C.double(options.Frame.Y),
|
|
789
|
+
C.double(options.Frame.Width),
|
|
790
|
+
C.double(options.Frame.Height),
|
|
791
|
+
styleMask,
|
|
792
|
+
titleBarStyle,
|
|
793
|
+
cbool(options.Transparent),
|
|
794
|
+
title,
|
|
795
|
+
cbool(options.Hidden),
|
|
796
|
+
cbool(options.Activate),
|
|
797
|
+
C.double(options.TrafficLightOffset.X),
|
|
798
|
+
C.double(options.TrafficLightOffset.Y),
|
|
799
|
+
cbool(options.Callbacks.Close != nil),
|
|
800
|
+
cbool(options.Callbacks.Move != nil),
|
|
801
|
+
cbool(options.Callbacks.Resize != nil),
|
|
802
|
+
cbool(options.Callbacks.Focus != nil),
|
|
803
|
+
cbool(options.Callbacks.Blur != nil),
|
|
804
|
+
cbool(options.Callbacks.Key != nil),
|
|
805
|
+
)
|
|
806
|
+
if windowID == 0 {
|
|
807
|
+
return 0, errors.New(c.LastError())
|
|
808
|
+
}
|
|
809
|
+
registerWindowCallbacks(uint32(windowID), options.Callbacks)
|
|
810
|
+
return uint32(windowID), nil
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
func (c *Core) SetWindowTitle(windowID uint32, title string) error {
|
|
814
|
+
titleCString, freeTitle, err := cString(title, "window title")
|
|
815
|
+
if err != nil {
|
|
816
|
+
return err
|
|
817
|
+
}
|
|
818
|
+
defer freeTitle()
|
|
819
|
+
C.eb_call_u32_string(c.symbol("setWindowTitle"), C.uint32_t(windowID), titleCString)
|
|
820
|
+
return c.ensureLastCallSucceeded()
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
func (c *Core) MinimizeWindow(windowID uint32) error {
|
|
824
|
+
C.eb_call_u32(c.symbol("minimizeWindow"), C.uint32_t(windowID))
|
|
825
|
+
return c.ensureLastCallSucceeded()
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
func (c *Core) RestoreWindow(windowID uint32) error {
|
|
829
|
+
C.eb_call_u32(c.symbol("restoreWindow"), C.uint32_t(windowID))
|
|
830
|
+
return c.ensureLastCallSucceeded()
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
func (c *Core) IsWindowMinimized(windowID uint32) bool {
|
|
834
|
+
return bool(C.eb_call_u32_bool_ret(c.symbol("isWindowMinimized"), C.uint32_t(windowID)))
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
func (c *Core) MaximizeWindow(windowID uint32) error {
|
|
838
|
+
C.eb_call_u32(c.symbol("maximizeWindow"), C.uint32_t(windowID))
|
|
839
|
+
return c.ensureLastCallSucceeded()
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
func (c *Core) UnmaximizeWindow(windowID uint32) error {
|
|
843
|
+
C.eb_call_u32(c.symbol("unmaximizeWindow"), C.uint32_t(windowID))
|
|
844
|
+
return c.ensureLastCallSucceeded()
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
func (c *Core) IsWindowMaximized(windowID uint32) bool {
|
|
848
|
+
return bool(C.eb_call_u32_bool_ret(c.symbol("isWindowMaximized"), C.uint32_t(windowID)))
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
func (c *Core) SetWindowFullScreen(windowID uint32, fullScreen bool) error {
|
|
852
|
+
C.eb_call_u32_bool(c.symbol("setWindowFullScreen"), C.uint32_t(windowID), cbool(fullScreen))
|
|
853
|
+
return c.ensureLastCallSucceeded()
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
func (c *Core) IsWindowFullScreen(windowID uint32) bool {
|
|
857
|
+
return bool(C.eb_call_u32_bool_ret(c.symbol("isWindowFullScreen"), C.uint32_t(windowID)))
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
func (c *Core) SetWindowAlwaysOnTop(windowID uint32, alwaysOnTop bool) error {
|
|
861
|
+
C.eb_call_u32_bool(c.symbol("setWindowAlwaysOnTop"), C.uint32_t(windowID), cbool(alwaysOnTop))
|
|
862
|
+
return c.ensureLastCallSucceeded()
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
func (c *Core) IsWindowAlwaysOnTop(windowID uint32) bool {
|
|
866
|
+
return bool(C.eb_call_u32_bool_ret(c.symbol("isWindowAlwaysOnTop"), C.uint32_t(windowID)))
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
func (c *Core) SetWindowVisibleOnAllWorkspaces(windowID uint32, visible bool) error {
|
|
870
|
+
C.eb_call_u32_bool(c.symbol("setWindowVisibleOnAllWorkspaces"), C.uint32_t(windowID), cbool(visible))
|
|
871
|
+
return c.ensureLastCallSucceeded()
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
func (c *Core) IsWindowVisibleOnAllWorkspaces(windowID uint32) bool {
|
|
875
|
+
return bool(C.eb_call_u32_bool_ret(c.symbol("isWindowVisibleOnAllWorkspaces"), C.uint32_t(windowID)))
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
func (c *Core) ShowWindow(windowID uint32, activate bool) error {
|
|
879
|
+
C.eb_call_u32_bool(c.symbol("showWindow"), C.uint32_t(windowID), cbool(activate))
|
|
880
|
+
return c.ensureLastCallSucceeded()
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
func (c *Core) ActivateWindow(windowID uint32) error {
|
|
884
|
+
C.eb_call_u32(c.symbol("activateWindow"), C.uint32_t(windowID))
|
|
885
|
+
return c.ensureLastCallSucceeded()
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
func (c *Core) HideWindow(windowID uint32) error {
|
|
889
|
+
C.eb_call_u32(c.symbol("hideWindow"), C.uint32_t(windowID))
|
|
890
|
+
return c.ensureLastCallSucceeded()
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
func (c *Core) SetWindowButtonPosition(windowID uint32, x, y float64) error {
|
|
894
|
+
C.eb_call_u32_f64_f64(c.symbol("setWindowButtonPosition"), C.uint32_t(windowID), C.double(x), C.double(y))
|
|
895
|
+
return c.ensureLastCallSucceeded()
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
func (c *Core) SetWindowPosition(windowID uint32, x, y float64) error {
|
|
899
|
+
C.eb_call_u32_f64_f64(c.symbol("setWindowPosition"), C.uint32_t(windowID), C.double(x), C.double(y))
|
|
900
|
+
return c.ensureLastCallSucceeded()
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
func (c *Core) SetWindowSize(windowID uint32, width, height float64) error {
|
|
904
|
+
C.eb_call_u32_f64_f64(c.symbol("setWindowSize"), C.uint32_t(windowID), C.double(width), C.double(height))
|
|
905
|
+
return c.ensureLastCallSucceeded()
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
func (c *Core) SetWindowFrame(windowID uint32, frame Rect) error {
|
|
909
|
+
C.eb_call_u32_f64_f64_f64_f64(c.symbol("setWindowFrame"), C.uint32_t(windowID), C.double(frame.X), C.double(frame.Y), C.double(frame.Width), C.double(frame.Height))
|
|
910
|
+
return c.ensureLastCallSucceeded()
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
func (c *Core) GetWindowFrame(windowID uint32) (Rect, error) {
|
|
914
|
+
var x, y, width, height C.double
|
|
915
|
+
C.eb_call_get_window_frame(c.symbol("getWindowFrame"), C.uint32_t(windowID), &x, &y, &width, &height)
|
|
916
|
+
if err := c.ensureLastCallSucceeded(); err != nil {
|
|
917
|
+
return Rect{}, err
|
|
918
|
+
}
|
|
919
|
+
return NewRect(float64(x), float64(y), float64(width), float64(height)), nil
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
func (c *Core) CloseWindow(windowID uint32) error {
|
|
923
|
+
C.eb_call_u32(c.symbol("closeWindow"), C.uint32_t(windowID))
|
|
924
|
+
return c.ensureLastCallSucceeded()
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
func (c *Core) CreateWebview(options WebviewOptions) (uint32, error) {
|
|
928
|
+
renderer, freeRenderer, err := cString(string(options.Renderer), "renderer")
|
|
929
|
+
if err != nil {
|
|
930
|
+
return 0, err
|
|
931
|
+
}
|
|
932
|
+
defer freeRenderer()
|
|
933
|
+
url, freeURL, err := cString(options.URL, "webview url")
|
|
934
|
+
if err != nil {
|
|
935
|
+
return 0, err
|
|
936
|
+
}
|
|
937
|
+
defer freeURL()
|
|
938
|
+
partition, freePartition, err := cString(options.Partition, "partition")
|
|
939
|
+
if err != nil {
|
|
940
|
+
return 0, err
|
|
941
|
+
}
|
|
942
|
+
defer freePartition()
|
|
943
|
+
secretKey, freeSecretKey, err := cString(options.SecretKey, "secret key")
|
|
944
|
+
if err != nil {
|
|
945
|
+
return 0, err
|
|
946
|
+
}
|
|
947
|
+
defer freeSecretKey()
|
|
948
|
+
preload, freePreload, err := cString(options.Preload, "preload")
|
|
949
|
+
if err != nil {
|
|
950
|
+
return 0, err
|
|
951
|
+
}
|
|
952
|
+
defer freePreload()
|
|
953
|
+
viewsRoot, freeViewsRoot, err := cString(options.ViewsRoot, "views root")
|
|
954
|
+
if err != nil {
|
|
955
|
+
return 0, err
|
|
956
|
+
}
|
|
957
|
+
defer freeViewsRoot()
|
|
958
|
+
|
|
959
|
+
hostBridge := options.Callbacks.HostBridge
|
|
960
|
+
if hostBridge == nil {
|
|
961
|
+
hostBridge = options.Callbacks.BunBridge
|
|
962
|
+
}
|
|
963
|
+
webviewID := C.eb_call_create_webview(
|
|
964
|
+
c.symbol("createWebview"),
|
|
965
|
+
C.uint32_t(options.WindowID),
|
|
966
|
+
C.uint32_t(options.HostWebviewID),
|
|
967
|
+
renderer,
|
|
968
|
+
url,
|
|
969
|
+
C.double(options.Frame.X),
|
|
970
|
+
C.double(options.Frame.Y),
|
|
971
|
+
C.double(options.Frame.Width),
|
|
972
|
+
C.double(options.Frame.Height),
|
|
973
|
+
cbool(options.AutoResize),
|
|
974
|
+
partition,
|
|
975
|
+
cbool(options.Callbacks.DecideNavigation != nil),
|
|
976
|
+
cbool(options.Callbacks.Event != nil),
|
|
977
|
+
cbool(options.Callbacks.EventBridge != nil),
|
|
978
|
+
cbool(hostBridge != nil),
|
|
979
|
+
cbool(options.Callbacks.InternalBridge != nil),
|
|
980
|
+
secretKey,
|
|
981
|
+
preload,
|
|
982
|
+
viewsRoot,
|
|
983
|
+
cbool(options.Sandbox),
|
|
984
|
+
cbool(options.StartTransparent),
|
|
985
|
+
cbool(options.StartPassthrough),
|
|
986
|
+
)
|
|
987
|
+
if webviewID == 0 {
|
|
988
|
+
return 0, errors.New(c.LastError())
|
|
989
|
+
}
|
|
990
|
+
callbacks := options.Callbacks
|
|
991
|
+
callbacks.HostBridge = hostBridge
|
|
992
|
+
registerWebviewCallbacks(uint32(webviewID), callbacks)
|
|
993
|
+
return uint32(webviewID), nil
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
func (c *Core) ResizeWebview(webviewID uint32, frame Rect, masksJSON string) error {
|
|
997
|
+
masks, freeMasks, err := cString(masksJSON, "resize masks json")
|
|
998
|
+
if err != nil {
|
|
999
|
+
return err
|
|
1000
|
+
}
|
|
1001
|
+
defer freeMasks()
|
|
1002
|
+
C.eb_call_resize_webview(c.symbol("resizeWebview"), C.uint32_t(webviewID), C.double(frame.X), C.double(frame.Y), C.double(frame.Width), C.double(frame.Height), masks)
|
|
1003
|
+
return c.ensureLastCallSucceeded()
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
func (c *Core) LoadURLInWebview(webviewID uint32, url string) error {
|
|
1007
|
+
urlCString, freeURL, err := cString(url, "webview url")
|
|
1008
|
+
if err != nil {
|
|
1009
|
+
return err
|
|
1010
|
+
}
|
|
1011
|
+
defer freeURL()
|
|
1012
|
+
C.eb_call_u32_string(c.symbol("loadURLInWebView"), C.uint32_t(webviewID), urlCString)
|
|
1013
|
+
return c.ensureLastCallSucceeded()
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
func (c *Core) LoadHTMLInWebview(webviewID uint32, html string) error {
|
|
1017
|
+
htmlCString, freeHTML, err := cString(html, "webview html")
|
|
1018
|
+
if err != nil {
|
|
1019
|
+
return err
|
|
1020
|
+
}
|
|
1021
|
+
defer freeHTML()
|
|
1022
|
+
C.eb_call_u32_string(c.symbol("loadHTMLInWebView"), C.uint32_t(webviewID), htmlCString)
|
|
1023
|
+
return c.ensureLastCallSucceeded()
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
func (c *Core) CanWebviewGoBack(webviewID uint32) bool {
|
|
1027
|
+
return bool(C.eb_call_u32_bool_ret(c.symbol("webviewCanGoBack"), C.uint32_t(webviewID)))
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
func (c *Core) CanWebviewGoForward(webviewID uint32) bool {
|
|
1031
|
+
return bool(C.eb_call_u32_bool_ret(c.symbol("webviewCanGoForward"), C.uint32_t(webviewID)))
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
func (c *Core) WebviewGoBack(webviewID uint32) error {
|
|
1035
|
+
C.eb_call_u32(c.symbol("webviewGoBack"), C.uint32_t(webviewID))
|
|
1036
|
+
return c.ensureLastCallSucceeded()
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
func (c *Core) WebviewGoForward(webviewID uint32) error {
|
|
1040
|
+
C.eb_call_u32(c.symbol("webviewGoForward"), C.uint32_t(webviewID))
|
|
1041
|
+
return c.ensureLastCallSucceeded()
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
func (c *Core) ReloadWebview(webviewID uint32) error {
|
|
1045
|
+
C.eb_call_u32(c.symbol("webviewReload"), C.uint32_t(webviewID))
|
|
1046
|
+
return c.ensureLastCallSucceeded()
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
func (c *Core) RemoveWebview(webviewID uint32) error {
|
|
1050
|
+
C.eb_call_u32(c.symbol("webviewRemove"), C.uint32_t(webviewID))
|
|
1051
|
+
forgetWebviewCallbacks(webviewID)
|
|
1052
|
+
return c.ensureLastCallSucceeded()
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
func (c *Core) SetWebviewHTMLContent(webviewID uint32, html string) error {
|
|
1056
|
+
htmlCString, freeHTML, err := cString(html, "webview html")
|
|
1057
|
+
if err != nil {
|
|
1058
|
+
return err
|
|
1059
|
+
}
|
|
1060
|
+
defer freeHTML()
|
|
1061
|
+
C.eb_call_u32_string(c.symbol("setWebviewHTMLContent"), C.uint32_t(webviewID), htmlCString)
|
|
1062
|
+
return c.ensureLastCallSucceeded()
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
func (c *Core) SetWebviewTransparent(webviewID uint32, transparent bool) error {
|
|
1066
|
+
C.eb_call_u32_bool(c.symbol("webviewSetTransparent"), C.uint32_t(webviewID), cbool(transparent))
|
|
1067
|
+
return c.ensureLastCallSucceeded()
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
func (c *Core) SetWebviewPassthrough(webviewID uint32, passthrough bool) error {
|
|
1071
|
+
C.eb_call_u32_bool(c.symbol("webviewSetPassthrough"), C.uint32_t(webviewID), cbool(passthrough))
|
|
1072
|
+
return c.ensureLastCallSucceeded()
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
func (c *Core) SetWebviewHidden(webviewID uint32, hidden bool) error {
|
|
1076
|
+
C.eb_call_u32_bool(c.symbol("webviewSetHidden"), C.uint32_t(webviewID), cbool(hidden))
|
|
1077
|
+
return c.ensureLastCallSucceeded()
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
func (c *Core) SetWebviewNavigationRules(webviewID uint32, rulesJSON string) error {
|
|
1081
|
+
rules, freeRules, err := cString(rulesJSON, "navigation rules json")
|
|
1082
|
+
if err != nil {
|
|
1083
|
+
return err
|
|
1084
|
+
}
|
|
1085
|
+
defer freeRules()
|
|
1086
|
+
C.eb_call_u32_string(c.symbol("setWebviewNavigationRules"), C.uint32_t(webviewID), rules)
|
|
1087
|
+
return c.ensureLastCallSucceeded()
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
func (c *Core) WebviewFindInPage(webviewID uint32, text string, forward, matchCase bool) error {
|
|
1091
|
+
textCString, freeText, err := cString(text, "find text")
|
|
1092
|
+
if err != nil {
|
|
1093
|
+
return err
|
|
1094
|
+
}
|
|
1095
|
+
defer freeText()
|
|
1096
|
+
C.eb_call_u32_string_bool_bool(c.symbol("webviewFindInPage"), C.uint32_t(webviewID), textCString, cbool(forward), cbool(matchCase))
|
|
1097
|
+
return c.ensureLastCallSucceeded()
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
func (c *Core) WebviewStopFind(webviewID uint32) error {
|
|
1101
|
+
C.eb_call_u32(c.symbol("webviewStopFind"), C.uint32_t(webviewID))
|
|
1102
|
+
return c.ensureLastCallSucceeded()
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
func (c *Core) OpenWebviewDevtools(webviewID uint32) error {
|
|
1106
|
+
C.eb_call_u32(c.symbol("webviewOpenDevTools"), C.uint32_t(webviewID))
|
|
1107
|
+
return c.ensureLastCallSucceeded()
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
func (c *Core) CloseWebviewDevtools(webviewID uint32) error {
|
|
1111
|
+
C.eb_call_u32(c.symbol("webviewCloseDevTools"), C.uint32_t(webviewID))
|
|
1112
|
+
return c.ensureLastCallSucceeded()
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
func (c *Core) ToggleWebviewDevtools(webviewID uint32) error {
|
|
1116
|
+
C.eb_call_u32(c.symbol("webviewToggleDevTools"), C.uint32_t(webviewID))
|
|
1117
|
+
return c.ensureLastCallSucceeded()
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
func (c *Core) SetWebviewPageZoom(webviewID uint32, zoomLevel float64) error {
|
|
1121
|
+
C.eb_call_u32_f64(c.symbol("webviewSetPageZoom"), C.uint32_t(webviewID), C.double(zoomLevel))
|
|
1122
|
+
return c.ensureLastCallSucceeded()
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
func (c *Core) GetWebviewPageZoom(webviewID uint32) float64 {
|
|
1126
|
+
return float64(C.eb_call_u32_f64_ret(c.symbol("webviewGetPageZoom"), C.uint32_t(webviewID)))
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
func (c *Core) SendInternalMessageToWebviewJSON(webviewID uint32, messageJSON string) error {
|
|
1130
|
+
message, freeMessage, err := cString(messageJSON, "internal message")
|
|
1131
|
+
if err != nil {
|
|
1132
|
+
return err
|
|
1133
|
+
}
|
|
1134
|
+
defer freeMessage()
|
|
1135
|
+
ok := C.eb_call_send_host_message(c.symbol("sendInternalMessageToWebview"), C.uint32_t(webviewID), message)
|
|
1136
|
+
if !bool(ok) {
|
|
1137
|
+
return errors.New(c.LastError())
|
|
1138
|
+
}
|
|
1139
|
+
return nil
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
func (c *Core) CreateWGPUView(options WGPUViewOptions) (uint32, error) {
|
|
1143
|
+
viewID := C.eb_call_create_wgpu_view(
|
|
1144
|
+
c.symbol("createWGPUView"),
|
|
1145
|
+
C.uint32_t(options.WindowID),
|
|
1146
|
+
C.double(options.Frame.X),
|
|
1147
|
+
C.double(options.Frame.Y),
|
|
1148
|
+
C.double(options.Frame.Width),
|
|
1149
|
+
C.double(options.Frame.Height),
|
|
1150
|
+
cbool(options.StartTransparent),
|
|
1151
|
+
cbool(options.StartPassthrough),
|
|
1152
|
+
cbool(options.Hidden),
|
|
1153
|
+
)
|
|
1154
|
+
if viewID == 0 {
|
|
1155
|
+
return 0, errors.New(c.LastError())
|
|
1156
|
+
}
|
|
1157
|
+
return uint32(viewID), nil
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
func (c *Core) SetWGPUViewFrame(viewID uint32, frame Rect) error {
|
|
1161
|
+
C.eb_call_u32_f64_f64_f64_f64(c.symbol("setWGPUViewFrame"), C.uint32_t(viewID), C.double(frame.X), C.double(frame.Y), C.double(frame.Width), C.double(frame.Height))
|
|
1162
|
+
return c.ensureLastCallSucceeded()
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
func (c *Core) ResizeWGPUView(viewID uint32, frame Rect, masksJSON string) error {
|
|
1166
|
+
masks, freeMasks, err := cString(masksJSON, "resize masks json")
|
|
1167
|
+
if err != nil {
|
|
1168
|
+
return err
|
|
1169
|
+
}
|
|
1170
|
+
defer freeMasks()
|
|
1171
|
+
C.eb_call_resize_webview(c.symbol("resizeWGPUView"), C.uint32_t(viewID), C.double(frame.X), C.double(frame.Y), C.double(frame.Width), C.double(frame.Height), masks)
|
|
1172
|
+
return c.ensureLastCallSucceeded()
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
func (c *Core) SetWGPUViewTransparent(viewID uint32, transparent bool) error {
|
|
1176
|
+
C.eb_call_u32_bool(c.symbol("setWGPUViewTransparent"), C.uint32_t(viewID), cbool(transparent))
|
|
1177
|
+
return c.ensureLastCallSucceeded()
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
func (c *Core) SetWGPUViewPassthrough(viewID uint32, passthrough bool) error {
|
|
1181
|
+
C.eb_call_u32_bool(c.symbol("setWGPUViewPassthrough"), C.uint32_t(viewID), cbool(passthrough))
|
|
1182
|
+
return c.ensureLastCallSucceeded()
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
func (c *Core) SetWGPUViewHidden(viewID uint32, hidden bool) error {
|
|
1186
|
+
C.eb_call_u32_bool(c.symbol("setWGPUViewHidden"), C.uint32_t(viewID), cbool(hidden))
|
|
1187
|
+
return c.ensureLastCallSucceeded()
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
func (c *Core) RemoveWGPUView(viewID uint32) error {
|
|
1191
|
+
C.eb_call_u32(c.symbol("removeWGPUView"), C.uint32_t(viewID))
|
|
1192
|
+
return c.ensureLastCallSucceeded()
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
func (c *Core) GetWGPUViewPointer(viewID uint32) (unsafe.Pointer, error) {
|
|
1196
|
+
ptr := C.eb_call_u32_ptr_ret(c.symbol("getWGPUViewPointer"), C.uint32_t(viewID))
|
|
1197
|
+
if ptr == nil {
|
|
1198
|
+
return nil, errors.New(c.LastError())
|
|
1199
|
+
}
|
|
1200
|
+
return ptr, nil
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
func (c *Core) GetWGPUViewNativeHandle(viewID uint32) (unsafe.Pointer, error) {
|
|
1204
|
+
ptr := C.eb_call_u32_ptr_ret(c.symbol("getWGPUViewNativeHandle"), C.uint32_t(viewID))
|
|
1205
|
+
if ptr == nil {
|
|
1206
|
+
return nil, errors.New(c.LastError())
|
|
1207
|
+
}
|
|
1208
|
+
return ptr, nil
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
func (c *Core) RunWGPUViewTest(viewID uint32) error {
|
|
1212
|
+
C.eb_call_u32(c.symbol("runWGPUViewTest"), C.uint32_t(viewID))
|
|
1213
|
+
return c.ensureLastCallSucceeded()
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
func (c *Core) ToggleWGPUViewTestShader(viewID uint32) error {
|
|
1217
|
+
C.eb_call_u32(c.symbol("toggleWGPUViewTestShader"), C.uint32_t(viewID))
|
|
1218
|
+
return c.ensureLastCallSucceeded()
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
func (c *Core) EvaluateJavaScriptWithNoCompletion(webviewID uint32, script string) error {
|
|
1222
|
+
scriptCString, freeScript, err := cString(script, "javascript")
|
|
1223
|
+
if err != nil {
|
|
1224
|
+
return err
|
|
1225
|
+
}
|
|
1226
|
+
defer freeScript()
|
|
1227
|
+
C.eb_call_u32_string(c.symbol("evaluateJavaScriptWithNoCompletion"), C.uint32_t(webviewID), scriptCString)
|
|
1228
|
+
return c.ensureLastCallSucceeded()
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
func (c *Core) SendHostMessageToWebviewJSON(webviewID uint32, messageJSON string) error {
|
|
1232
|
+
message, freeMessage, err := cString(messageJSON, "host message")
|
|
1233
|
+
if err != nil {
|
|
1234
|
+
return err
|
|
1235
|
+
}
|
|
1236
|
+
defer freeMessage()
|
|
1237
|
+
ok := C.eb_call_send_host_message(c.symbol("sendHostMessageToWebviewViaTransport"), C.uint32_t(webviewID), message)
|
|
1238
|
+
if !bool(ok) {
|
|
1239
|
+
return c.EvaluateJavaScriptWithNoCompletion(
|
|
1240
|
+
webviewID,
|
|
1241
|
+
fmt.Sprintf("window.__electrobun.receiveMessageFromHost(%s);", messageJSON),
|
|
1242
|
+
)
|
|
1243
|
+
}
|
|
1244
|
+
return nil
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
func (c *Core) PopNextQueuedHostMessageString() (uint32, string, bool) {
|
|
1248
|
+
var webviewID C.uint32_t
|
|
1249
|
+
ptr := C.eb_call_pop_host_message(c.symbol("popNextQueuedHostMessage"), &webviewID)
|
|
1250
|
+
if ptr == nil {
|
|
1251
|
+
return 0, "", false
|
|
1252
|
+
}
|
|
1253
|
+
message := C.GoString(ptr)
|
|
1254
|
+
C.eb_call_free_core_string(c.symbol("freeCoreString"), ptr)
|
|
1255
|
+
return uint32(webviewID), message, true
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
func (c *Core) CreateTray(options TrayOptions) (uint32, error) {
|
|
1259
|
+
title, freeTitle, err := cString(options.Title, "tray title")
|
|
1260
|
+
if err != nil {
|
|
1261
|
+
return 0, err
|
|
1262
|
+
}
|
|
1263
|
+
defer freeTitle()
|
|
1264
|
+
image, freeImage, err := cString(options.Image, "tray image")
|
|
1265
|
+
if err != nil {
|
|
1266
|
+
return 0, err
|
|
1267
|
+
}
|
|
1268
|
+
defer freeImage()
|
|
1269
|
+
setStatusItemHandler(options.Handler)
|
|
1270
|
+
trayID := C.eb_call_create_tray(c.symbol("createTray"), title, image, cbool(options.IsTemplate), C.uint32_t(options.Width), C.uint32_t(options.Height), cbool(options.Handler != nil))
|
|
1271
|
+
if trayID == 0 {
|
|
1272
|
+
return 0, errors.New(c.LastError())
|
|
1273
|
+
}
|
|
1274
|
+
return uint32(trayID), nil
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
func (c *Core) ShowTray(trayID uint32) error {
|
|
1278
|
+
if !bool(C.eb_call_show_tray(c.symbol("showTray"), C.uint32_t(trayID))) {
|
|
1279
|
+
return errors.New(c.LastError())
|
|
1280
|
+
}
|
|
1281
|
+
return nil
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
func (c *Core) HideTray(trayID uint32) error {
|
|
1285
|
+
C.eb_call_u32(c.symbol("hideTray"), C.uint32_t(trayID))
|
|
1286
|
+
return c.ensureLastCallSucceeded()
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
func (c *Core) SetTrayTitle(trayID uint32, title string) error {
|
|
1290
|
+
titleCString, freeTitle, err := cString(title, "tray title")
|
|
1291
|
+
if err != nil {
|
|
1292
|
+
return err
|
|
1293
|
+
}
|
|
1294
|
+
defer freeTitle()
|
|
1295
|
+
C.eb_call_u32_string(c.symbol("setTrayTitle"), C.uint32_t(trayID), titleCString)
|
|
1296
|
+
return c.ensureLastCallSucceeded()
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
func (c *Core) RemoveTray(trayID uint32) error {
|
|
1300
|
+
C.eb_call_u32(c.symbol("removeTray"), C.uint32_t(trayID))
|
|
1301
|
+
return c.ensureLastCallSucceeded()
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
func (c *Core) GetTrayBounds(trayID uint32) (Rect, error) {
|
|
1305
|
+
ptr := C.eb_call_u32_const_string_ret(c.symbol("getTrayBounds"), C.uint32_t(trayID))
|
|
1306
|
+
if ptr == nil {
|
|
1307
|
+
return Rect{}, errors.New(c.LastError())
|
|
1308
|
+
}
|
|
1309
|
+
return ParseRectJSON(C.GoString(ptr)), nil
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
func (c *Core) SetDockIconVisible(visible bool) error {
|
|
1313
|
+
C.eb_call_bool(c.symbol("setDockIconVisible"), cbool(visible))
|
|
1314
|
+
return c.ensureLastCallSucceeded()
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
func (c *Core) IsDockIconVisible() bool {
|
|
1318
|
+
return bool(C.eb_call_bool_ret(c.symbol("isDockIconVisible")))
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
func (c *Core) GetPrimaryDisplay() (Display, error) {
|
|
1322
|
+
ptr := C.eb_call_string_ret(c.symbol("getPrimaryDisplay"))
|
|
1323
|
+
if ptr == nil {
|
|
1324
|
+
return Display{}, errors.New(c.LastError())
|
|
1325
|
+
}
|
|
1326
|
+
jsonValue := C.GoString(ptr)
|
|
1327
|
+
return ParseDisplayJSON(jsonValue), nil
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
func (c *Core) GetAllDisplays() ([]Display, error) {
|
|
1331
|
+
ptr := C.eb_call_string_ret(c.symbol("getAllDisplays"))
|
|
1332
|
+
if ptr == nil {
|
|
1333
|
+
return nil, errors.New(c.LastError())
|
|
1334
|
+
}
|
|
1335
|
+
jsonValue := C.GoString(ptr)
|
|
1336
|
+
var displays []Display
|
|
1337
|
+
if err := json.Unmarshal([]byte(jsonValue), &displays); err != nil {
|
|
1338
|
+
return nil, err
|
|
1339
|
+
}
|
|
1340
|
+
return displays, nil
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
func (c *Core) GetCursorScreenPoint() (Point, error) {
|
|
1344
|
+
ptr := C.eb_call_string_ret(c.symbol("getCursorScreenPoint"))
|
|
1345
|
+
if ptr == nil {
|
|
1346
|
+
return Point{}, errors.New(c.LastError())
|
|
1347
|
+
}
|
|
1348
|
+
jsonValue := C.GoString(ptr)
|
|
1349
|
+
var point Point
|
|
1350
|
+
if err := json.Unmarshal([]byte(jsonValue), &point); err != nil {
|
|
1351
|
+
return Point{}, err
|
|
1352
|
+
}
|
|
1353
|
+
return point, nil
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
func (c *Core) MoveToTrash(path string) (bool, error) {
|
|
1357
|
+
pathCString, freePath, err := cString(path, "path")
|
|
1358
|
+
if err != nil {
|
|
1359
|
+
return false, err
|
|
1360
|
+
}
|
|
1361
|
+
defer freePath()
|
|
1362
|
+
return bool(C.eb_call_string_bool_ret(c.symbol("moveToTrash"), pathCString)), nil
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
func (c *Core) ShowItemInFolder(path string) error {
|
|
1366
|
+
pathCString, freePath, err := cString(path, "path")
|
|
1367
|
+
if err != nil {
|
|
1368
|
+
return err
|
|
1369
|
+
}
|
|
1370
|
+
defer freePath()
|
|
1371
|
+
C.eb_call_string(c.symbol("showItemInFolder"), pathCString)
|
|
1372
|
+
return c.ensureLastCallSucceeded()
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
func (c *Core) OpenExternal(url string) (bool, error) {
|
|
1376
|
+
urlCString, freeURL, err := cString(url, "url")
|
|
1377
|
+
if err != nil {
|
|
1378
|
+
return false, err
|
|
1379
|
+
}
|
|
1380
|
+
defer freeURL()
|
|
1381
|
+
return bool(C.eb_call_string_bool_ret(c.symbol("openExternal"), urlCString)), nil
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
func (c *Core) OpenPath(path string) (bool, error) {
|
|
1385
|
+
pathCString, freePath, err := cString(path, "path")
|
|
1386
|
+
if err != nil {
|
|
1387
|
+
return false, err
|
|
1388
|
+
}
|
|
1389
|
+
defer freePath()
|
|
1390
|
+
return bool(C.eb_call_string_bool_ret(c.symbol("openPath"), pathCString)), nil
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
func (c *Core) ShowNotification(options NotificationOptions) error {
|
|
1394
|
+
title, freeTitle, err := cString(options.Title, "notification title")
|
|
1395
|
+
if err != nil {
|
|
1396
|
+
return err
|
|
1397
|
+
}
|
|
1398
|
+
defer freeTitle()
|
|
1399
|
+
body, freeBody, err := cString(options.Body, "notification body")
|
|
1400
|
+
if err != nil {
|
|
1401
|
+
return err
|
|
1402
|
+
}
|
|
1403
|
+
defer freeBody()
|
|
1404
|
+
subtitle, freeSubtitle, err := cString(options.Subtitle, "notification subtitle")
|
|
1405
|
+
if err != nil {
|
|
1406
|
+
return err
|
|
1407
|
+
}
|
|
1408
|
+
defer freeSubtitle()
|
|
1409
|
+
C.eb_call_notification(c.symbol("showNotification"), title, body, subtitle, cbool(options.Silent))
|
|
1410
|
+
return c.ensureLastCallSucceeded()
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
func (c *Core) ClipboardReadText() (string, bool, error) {
|
|
1414
|
+
ptr := C.eb_call_string_ret(c.symbol("clipboardReadText"))
|
|
1415
|
+
if ptr == nil {
|
|
1416
|
+
return "", false, nil
|
|
1417
|
+
}
|
|
1418
|
+
text := C.GoString(ptr)
|
|
1419
|
+
return text, true, nil
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
func (c *Core) ClipboardWriteText(text string) error {
|
|
1423
|
+
textCString, freeText, err := cString(text, "clipboard text")
|
|
1424
|
+
if err != nil {
|
|
1425
|
+
return err
|
|
1426
|
+
}
|
|
1427
|
+
defer freeText()
|
|
1428
|
+
C.eb_call_string(c.symbol("clipboardWriteText"), textCString)
|
|
1429
|
+
return c.ensureLastCallSucceeded()
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
func (c *Core) ClipboardClear() error {
|
|
1433
|
+
C.eb_call_void(c.symbol("clipboardClear"))
|
|
1434
|
+
return c.ensureLastCallSucceeded()
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
func (c *Core) ClipboardAvailableFormatsCSV() (string, error) {
|
|
1438
|
+
ptr := C.eb_call_string_ret(c.symbol("clipboardAvailableFormats"))
|
|
1439
|
+
if ptr == nil {
|
|
1440
|
+
return "", nil
|
|
1441
|
+
}
|
|
1442
|
+
formats := C.GoString(ptr)
|
|
1443
|
+
return formats, nil
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
func (c *Core) SetApplicationMenuJSON(menuJSON string, handler StatusItemHandler) error {
|
|
1447
|
+
menu, freeMenu, err := cString(menuJSON, "application menu json")
|
|
1448
|
+
if err != nil {
|
|
1449
|
+
return err
|
|
1450
|
+
}
|
|
1451
|
+
defer freeMenu()
|
|
1452
|
+
setStatusItemHandler(handler)
|
|
1453
|
+
C.eb_call_menu(c.symbol("setApplicationMenu"), menu, cbool(handler != nil))
|
|
1454
|
+
return c.ensureLastCallSucceeded()
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
func (c *Core) ShowContextMenuJSON(menuJSON string, handler StatusItemHandler) error {
|
|
1458
|
+
menu, freeMenu, err := cString(menuJSON, "context menu json")
|
|
1459
|
+
if err != nil {
|
|
1460
|
+
return err
|
|
1461
|
+
}
|
|
1462
|
+
defer freeMenu()
|
|
1463
|
+
setStatusItemHandler(handler)
|
|
1464
|
+
C.eb_call_menu(c.symbol("showContextMenu"), menu, cbool(handler != nil))
|
|
1465
|
+
return c.ensureLastCallSucceeded()
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
func (c *Core) OpenFileDialog(options OpenFileDialogOptions) (string, error) {
|
|
1469
|
+
startingFolder, freeStartingFolder, err := cString(options.StartingFolder, "starting folder")
|
|
1470
|
+
if err != nil {
|
|
1471
|
+
return "", err
|
|
1472
|
+
}
|
|
1473
|
+
defer freeStartingFolder()
|
|
1474
|
+
allowedFileTypes, freeAllowedFileTypes, err := cString(options.AllowedFileTypes, "allowed file types")
|
|
1475
|
+
if err != nil {
|
|
1476
|
+
return "", err
|
|
1477
|
+
}
|
|
1478
|
+
defer freeAllowedFileTypes()
|
|
1479
|
+
ptr := C.eb_call_open_file_dialog(
|
|
1480
|
+
c.symbol("openFileDialog"),
|
|
1481
|
+
startingFolder,
|
|
1482
|
+
allowedFileTypes,
|
|
1483
|
+
boolInt(options.CanChooseFiles),
|
|
1484
|
+
boolInt(options.CanChooseDirectory),
|
|
1485
|
+
boolInt(options.AllowsMultipleSelection),
|
|
1486
|
+
)
|
|
1487
|
+
if ptr == nil {
|
|
1488
|
+
return "", nil
|
|
1489
|
+
}
|
|
1490
|
+
value := C.GoString(ptr)
|
|
1491
|
+
return value, nil
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
func (c *Core) ShowMessageBox(options MessageBoxOptions) (int, error) {
|
|
1495
|
+
boxType, freeBoxType, err := cString(options.BoxType, "message box type")
|
|
1496
|
+
if err != nil {
|
|
1497
|
+
return 0, err
|
|
1498
|
+
}
|
|
1499
|
+
defer freeBoxType()
|
|
1500
|
+
title, freeTitle, err := cString(options.Title, "message box title")
|
|
1501
|
+
if err != nil {
|
|
1502
|
+
return 0, err
|
|
1503
|
+
}
|
|
1504
|
+
defer freeTitle()
|
|
1505
|
+
message, freeMessage, err := cString(options.Message, "message box message")
|
|
1506
|
+
if err != nil {
|
|
1507
|
+
return 0, err
|
|
1508
|
+
}
|
|
1509
|
+
defer freeMessage()
|
|
1510
|
+
detail, freeDetail, err := cString(options.Detail, "message box detail")
|
|
1511
|
+
if err != nil {
|
|
1512
|
+
return 0, err
|
|
1513
|
+
}
|
|
1514
|
+
defer freeDetail()
|
|
1515
|
+
buttons, freeButtons, err := cString(strings.Join(options.Buttons, ","), "message box buttons")
|
|
1516
|
+
if err != nil {
|
|
1517
|
+
return 0, err
|
|
1518
|
+
}
|
|
1519
|
+
defer freeButtons()
|
|
1520
|
+
response := C.eb_call_show_message_box(c.symbol("showMessageBox"), boxType, title, message, detail, buttons, C.int(options.DefaultID), C.int(options.CancelID))
|
|
1521
|
+
if err := c.ensureLastCallSucceeded(); err != nil {
|
|
1522
|
+
return 0, err
|
|
1523
|
+
}
|
|
1524
|
+
return int(response), nil
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
func (c *Core) SetGlobalShortcutCallback(handler func(string)) error {
|
|
1528
|
+
setGlobalShortcutHandler(handler)
|
|
1529
|
+
C.eb_call_set_global_shortcut_callback(c.symbol("setGlobalShortcutCallback"), cbool(handler != nil))
|
|
1530
|
+
return c.ensureLastCallSucceeded()
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
func (c *Core) RegisterGlobalShortcut(accelerator string) (bool, error) {
|
|
1534
|
+
value, freeValue, err := cString(accelerator, "accelerator")
|
|
1535
|
+
if err != nil {
|
|
1536
|
+
return false, err
|
|
1537
|
+
}
|
|
1538
|
+
defer freeValue()
|
|
1539
|
+
return bool(C.eb_call_string_bool_ret(c.symbol("registerGlobalShortcut"), value)), nil
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
func (c *Core) UnregisterGlobalShortcut(accelerator string) (bool, error) {
|
|
1543
|
+
value, freeValue, err := cString(accelerator, "accelerator")
|
|
1544
|
+
if err != nil {
|
|
1545
|
+
return false, err
|
|
1546
|
+
}
|
|
1547
|
+
defer freeValue()
|
|
1548
|
+
return bool(C.eb_call_string_bool_ret(c.symbol("unregisterGlobalShortcut"), value)), nil
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
func (c *Core) UnregisterAllGlobalShortcuts() error {
|
|
1552
|
+
C.eb_call_void(c.symbol("unregisterAllGlobalShortcuts"))
|
|
1553
|
+
return c.ensureLastCallSucceeded()
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
func (c *Core) IsGlobalShortcutRegistered(accelerator string) (bool, error) {
|
|
1557
|
+
value, freeValue, err := cString(accelerator, "accelerator")
|
|
1558
|
+
if err != nil {
|
|
1559
|
+
return false, err
|
|
1560
|
+
}
|
|
1561
|
+
defer freeValue()
|
|
1562
|
+
return bool(C.eb_call_string_bool_ret(c.symbol("isGlobalShortcutRegistered"), value)), nil
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
func (c *Core) SessionGetCookies(partition, filterJSON string) (string, error) {
|
|
1566
|
+
partitionCString, freePartition, err := cString(partition, "session partition")
|
|
1567
|
+
if err != nil {
|
|
1568
|
+
return "", err
|
|
1569
|
+
}
|
|
1570
|
+
defer freePartition()
|
|
1571
|
+
filterCString, freeFilter, err := cString(filterJSON, "cookie filter json")
|
|
1572
|
+
if err != nil {
|
|
1573
|
+
return "", err
|
|
1574
|
+
}
|
|
1575
|
+
defer freeFilter()
|
|
1576
|
+
ptr := C.eb_call_string_string_ret(c.symbol("sessionGetCookies"), partitionCString, filterCString)
|
|
1577
|
+
if ptr == nil {
|
|
1578
|
+
return "[]", nil
|
|
1579
|
+
}
|
|
1580
|
+
value := C.GoString(ptr)
|
|
1581
|
+
return value, nil
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
func (c *Core) SessionSetCookie(partition, cookieJSON string) (bool, error) {
|
|
1585
|
+
partitionCString, freePartition, err := cString(partition, "session partition")
|
|
1586
|
+
if err != nil {
|
|
1587
|
+
return false, err
|
|
1588
|
+
}
|
|
1589
|
+
defer freePartition()
|
|
1590
|
+
cookieCString, freeCookie, err := cString(cookieJSON, "cookie json")
|
|
1591
|
+
if err != nil {
|
|
1592
|
+
return false, err
|
|
1593
|
+
}
|
|
1594
|
+
defer freeCookie()
|
|
1595
|
+
return bool(C.eb_call_string_string_bool_ret(c.symbol("sessionSetCookie"), partitionCString, cookieCString)), nil
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
func (c *Core) SessionRemoveCookie(partition, url, name string) (bool, error) {
|
|
1599
|
+
partitionCString, freePartition, err := cString(partition, "session partition")
|
|
1600
|
+
if err != nil {
|
|
1601
|
+
return false, err
|
|
1602
|
+
}
|
|
1603
|
+
defer freePartition()
|
|
1604
|
+
urlCString, freeURL, err := cString(url, "cookie url")
|
|
1605
|
+
if err != nil {
|
|
1606
|
+
return false, err
|
|
1607
|
+
}
|
|
1608
|
+
defer freeURL()
|
|
1609
|
+
nameCString, freeName, err := cString(name, "cookie name")
|
|
1610
|
+
if err != nil {
|
|
1611
|
+
return false, err
|
|
1612
|
+
}
|
|
1613
|
+
defer freeName()
|
|
1614
|
+
return bool(C.eb_call_string_string_string_bool_ret(c.symbol("sessionRemoveCookie"), partitionCString, urlCString, nameCString)), nil
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
func (c *Core) SessionClearCookies(partition string) error {
|
|
1618
|
+
partitionCString, freePartition, err := cString(partition, "session partition")
|
|
1619
|
+
if err != nil {
|
|
1620
|
+
return err
|
|
1621
|
+
}
|
|
1622
|
+
defer freePartition()
|
|
1623
|
+
C.eb_call_string(c.symbol("sessionClearCookies"), partitionCString)
|
|
1624
|
+
return c.ensureLastCallSucceeded()
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
func (c *Core) SessionClearStorageData(partition, storageTypesJSON string) error {
|
|
1628
|
+
partitionCString, freePartition, err := cString(partition, "session partition")
|
|
1629
|
+
if err != nil {
|
|
1630
|
+
return err
|
|
1631
|
+
}
|
|
1632
|
+
defer freePartition()
|
|
1633
|
+
storageCString, freeStorage, err := cString(storageTypesJSON, "storage types json")
|
|
1634
|
+
if err != nil {
|
|
1635
|
+
return err
|
|
1636
|
+
}
|
|
1637
|
+
defer freeStorage()
|
|
1638
|
+
C.eb_call_string_string(c.symbol("sessionClearStorageData"), partitionCString, storageCString)
|
|
1639
|
+
return c.ensureLastCallSucceeded()
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
func (c *Core) SetURLOpenHandler(handler func(string)) error {
|
|
1643
|
+
setURLOpenHandler(handler)
|
|
1644
|
+
C.eb_call_set_url_open_handler(c.symbol("setURLOpenHandler"), cbool(handler != nil))
|
|
1645
|
+
return c.ensureLastCallSucceeded()
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
func (c *Core) SetAppReopenHandler(handler func()) error {
|
|
1649
|
+
setAppReopenHandler(handler)
|
|
1650
|
+
C.eb_call_set_app_reopen_handler(c.symbol("setAppReopenHandler"), cbool(handler != nil))
|
|
1651
|
+
return c.ensureLastCallSucceeded()
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
func (c *Core) SetQuitRequestedHandler(handler func()) error {
|
|
1655
|
+
setQuitRequestedHandler(handler)
|
|
1656
|
+
C.eb_call_set_quit_requested_handler(c.symbol("setQuitRequestedHandler"), cbool(handler != nil))
|
|
1657
|
+
return c.ensureLastCallSucceeded()
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
func (c *Core) StopEventLoop() error {
|
|
1661
|
+
C.eb_call_void(c.symbol("stopEventLoop"))
|
|
1662
|
+
return c.ensureLastCallSucceeded()
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
func (c *Core) WaitForShutdownComplete(timeoutMS int) error {
|
|
1666
|
+
C.eb_call_int(c.symbol("waitForShutdownComplete"), C.int(timeoutMS))
|
|
1667
|
+
return c.ensureLastCallSucceeded()
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
func (c *Core) ForceExit(code int) {
|
|
1671
|
+
C.eb_call_int(c.symbol("forceExit"), C.int(code))
|
|
1672
|
+
os.Exit(code)
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
func (c *Core) WgpuCreateSurfaceForView(instance, viewPtr unsafe.Pointer) (unsafe.Pointer, error) {
|
|
1676
|
+
ptr := C.eb_call_ptr_ptr_ptr_ret(c.symbol("wgpuCreateSurfaceForView"), instance, viewPtr)
|
|
1677
|
+
if ptr == nil {
|
|
1678
|
+
return nil, errors.New(c.LastError())
|
|
1679
|
+
}
|
|
1680
|
+
return ptr, nil
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
func (c *Core) WgpuCreateAdapterDeviceMainThread(instance, surface unsafe.Pointer) (WgpuAdapterDevice, error) {
|
|
1684
|
+
buffer := C.calloc(2, C.size_t(unsafe.Sizeof(uintptr(0))))
|
|
1685
|
+
if buffer == nil {
|
|
1686
|
+
return WgpuAdapterDevice{}, errors.New("failed to allocate WGPU adapter/device buffer")
|
|
1687
|
+
}
|
|
1688
|
+
defer C.free(buffer)
|
|
1689
|
+
C.eb_call_ptr_ptr_ptr(c.symbol("wgpuCreateAdapterDeviceMainThread"), instance, surface, buffer)
|
|
1690
|
+
if err := c.ensureLastCallSucceeded(); err != nil {
|
|
1691
|
+
return WgpuAdapterDevice{}, err
|
|
1692
|
+
}
|
|
1693
|
+
values := (*[2]unsafe.Pointer)(buffer)
|
|
1694
|
+
adapterDevice := WgpuAdapterDevice{Adapter: values[0], Device: values[1]}
|
|
1695
|
+
if adapterDevice.Adapter == nil || adapterDevice.Device == nil {
|
|
1696
|
+
return WgpuAdapterDevice{}, errors.New("missing WGPU adapter or device")
|
|
1697
|
+
}
|
|
1698
|
+
return adapterDevice, nil
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
func (c *Core) WgpuSurfaceConfigureMainThread(surface, config unsafe.Pointer) error {
|
|
1702
|
+
C.eb_call_ptr_ptr(c.symbol("wgpuSurfaceConfigureMainThread"), surface, config)
|
|
1703
|
+
return c.ensureLastCallSucceeded()
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
func (c *Core) WgpuSurfaceGetCurrentTextureMainThread(surface, surfaceTexture unsafe.Pointer) error {
|
|
1707
|
+
C.eb_call_ptr_ptr(c.symbol("wgpuSurfaceGetCurrentTextureMainThread"), surface, surfaceTexture)
|
|
1708
|
+
return c.ensureLastCallSucceeded()
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
func (c *Core) WgpuSurfacePresentMainThread(surface unsafe.Pointer) (int, error) {
|
|
1712
|
+
status := C.eb_call_ptr_int_ret(c.symbol("wgpuSurfacePresentMainThread"), surface)
|
|
1713
|
+
if err := c.ensureLastCallSucceeded(); err != nil {
|
|
1714
|
+
return 0, err
|
|
1715
|
+
}
|
|
1716
|
+
return int(status), nil
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
func (c *Core) RunMainThread(appInfo AppInfo) error {
|
|
1720
|
+
identifier, freeIdentifier, err := cString(appInfo.Identifier, "app identifier")
|
|
1721
|
+
if err != nil {
|
|
1722
|
+
return err
|
|
1723
|
+
}
|
|
1724
|
+
defer freeIdentifier()
|
|
1725
|
+
name, freeName, err := cString(appInfo.Name, "app name")
|
|
1726
|
+
if err != nil {
|
|
1727
|
+
return err
|
|
1728
|
+
}
|
|
1729
|
+
defer freeName()
|
|
1730
|
+
channel, freeChannel, err := cString(appInfo.Channel, "app channel")
|
|
1731
|
+
if err != nil {
|
|
1732
|
+
return err
|
|
1733
|
+
}
|
|
1734
|
+
defer freeChannel()
|
|
1735
|
+
status := C.eb_call_run_main_thread(c.symbol("electrobun_core_run_main_thread"), identifier, name, channel, 0)
|
|
1736
|
+
if status != 0 {
|
|
1737
|
+
return errors.New(c.LastError())
|
|
1738
|
+
}
|
|
1739
|
+
return nil
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
func (c *Core) LastError() string {
|
|
1743
|
+
ptr := C.eb_call_last_error(c.symbol("electrobun_core_last_error"))
|
|
1744
|
+
return cConstString(ptr)
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
func (c *Core) ensureLastCallSucceeded() error {
|
|
1748
|
+
message := c.LastError()
|
|
1749
|
+
if message == "" {
|
|
1750
|
+
return nil
|
|
1751
|
+
}
|
|
1752
|
+
return errors.New(message)
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
func ResolveBundlePaths() (BundlePaths, error) {
|
|
1756
|
+
exePath, err := os.Executable()
|
|
1757
|
+
if err != nil {
|
|
1758
|
+
return BundlePaths{}, fmt.Errorf("failed to resolve executable path: %w", err)
|
|
1759
|
+
}
|
|
1760
|
+
exeDir := filepath.Dir(exePath)
|
|
1761
|
+
return BundlePaths{
|
|
1762
|
+
ExeDir: exeDir,
|
|
1763
|
+
ResourcesDir: filepath.Clean(filepath.Join(exeDir, "..", "Resources")),
|
|
1764
|
+
}, nil
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
func ResolveAppInfoFromBundle(bundlePaths BundlePaths) (AppInfo, error) {
|
|
1768
|
+
versionJSON, err := os.ReadFile(filepath.Join(bundlePaths.ResourcesDir, "version.json"))
|
|
1769
|
+
if err != nil {
|
|
1770
|
+
return AppInfo{}, err
|
|
1771
|
+
}
|
|
1772
|
+
return AppInfo{
|
|
1773
|
+
Identifier: JsonStringField(string(versionJSON), "identifier", "sh.blackboard.electrobun"),
|
|
1774
|
+
Name: JsonStringField(string(versionJSON), "name", "Electrobun"),
|
|
1775
|
+
Channel: JsonStringField(string(versionJSON), "channel", "dev"),
|
|
1776
|
+
}, nil
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
func ResolvePaths(appInfo AppInfo) (Paths, error) {
|
|
1780
|
+
home, err := os.UserHomeDir()
|
|
1781
|
+
if err != nil {
|
|
1782
|
+
return Paths{}, err
|
|
1783
|
+
}
|
|
1784
|
+
appData := appDataDir(home)
|
|
1785
|
+
config := configDir(home)
|
|
1786
|
+
cache := cacheDir(home)
|
|
1787
|
+
logs := logsDir(home)
|
|
1788
|
+
scoped := appInfo.Identifier
|
|
1789
|
+
if scoped == "" {
|
|
1790
|
+
scoped = appInfo.Name
|
|
1791
|
+
}
|
|
1792
|
+
return Paths{
|
|
1793
|
+
Home: home,
|
|
1794
|
+
AppData: appData,
|
|
1795
|
+
Config: config,
|
|
1796
|
+
Cache: cache,
|
|
1797
|
+
Temp: tempDir(),
|
|
1798
|
+
Logs: logs,
|
|
1799
|
+
Documents: filepath.Join(home, "Documents"),
|
|
1800
|
+
Downloads: filepath.Join(home, "Downloads"),
|
|
1801
|
+
Desktop: filepath.Join(home, "Desktop"),
|
|
1802
|
+
Pictures: filepath.Join(home, "Pictures"),
|
|
1803
|
+
Music: filepath.Join(home, "Music"),
|
|
1804
|
+
Videos: filepath.Join(home, "Videos"),
|
|
1805
|
+
UserData: filepath.Join(appData, scoped),
|
|
1806
|
+
UserCache: filepath.Join(cache, scoped),
|
|
1807
|
+
UserLogs: filepath.Join(logs, scoped),
|
|
1808
|
+
}, nil
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
func AllowAllNavigation(_ uint32, _ string) uint32 {
|
|
1812
|
+
return 1
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
func NoopWebviewEvent(_ uint32, _, _ string) {}
|
|
1816
|
+
|
|
1817
|
+
func NoopWebviewPostMessage(_ uint32, _ string) {}
|
|
1818
|
+
|
|
1819
|
+
func JsonStringLiteral(value string) string {
|
|
1820
|
+
bytes, _ := json.Marshal(value)
|
|
1821
|
+
return string(bytes)
|
|
1822
|
+
}
|
|
1823
|
+
|
|
1824
|
+
func JsonStringField(source, key, fallback string) string {
|
|
1825
|
+
var obj map[string]json.RawMessage
|
|
1826
|
+
if json.Unmarshal([]byte(source), &obj) != nil {
|
|
1827
|
+
return fallback
|
|
1828
|
+
}
|
|
1829
|
+
var value string
|
|
1830
|
+
if raw, ok := obj[key]; ok && json.Unmarshal(raw, &value) == nil {
|
|
1831
|
+
return value
|
|
1832
|
+
}
|
|
1833
|
+
return fallback
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
func JsonOptionalStringField(source, key string) (string, bool) {
|
|
1837
|
+
var obj map[string]json.RawMessage
|
|
1838
|
+
if json.Unmarshal([]byte(source), &obj) != nil {
|
|
1839
|
+
return "", false
|
|
1840
|
+
}
|
|
1841
|
+
var value string
|
|
1842
|
+
if raw, ok := obj[key]; ok && json.Unmarshal(raw, &value) == nil {
|
|
1843
|
+
return value, true
|
|
1844
|
+
}
|
|
1845
|
+
return "", false
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
func JsonNumberField(source, key string) (float64, bool) {
|
|
1849
|
+
var obj map[string]json.RawMessage
|
|
1850
|
+
if json.Unmarshal([]byte(source), &obj) != nil {
|
|
1851
|
+
return 0, false
|
|
1852
|
+
}
|
|
1853
|
+
var value float64
|
|
1854
|
+
if raw, ok := obj[key]; ok && json.Unmarshal(raw, &value) == nil {
|
|
1855
|
+
return value, true
|
|
1856
|
+
}
|
|
1857
|
+
return 0, false
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
func JsonBoolField(source, key string) (bool, bool) {
|
|
1861
|
+
var obj map[string]json.RawMessage
|
|
1862
|
+
if json.Unmarshal([]byte(source), &obj) != nil {
|
|
1863
|
+
return false, false
|
|
1864
|
+
}
|
|
1865
|
+
var value bool
|
|
1866
|
+
if raw, ok := obj[key]; ok && json.Unmarshal(raw, &value) == nil {
|
|
1867
|
+
return value, true
|
|
1868
|
+
}
|
|
1869
|
+
return false, false
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
func JsonObjectField(source, key string) (string, bool) {
|
|
1873
|
+
var obj map[string]json.RawMessage
|
|
1874
|
+
if json.Unmarshal([]byte(source), &obj) != nil {
|
|
1875
|
+
return "", false
|
|
1876
|
+
}
|
|
1877
|
+
if raw, ok := obj[key]; ok && len(raw) > 0 && raw[0] == '{' {
|
|
1878
|
+
return string(raw), true
|
|
1879
|
+
}
|
|
1880
|
+
return "", false
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
func ParseRectJSON(source string) Rect {
|
|
1884
|
+
var rect Rect
|
|
1885
|
+
_ = json.Unmarshal([]byte(source), &rect)
|
|
1886
|
+
return rect
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
func ParseDisplayJSON(source string) Display {
|
|
1890
|
+
var display Display
|
|
1891
|
+
_ = json.Unmarshal([]byte(source), &display)
|
|
1892
|
+
return display
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
func cString(value, label string) (*C.char, func(), error) {
|
|
1896
|
+
if strings.ContainsRune(value, '\x00') {
|
|
1897
|
+
return nil, nil, fmt.Errorf("%s contains an interior null byte", label)
|
|
1898
|
+
}
|
|
1899
|
+
ptr := C.CString(value)
|
|
1900
|
+
return ptr, func() { C.free(unsafe.Pointer(ptr)) }, nil
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
func cConstString(ptr *C.char) string {
|
|
1904
|
+
if ptr == nil {
|
|
1905
|
+
return ""
|
|
1906
|
+
}
|
|
1907
|
+
return C.GoString(ptr)
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
func cbool(value bool) C.bool {
|
|
1911
|
+
if value {
|
|
1912
|
+
return C.bool(true)
|
|
1913
|
+
}
|
|
1914
|
+
return C.bool(false)
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
func boolInt(value bool) C.int {
|
|
1918
|
+
if value {
|
|
1919
|
+
return 1
|
|
1920
|
+
}
|
|
1921
|
+
return 0
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
func coreLibraryName() string {
|
|
1925
|
+
switch runtime.GOOS {
|
|
1926
|
+
case "windows":
|
|
1927
|
+
return "ElectrobunCore.dll"
|
|
1928
|
+
case "darwin":
|
|
1929
|
+
return "libElectrobunCore.dylib"
|
|
1930
|
+
default:
|
|
1931
|
+
return "libElectrobunCore.so"
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
func wgpuLibraryName() string {
|
|
1936
|
+
switch runtime.GOOS {
|
|
1937
|
+
case "windows":
|
|
1938
|
+
return "webgpu_dawn.dll"
|
|
1939
|
+
case "darwin":
|
|
1940
|
+
return "libwebgpu_dawn.dylib"
|
|
1941
|
+
default:
|
|
1942
|
+
return "libwebgpu_dawn.so"
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
func tempDir() string {
|
|
1947
|
+
if runtime.GOOS == "windows" {
|
|
1948
|
+
if value := os.Getenv("TEMP"); value != "" {
|
|
1949
|
+
return value
|
|
1950
|
+
}
|
|
1951
|
+
if value := os.Getenv("TMP"); value != "" {
|
|
1952
|
+
return value
|
|
1953
|
+
}
|
|
1954
|
+
return `C:\Temp`
|
|
1955
|
+
}
|
|
1956
|
+
if value := os.Getenv("TMPDIR"); value != "" {
|
|
1957
|
+
return value
|
|
1958
|
+
}
|
|
1959
|
+
if value := os.Getenv("TMP"); value != "" {
|
|
1960
|
+
return value
|
|
1961
|
+
}
|
|
1962
|
+
return "/tmp"
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1965
|
+
func appDataDir(home string) string {
|
|
1966
|
+
switch runtime.GOOS {
|
|
1967
|
+
case "darwin":
|
|
1968
|
+
return filepath.Join(home, "Library", "Application Support")
|
|
1969
|
+
case "windows":
|
|
1970
|
+
if value := os.Getenv("APPDATA"); value != "" {
|
|
1971
|
+
return value
|
|
1972
|
+
}
|
|
1973
|
+
return filepath.Join(home, "AppData", "Roaming")
|
|
1974
|
+
default:
|
|
1975
|
+
if value := os.Getenv("XDG_DATA_HOME"); value != "" {
|
|
1976
|
+
return value
|
|
1977
|
+
}
|
|
1978
|
+
return filepath.Join(home, ".local", "share")
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
func configDir(home string) string {
|
|
1983
|
+
switch runtime.GOOS {
|
|
1984
|
+
case "darwin":
|
|
1985
|
+
return filepath.Join(home, "Library", "Application Support")
|
|
1986
|
+
case "windows":
|
|
1987
|
+
if value := os.Getenv("APPDATA"); value != "" {
|
|
1988
|
+
return value
|
|
1989
|
+
}
|
|
1990
|
+
return filepath.Join(home, "AppData", "Roaming")
|
|
1991
|
+
default:
|
|
1992
|
+
if value := os.Getenv("XDG_CONFIG_HOME"); value != "" {
|
|
1993
|
+
return value
|
|
1994
|
+
}
|
|
1995
|
+
return filepath.Join(home, ".config")
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
func cacheDir(home string) string {
|
|
2000
|
+
switch runtime.GOOS {
|
|
2001
|
+
case "darwin":
|
|
2002
|
+
return filepath.Join(home, "Library", "Caches")
|
|
2003
|
+
case "windows":
|
|
2004
|
+
if value := os.Getenv("LOCALAPPDATA"); value != "" {
|
|
2005
|
+
return value
|
|
2006
|
+
}
|
|
2007
|
+
return filepath.Join(home, "AppData", "Local")
|
|
2008
|
+
default:
|
|
2009
|
+
if value := os.Getenv("XDG_CACHE_HOME"); value != "" {
|
|
2010
|
+
return value
|
|
2011
|
+
}
|
|
2012
|
+
return filepath.Join(home, ".cache")
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
func logsDir(home string) string {
|
|
2017
|
+
if runtime.GOOS == "darwin" {
|
|
2018
|
+
return filepath.Join(home, "Library", "Logs")
|
|
2019
|
+
}
|
|
2020
|
+
return cacheDir(home)
|
|
2021
|
+
}
|