1use super::*;
2use crate::default_instance;
3use crate::error::hypr_err;
4use crate::instance::Instance;
5use derive_more::Display;
6use serde::{Deserialize, Serialize};
7use serde_repr::{Deserialize_repr, Serialize_repr};
8
9#[derive(Debug, Display, Clone, Copy, PartialEq, Eq)]
11pub(crate) enum DataCommands {
12 #[display("monitors all")]
13 Monitors,
14 #[display("workspaces")]
15 Workspaces,
16 #[display("activeworkspace")]
17 ActiveWorkspace,
18 #[display("clients")]
19 Clients,
20 #[display("activewindow")]
21 ActiveWindow,
22 #[display("layers")]
23 Layers,
24 #[display("devices")]
25 Devices,
26 #[display("version")]
27 Version,
28 #[display("cursorpos")]
29 CursorPosition,
30 #[display("binds")]
31 Binds,
32 #[display("animations")]
33 Animations,
34 #[display("workspacerules")]
35 WorkspaceRules,
36}
37
38#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
40pub struct WorkspaceBasic {
41 pub id: WorkspaceId,
43 pub name: String,
45}
46
47#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, PartialEq, Eq, Copy)]
49#[repr(u8)]
50pub enum Transforms {
51 Normal = 0,
53 Normal90 = 1,
55 Normal180 = 2,
57 Normal270 = 3,
59 Flipped = 4,
61 Flipped90 = 5,
63 Flipped180 = 6,
65 Flipped270 = 7,
67}
68
69#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
71pub struct Monitor {
72 pub id: MonitorId,
74 pub name: String,
76 pub description: String,
78 pub width: u16,
80 pub height: u16,
82 #[serde(rename = "refreshRate")]
84 pub refresh_rate: f32,
85 pub x: i32,
87 pub y: i32,
89 #[serde(rename = "activeWorkspace")]
91 pub active_workspace: WorkspaceBasic,
92 #[serde(rename = "specialWorkspace")]
94 pub special_workspace: WorkspaceBasic,
95 pub reserved: (u16, u16, u16, u16),
97 pub scale: f32,
99 pub transform: Transforms,
101 pub focused: bool,
103 #[serde(rename = "dpmsStatus")]
105 pub dpms_status: bool,
106 pub vrr: bool,
108 pub disabled: bool,
110 #[serde(rename = "physicalWidth", default)]
112 pub physical_width: u16,
113 #[serde(rename = "physicalHeight", default)]
115 pub physical_height: u16,
116}
117
118impl HyprDataActive for Monitor {
119 fn get_active() -> crate::Result<Self> {
120 Self::instance_get_active(default_instance()?)
121 }
122 #[cfg(any(feature = "async-lite", feature = "tokio"))]
123 async fn get_active_async() -> crate::Result<Self> {
124 Self::instance_get_active_async(default_instance()?).await
125 }
126 fn instance_get_active(instance: &Instance) -> crate::Result<Self> {
127 let all = Monitors::instance_get(instance)?;
128 if let Some(it) = all.into_iter().find(|item| item.focused) {
129 Ok(it)
130 } else {
131 hypr_err!("No active Hyprland monitor detected!")
132 }
133 }
134 #[cfg(any(feature = "async-lite", feature = "tokio"))]
135 async fn instance_get_active_async(instance: &Instance) -> crate::Result<Self> {
136 let all = Monitors::instance_get_async(instance).await?;
137 if let Some(it) = all.into_iter().find(|item| item.focused) {
138 Ok(it)
139 } else {
140 hypr_err!("No active Hyprland monitor detected!")
141 }
142 }
143}
144
145create_data_struct!(
146 vector,
147 name: Monitors,
148 command: DataCommands::Monitors,
149 holding_type: Monitor,
150 doc: "This struct holds a vector of monitors"
151);
152
153#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
155pub struct Workspace {
156 pub id: WorkspaceId,
158 pub name: String,
160 pub monitor: String,
162 #[serde(rename = "monitorID")]
164 pub monitor_id: Option<MonitorId>,
165 pub windows: u16,
167 #[serde(rename = "hasfullscreen")]
169 pub fullscreen: bool,
170 #[serde(rename = "lastwindow")]
172 pub last_window: Address,
173 #[serde(rename = "lastwindowtitle")]
175 pub last_window_title: String,
176}
177
178impl HyprDataActive for Workspace {
179 fn get_active() -> crate::Result<Self> {
180 Self::instance_get_active(default_instance()?)
181 }
182 #[cfg(any(feature = "async-lite", feature = "tokio"))]
183 async fn get_active_async() -> crate::Result<Self> {
184 Self::instance_get_active_async(default_instance()?).await
185 }
186 fn instance_get_active(instance: &Instance) -> crate::Result<Self> {
187 let data = instance.write_to_socket(command!(JSON, "{}", DataCommands::ActiveWorkspace))?;
188 let deserialized: Workspace = serde_json::from_str(&data)?;
189 Ok(deserialized)
190 }
191 #[cfg(any(feature = "async-lite", feature = "tokio"))]
192 async fn instance_get_active_async(instance: &Instance) -> crate::Result<Self> {
193 let data = instance
194 .write_to_socket_async(command!(JSON, "{}", DataCommands::ActiveWorkspace))
195 .await?;
196 let deserialized: Workspace = serde_json::from_str(&data)?;
197 Ok(deserialized)
198 }
199}
200
201create_data_struct!(
202 vector,
203 name: Workspaces,
204 command: DataCommands::Workspaces,
205 holding_type: Workspace,
206 doc: "This type provides a vector of workspaces"
207);
208
209#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, PartialEq, Eq, Copy)]
211#[repr(u8)]
212pub enum FullscreenMode {
213 None = 0,
215 Maximized = 1,
217 Fullscreen = 2,
219 MaximizedFullscreen = 3,
221}
222
223#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
225pub struct Client {
226 pub address: Address,
228 pub at: (i16, i16),
230 pub size: (i16, i16),
232 pub workspace: WorkspaceBasic,
234 pub floating: bool,
236 pub fullscreen: FullscreenMode,
238 #[serde(rename = "fullscreenClient")]
240 pub fullscreen_client: FullscreenMode,
241 pub monitor: Option<MonitorId>,
243 #[serde(rename = "initialClass")]
245 pub initial_class: String,
246 pub class: String,
248 #[serde(rename = "initialTitle")]
250 pub initial_title: String,
251 pub title: String,
253 pub pid: i32,
255 pub xwayland: bool,
257 pub pinned: bool,
259 pub grouped: Vec<Box<Address>>,
261 pub mapped: bool,
263 pub swallowing: Option<Box<Address>>,
265 #[serde(rename = "focusHistoryID")]
267 pub focus_history_id: i8,
268}
269
270#[derive(Deserialize, Debug)]
271#[serde(deny_unknown_fields)]
272struct Empty {}
273
274impl HyprDataActiveOptional for Client {
275 fn get_active() -> crate::Result<Option<Self>> {
276 Self::instance_get_active(default_instance()?)
277 }
278 #[cfg(any(feature = "async-lite", feature = "tokio"))]
279 async fn get_active_async() -> crate::Result<Option<Self>> {
280 Self::instance_get_active_async(default_instance()?).await
281 }
282 fn instance_get_active(instance: &Instance) -> crate::Result<Option<Self>> {
283 let data = instance.write_to_socket(command!(JSON, "{}", DataCommands::ActiveWindow))?;
284 let res = serde_json::from_str::<Empty>(&data);
285 if res.is_err() {
286 let t = serde_json::from_str::<Client>(&data)?;
287 Ok(Some(t))
288 } else {
289 Ok(None)
290 }
291 }
292 #[cfg(any(feature = "async-lite", feature = "tokio"))]
293 async fn instance_get_active_async(instance: &Instance) -> crate::Result<Option<Self>> {
294 let data = instance
295 .write_to_socket_async(command!(JSON, "{}", DataCommands::ActiveWindow))
296 .await?;
297 let res = serde_json::from_str::<Empty>(&data);
298 if res.is_err() {
299 let t = serde_json::from_str::<Client>(&data)?;
300 Ok(Some(t))
301 } else {
302 Ok(None)
303 }
304 }
305}
306
307create_data_struct!(
308 vector,
309 name: Clients,
310 command: DataCommands::Clients,
311 holding_type: Client,
312 doc: "This struct holds a vector of clients"
313);
314
315#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
317pub struct LayerClient {
318 pub address: Address,
320 pub x: i32,
322 pub y: i32,
324 pub w: i16,
326 pub h: i16,
328 pub namespace: String,
330}
331
332#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
334pub struct LayerDisplay {
335 pub levels: HashMap<String, Vec<LayerClient>>,
337}
338
339implement_iterators!(
340 table,
341 name: LayerDisplay,
342 iterated_field: levels,
343 key: String,
344 value: Vec<LayerClient>,
345);
346
347create_data_struct!(
348 table,
349 name: Layers,
350 command: DataCommands::Layers,
351 key: String,
352 value: LayerDisplay,
353 doc: "This struct holds a hashmap of all current displays, and their layer surfaces"
354);
355
356#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
358pub struct Mouse {
359 pub address: Address,
361 pub name: String,
363}
364
365#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
367pub struct Keyboard {
368 pub address: Address,
370 pub name: String,
372 pub rules: String,
374 pub model: String,
376 pub layout: String,
378 pub variant: String,
380 pub options: String,
382 pub active_keymap: String,
384 pub main: bool,
386}
387
388#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
390pub enum TabletType {
391 #[serde(rename = "tabletPad")]
393 TabletPad,
394 #[serde(rename = "tabletTool")]
396 TabletTool,
397}
398
399#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
401#[serde(untagged)]
402pub enum TabletBelongsTo {
403 TabletPad {
405 name: String,
407 address: Address,
409 },
410 Address(Address),
412}
413
414#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
416pub struct Tablet {
417 pub address: Address,
419 #[serde(rename = "type")]
421 pub tablet_type: Option<TabletType>,
422 #[serde(rename = "belongsTo")]
424 pub belongs_to: Option<TabletBelongsTo>,
425 pub name: Option<String>,
427}
428
429#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
431pub struct Devices {
432 pub mice: Vec<Mouse>,
434 pub keyboards: Vec<Keyboard>,
436 pub tablets: Vec<Tablet>,
438}
439impl_on!(Devices);
440
441#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
443pub struct Version {
444 pub branch: String,
446 pub commit: String,
448 #[serde(default)]
449 pub version: Option<String>,
451 pub dirty: bool,
453 pub commit_message: String,
455 pub commit_date: String,
457 pub tag: String,
459 pub commits: String,
461 #[serde(rename = "buildAquamarine")]
463 pub build_aquamarine: String,
464 pub flags: Vec<String>,
466}
467impl_on!(Version);
468
469#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
471pub struct CursorPosition {
472 pub x: i64,
474 pub y: i64,
476}
477impl_on!(CursorPosition);
478
479#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
481pub struct Bind {
482 pub locked: bool,
484 pub mouse: bool,
486 pub release: bool,
488 pub repeat: bool,
490 pub modmask: u16,
492 pub submap: String,
494 pub key: String,
496 pub keycode: i16,
498 pub dispatcher: String,
500 pub arg: String,
502 pub description: String,
504}
505
506create_data_struct!(
507 vector,
508 name: Binds,
509 command: DataCommands::Binds,
510 holding_type: Bind,
511 doc: "This struct holds a vector of binds"
512);
513
514#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
516pub enum AnimationStyle {
517 Slide,
519 SlideVert,
521 SlideFade,
523 SlideFadeVert,
525 PopIn(u8),
527 Fade,
529 Once,
531 Loop,
533 None,
535 Unknown(String),
537}
538
539impl From<String> for AnimationStyle {
540 fn from(value: String) -> Self {
541 if value.starts_with("popin") {
542 let mut iter = value.split(' ');
543 iter.next();
544 AnimationStyle::PopIn({
545 let mut str = iter.next().unwrap_or("100%").to_string();
546 str.remove(str.len() - 1);
547
548 str.parse().unwrap_or(100_u8)
549 })
550 } else {
551 match value.as_str() {
552 "slide" => AnimationStyle::Slide,
553 "slidevert" => AnimationStyle::SlideVert,
554 "fade" => AnimationStyle::Fade,
555 "slidefade" => AnimationStyle::SlideFade,
556 "slidefadevert" => AnimationStyle::SlideFadeVert,
557 "once" => AnimationStyle::Once,
558 "loop" => AnimationStyle::Loop,
559 "" => AnimationStyle::None,
560 _ => AnimationStyle::Unknown(value),
561 }
562 }
563 }
564}
565#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
567pub enum BezierIdent {
568 #[serde(rename = "")]
570 None,
571 #[serde(rename = "default")]
573 Default,
574 #[serde(rename = "name")]
576 Specified(String),
577}
578
579impl From<String> for BezierIdent {
580 fn from(value: String) -> Self {
581 match value.as_str() {
582 "" => BezierIdent::None,
583 "default" => BezierIdent::Default,
584 _ => BezierIdent::Specified(value),
585 }
586 }
587}
588
589#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
590struct RawBezierIdent {
591 pub name: String,
592}
593
594#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
596pub struct Bezier {
597 pub name: String,
599 pub x0: f32,
601 pub y0: f32,
603 pub x1: f32,
605 pub y1: f32,
607}
608
609#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
611struct AnimationRaw {
612 pub name: String,
614 pub overridden: bool,
616 pub bezier: String,
618 pub enabled: bool,
620 pub speed: f32,
622 pub style: String,
624}
625
626#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
628pub struct Animation {
629 pub name: String,
631 pub overridden: bool,
633 pub bezier: BezierIdent,
635 pub enabled: bool,
637 pub speed: f32,
639 pub style: AnimationStyle,
641}
642
643#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
644struct AnimationsRaw(Vec<AnimationRaw>, Vec<RawBezierIdent>);
645
646#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
648pub struct Animations(pub Vec<Animation>, pub Vec<BezierIdent>);
649
650impl HyprData for Animations {
651 fn get() -> crate::Result<Self> {
652 Self::instance_get(default_instance()?)
653 }
654
655 #[cfg(any(feature = "async-lite", feature = "tokio"))]
656 async fn get_async() -> crate::Result<Self> {
657 Self::instance_get_async(default_instance()?).await
658 }
659
660 fn instance_get(instance: &Instance) -> crate::Result<Self> {
661 let out = instance.write_to_socket(command!(JSON, "{}", DataCommands::Animations))?;
662 let des: AnimationsRaw = serde_json::from_str(&out)?;
663 let AnimationsRaw(anims, beziers) = des;
664 let new_anims: Vec<Animation> = anims
665 .into_iter()
666 .map(|item| Animation {
667 name: item.name,
668 overridden: item.overridden,
669 bezier: item.bezier.into(),
670 enabled: item.enabled,
671 speed: item.speed,
672 style: item.style.into(),
673 })
674 .collect();
675 let new_bezs: Vec<BezierIdent> = beziers.into_iter().map(|item| item.name.into()).collect();
676 Ok(Animations(new_anims, new_bezs))
677 }
678 #[cfg(any(feature = "async-lite", feature = "tokio"))]
679 async fn instance_get_async(instance: &Instance) -> crate::Result<Self> {
680 let out = instance
681 .write_to_socket_async(command!(JSON, "{}", DataCommands::Animations))
682 .await?;
683 let des: AnimationsRaw = serde_json::from_str(&out)?;
684 let AnimationsRaw(anims, beziers) = des;
685 let new_anims: Vec<Animation> = anims
686 .into_iter()
687 .map(|item| Animation {
688 name: item.name,
689 overridden: item.overridden,
690 bezier: item.bezier.into(),
691 enabled: item.enabled,
692 speed: item.speed,
693 style: item.style.into(),
694 })
695 .collect();
696 let new_bezs: Vec<BezierIdent> = beziers.into_iter().map(|item| item.name.into()).collect();
697 Ok(Animations(new_anims, new_bezs))
698 }
699}
700
701#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
705pub struct WorkspaceRuleset {
706 #[serde(rename = "workspaceString")]
708 pub workspace_string: String,
709 pub monitor: Option<String>,
711 pub default: Option<bool>,
713 #[serde(rename = "gapsIn")]
715 pub gaps_in: Option<Vec<i64>>,
716 #[serde(rename = "gapsOut")]
718 pub gaps_out: Option<Vec<i64>>,
719 #[serde(rename = "borderSize")]
721 pub border_size: Option<i64>,
722 pub border: Option<bool>,
724 pub shadow: Option<bool>,
726 pub rounding: Option<bool>,
728 pub decorate: Option<bool>,
730 pub persistent: Option<bool>,
732}
733
734create_data_struct!(
735 vector,
736 name: WorkspaceRules,
737 command: DataCommands::WorkspaceRules,
738 holding_type: WorkspaceRuleset,
739 doc: "This struct holds a vector of workspace rules per workspace"
740);