freya_winit/
tray_icon.rs

1use std::borrow::Cow;
2
3use freya_core::prelude::ScreenReader;
4use freya_engine::prelude::{
5    FontCollection,
6    FontMgr,
7};
8use rustc_hash::FxHashMap;
9use tray_icon::{
10    TrayIconEvent,
11    menu::MenuEvent,
12};
13use winit::{
14    event_loop::{
15        ActiveEventLoop,
16        EventLoopProxy,
17    },
18    window::WindowId,
19};
20
21use crate::{
22    config::{
23        TrayHandler,
24        WindowConfig,
25    },
26    plugins::PluginsManager,
27    renderer::{
28        NativeEvent,
29        NativeWindowEvent,
30        NativeWindowEventAction,
31        WinitRenderer,
32    },
33    window::AppWindow,
34};
35
36#[derive(Clone, Debug)]
37pub enum TrayEvent {
38    Icon(TrayIconEvent),
39    Menu(MenuEvent),
40}
41
42pub struct TrayContext<'a> {
43    pub windows: &'a mut FxHashMap<WindowId, AppWindow>,
44    pub proxy: &'a mut EventLoopProxy<NativeEvent>,
45    pub plugins: &'a mut PluginsManager,
46    pub fallback_fonts: &'a mut Vec<Cow<'static, str>>,
47    pub screen_reader: &'a mut ScreenReader,
48    pub font_manager: &'a mut FontMgr,
49    pub font_collection: &'a mut FontCollection,
50    pub(crate) active_event_loop: &'a ActiveEventLoop,
51}
52
53impl<'a> TrayContext<'a> {
54    pub fn new(
55        active_event_loop: &'a ActiveEventLoop,
56        renderer: &'a mut WinitRenderer,
57    ) -> Option<(Self, &'a mut TrayHandler)> {
58        let tray_handler = renderer.tray.1.as_mut()?;
59
60        let context = TrayContext {
61            active_event_loop,
62            windows: &mut renderer.windows,
63            proxy: &mut renderer.proxy,
64            plugins: &mut renderer.plugins,
65            fallback_fonts: &mut renderer.fallback_fonts,
66            screen_reader: &mut renderer.screen_reader,
67            font_manager: &mut renderer.font_manager,
68            font_collection: &mut renderer.font_collection,
69        };
70
71        Some((context, tray_handler))
72    }
73}
74
75impl TrayContext<'_> {
76    pub fn launch_window(&mut self, window_config: WindowConfig) -> WindowId {
77        let app_window = AppWindow::new(
78            window_config,
79            self.active_event_loop,
80            self.proxy,
81            self.plugins,
82            self.font_collection,
83            self.font_manager,
84            self.fallback_fonts,
85            self.screen_reader.clone(),
86        );
87
88        let window_id = app_window.window.id();
89
90        self.proxy
91            .send_event(NativeEvent::Window(NativeWindowEvent {
92                window_id,
93                action: NativeWindowEventAction::PollRunner,
94            }))
95            .ok();
96
97        self.windows.insert(window_id, app_window);
98
99        window_id
100    }
101
102    pub fn windows(&self) -> &FxHashMap<WindowId, AppWindow> {
103        self.windows
104    }
105
106    pub fn windows_mut(&mut self) -> &mut FxHashMap<WindowId, AppWindow> {
107        self.windows
108    }
109
110    pub fn exit(&mut self) {
111        self.active_event_loop.exit();
112    }
113}