mock_runtime.rs 14 KB

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