client.rs

 1use std::cell::RefCell;
 2use std::ops::Deref;
 3use std::rc::Rc;
 4use std::time::{Duration, Instant};
 5
 6use calloop::{EventLoop, LoopHandle};
 7use collections::HashMap;
 8
 9use util::ResultExt;
10
11use crate::platform::linux::LinuxClient;
12use crate::platform::{LinuxCommon, PlatformWindow};
13use crate::{
14    px, AnyWindowHandle, Bounds, CursorStyle, DisplayId, Modifiers, ModifiersChangedEvent, Pixels,
15    PlatformDisplay, PlatformInput, Point, ScrollDelta, Size, TouchPhase, WindowParams,
16};
17
18use calloop::{
19    generic::{FdWrapper, Generic},
20    RegistrationToken,
21};
22
23pub struct HeadlessClientState {
24    pub(crate) loop_handle: LoopHandle<'static, HeadlessClient>,
25    pub(crate) event_loop: Option<calloop::EventLoop<'static, HeadlessClient>>,
26    pub(crate) common: LinuxCommon,
27}
28
29#[derive(Clone)]
30pub(crate) struct HeadlessClient(Rc<RefCell<HeadlessClientState>>);
31
32impl HeadlessClient {
33    pub(crate) fn new() -> Self {
34        let event_loop = EventLoop::try_new().unwrap();
35
36        let (common, main_receiver) = LinuxCommon::new(event_loop.get_signal());
37
38        let handle = event_loop.handle();
39
40        handle.insert_source(main_receiver, |event, _, _: &mut HeadlessClient| {
41            if let calloop::channel::Event::Msg(runnable) = event {
42                runnable.run();
43            }
44        });
45
46        HeadlessClient(Rc::new(RefCell::new(HeadlessClientState {
47            event_loop: Some(event_loop),
48            loop_handle: handle,
49            common,
50        })))
51    }
52}
53
54impl LinuxClient for HeadlessClient {
55    fn with_common<R>(&self, f: impl FnOnce(&mut LinuxCommon) -> R) -> R {
56        f(&mut self.0.borrow_mut().common)
57    }
58
59    fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>> {
60        vec![]
61    }
62
63    fn primary_display(&self) -> Option<Rc<dyn PlatformDisplay>> {
64        None
65    }
66
67    fn display(&self, id: DisplayId) -> Option<Rc<dyn PlatformDisplay>> {
68        None
69    }
70
71    fn open_window(
72        &self,
73        _handle: AnyWindowHandle,
74        params: WindowParams,
75    ) -> Box<dyn PlatformWindow> {
76        unimplemented!()
77    }
78
79    //todo(linux)
80    fn set_cursor_style(&self, _style: CursorStyle) {}
81
82    fn write_to_clipboard(&self, item: crate::ClipboardItem) {}
83
84    fn read_from_clipboard(&self) -> Option<crate::ClipboardItem> {
85        None
86    }
87
88    fn run(&self) {
89        let mut event_loop = self
90            .0
91            .borrow_mut()
92            .event_loop
93            .take()
94            .expect("App is already running");
95
96        event_loop.run(None, &mut self.clone(), |_| {}).log_err();
97    }
98}