mock_runtime.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. // Copyright 2019-2023 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. #![allow(dead_code)]
  5. #![allow(missing_docs)]
  6. use tauri_runtime::{
  7. monitor::Monitor,
  8. webview::{WindowBuilder, WindowBuilderBase},
  9. window::{
  10. dpi::{PhysicalPosition, PhysicalSize, Position, Size},
  11. CursorIcon, DetachedWindow, PendingWindow, RawWindow, WindowEvent,
  12. },
  13. DeviceEventFilter, Dispatch, Error, EventLoopProxy, ExitRequestedEventAction, Icon, Result,
  14. RunEvent, Runtime, RuntimeHandle, RuntimeInitArgs, UserAttentionType, UserEvent, WindowEventId,
  15. };
  16. #[cfg(target_os = "macos")]
  17. use tauri_utils::TitleBarStyle;
  18. use tauri_utils::{config::WindowConfig, ProgressBarState, Theme};
  19. use url::Url;
  20. #[cfg(windows)]
  21. use windows::Win32::Foundation::HWND;
  22. use std::{
  23. cell::RefCell,
  24. collections::HashMap,
  25. fmt,
  26. sync::{
  27. atomic::{AtomicBool, AtomicU32, Ordering},
  28. mpsc::{channel, sync_channel, Receiver, SyncSender},
  29. Arc, Mutex,
  30. },
  31. };
  32. type ShortcutMap = HashMap<String, Box<dyn Fn() + Send + 'static>>;
  33. type WindowId = u32;
  34. enum Message {
  35. Task(Box<dyn FnOnce() + Send>),
  36. CloseWindow(WindowId),
  37. }
  38. struct Window;
  39. #[derive(Clone)]
  40. pub struct RuntimeContext {
  41. is_running: Arc<AtomicBool>,
  42. windows: Arc<RefCell<HashMap<WindowId, Window>>>,
  43. shortcuts: Arc<Mutex<ShortcutMap>>,
  44. run_tx: SyncSender<Message>,
  45. next_window_id: Arc<AtomicU32>,
  46. next_window_event_id: Arc<AtomicU32>,
  47. }
  48. // SAFETY: we ensure this type is only used on the main thread.
  49. #[allow(clippy::non_send_fields_in_send_ty)]
  50. unsafe impl Send for RuntimeContext {}
  51. // SAFETY: we ensure this type is only used on the main thread.
  52. #[allow(clippy::non_send_fields_in_send_ty)]
  53. unsafe impl Sync for RuntimeContext {}
  54. impl RuntimeContext {
  55. fn send_message(&self, message: Message) -> Result<()> {
  56. if self.is_running.load(Ordering::Relaxed) {
  57. self
  58. .run_tx
  59. .send(message)
  60. .map_err(|_| Error::FailedToSendMessage)
  61. } else {
  62. match message {
  63. Message::Task(task) => task(),
  64. Message::CloseWindow(id) => {
  65. self.windows.borrow_mut().remove(&id);
  66. }
  67. }
  68. Ok(())
  69. }
  70. }
  71. fn next_window_id(&self) -> WindowId {
  72. self.next_window_id.fetch_add(1, Ordering::Relaxed)
  73. }
  74. fn next_window_event_id(&self) -> WindowEventId {
  75. self.next_window_event_id.fetch_add(1, Ordering::Relaxed)
  76. }
  77. }
  78. impl fmt::Debug for RuntimeContext {
  79. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  80. f.debug_struct("RuntimeContext").finish()
  81. }
  82. }
  83. #[derive(Debug, Clone)]
  84. pub struct MockRuntimeHandle {
  85. context: RuntimeContext,
  86. }
  87. impl<T: UserEvent> RuntimeHandle<T> for MockRuntimeHandle {
  88. type Runtime = MockRuntime;
  89. fn create_proxy(&self) -> EventProxy {
  90. EventProxy {}
  91. }
  92. /// Create a new webview window.
  93. fn create_window<F: Fn(RawWindow<'_>) + Send + 'static>(
  94. &self,
  95. pending: PendingWindow<T, Self::Runtime>,
  96. _before_webview_creation: Option<F>,
  97. ) -> Result<DetachedWindow<T, Self::Runtime>> {
  98. let id = self.context.next_window_id();
  99. self.context.windows.borrow_mut().insert(id, Window);
  100. Ok(DetachedWindow {
  101. label: pending.label,
  102. dispatcher: MockDispatcher {
  103. id,
  104. context: self.context.clone(),
  105. last_evaluated_script: Default::default(),
  106. url: Arc::new(Mutex::new(pending.url)),
  107. },
  108. })
  109. }
  110. /// Run a task on the main thread.
  111. fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()> {
  112. self.context.send_message(Message::Task(Box::new(f)))
  113. }
  114. fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle {
  115. #[cfg(target_os = "linux")]
  116. return raw_window_handle::RawDisplayHandle::Xlib(raw_window_handle::XlibDisplayHandle::empty());
  117. #[cfg(target_os = "macos")]
  118. return raw_window_handle::RawDisplayHandle::AppKit(
  119. raw_window_handle::AppKitDisplayHandle::empty(),
  120. );
  121. #[cfg(windows)]
  122. return raw_window_handle::RawDisplayHandle::Windows(
  123. raw_window_handle::WindowsDisplayHandle::empty(),
  124. );
  125. #[cfg(not(any(target_os = "linux", target_os = "macos", windows)))]
  126. return unimplemented!();
  127. }
  128. fn primary_monitor(&self) -> Option<Monitor> {
  129. unimplemented!()
  130. }
  131. fn available_monitors(&self) -> Vec<Monitor> {
  132. unimplemented!()
  133. }
  134. /// Shows the application, but does not automatically focus it.
  135. #[cfg(target_os = "macos")]
  136. fn show(&self) -> Result<()> {
  137. Ok(())
  138. }
  139. /// Hides the application.
  140. #[cfg(target_os = "macos")]
  141. fn hide(&self) -> Result<()> {
  142. Ok(())
  143. }
  144. #[cfg(target_os = "android")]
  145. fn find_class<'a>(
  146. &self,
  147. env: &mut jni::JNIEnv<'a>,
  148. activity: &jni::objects::JObject<'_>,
  149. name: impl Into<String>,
  150. ) -> std::result::Result<jni::objects::JClass<'a>, jni::errors::Error> {
  151. todo!()
  152. }
  153. #[cfg(target_os = "android")]
  154. fn run_on_android_context<F>(&self, f: F)
  155. where
  156. F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static,
  157. {
  158. todo!()
  159. }
  160. }
  161. #[derive(Debug, Clone)]
  162. pub struct MockDispatcher {
  163. id: WindowId,
  164. context: RuntimeContext,
  165. url: Arc<Mutex<String>>,
  166. last_evaluated_script: Arc<Mutex<Option<String>>>,
  167. }
  168. impl MockDispatcher {
  169. pub fn last_evaluated_script(&self) -> Option<String> {
  170. self.last_evaluated_script.lock().unwrap().clone()
  171. }
  172. }
  173. #[derive(Debug, Clone)]
  174. pub struct MockWindowBuilder {}
  175. impl WindowBuilderBase for MockWindowBuilder {}
  176. impl WindowBuilder for MockWindowBuilder {
  177. fn new() -> Self {
  178. Self {}
  179. }
  180. fn with_config(config: WindowConfig) -> Self {
  181. Self {}
  182. }
  183. fn center(self) -> Self {
  184. self
  185. }
  186. fn position(self, x: f64, y: f64) -> Self {
  187. self
  188. }
  189. fn inner_size(self, min_width: f64, min_height: f64) -> Self {
  190. self
  191. }
  192. fn min_inner_size(self, min_width: f64, min_height: f64) -> Self {
  193. self
  194. }
  195. fn max_inner_size(self, max_width: f64, max_height: f64) -> Self {
  196. self
  197. }
  198. fn resizable(self, resizable: bool) -> Self {
  199. self
  200. }
  201. fn maximizable(self, resizable: bool) -> Self {
  202. self
  203. }
  204. fn minimizable(self, resizable: bool) -> Self {
  205. self
  206. }
  207. fn closable(self, resizable: bool) -> Self {
  208. self
  209. }
  210. fn title<S: Into<String>>(self, title: S) -> Self {
  211. self
  212. }
  213. fn fullscreen(self, fullscreen: bool) -> Self {
  214. self
  215. }
  216. fn focused(self, focused: bool) -> Self {
  217. self
  218. }
  219. fn maximized(self, maximized: bool) -> Self {
  220. self
  221. }
  222. fn visible(self, visible: bool) -> Self {
  223. self
  224. }
  225. #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
  226. #[cfg_attr(
  227. doc_cfg,
  228. doc(cfg(any(not(target_os = "macos"), feature = "macos-private-api")))
  229. )]
  230. fn transparent(self, transparent: bool) -> Self {
  231. self
  232. }
  233. fn decorations(self, decorations: bool) -> Self {
  234. self
  235. }
  236. fn always_on_bottom(self, always_on_bottom: bool) -> Self {
  237. self
  238. }
  239. fn always_on_top(self, always_on_top: bool) -> Self {
  240. self
  241. }
  242. fn visible_on_all_workspaces(self, visible_on_all_workspaces: bool) -> Self {
  243. self
  244. }
  245. fn content_protected(self, protected: bool) -> Self {
  246. self
  247. }
  248. fn icon(self, icon: Icon) -> Result<Self> {
  249. Ok(self)
  250. }
  251. fn skip_taskbar(self, skip: bool) -> Self {
  252. self
  253. }
  254. fn shadow(self, enable: bool) -> Self {
  255. self
  256. }
  257. #[cfg(windows)]
  258. fn parent_window(self, parent: HWND) -> Self {
  259. self
  260. }
  261. #[cfg(target_os = "macos")]
  262. fn parent_window(self, parent: *mut std::ffi::c_void) -> Self {
  263. self
  264. }
  265. #[cfg(windows)]
  266. fn owner_window(self, owner: HWND) -> Self {
  267. self
  268. }
  269. #[cfg(target_os = "macos")]
  270. fn title_bar_style(self, style: TitleBarStyle) -> Self {
  271. self
  272. }
  273. #[cfg(target_os = "macos")]
  274. fn hidden_title(self, transparent: bool) -> Self {
  275. self
  276. }
  277. #[cfg(target_os = "macos")]
  278. fn tabbing_identifier(self, identifier: &str) -> Self {
  279. self
  280. }
  281. fn theme(self, theme: Option<Theme>) -> Self {
  282. self
  283. }
  284. fn has_icon(&self) -> bool {
  285. false
  286. }
  287. }
  288. impl<T: UserEvent> Dispatch<T> for MockDispatcher {
  289. type Runtime = MockRuntime;
  290. type WindowBuilder = MockWindowBuilder;
  291. fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()> {
  292. self.context.send_message(Message::Task(Box::new(f)))
  293. }
  294. fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> WindowEventId {
  295. self.context.next_window_event_id()
  296. }
  297. fn with_webview<F: FnOnce(Box<dyn std::any::Any>) + Send + 'static>(&self, f: F) -> Result<()> {
  298. Ok(())
  299. }
  300. #[cfg(any(debug_assertions, feature = "devtools"))]
  301. fn open_devtools(&self) {}
  302. #[cfg(any(debug_assertions, feature = "devtools"))]
  303. fn close_devtools(&self) {}
  304. #[cfg(any(debug_assertions, feature = "devtools"))]
  305. fn is_devtools_open(&self) -> Result<bool> {
  306. Ok(false)
  307. }
  308. fn url(&self) -> Result<url::Url> {
  309. self
  310. .url
  311. .lock()
  312. .unwrap()
  313. .parse()
  314. .map_err(|_| Error::FailedToReceiveMessage)
  315. }
  316. fn scale_factor(&self) -> Result<f64> {
  317. Ok(1.0)
  318. }
  319. fn inner_position(&self) -> Result<PhysicalPosition<i32>> {
  320. Ok(PhysicalPosition { x: 0, y: 0 })
  321. }
  322. fn outer_position(&self) -> Result<PhysicalPosition<i32>> {
  323. Ok(PhysicalPosition { x: 0, y: 0 })
  324. }
  325. fn inner_size(&self) -> Result<PhysicalSize<u32>> {
  326. Ok(PhysicalSize {
  327. width: 0,
  328. height: 0,
  329. })
  330. }
  331. fn outer_size(&self) -> Result<PhysicalSize<u32>> {
  332. Ok(PhysicalSize {
  333. width: 0,
  334. height: 0,
  335. })
  336. }
  337. fn is_fullscreen(&self) -> Result<bool> {
  338. Ok(false)
  339. }
  340. fn is_minimized(&self) -> Result<bool> {
  341. Ok(false)
  342. }
  343. fn is_maximized(&self) -> Result<bool> {
  344. Ok(false)
  345. }
  346. fn is_focused(&self) -> Result<bool> {
  347. Ok(false)
  348. }
  349. fn is_decorated(&self) -> Result<bool> {
  350. Ok(false)
  351. }
  352. fn is_resizable(&self) -> Result<bool> {
  353. Ok(false)
  354. }
  355. fn is_maximizable(&self) -> Result<bool> {
  356. Ok(true)
  357. }
  358. fn is_minimizable(&self) -> Result<bool> {
  359. Ok(true)
  360. }
  361. fn is_closable(&self) -> Result<bool> {
  362. Ok(true)
  363. }
  364. fn is_visible(&self) -> Result<bool> {
  365. Ok(true)
  366. }
  367. fn title(&self) -> Result<String> {
  368. Ok(String::new())
  369. }
  370. fn current_monitor(&self) -> Result<Option<Monitor>> {
  371. Ok(None)
  372. }
  373. fn primary_monitor(&self) -> Result<Option<Monitor>> {
  374. Ok(None)
  375. }
  376. fn available_monitors(&self) -> Result<Vec<Monitor>> {
  377. Ok(Vec::new())
  378. }
  379. fn theme(&self) -> Result<Theme> {
  380. Ok(Theme::Light)
  381. }
  382. #[cfg(any(
  383. target_os = "linux",
  384. target_os = "dragonfly",
  385. target_os = "freebsd",
  386. target_os = "netbsd",
  387. target_os = "openbsd"
  388. ))]
  389. fn gtk_window(&self) -> Result<gtk::ApplicationWindow> {
  390. unimplemented!()
  391. }
  392. #[cfg(any(
  393. target_os = "linux",
  394. target_os = "dragonfly",
  395. target_os = "freebsd",
  396. target_os = "netbsd",
  397. target_os = "openbsd"
  398. ))]
  399. fn default_vbox(&self) -> Result<gtk::Box> {
  400. unimplemented!()
  401. }
  402. fn raw_window_handle(&self) -> Result<raw_window_handle::RawWindowHandle> {
  403. #[cfg(target_os = "linux")]
  404. return Ok(raw_window_handle::RawWindowHandle::Xlib(
  405. raw_window_handle::XlibWindowHandle::empty(),
  406. ));
  407. #[cfg(target_os = "macos")]
  408. return Ok(raw_window_handle::RawWindowHandle::AppKit(
  409. raw_window_handle::AppKitWindowHandle::empty(),
  410. ));
  411. #[cfg(windows)]
  412. return Ok(raw_window_handle::RawWindowHandle::Win32(
  413. raw_window_handle::Win32WindowHandle::empty(),
  414. ));
  415. #[cfg(not(any(target_os = "linux", target_os = "macos", windows)))]
  416. return unimplemented!();
  417. }
  418. fn center(&self) -> Result<()> {
  419. Ok(())
  420. }
  421. fn print(&self) -> Result<()> {
  422. Ok(())
  423. }
  424. fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()> {
  425. Ok(())
  426. }
  427. fn create_window<F: Fn(RawWindow<'_>) + Send + 'static>(
  428. &mut self,
  429. pending: PendingWindow<T, Self::Runtime>,
  430. _before_webview_creation: Option<F>,
  431. ) -> Result<DetachedWindow<T, Self::Runtime>> {
  432. let id = self.context.next_window_id();
  433. self.context.windows.borrow_mut().insert(id, Window);
  434. Ok(DetachedWindow {
  435. label: pending.label,
  436. dispatcher: MockDispatcher {
  437. id,
  438. context: self.context.clone(),
  439. last_evaluated_script: Default::default(),
  440. url: Arc::new(Mutex::new(pending.url)),
  441. },
  442. })
  443. }
  444. fn set_resizable(&self, resizable: bool) -> Result<()> {
  445. Ok(())
  446. }
  447. fn set_maximizable(&self, maximizable: bool) -> Result<()> {
  448. Ok(())
  449. }
  450. fn set_minimizable(&self, minimizable: bool) -> Result<()> {
  451. Ok(())
  452. }
  453. fn set_closable(&self, closable: bool) -> Result<()> {
  454. Ok(())
  455. }
  456. fn set_title<S: Into<String>>(&self, title: S) -> Result<()> {
  457. Ok(())
  458. }
  459. fn navigate(&self, url: Url) -> Result<()> {
  460. *self.url.lock().unwrap() = url.to_string();
  461. Ok(())
  462. }
  463. fn maximize(&self) -> Result<()> {
  464. Ok(())
  465. }
  466. fn unmaximize(&self) -> Result<()> {
  467. Ok(())
  468. }
  469. fn minimize(&self) -> Result<()> {
  470. Ok(())
  471. }
  472. fn unminimize(&self) -> Result<()> {
  473. Ok(())
  474. }
  475. fn show(&self) -> Result<()> {
  476. Ok(())
  477. }
  478. fn hide(&self) -> Result<()> {
  479. Ok(())
  480. }
  481. fn close(&self) -> Result<()> {
  482. self.context.send_message(Message::CloseWindow(self.id))?;
  483. Ok(())
  484. }
  485. fn set_decorations(&self, decorations: bool) -> Result<()> {
  486. Ok(())
  487. }
  488. fn set_shadow(&self, shadow: bool) -> Result<()> {
  489. Ok(())
  490. }
  491. fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()> {
  492. Ok(())
  493. }
  494. fn set_always_on_top(&self, always_on_top: bool) -> Result<()> {
  495. Ok(())
  496. }
  497. fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()> {
  498. Ok(())
  499. }
  500. fn set_content_protected(&self, protected: bool) -> Result<()> {
  501. Ok(())
  502. }
  503. fn set_size(&self, size: Size) -> Result<()> {
  504. Ok(())
  505. }
  506. fn set_min_size(&self, size: Option<Size>) -> Result<()> {
  507. Ok(())
  508. }
  509. fn set_max_size(&self, size: Option<Size>) -> Result<()> {
  510. Ok(())
  511. }
  512. fn set_position(&self, position: Position) -> Result<()> {
  513. Ok(())
  514. }
  515. fn set_fullscreen(&self, fullscreen: bool) -> Result<()> {
  516. Ok(())
  517. }
  518. fn set_focus(&self) -> Result<()> {
  519. Ok(())
  520. }
  521. fn set_icon(&self, icon: Icon) -> Result<()> {
  522. Ok(())
  523. }
  524. fn set_skip_taskbar(&self, skip: bool) -> Result<()> {
  525. Ok(())
  526. }
  527. fn set_cursor_grab(&self, grab: bool) -> Result<()> {
  528. Ok(())
  529. }
  530. fn set_cursor_visible(&self, visible: bool) -> Result<()> {
  531. Ok(())
  532. }
  533. fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()> {
  534. Ok(())
  535. }
  536. fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()> {
  537. Ok(())
  538. }
  539. fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()> {
  540. Ok(())
  541. }
  542. fn start_dragging(&self) -> Result<()> {
  543. Ok(())
  544. }
  545. fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
  546. self
  547. .last_evaluated_script
  548. .lock()
  549. .unwrap()
  550. .replace(script.into());
  551. Ok(())
  552. }
  553. fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()> {
  554. Ok(())
  555. }
  556. }
  557. #[derive(Debug, Clone)]
  558. pub struct EventProxy {}
  559. impl<T: UserEvent> EventLoopProxy<T> for EventProxy {
  560. fn send_event(&self, event: T) -> Result<()> {
  561. Ok(())
  562. }
  563. }
  564. #[derive(Debug)]
  565. pub struct MockRuntime {
  566. is_running: Arc<AtomicBool>,
  567. pub context: RuntimeContext,
  568. run_rx: Receiver<Message>,
  569. }
  570. impl MockRuntime {
  571. fn init() -> Self {
  572. let is_running = Arc::new(AtomicBool::new(false));
  573. let (tx, rx) = sync_channel(1);
  574. let context = RuntimeContext {
  575. is_running: is_running.clone(),
  576. windows: Default::default(),
  577. shortcuts: Default::default(),
  578. run_tx: tx,
  579. next_window_id: Default::default(),
  580. next_window_event_id: Default::default(),
  581. };
  582. Self {
  583. is_running,
  584. context,
  585. run_rx: rx,
  586. }
  587. }
  588. }
  589. impl<T: UserEvent> Runtime<T> for MockRuntime {
  590. type Dispatcher = MockDispatcher;
  591. type Handle = MockRuntimeHandle;
  592. type EventLoopProxy = EventProxy;
  593. fn new(_args: RuntimeInitArgs) -> Result<Self> {
  594. Ok(Self::init())
  595. }
  596. #[cfg(any(windows, target_os = "linux"))]
  597. fn new_any_thread(_args: RuntimeInitArgs) -> Result<Self> {
  598. Ok(Self::init())
  599. }
  600. fn create_proxy(&self) -> EventProxy {
  601. EventProxy {}
  602. }
  603. fn handle(&self) -> Self::Handle {
  604. MockRuntimeHandle {
  605. context: self.context.clone(),
  606. }
  607. }
  608. fn create_window<F: Fn(RawWindow<'_>) + Send + 'static>(
  609. &self,
  610. pending: PendingWindow<T, Self>,
  611. _before_webview_creation: Option<F>,
  612. ) -> Result<DetachedWindow<T, Self>> {
  613. let id = self.context.next_window_id();
  614. self.context.windows.borrow_mut().insert(id, Window);
  615. Ok(DetachedWindow {
  616. label: pending.label,
  617. dispatcher: MockDispatcher {
  618. id,
  619. context: self.context.clone(),
  620. last_evaluated_script: Default::default(),
  621. url: Arc::new(Mutex::new(pending.url)),
  622. },
  623. })
  624. }
  625. fn primary_monitor(&self) -> Option<Monitor> {
  626. unimplemented!()
  627. }
  628. fn available_monitors(&self) -> Vec<Monitor> {
  629. unimplemented!()
  630. }
  631. #[cfg(target_os = "macos")]
  632. #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))]
  633. fn set_activation_policy(&mut self, activation_policy: tauri_runtime::ActivationPolicy) {}
  634. #[cfg(target_os = "macos")]
  635. #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))]
  636. fn show(&self) {}
  637. #[cfg(target_os = "macos")]
  638. #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))]
  639. fn hide(&self) {}
  640. fn set_device_event_filter(&mut self, filter: DeviceEventFilter) {}
  641. #[cfg(any(
  642. target_os = "macos",
  643. windows,
  644. target_os = "linux",
  645. target_os = "dragonfly",
  646. target_os = "freebsd",
  647. target_os = "netbsd",
  648. target_os = "openbsd"
  649. ))]
  650. fn run_iteration<F: Fn(RunEvent<T>) + 'static>(
  651. &mut self,
  652. callback: F,
  653. ) -> tauri_runtime::RunIteration {
  654. Default::default()
  655. }
  656. fn run<F: FnMut(RunEvent<T>) + 'static>(self, mut callback: F) {
  657. self.is_running.store(true, Ordering::Relaxed);
  658. callback(RunEvent::Ready);
  659. loop {
  660. if let Ok(m) = self.run_rx.try_recv() {
  661. match m {
  662. Message::Task(p) => p(),
  663. Message::CloseWindow(id) => {
  664. let removed = self.context.windows.borrow_mut().remove(&id).is_some();
  665. if removed {
  666. let is_empty = self.context.windows.borrow().is_empty();
  667. if is_empty {
  668. let (tx, rx) = channel();
  669. callback(RunEvent::ExitRequested { tx });
  670. let recv = rx.try_recv();
  671. let should_prevent = matches!(recv, Ok(ExitRequestedEventAction::Prevent));
  672. if !should_prevent {
  673. break;
  674. }
  675. }
  676. }
  677. }
  678. }
  679. }
  680. callback(RunEvent::MainEventsCleared);
  681. std::thread::sleep(std::time::Duration::from_secs(1));
  682. }
  683. callback(RunEvent::Exit);
  684. }
  685. }