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 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}