freya_winit/
lib.rs

1pub mod reexports {
2    pub use winit;
3}
4
5use std::sync::Arc;
6
7use crate::{
8    config::LaunchConfig,
9    renderer::{
10        NativeEvent,
11        NativeGenericEvent,
12        WinitRenderer,
13    },
14};
15mod accessibility;
16pub mod config;
17mod drivers;
18pub mod extensions;
19pub mod plugins;
20pub mod renderer;
21#[cfg(feature = "tray")]
22mod tray_icon;
23mod window;
24mod winit_mappings;
25
26pub use extensions::*;
27use futures_util::task::{
28    ArcWake,
29    waker,
30};
31
32use crate::winit::event_loop::EventLoopProxy;
33
34pub mod winit {
35    pub use winit::*;
36}
37
38#[cfg(feature = "tray")]
39pub mod tray {
40    pub use tray_icon::*;
41
42    pub use crate::tray_icon::*;
43}
44
45pub fn launch(launch_config: LaunchConfig) {
46    use std::collections::HashMap;
47
48    use freya_core::integration::*;
49    use freya_engine::prelude::{
50        FontCollection,
51        FontMgr,
52        TypefaceFontProvider,
53    };
54    use winit::event_loop::EventLoop;
55
56    let mut event_loop_builder = EventLoop::<NativeEvent>::with_user_event();
57
58    let event_loop = event_loop_builder
59        .build()
60        .expect("Failed to create event loop.");
61
62    let proxy = event_loop.create_proxy();
63
64    let mut font_collection = FontCollection::new();
65    let def_mgr = FontMgr::default();
66    let mut provider = TypefaceFontProvider::new();
67    for (font_name, font_data) in launch_config.embedded_fonts {
68        let ft_type = def_mgr
69            .new_from_data(&font_data, None)
70            .unwrap_or_else(|| panic!("Failed to load font {font_name}."));
71        provider.register_typeface(ft_type, Some(font_name.as_ref()));
72    }
73    let font_mgr: FontMgr = provider.into();
74    font_collection.set_default_font_manager(def_mgr, None);
75    font_collection.set_dynamic_font_manager(font_mgr.clone());
76    font_collection.paragraph_cache_mut().turn_on(false);
77
78    let screen_reader = ScreenReader::new();
79
80    struct FuturesWaker(EventLoopProxy<NativeEvent>);
81
82    impl ArcWake for FuturesWaker {
83        fn wake_by_ref(arc_self: &Arc<Self>) {
84            _ = arc_self
85                .0
86                .send_event(NativeEvent::Generic(NativeGenericEvent::PollFutures));
87        }
88    }
89
90    let waker = waker(Arc::new(FuturesWaker(proxy.clone())));
91
92    let mut renderer = WinitRenderer {
93        windows: HashMap::default(),
94        #[cfg(feature = "tray")]
95        tray: launch_config.tray,
96        resumed: false,
97        proxy,
98        font_manager: font_mgr,
99        font_collection,
100        windows_configs: launch_config.windows_configs,
101        plugins: launch_config.plugins,
102        fallback_fonts: launch_config.fallback_fonts,
103        screen_reader,
104        futures: launch_config.futures,
105        waker,
106    };
107
108    #[cfg(feature = "tray")]
109    {
110        use crate::{
111            renderer::{
112                NativeTrayEvent,
113                NativeTrayEventAction,
114            },
115            tray::{
116                TrayIconEvent,
117                menu::MenuEvent,
118            },
119        };
120
121        let proxy = renderer.proxy.clone();
122        MenuEvent::set_event_handler(Some(move |event| {
123            let _ = proxy.send_event(NativeEvent::Tray(NativeTrayEvent {
124                action: NativeTrayEventAction::MenuEvent(event),
125            }));
126        }));
127        let proxy = renderer.proxy.clone();
128        TrayIconEvent::set_event_handler(Some(move |event| {
129            let _ = proxy.send_event(NativeEvent::Tray(NativeTrayEvent {
130                action: NativeTrayEventAction::TrayEvent(event),
131            }));
132        }));
133
134        #[cfg(target_os = "linux")]
135        if let Some(tray_icon) = renderer.tray.0.take() {
136            std::thread::spawn(move || {
137                gtk::init().expect("Failed to initialize GTK for the Tray Icon.");
138
139                let _tray_icon = (tray_icon)();
140
141                gtk::main();
142            });
143        }
144    }
145
146    event_loop.run_app(&mut renderer).unwrap();
147}