mock_runtime.rs 12 KB

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