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 name: Option<String>,
135    pub output: Option<String>,
136    pub layout: ClusterLayoutKind,
137    pub member_count: usize,
138    pub active: bool,
139    pub focused: bool,
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct ClusterOutputGroup {
144    pub output: String,
145    pub clusters: Vec<ClusterSummary>,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct ClusterListResponse {
150    pub outputs: Vec<ClusterOutputGroup>,
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct ClusterInfo {
155    pub id: u64,
156    pub name: Option<String>,
157    pub output: Option<String>,
158    pub layout: ClusterLayoutKind,
159    pub member_count: usize,
160    pub active: bool,
161    pub focused: bool,
162    pub focused_member_index: Option<usize>,
163    pub focused_member_id: Option<u64>,
164    pub members: Vec<NodeInfo>,
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct NodeOutputGroup {
169    pub output: String,
170    pub nodes: Vec<NodeInfo>,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize)]
174pub struct NodeListResponse {
175    pub outputs: Vec<NodeOutputGroup>,
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize)]
179pub struct TrailEntryInfo {
180    pub index: usize,
181    pub cursor: bool,
182    pub node: NodeInfo,
183}
184
185#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct TrailListResponse {
187    pub output: String,
188    pub entries: Vec<TrailEntryInfo>,
189    pub cursor_index: Option<usize>,
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct BearingsStatusResponse {
194    pub visible: bool,
195}
196
197#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct CaptureStatusResponse {
199    pub active: bool,
200    pub session_serial: Option<u64>,
201    pub last_finished_serial: Option<u64>,
202    pub saved_path: Option<String>,
203    pub error: Option<String>,
204}
205
206impl ModeInfo {
207    pub fn display_string(&self) -> String {
208        match self.refresh_hz {
209            Some(hz) => format!("{}x{} @ {:.2}Hz", self.width, self.height, hz),
210            None => format!("{}x{}", self.width, self.height),
211        }
212    }
213}