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 = include_str!("../docs/entry.md")]
8#![warn(missing_docs)]
9mod configure;
10#[cfg(docsrs)]
11mod dummy_skia_docs;
12mod event_macros;
13pub mod forge;
14#[cfg(feature = "i-slint-renderer-skia")]
15#[cfg(not(docsrs))]
16#[doc(hidden)]
17mod skia_non_docs;
18pub mod slint_adapter;
19pub mod vault;
20pub mod wayland_adapter;
21/// It contains related enums and struct which are used to manage,
22/// define and update various properties of a widget(viz a viz layer). You can import necessary
23/// types from this module to implement relevant features. See docs of related objects for
24/// their overview.
25pub mod layer_properties {
26    pub use crate::configure::{WindowConf, WindowConfBuilder};
27    pub use smithay_client_toolkit::shell::wlr_layer::Anchor as LayerAnchor;
28    pub use smithay_client_toolkit::shell::wlr_layer::KeyboardInteractivity as BoardType;
29    pub use smithay_client_toolkit::shell::wlr_layer::Layer as LayerType;
30}
31/// Components of this module are not be used by end user directly. This module contains
32/// certain reexports used by public facing macros like [cast_spell] and [generate_widgets]
33/// internally.
34pub mod macro_internal {
35    pub use crate::vault::set_notification;
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(&self, key: &str, val: &str);
53
54    /// This method is invoked is neither update nor look is called. Can be used to perform custom
55    /// operations.
56    fn custom_command(&self, _command: &str) {}
57}
58
59/// This is an internal trait implemented by objects generated from [`generate_widgets`].
60/// It helps in running every SpellWidget (like [SpellWin](`wayland_adapter::SpellWin`),
61/// [SpellLock](`wayland_adapter::SpellLock`)) through the same event_loop function.
62pub trait SpellAssociatedNew: std::fmt::Debug {
63    /// Internal method used to call to update UI in a loop.
64    fn on_call(&mut self) -> Result<(), Box<dyn Error>>;
65
66    /// Internal method used to retrive logging span of a window.
67    fn get_span(&self) -> span::Span {
68        span!(Level::INFO, "unnamed-widget")
69    }
70
71    /// Internal method used to specify when to eliminate the event loop.
72    fn is_locked(&self) -> bool {
73        true
74    }
75}
76
77/// event loop function internally used by [`cast_spell`] for single widget setups.
78/// Not to be used by end user,
79pub fn cast_spell_inner<S: SpellAssociatedNew>(mut waywindow: S) -> Result<(), Box<dyn Error>> {
80    let span = waywindow.get_span();
81    let _gaurd = span.enter();
82    trace!("{:?}", &waywindow);
83    while waywindow.is_locked() {
84        waywindow.on_call()?
85    }
86    Ok(())
87}
88
89/// event loop function internally used by [`cast_spell`] for multiple widget setups.
90/// Not to be used by end user.
91pub fn cast_spells_new(
92    mut windows: Vec<Box<dyn SpellAssociatedNew>>,
93) -> Result<(), Box<dyn Error>> {
94    loop {
95        for win in windows.iter_mut() {
96            let span = win.get_span().clone();
97            let _gaurd = span.enter();
98            win.on_call()?;
99        }
100    }
101}
102
103// TODO Update docs of spellock and spellwin to justify their use being purely internal.
104// TODO update the blog with latest API changes in spell-framework.
105// TODO update the constant vals so that the new APIs are used.
106// TODO and configuration file to ensure that a single widget is open for a single layer name.
107// TODO IMPORTANT LOGGING SUBSCRIBER LOGIC NEEDS TO BE UNIFIED AND NOT WINDOW SPECIFIC.
108// TODO it is necessary to call join unwrap on spawned threads to ensure
109// that they are closed when main thread closes.
110// TODO linux's DNF Buffers needs to be used to improve rendering and avoid conversions
111// from CPU to GPU and vice versa.
112// TO REMEMBER I removed dirty region from spellskiawinadapter but it can be added
113// if I want to make use of the dirty region information to strengthen my rendering.
114// TODO lock screen behaviour in a multi-monitor setup needs to be tested.
115// Provide a method in the macro to disable tracing_subsriber completely for some project
116// which want's to do it themselves.
117// cast spell macro should be having following values.
118// 1. Disable log: should disable setting subscriber, generally for the project to use or for
119// someone to set their own.
120// 2. forge: provide a forge instance to run independently.
121// 3. exclusive_zone: true or false or with specified value.
122// 4. it should have the option to take a window_conf or directly the window configurations
123// into the macro, removing the need to define it previously.
124// 5. monitor: Specify the monitor to show the widget in.
125// Build a consistent error type to deal with CLI, dbus and window creation errors