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