Skip to main content

spell_framework/
lib.rs

1#![doc(
2    html_logo_url = "https://raw.githubusercontent.com/VimYoung/Spell/main/spell-framework/assets/spell_trans.png"
3)]
4#![doc(
5    html_favicon_url = "https://raw.githubusercontent.com/VimYoung/Spell/main/spell-framework/assets/spell_trans.ico"
6)]
7// #![doc(html_favicon_url = "https://github.com/VimYoung/Spell/blob/bb01ae94a365d237ebb0db1df1b6eb37aea25367/spell-framework/assets/Spell.png")]
8#![doc = include_str!("../docs/entry.md")]
9#![warn(missing_docs)]
10mod configure;
11#[cfg(docsrs)]
12mod dummy_skia_docs;
13mod event_macros;
14pub mod forge;
15#[cfg(feature = "i-slint-renderer-skia")]
16#[cfg(not(docsrs))]
17#[doc(hidden)]
18mod skia_non_docs;
19pub mod slint_adapter;
20pub mod vault;
21pub mod wayland_adapter;
22/// It contains related enums and struct which are used to manage,
23/// define and update various properties of a widget(viz a viz layer). You can import necessary
24/// types from this module to implement relevant features. See docs of related objects for
25/// their overview.
26pub mod layer_properties {
27    pub use crate::configure::{WindowConf, WindowConfBuilder};
28    pub use smithay_client_toolkit::shell::wlr_layer::Anchor as LayerAnchor;
29    pub use smithay_client_toolkit::shell::wlr_layer::KeyboardInteractivity as BoardType;
30    pub use smithay_client_toolkit::shell::wlr_layer::Layer as LayerType;
31}
32/// Components of this module are not be used by end user directly. This module contains
33/// certain reexports used by public facing macros like [cast_spell] and [generate_widgets]
34/// internally.
35pub mod macro_internal {
36    pub use paste::paste;
37    pub use smithay_client_toolkit::reexports::calloop::{
38        Interest, Mode, PostAction, generic::Generic,
39    };
40    pub use tracing::{info, span::Span, warn};
41}
42use std::error::Error;
43use tracing::{Level, span, trace};
44
45/// This trait is implemented upon slint generated windows to enable IPC handling
46pub trait IpcController {
47    /// On calling `spell-cli -l layer_name look
48    /// var_name`, the cli calls `get_type` method of the trait with `var_name` as input.
49    fn get_type(&self, key: &str) -> String;
50    /// It is called on `spell-cli -l layer_name update key value`. `as_any` is for syncing the changes
51    /// internally for now and need not be implemented by the end user.
52    fn change_val(&mut self, key: &str, val: &str);
53}
54
55/// This is an internal trait implemented by objects generated from [`generate_widgets`].
56/// It helps in running every SpellWidget (like [SpellWin](`wayland_adapter::SpellWin`),
57/// [SpellLock](`wayland_adapter::SpellLock`)) through the same event_loop function.
58pub trait SpellAssociatedNew: std::fmt::Debug {
59    /// Internal method used to call to update UI in a loop.
60    fn on_call(&mut self) -> Result<(), Box<dyn Error>>;
61
62    /// Internal method used to retrive logging span of a window.
63    fn get_span(&self) -> span::Span {
64        span!(Level::INFO, "unnamed-widget")
65    }
66
67    /// Internal method used to specify when to eliminate the event loop.
68    fn is_locked(&self) -> bool {
69        true
70    }
71}
72
73/// event loop function internally used by [`cast_spell`] for single widget setups.
74/// Not to be used by end user,
75pub fn cast_spell_inner<S: SpellAssociatedNew>(mut waywindow: S) -> Result<(), Box<dyn Error>> {
76    let span = waywindow.get_span();
77    let _gaurd = span.enter();
78    trace!("{:?}", &waywindow);
79    while waywindow.is_locked() {
80        waywindow.on_call()?
81    }
82    Ok(())
83}
84
85/// event loop function internally used by [`cast_spell`] for multiple widget setups.
86/// Not to be used by end user.
87pub fn cast_spells_new(
88    mut windows: Vec<Box<dyn SpellAssociatedNew>>,
89) -> Result<(), Box<dyn Error>> {
90    loop {
91        for win in windows.iter_mut() {
92            let span = win.get_span().clone();
93            let _gaurd = span.enter();
94            win.on_call()?;
95        }
96    }
97}
98
99// TODO Update docs of spellock and spellwin to justify their use being purely internal.
100// TODO update the blog with latest API changes in spell-framework.
101// TODO update the constant vals so that the new APIs are used.
102// TODO and configuration file to ensure that a single widget is open for a single layer name.
103// TODO IMPORTANT LOGGING SUBSCRIBER LOGIC NEEDS TO BE UNIFIED AND NOT WINDOW SPECIFIC.
104// Code to launch a Zbus service
105// <BS>
106// pub async fn deploy_zbus_service(
107//     state: State,
108//     state_updater: Sender<InternalHandle>,
109//     layer_name: String,
110// ) -> zbus::Result<()> {
111//     let connection = BusConn::session().await.unwrap();
112//     connection
113//         .object_server()
114//         .at(
115//             "/org/VimYoung/VarHandler",
116//             VarHandler {
117//                 state: state.clone(),
118//                 state_updater: state_updater.clone(),
119//                 layer_name: layer_name.clone(),
120//             },
121//         )
122//         .await?;
123//     trace!("Object server set up");
124//     // connection.request_name("org.VimYoung.Spell").await?;
125//     // open_sec_service(state, state_updater, layer_name).await?;
126//     if let Err(err) = connection
127//         .request_name_with_flags("org.VimYoung.Spell", RequestNameFlags::DoNotQueue.into())
128//         .await
129//     {
130//         open_sec_service(state, state_updater, layer_name).await?;
131//         info!("Successfully created secondary service, Error: {}", err);
132//     } else {
133//         info!("Successfully created main service");
134//     }
135//     std::future::pending::<()>().await;
136//     Ok(())
137// }
138// Macro on top of VarHandler impl.
139// #[interface(name = "org.VimYoung.Spell1", proxy(gen_blocking = false,))]
140// TODO it is necessary to call join unwrap on spawned threads to ensure
141// that they are closed when main thread closes.
142// TODO linux's DNF Buffers needs to be used to improve rendering and avoid conversions
143// from CPU to GPU and vice versa.
144// TO REMEMBER I removed dirty region from spellskiawinadapter but it can be added
145// if I want to make use of the dirty region information to strengthen my rendering.
146// TODO lock screen behaviour in a multi-monitor setup needs to be tested.
147// TODO implement logging for SpellLock.
148// Provide a method in the macro to disable tracing_subsriber completely for some project
149// which want's to do it themselves.
150// cast spell macro should be having following values.
151// 1. Disable log: should disable setting subscriber, generally for the project to use or for
152// someone to set their own.
153// 2. forge: provide a forge instance to run independently.
154// 3. exclusive_zone: true or false or with specified value.
155// 4. it should have the option to take a window_conf or directly the window configurations
156// into the macro, removing the need to define it previously.
157// 5. monitor: Specify the monitor to show the widget in.
158// Also, a procedural macro to mimic the functionalities of ForeignController.
159// Build a consistent error type to deal with CLI, dbus and window creation errors
160// (including window conf) more gracefully.