Skip to repository content144 lines · 4.1 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T04:59:32.719Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
client.rs
1use std::cell::RefCell;
2use std::rc::Rc;
3
4use calloop::{EventLoop, LoopHandle};
5use gpui_util::ResultExt;
6
7use crate::linux::headless::window::{HeadlessDisplay, HeadlessWindow};
8use crate::linux::{LinuxClient, LinuxCommon, LinuxKeyboardLayout};
9use gpui::{
10 AnyWindowHandle, CursorStyle, DisplayId, PlatformDisplay, PlatformKeyboardLayout,
11 PlatformWindow, WindowParams,
12};
13
14pub struct HeadlessClientState {
15 pub(crate) _loop_handle: LoopHandle<'static, HeadlessClient>,
16 pub(crate) event_loop: Option<calloop::EventLoop<'static, HeadlessClient>>,
17 pub(crate) common: LinuxCommon,
18 pub(crate) display: Rc<dyn PlatformDisplay>,
19}
20
21#[derive(Clone)]
22pub(crate) struct HeadlessClient(Rc<RefCell<HeadlessClientState>>);
23
24impl HeadlessClient {
25 pub(crate) fn new() -> Self {
26 let event_loop = EventLoop::try_new().unwrap();
27
28 let (common, main_receiver, wake_receiver) = LinuxCommon::new(event_loop.get_signal());
29
30 let handle = event_loop.handle();
31
32 handle
33 .insert_source(main_receiver, |event, _, _: &mut HeadlessClient| {
34 if let calloop::channel::Event::Msg(runnable) = event {
35 runnable.run();
36 }
37 })
38 .ok();
39
40 handle
41 .insert_source(wake_receiver, |event, _, client: &mut HeadlessClient| {
42 if let calloop::channel::Event::Msg(()) = event {
43 client.with_common(|common| common.handle_system_wake());
44 }
45 })
46 .ok();
47
48 HeadlessClient(Rc::new(RefCell::new(HeadlessClientState {
49 event_loop: Some(event_loop),
50 _loop_handle: handle,
51 common,
52 display: Rc::new(HeadlessDisplay::new()),
53 })))
54 }
55}
56
57impl LinuxClient for HeadlessClient {
58 fn with_common<R>(&self, f: impl FnOnce(&mut LinuxCommon) -> R) -> R {
59 f(&mut self.0.borrow_mut().common)
60 }
61
62 fn keyboard_layout(&self) -> Box<dyn PlatformKeyboardLayout> {
63 Box::new(LinuxKeyboardLayout::new("unknown".into()))
64 }
65
66 fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>> {
67 vec![self.0.borrow().display.clone()]
68 }
69
70 fn primary_display(&self) -> Option<Rc<dyn PlatformDisplay>> {
71 Some(self.0.borrow().display.clone())
72 }
73
74 fn display(&self, id: DisplayId) -> Option<Rc<dyn PlatformDisplay>> {
75 let display = self.0.borrow().display.clone();
76 (display.id() == id).then_some(display)
77 }
78
79 #[cfg(feature = "screen-capture")]
80 fn screen_capture_sources(
81 &self,
82 ) -> futures::channel::oneshot::Receiver<anyhow::Result<Vec<Rc<dyn gpui::ScreenCaptureSource>>>>
83 {
84 let (tx, rx) = futures::channel::oneshot::channel();
85 tx.send(Err(anyhow::anyhow!(
86 "Headless mode does not support screen capture."
87 )))
88 .ok();
89 rx
90 }
91
92 fn active_window(&self) -> Option<AnyWindowHandle> {
93 None
94 }
95
96 fn window_stack(&self) -> Option<Vec<AnyWindowHandle>> {
97 None
98 }
99
100 fn open_window(
101 &self,
102 _handle: AnyWindowHandle,
103 params: WindowParams,
104 ) -> anyhow::Result<Box<dyn PlatformWindow>> {
105 Ok(Box::new(HeadlessWindow::new(
106 params,
107 self.0.borrow().display.clone(),
108 )))
109 }
110
111 fn compositor_name(&self) -> &'static str {
112 "headless"
113 }
114
115 fn set_cursor_style(&self, _style: CursorStyle) {}
116
117 fn open_uri(&self, _uri: &str) {}
118
119 fn reveal_path(&self, _path: std::path::PathBuf) {}
120
121 fn write_to_primary(&self, _item: gpui::ClipboardItem) {}
122
123 fn write_to_clipboard(&self, _item: gpui::ClipboardItem) {}
124
125 fn read_from_primary(&self) -> Option<gpui::ClipboardItem> {
126 None
127 }
128
129 fn read_from_clipboard(&self) -> Option<gpui::ClipboardItem> {
130 None
131 }
132
133 fn run(&self) {
134 let mut event_loop = self
135 .0
136 .borrow_mut()
137 .event_loop
138 .take()
139 .expect("App is already running");
140
141 event_loop.run(None, &mut self.clone(), |_| {}).log_err();
142 }
143}
144