Skip to main content

halley_ipc/
types.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub struct OutputsResponse {
5    pub outputs: Vec<OutputInfo>,
6}
7
8#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
9#[serde(rename_all = "kebab-case")]
10pub enum ApertureMode {
11    Normal,
12    Collapsed,
13    Hidden,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct ApertureStatusResponse {
18    pub output: Option<String>,
19    pub mode: ApertureMode,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct OutputInfo {
24    pub name: String,
25    pub status: OutputStatus,
26    pub enabled: bool,
27    pub current_mode: Option<ModeInfo>,
28    pub modes: Vec<ModeInfo>,
29    pub vrr_mode: Option<String>,
30    pub vrr_support: Option<String>,
31    pub direct_scanout_candidate_node: Option<u64>,
32    pub direct_scanout_active_node: Option<u64>,
33    pub direct_scanout_reason: Option<String>,
34    pub logical: Option<LogicalOutputInfo>,
35}
36
37#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
38pub enum OutputStatus {
39    Connected,
40    Disconnected,
41    Unknown,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct ModeInfo {
46    pub width: u32,
47    pub height: u32,
48    pub refresh_hz: Option<f64>,
49    pub preferred: bool,
50    pub current: bool,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct LogicalOutputInfo {
55    pub scale: f64,
56    pub focused: bool,
57    pub offset_x: i32,
58    pub offset_y: i32,
59}
60
61#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
62pub enum NodeKind {
63    Surface,
64    Core,
65}
66
67#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
68pub enum NodeState {
69    Active,
70    Drifting,
71    Node,
72    Core,
73}
74
75#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
76#[serde(rename_all = "kebab-case")]
77pub enum NodeRole {
78    NormalToplevel,
79    Dialog,
80    Popup,
81    Unknown,
82}
83
84#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
85#[serde(rename_all = "kebab-case")]
86pub enum NodeProtocolFamily {
87    XdgToplevel,
88    XdgPopup,
89    Xwayland,
90    Unknown,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
94pub struct NodeRelationInfo {
95    pub node_id: Option<u64>,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct NodeInfo {
100    /// Stable session-scoped node id. Halley does not recycle node ids during
101    /// a compositor run, so scripts can safely correlate parent/transient
102    /// relationships against this handle.
103    pub id: u64,
104    pub title: String,
105    pub app_id: Option<String>,
106    pub output: Option<String>,
107    pub kind: NodeKind,
108    pub state: NodeState,
109    pub visible: bool,
110    pub focused: bool,
111    pub latest: bool,
112    pub role: NodeRole,
113    pub protocol_family: NodeProtocolFamily,
114    pub modal: bool,
115    pub parent: Option<NodeRelationInfo>,
116    pub transient_for: Option<NodeRelationInfo>,
117    pub child_popup_count: usize,
118    pub pos_x: f32,
119    pub pos_y: f32,
120    pub width: f32,
121    pub height: f32,
122}
123
124#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
125#[serde(rename_all = "kebab-case")]
126pub enum ClusterLayoutKind {
127    Tiling,
128    Stacking,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct ClusterSummary {
133    pub id: u64,
134    pub slot: Option<u8>,
135    pub name: Option<String>,
136    pub output: Option<String>,
137    pub layout: ClusterLayoutKind,
138    pub member_count: usize,
139    pub active: bool,
140    pub focused: bool,
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct ClusterOutputGroup {
145    pub output: String,
146    pub clusters: Vec<ClusterSummary>,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct ClusterListResponse {
151    pub outputs: Vec<ClusterOutputGroup>,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize)]
155pub struct ClusterInfo {
156    pub id: u64,
157    pub slot: Option<u8>,
158    pub name: Option<String>,
159    pub output: Option<String>,
160    pub layout: ClusterLayoutKind,
161    pub member_count: usize,
162    pub active: bool,
163    pub focused: bool,
164    pub focused_member_index: Option<usize>,
165    pub focused_member_id: Option<u64>,
166    pub members: Vec<NodeInfo>,
167}
168
169#[derive(Debug, Clone, Serialize, Deserialize)]
170pub struct NodeOutputGroup {
171    pub output: String,
172    pub nodes: Vec<NodeInfo>,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct NodeListResponse {
177    pub outputs: Vec<NodeOutputGroup>,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct TrailEntryInfo {
182    pub index: usize,
183    pub cursor: bool,
184    pub node: NodeInfo,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize)]
188pub struct TrailListResponse {
189    pub output: String,
190    pub entries: Vec<TrailEntryInfo>,
191    pub cursor_index: Option<usize>,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
195pub struct BearingsStatusResponse {
196    pub visible: bool,
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct CaptureStatusResponse {
201    pub active: bool,
202    pub session_serial: Option<u64>,
203    pub last_finished_serial: Option<u64>,
204    pub saved_path: Option<String>,
205    pub error: Option<String>,
206}
207
208impl ModeInfo {
209    pub fn display_string(&self) -> String {
210        match self.refresh_hz {
211            Some(hz) => format!("{}x{} @ {:.2}Hz", self.width, self.height, hz),
212            None => format!("{}x{}", self.width, self.height),
213        }
214    }
215}