1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
//! Wew is a cross-platform WebView rendering library based on Chromium Embedded
//! Framework (CEF). It supports mouse, keyboard, touch, input methods,
//! off-screen rendering, and communication with web pages.
//!
//! ## Thread Considerations
//!
//! In the current project, WebView and Runtime calls are best executed on the
//! UI thread, which is the main thread of the application process.
//!
//! Creating a Runtime must be completed on the UI thread, and all message loop
//! calls must also be operated on the UI thread.
//!
//! Other calls should be executed on the UI thread whenever possible, unless it
//! is truly unavoidable. Although these calls can run on any thread, there is
//! currently no guarantee that they will not cause other side effects.
//!
//! However, it is important to note that if the WebView manages window events
//! on its own, such as not using off-screen rendering, then the WebView can be
//! created on any thread.
//!
//!
//! ## Examples
//!
//! ```no_run
//! use std::{
//! sync::mpsc::{Sender, channel},
//! thread,
//! };
//!
//! use wew::{
//! MainThreadMessageLoop, MessageLoopAbstract, NativeWindowWebView,
//! runtime::{LogLevel, RuntimeHandler},
//! webview::{WebViewAttributes, WebViewHandler, WebViewState},
//! };
//!
//! struct RuntimeObserver {
//! tx: Sender<()>,
//! }
//!
//! impl RuntimeHandler for RuntimeObserver {
//! fn on_context_initialized(&self) {
//! self.tx.send(()).unwrap();
//! }
//! }
//!
//! struct WebViewObserver;
//!
//! impl WebViewHandler for WebViewObserver {
//! fn on_state_change(&self, state: WebViewState) {
//! if state == WebViewState::Close {
//! std::process::exit(0);
//! }
//! }
//! }
//!
//! fn main() {
//! if wew::is_subprocess() {
//! wew::execute_subprocess();
//!
//! return;
//! }
//!
//! #[cfg(target_os = "macos")]
//! wew::utils::startup_nsapplication();
//!
//! let message_loop = MainThreadMessageLoop::default();
//!
//! let mut runtime_attributes_builder =
//! message_loop.create_runtime_attributes_builder::<NativeWindowWebView>();
//!
//! runtime_attributes_builder = runtime_attributes_builder
//! // Set cache path, here we use environment variables passed by the build script.
//! .with_root_cache_path(option_env!("CACHE_PATH").unwrap())
//! .with_cache_path(option_env!("CACHE_PATH").unwrap())
//! .with_log_severity(LogLevel::Info);
//!
//! let (tx, rx) = channel();
//!
//! // Create runtime, wait for the `on_context_initialized` event to be triggered
//! // before considering the creation successful.
//! let runtime = runtime_attributes_builder
//! .build()
//! .create_runtime(RuntimeObserver { tx })
//! .unwrap();
//!
//! thread::spawn(move || {
//! rx.recv().unwrap();
//!
//! let webview = runtime
//! .create_webview(
//! "https://www.google.com",
//! WebViewAttributes::default(),
//! WebViewObserver,
//! )
//! .unwrap();
//!
//! std::mem::forget(webview);
//! std::mem::forget(runtime);
//! });
//!
//! message_loop.block_run();
//! }
//! ```
use Ordering;
use ;
pub use winit;
pub use raw_window_handle;
/// Represents a rectangular area
/// Message loop abstraction
///
/// Message loop abstraction, used to implement different message loop types.
/// Multi-threaded message loop
///
/// Using multi-threaded message runtime will create a separate thread inside
/// the runtime to run the message loop.
///
/// Note that macOS does not support this type of message loop.
;
/// Main thread message loop
///
/// You need to manually run the message loop in the main thread of the process.
;
/// Message loop pump
///
/// If you need to integrate with existing message loops, the message pump
/// mechanism provides a way for you to drive the message loop yourself.
;
/// WebView abstraction
///
/// WebView abstraction, used to implement different WebView types.
/// Off-screen rendering mode
///
/// When using off-screen rendering mode, the WebView will not be displayed on
/// screen, but the rendering results will be pushed through
/// **`WindowlessRenderWebViewHandler::on_frame`**, and you can handle the video
/// frames yourself. Also, in this mode, mouse and keyboard events need to be
/// passed to the WebView by yourself.
;
/// Native window mode
///
/// When using native window mode, the WebView will create a native window and
/// display it on screen.
;
/// Execute subprocess
///
/// This method is used to start a subprocess in a separate process.
///
/// ## Examples
///
/// ```no_run
/// fn main() {
/// if wew::is_subprocess() {
/// wew::execute_subprocess();
///
/// return;
/// }
/// }
/// ```
///
/// #### Please be careful!
///
/// Do not call this function in an asynchronous runtime, such as tokio,
/// which can lead to unexpected crashes!
/// Check if current process is a subprocess
///
/// This function is used to check if the current process is a subprocess.
///
/// Note that if the current process is a subprocess, it will block until the
/// subprocess exits.