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