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.