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, Serialize, Deserialize)]
9pub struct VersionInfo {
10 pub version: String,
11 pub ipc_protocol: u32,
12}
13
14#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
15#[serde(rename_all = "kebab-case")]
16pub enum ApertureMode {
17 Normal,
18 Collapsed,
19 Minimal,
20 Hidden,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct ApertureStatusResponse {
25 pub output: Option<String>,
26 pub mode: ApertureMode,
27 pub outputs: Vec<ApertureOutputStatus>,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct ApertureOutputStatus {
32 pub output: String,
33 pub mode: ApertureMode,
34}
35
36#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
37#[serde(rename_all = "kebab-case")]
38pub enum RailVisibility {
39 Visible,
40 HiddenEmpty,
41 HiddenFullscreen,
42 HiddenMaximized,
43 HiddenObstructed,
44 HiddenTiledCluster,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
48pub struct RailItemInfo {
49 pub node_id: u64,
50 pub title: String,
51 pub app_id: Option<String>,
52 pub pinned: bool,
53 pub focused: bool,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
57pub struct RailOutputSnapshot {
58 pub output: String,
59 pub visibility: RailVisibility,
60 pub items: Vec<RailItemInfo>,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
64pub struct RailStatusResponse {
65 pub output: Option<String>,
66 pub outputs: Vec<RailOutputSnapshot>,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct OutputInfo {
71 pub name: String,
72 pub status: OutputStatus,
73 pub enabled: bool,
74 pub current_mode: Option<ModeInfo>,
75 pub modes: Vec<ModeInfo>,
76 pub vrr_mode: Option<String>,
77 pub vrr_support: Option<String>,
78 pub direct_scanout_candidate_node: Option<u64>,
79 pub direct_scanout_active_node: Option<u64>,
80 pub direct_scanout_reason: Option<String>,
81 pub logical: Option<LogicalOutputInfo>,
82}
83
84#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
85pub enum OutputStatus {
86 Connected,
87 Disconnected,
88 Unknown,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct ModeInfo {
93 pub width: u32,
94 pub height: u32,
95 pub refresh_hz: Option<f64>,
96 pub preferred: bool,
97 pub current: bool,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct LogicalOutputInfo {
102 pub scale: f64,
103 pub focused: bool,
104 pub offset_x: i32,
105 pub offset_y: i32,
106}
107
108#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
109pub enum NodeKind {
110 Surface,
111 Core,
112}
113
114#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
115pub enum NodeState {
116 Active,
117 Drifting,
118 Node,
119 Core,
120}
121
122#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
123#[serde(rename_all = "kebab-case")]
124pub enum NodeRole {
125 NormalToplevel,
126 Dialog,
127 Popup,
128 Unknown,
129}
130
131#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
132#[serde(rename_all = "kebab-case")]
133pub enum NodeProtocolFamily {
134 XdgToplevel,
135 XdgPopup,
136 Xwayland,
137 Unknown,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
141pub struct NodeRelationInfo {
142 pub node_id: Option<u64>,
143}
144
145#[derive(Debug, Clone, Serialize, Deserialize)]
146pub struct NodeInfo {
147 pub id: u64,
148 pub title: String,
149 pub app_id: Option<String>,
150 pub output: Option<String>,
151 pub kind: NodeKind,
152 pub state: NodeState,
153 pub visible: bool,
154 pub focused: bool,
155 pub latest: bool,
156 pub role: NodeRole,
157 pub protocol_family: NodeProtocolFamily,
158 pub modal: bool,
159 pub parent: Option<NodeRelationInfo>,
160 pub transient_for: Option<NodeRelationInfo>,
161 pub child_popup_count: usize,
162 pub pos_x: f32,
163 pub pos_y: f32,
164 pub width: f32,
165 pub height: f32,
166}
167
168#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
169#[serde(rename_all = "kebab-case")]
170pub enum ClusterLayoutKind {
171 Tiling,
172 Stacking,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct ClusterSummary {
177 pub id: u64,
178 pub slot: Option<u8>,
179 pub name: Option<String>,
180 pub output: Option<String>,
181 pub layout: ClusterLayoutKind,
182 pub member_count: usize,
183 pub active: bool,
184 pub focused: bool,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize)]
188pub struct ClusterOutputGroup {
189 pub output: String,
190 pub clusters: Vec<ClusterSummary>,
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct ClusterListResponse {
195 pub outputs: Vec<ClusterOutputGroup>,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
199pub struct ClusterInfo {
200 pub id: u64,
201 pub slot: Option<u8>,
202 pub name: Option<String>,
203 pub output: Option<String>,
204 pub layout: ClusterLayoutKind,
205 pub member_count: usize,
206 pub active: bool,
207 pub focused: bool,
208 pub focused_member_index: Option<usize>,
209 pub focused_member_id: Option<u64>,
210 pub members: Vec<NodeInfo>,
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
214pub struct NodeOutputGroup {
215 pub output: String,
216 pub nodes: Vec<NodeInfo>,
217}
218
219#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct NodeListResponse {
221 pub outputs: Vec<NodeOutputGroup>,
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct TrailEntryInfo {
226 pub index: usize,
227 pub cursor: bool,
228 pub node: NodeInfo,
229}
230
231#[derive(Debug, Clone, Serialize, Deserialize)]
232pub struct TrailListResponse {
233 pub output: String,
234 pub entries: Vec<TrailEntryInfo>,
235 pub cursor_index: Option<usize>,
236}
237
238#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct BearingsStatusResponse {
240 pub visible: bool,
241}
242
243#[derive(Debug, Clone, Serialize, Deserialize)]
244pub struct CaptureStatusResponse {
245 pub active: bool,
246 pub session_serial: Option<u64>,
247 pub last_finished_serial: Option<u64>,
248 pub saved_path: Option<String>,
249 pub error: Option<String>,
250}
251
252impl ModeInfo {
253 pub fn display_string(&self) -> String {
254 match self.refresh_hz {
255 Some(hz) => format!("{}x{} @ {:.2}Hz", self.width, self.height, hz),
256 None => format!("{}x{}", self.width, self.height),
257 }
258 }
259}