tauri_nspanel/
lib.rs

1mod macros;
2pub mod raw_nspanel;
3
4use std::{collections::HashMap, sync::Mutex};
5
6use cocoa::base::id;
7use objc_id::ShareId;
8use raw_nspanel::RawNSPanel;
9use tauri::{
10    plugin::{Builder, TauriPlugin},
11    Manager, Runtime, WebviewWindow,
12};
13
14pub extern crate block;
15pub extern crate cocoa;
16pub extern crate objc;
17pub extern crate objc_foundation;
18pub extern crate objc_id;
19pub extern crate tauri;
20
21pub type Panel = ShareId<RawNSPanel>;
22
23#[derive(Default)]
24pub struct Store {
25    panels: HashMap<String, ShareId<RawNSPanel>>,
26}
27
28pub struct WebviewPanelManager(pub Mutex<Store>);
29
30impl Default for WebviewPanelManager {
31    fn default() -> Self {
32        Self(Mutex::new(Store::default()))
33    }
34}
35
36pub trait ManagerExt<R: Runtime> {
37    fn get_webview_panel(&self, label: &str) -> Result<ShareId<RawNSPanel>, Error>;
38}
39
40#[derive(Debug)]
41pub enum Error {
42    PanelNotFound,
43}
44
45impl<R: Runtime, T: Manager<R>> ManagerExt<R> for T {
46    fn get_webview_panel(&self, label: &str) -> Result<ShareId<RawNSPanel>, Error> {
47        let manager = self.state::<self::WebviewPanelManager>();
48        let manager = manager.0.lock().unwrap();
49
50        match manager.panels.get(label) {
51            Some(panel) => Ok(panel.clone()),
52            None => Err(Error::PanelNotFound),
53        }
54    }
55}
56
57#[derive(Default)]
58pub struct WebviewPanelConfig {
59    pub delegate: Option<id>,
60}
61
62pub trait WebviewWindowExt<R: Runtime> {
63    fn to_panel(&self) -> tauri::Result<ShareId<RawNSPanel>>;
64}
65
66impl<R: Runtime> WebviewWindowExt<R> for WebviewWindow<R> {
67    fn to_panel(&self) -> tauri::Result<ShareId<RawNSPanel>> {
68        let panel = RawNSPanel::from_window(self.to_owned());
69        let shared_panel = panel.share();
70        let manager = self.state::<self::WebviewPanelManager>();
71
72        manager
73            .0
74            .lock()
75            .unwrap()
76            .panels
77            .insert(self.label().into(), shared_panel.clone());
78
79        Ok(shared_panel)
80    }
81}
82
83/// Initializes the plugin.
84pub fn init<R: Runtime>() -> TauriPlugin<R> {
85    Builder::new("nspanel")
86        .setup(|app, _api| {
87            app.manage(self::WebviewPanelManager::default());
88
89            Ok(())
90        })
91        .build()
92}