mock_runtime.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. // Copyright 2019-2022 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. #![allow(dead_code)]
  5. use tauri_runtime::{
  6. menu::{Menu, MenuUpdate},
  7. monitor::Monitor,
  8. webview::{WindowBuilder, WindowBuilderBase},
  9. window::{
  10. dpi::{PhysicalPosition, PhysicalSize, Position, Size},
  11. CursorIcon, DetachedWindow, MenuEvent, PendingWindow, WindowEvent,
  12. },
  13. DeviceEventFilter, Dispatch, EventLoopProxy, Icon, Result, RunEvent, Runtime, RuntimeHandle,
  14. UserAttentionType, UserEvent,
  15. };
  16. #[cfg(all(desktop, feature = "system-tray"))]
  17. use tauri_runtime::{
  18. menu::{SystemTrayMenu, TrayHandle},
  19. SystemTray, SystemTrayEvent, TrayId,
  20. };
  21. #[cfg(target_os = "macos")]
  22. use tauri_utils::TitleBarStyle;
  23. use tauri_utils::{config::WindowConfig, Theme};
  24. use uuid::Uuid;
  25. #[cfg(windows)]
  26. use windows::Win32::Foundation::HWND;
  27. use std::{
  28. collections::HashMap,
  29. fmt,
  30. sync::{Arc, Mutex},
  31. };
  32. type ShortcutMap = HashMap<String, Box<dyn Fn() + Send + 'static>>;
  33. #[derive(Clone)]
  34. pub struct RuntimeContext {
  35. shortcuts: Arc<Mutex<ShortcutMap>>,
  36. clipboard: Arc<Mutex<Option<String>>>,
  37. }
  38. impl fmt::Debug for RuntimeContext {
  39. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  40. f.debug_struct("RuntimeContext")
  41. .field("clipboard", &self.clipboard)
  42. .finish()
  43. }
  44. }
  45. #[derive(Debug, Clone)]
  46. pub struct MockRuntimeHandle {
  47. context: RuntimeContext,
  48. }
  49. impl<T: UserEvent> RuntimeHandle<T> for MockRuntimeHandle {
  50. type Runtime = MockRuntime;
  51. fn create_proxy(&self) -> EventProxy {
  52. unimplemented!()
  53. }
  54. /// Create a new webview window.
  55. fn create_window(
  56. &self,
  57. pending: PendingWindow<T, Self::Runtime>,
  58. ) -> Result<DetachedWindow<T, Self::Runtime>> {
  59. Ok(DetachedWindow {
  60. label: pending.label,
  61. dispatcher: MockDispatcher {
  62. context: self.context.clone(),
  63. },
  64. menu_ids: Default::default(),
  65. js_event_listeners: Default::default(),
  66. })
  67. }
  68. /// Run a task on the main thread.
  69. fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()> {
  70. unimplemented!()
  71. }
  72. #[cfg(all(desktop, feature = "system-tray"))]
  73. #[cfg_attr(doc_cfg, doc(cfg(all(desktop, feature = "system-tray"))))]
  74. fn system_tray(
  75. &self,
  76. system_tray: SystemTray,
  77. ) -> Result<<Self::Runtime as Runtime<T>>::TrayHandler> {
  78. unimplemented!()
  79. }
  80. fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle {
  81. unimplemented!()
  82. }
  83. /// Shows the application, but does not automatically focus it.
  84. #[cfg(target_os = "macos")]
  85. fn show(&self) -> Result<()> {
  86. Ok(())
  87. }
  88. /// Hides the application.
  89. #[cfg(target_os = "macos")]
  90. fn hide(&self) -> Result<()> {
  91. Ok(())
  92. }
  93. }
  94. #[derive(Debug, Clone)]
  95. pub struct MockDispatcher {
  96. context: RuntimeContext,
  97. }
  98. #[cfg(all(desktop, feature = "global-shortcut"))]
  99. #[derive(Debug, Clone)]
  100. pub struct MockGlobalShortcutManager {
  101. context: RuntimeContext,
  102. }
  103. #[cfg(all(desktop, feature = "global-shortcut"))]
  104. impl tauri_runtime::GlobalShortcutManager for MockGlobalShortcutManager {
  105. fn is_registered(&self, accelerator: &str) -> Result<bool> {
  106. Ok(
  107. self
  108. .context
  109. .shortcuts
  110. .lock()
  111. .unwrap()
  112. .contains_key(accelerator),
  113. )
  114. }
  115. fn register<F: Fn() + Send + 'static>(&mut self, accelerator: &str, handler: F) -> Result<()> {
  116. self
  117. .context
  118. .shortcuts
  119. .lock()
  120. .unwrap()
  121. .insert(accelerator.into(), Box::new(handler));
  122. Ok(())
  123. }
  124. fn unregister_all(&mut self) -> Result<()> {
  125. *self.context.shortcuts.lock().unwrap() = Default::default();
  126. Ok(())
  127. }
  128. fn unregister(&mut self, accelerator: &str) -> Result<()> {
  129. self.context.shortcuts.lock().unwrap().remove(accelerator);
  130. Ok(())
  131. }
  132. }
  133. #[cfg(feature = "clipboard")]
  134. #[derive(Debug, Clone)]
  135. pub struct MockClipboardManager {
  136. context: RuntimeContext,
  137. }
  138. #[cfg(feature = "clipboard")]
  139. impl tauri_runtime::ClipboardManager for MockClipboardManager {
  140. fn write_text<T: Into<String>>(&mut self, text: T) -> Result<()> {
  141. self.context.clipboard.lock().unwrap().replace(text.into());
  142. Ok(())
  143. }
  144. fn read_text(&self) -> Result<Option<String>> {
  145. Ok(self.context.clipboard.lock().unwrap().clone())
  146. }
  147. }
  148. #[derive(Debug, Clone)]
  149. pub struct MockWindowBuilder {}
  150. impl WindowBuilderBase for MockWindowBuilder {}
  151. impl WindowBuilder for MockWindowBuilder {
  152. fn new() -> Self {
  153. Self {}
  154. }
  155. fn with_config(config: WindowConfig) -> Self {
  156. Self {}
  157. }
  158. fn menu(self, menu: Menu) -> Self {
  159. self
  160. }
  161. fn center(self) -> Self {
  162. self
  163. }
  164. fn position(self, x: f64, y: f64) -> Self {
  165. self
  166. }
  167. fn inner_size(self, min_width: f64, min_height: f64) -> Self {
  168. self
  169. }
  170. fn min_inner_size(self, min_width: f64, min_height: f64) -> Self {
  171. self
  172. }
  173. fn max_inner_size(self, max_width: f64, max_height: f64) -> Self {
  174. self
  175. }
  176. fn resizable(self, resizable: bool) -> Self {
  177. self
  178. }
  179. fn title<S: Into<String>>(self, title: S) -> Self {
  180. self
  181. }
  182. fn fullscreen(self, fullscreen: bool) -> Self {
  183. self
  184. }
  185. fn focused(self, focused: bool) -> Self {
  186. self
  187. }
  188. fn maximized(self, maximized: bool) -> Self {
  189. self
  190. }
  191. fn visible(self, visible: bool) -> Self {
  192. self
  193. }
  194. #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
  195. #[cfg_attr(
  196. doc_cfg,
  197. doc(cfg(any(not(target_os = "macos"), feature = "macos-private-api")))
  198. )]
  199. fn transparent(self, transparent: bool) -> Self {
  200. self
  201. }
  202. fn decorations(self, decorations: bool) -> Self {
  203. self
  204. }
  205. fn always_on_top(self, always_on_top: bool) -> Self {
  206. self
  207. }
  208. fn content_protected(self, protected: bool) -> Self {
  209. self
  210. }
  211. fn icon(self, icon: Icon) -> Result<Self> {
  212. Ok(self)
  213. }
  214. fn skip_taskbar(self, skip: bool) -> Self {
  215. self
  216. }
  217. #[cfg(windows)]
  218. fn parent_window(self, parent: HWND) -> Self {
  219. self
  220. }
  221. #[cfg(target_os = "macos")]
  222. fn parent_window(self, parent: *mut std::ffi::c_void) -> Self {
  223. self
  224. }
  225. #[cfg(windows)]
  226. fn owner_window(self, owner: HWND) -> Self {
  227. self
  228. }
  229. #[cfg(target_os = "macos")]
  230. fn title_bar_style(self, style: TitleBarStyle) -> Self {
  231. self
  232. }
  233. #[cfg(target_os = "macos")]
  234. fn hidden_title(self, transparent: bool) -> Self {
  235. self
  236. }
  237. #[cfg(target_os = "macos")]
  238. fn tabbing_identifier(self, identifier: &str) -> Self {
  239. self
  240. }
  241. fn theme(self, theme: Option<Theme>) -> Self {
  242. self
  243. }
  244. fn has_icon(&self) -> bool {
  245. false
  246. }
  247. fn get_menu(&self) -> Option<&Menu> {
  248. None
  249. }
  250. }
  251. impl<T: UserEvent> Dispatch<T> for MockDispatcher {
  252. type Runtime = MockRuntime;
  253. type WindowBuilder = MockWindowBuilder;
  254. fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()> {
  255. Ok(())
  256. }
  257. fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> Uuid {
  258. Uuid::new_v4()
  259. }
  260. fn on_menu_event<F: Fn(&MenuEvent) + Send + 'static>(&self, f: F) -> Uuid {
  261. Uuid::new_v4()
  262. }
  263. #[cfg(any(debug_assertions, feature = "devtools"))]
  264. fn open_devtools(&self) {}
  265. #[cfg(any(debug_assertions, feature = "devtools"))]
  266. fn close_devtools(&self) {}
  267. #[cfg(any(debug_assertions, feature = "devtools"))]
  268. fn is_devtools_open(&self) -> Result<bool> {
  269. Ok(false)
  270. }
  271. fn url(&self) -> Result<url::Url> {
  272. todo!()
  273. }
  274. fn scale_factor(&self) -> Result<f64> {
  275. Ok(1.0)
  276. }
  277. fn inner_position(&self) -> Result<PhysicalPosition<i32>> {
  278. Ok(PhysicalPosition { x: 0, y: 0 })
  279. }
  280. fn outer_position(&self) -> Result<PhysicalPosition<i32>> {
  281. Ok(PhysicalPosition { x: 0, y: 0 })
  282. }
  283. fn inner_size(&self) -> Result<PhysicalSize<u32>> {
  284. Ok(PhysicalSize {
  285. width: 0,
  286. height: 0,
  287. })
  288. }
  289. fn outer_size(&self) -> Result<PhysicalSize<u32>> {
  290. Ok(PhysicalSize {
  291. width: 0,
  292. height: 0,
  293. })
  294. }
  295. fn is_fullscreen(&self) -> Result<bool> {
  296. Ok(false)
  297. }
  298. fn is_minimized(&self) -> Result<bool> {
  299. Ok(false)
  300. }
  301. fn is_maximized(&self) -> Result<bool> {
  302. Ok(false)
  303. }
  304. fn is_decorated(&self) -> Result<bool> {
  305. Ok(false)
  306. }
  307. fn is_resizable(&self) -> Result<bool> {
  308. Ok(false)
  309. }
  310. fn is_visible(&self) -> Result<bool> {
  311. Ok(true)
  312. }
  313. fn title(&self) -> Result<String> {
  314. Ok(String::new())
  315. }
  316. fn is_menu_visible(&self) -> Result<bool> {
  317. Ok(true)
  318. }
  319. fn current_monitor(&self) -> Result<Option<Monitor>> {
  320. Ok(None)
  321. }
  322. fn primary_monitor(&self) -> Result<Option<Monitor>> {
  323. Ok(None)
  324. }
  325. fn available_monitors(&self) -> Result<Vec<Monitor>> {
  326. Ok(Vec::new())
  327. }
  328. fn theme(&self) -> Result<Theme> {
  329. Ok(Theme::Light)
  330. }
  331. #[cfg(any(
  332. target_os = "linux",
  333. target_os = "dragonfly",
  334. target_os = "freebsd",
  335. target_os = "netbsd",
  336. target_os = "openbsd"
  337. ))]
  338. fn gtk_window(&self) -> Result<gtk::ApplicationWindow> {
  339. unimplemented!()
  340. }
  341. fn raw_window_handle(&self) -> Result<raw_window_handle::RawWindowHandle> {
  342. unimplemented!()
  343. }
  344. fn center(&self) -> Result<()> {
  345. Ok(())
  346. }
  347. fn print(&self) -> Result<()> {
  348. Ok(())
  349. }
  350. fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()> {
  351. Ok(())
  352. }
  353. fn create_window(
  354. &mut self,
  355. pending: PendingWindow<T, Self::Runtime>,
  356. ) -> Result<DetachedWindow<T, Self::Runtime>> {
  357. unimplemented!()
  358. }
  359. fn set_resizable(&self, resizable: bool) -> Result<()> {
  360. Ok(())
  361. }
  362. fn set_title<S: Into<String>>(&self, title: S) -> Result<()> {
  363. Ok(())
  364. }
  365. fn maximize(&self) -> Result<()> {
  366. Ok(())
  367. }
  368. fn unmaximize(&self) -> Result<()> {
  369. Ok(())
  370. }
  371. fn minimize(&self) -> Result<()> {
  372. Ok(())
  373. }
  374. fn unminimize(&self) -> Result<()> {
  375. Ok(())
  376. }
  377. fn show_menu(&self) -> Result<()> {
  378. Ok(())
  379. }
  380. fn hide_menu(&self) -> Result<()> {
  381. Ok(())
  382. }
  383. fn show(&self) -> Result<()> {
  384. Ok(())
  385. }
  386. fn hide(&self) -> Result<()> {
  387. Ok(())
  388. }
  389. fn close(&self) -> Result<()> {
  390. Ok(())
  391. }
  392. fn set_decorations(&self, decorations: bool) -> Result<()> {
  393. Ok(())
  394. }
  395. fn set_always_on_top(&self, always_on_top: bool) -> Result<()> {
  396. Ok(())
  397. }
  398. fn set_content_protected(&self, protected: bool) -> Result<()> {
  399. Ok(())
  400. }
  401. fn set_size(&self, size: Size) -> Result<()> {
  402. Ok(())
  403. }
  404. fn set_min_size(&self, size: Option<Size>) -> Result<()> {
  405. Ok(())
  406. }
  407. fn set_max_size(&self, size: Option<Size>) -> Result<()> {
  408. Ok(())
  409. }
  410. fn set_position(&self, position: Position) -> Result<()> {
  411. Ok(())
  412. }
  413. fn set_fullscreen(&self, fullscreen: bool) -> Result<()> {
  414. Ok(())
  415. }
  416. fn set_focus(&self) -> Result<()> {
  417. Ok(())
  418. }
  419. fn set_icon(&self, icon: Icon) -> Result<()> {
  420. Ok(())
  421. }
  422. fn set_skip_taskbar(&self, skip: bool) -> Result<()> {
  423. Ok(())
  424. }
  425. fn set_cursor_grab(&self, grab: bool) -> Result<()> {
  426. Ok(())
  427. }
  428. fn set_cursor_visible(&self, visible: bool) -> Result<()> {
  429. Ok(())
  430. }
  431. fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()> {
  432. Ok(())
  433. }
  434. fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()> {
  435. Ok(())
  436. }
  437. fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()> {
  438. Ok(())
  439. }
  440. fn start_dragging(&self) -> Result<()> {
  441. Ok(())
  442. }
  443. fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
  444. Ok(())
  445. }
  446. fn update_menu_item(&self, id: u16, update: MenuUpdate) -> Result<()> {
  447. Ok(())
  448. }
  449. }
  450. #[cfg(all(desktop, feature = "system-tray"))]
  451. #[derive(Debug, Clone)]
  452. pub struct MockTrayHandler {
  453. context: RuntimeContext,
  454. }
  455. #[cfg(all(desktop, feature = "system-tray"))]
  456. impl TrayHandle for MockTrayHandler {
  457. fn set_icon(&self, icon: Icon) -> Result<()> {
  458. Ok(())
  459. }
  460. fn set_menu(&self, menu: SystemTrayMenu) -> Result<()> {
  461. Ok(())
  462. }
  463. fn update_item(&self, id: u16, update: MenuUpdate) -> Result<()> {
  464. Ok(())
  465. }
  466. #[cfg(target_os = "macos")]
  467. fn set_icon_as_template(&self, is_template: bool) -> Result<()> {
  468. Ok(())
  469. }
  470. #[cfg(target_os = "macos")]
  471. fn set_title(&self, title: &str) -> tauri_runtime::Result<()> {
  472. Ok(())
  473. }
  474. fn destroy(&self) -> Result<()> {
  475. Ok(())
  476. }
  477. }
  478. #[derive(Debug, Clone)]
  479. pub struct EventProxy {}
  480. impl<T: UserEvent> EventLoopProxy<T> for EventProxy {
  481. fn send_event(&self, event: T) -> Result<()> {
  482. Ok(())
  483. }
  484. }
  485. #[derive(Debug)]
  486. pub struct MockRuntime {
  487. pub context: RuntimeContext,
  488. #[cfg(all(desktop, feature = "global-shortcut"))]
  489. global_shortcut_manager: MockGlobalShortcutManager,
  490. #[cfg(feature = "clipboard")]
  491. clipboard_manager: MockClipboardManager,
  492. #[cfg(all(desktop, feature = "system-tray"))]
  493. tray_handler: MockTrayHandler,
  494. }
  495. impl MockRuntime {
  496. fn init() -> Self {
  497. let context = RuntimeContext {
  498. shortcuts: Default::default(),
  499. clipboard: Default::default(),
  500. };
  501. Self {
  502. #[cfg(all(desktop, feature = "global-shortcut"))]
  503. global_shortcut_manager: MockGlobalShortcutManager {
  504. context: context.clone(),
  505. },
  506. #[cfg(feature = "clipboard")]
  507. clipboard_manager: MockClipboardManager {
  508. context: context.clone(),
  509. },
  510. #[cfg(all(desktop, feature = "system-tray"))]
  511. tray_handler: MockTrayHandler {
  512. context: context.clone(),
  513. },
  514. context,
  515. }
  516. }
  517. }
  518. impl<T: UserEvent> Runtime<T> for MockRuntime {
  519. type Dispatcher = MockDispatcher;
  520. type Handle = MockRuntimeHandle;
  521. #[cfg(all(desktop, feature = "global-shortcut"))]
  522. type GlobalShortcutManager = MockGlobalShortcutManager;
  523. #[cfg(feature = "clipboard")]
  524. type ClipboardManager = MockClipboardManager;
  525. #[cfg(all(desktop, feature = "system-tray"))]
  526. type TrayHandler = MockTrayHandler;
  527. type EventLoopProxy = EventProxy;
  528. fn new() -> Result<Self> {
  529. Ok(Self::init())
  530. }
  531. #[cfg(any(windows, target_os = "linux"))]
  532. fn new_any_thread() -> Result<Self> {
  533. Ok(Self::init())
  534. }
  535. fn create_proxy(&self) -> EventProxy {
  536. unimplemented!()
  537. }
  538. fn handle(&self) -> Self::Handle {
  539. MockRuntimeHandle {
  540. context: self.context.clone(),
  541. }
  542. }
  543. #[cfg(all(desktop, feature = "global-shortcut"))]
  544. fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager {
  545. self.global_shortcut_manager.clone()
  546. }
  547. #[cfg(feature = "clipboard")]
  548. fn clipboard_manager(&self) -> Self::ClipboardManager {
  549. self.clipboard_manager.clone()
  550. }
  551. fn create_window(&self, pending: PendingWindow<T, Self>) -> Result<DetachedWindow<T, Self>> {
  552. Ok(DetachedWindow {
  553. label: pending.label,
  554. dispatcher: MockDispatcher {
  555. context: self.context.clone(),
  556. },
  557. menu_ids: Default::default(),
  558. js_event_listeners: Default::default(),
  559. })
  560. }
  561. #[cfg(all(desktop, feature = "system-tray"))]
  562. #[cfg_attr(doc_cfg, doc(cfg(feature = "system-tray")))]
  563. fn system_tray(&self, system_tray: SystemTray) -> Result<Self::TrayHandler> {
  564. Ok(self.tray_handler.clone())
  565. }
  566. #[cfg(all(desktop, feature = "system-tray"))]
  567. #[cfg_attr(doc_cfg, doc(cfg(feature = "system-tray")))]
  568. fn on_system_tray_event<F: Fn(TrayId, &SystemTrayEvent) + Send + 'static>(&mut self, f: F) {}
  569. #[cfg(target_os = "macos")]
  570. #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))]
  571. fn set_activation_policy(&mut self, activation_policy: tauri_runtime::ActivationPolicy) {}
  572. #[cfg(target_os = "macos")]
  573. #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))]
  574. fn show(&self) {}
  575. #[cfg(target_os = "macos")]
  576. #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))]
  577. fn hide(&self) {}
  578. fn set_device_event_filter(&mut self, filter: DeviceEventFilter) {}
  579. #[cfg(any(
  580. target_os = "macos",
  581. windows,
  582. target_os = "linux",
  583. target_os = "dragonfly",
  584. target_os = "freebsd",
  585. target_os = "netbsd",
  586. target_os = "openbsd"
  587. ))]
  588. fn run_iteration<F: Fn(RunEvent<T>) + 'static>(
  589. &mut self,
  590. callback: F,
  591. ) -> tauri_runtime::RunIteration {
  592. Default::default()
  593. }
  594. fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) {
  595. loop {
  596. std::thread::sleep(std::time::Duration::from_secs(1));
  597. }
  598. }
  599. }