hyprshell_exec_lib/
collect.rs1use crate::to_client_id;
2use core_lib::{
3 ClientData, ClientId, FindByFirst, MonitorData, MonitorId, WorkspaceData, WorkspaceId,
4};
5use hyprland::data::{Client, Clients, Monitor, Monitors, Workspace, Workspaces};
6use hyprland::prelude::*;
7use tracing::{debug_span, warn};
8
9fn get_hypr_data() -> anyhow::Result<(Vec<Monitor>, Vec<Workspace>, Vec<Client>)> {
10 let _span = debug_span!("get_hypr_data").entered();
11 let monitors = Monitors::get()?.to_vec();
12 let workspaces = {
14 let mut workspaces = Workspaces::get()?
15 .into_iter()
16 .filter(|w| w.id != -1) .filter(|w| !w.id < 0) .collect::<Vec<_>>();
19
20 workspaces.sort_by(|a, b| a.id.cmp(&b.id));
21 workspaces
22 };
23 let clients = Clients::get()?
24 .into_iter()
25 .filter(|c| c.workspace.id != -1) .filter(|w| !w.workspace.id < 0) .collect::<Vec<_>>();
28
29 Ok((monitors, workspaces, clients))
30}
31
32#[allow(clippy::type_complexity)]
33pub fn collect_hypr_data() -> anyhow::Result<(
34 Vec<(ClientId, ClientData)>,
35 Vec<(WorkspaceId, WorkspaceData)>,
36 Vec<(MonitorId, MonitorData)>,
37 Option<(String, ClientId)>,
38 WorkspaceId,
39 MonitorId,
40)> {
41 let _span = debug_span!("convert_hypr_data").entered();
42
43 let (monitors, workspaces, clients) = get_hypr_data()?;
44
45 let mut monitor_data = {
48 let mut md: Vec<(MonitorId, MonitorData)> = Vec::with_capacity(monitors.iter().len());
49
50 for monitor in &monitors {
51 #[allow(clippy::cast_sign_loss)]
52 md.push((
53 monitor.id,
54 MonitorData {
55 x: monitor.x,
56 y: monitor.y,
57 width: (f32::from(monitor.width) / monitor.scale) as u16,
58 height: (f32::from(monitor.height) / monitor.scale) as u16,
59 connector: monitor.name.clone(),
60 },
61 ));
62 }
63 md
64 };
65
66 let mut workspace_data = {
68 let mut wd: Vec<(WorkspaceId, WorkspaceData)> = Vec::with_capacity(workspaces.len());
69
70 for (monitor_id, monitor_data) in &monitor_data {
71 let mut x_offset: i32 = 0;
72 workspaces
73 .iter()
74 .filter(|ws| ws.monitor_id == Some(*monitor_id))
75 .for_each(|workspace| {
76 wd.push((
77 workspace.id,
78 WorkspaceData {
79 x: x_offset,
80 y: monitor_data.y,
81 name: workspace.name.clone(),
82 monitor: *monitor_id,
83 height: monitor_data.height,
84 width: monitor_data.width,
85 any_client_enabled: false, },
87 ));
88 x_offset += i32::from(monitor_data.width);
89 });
90 }
91 wd
92 };
93
94 let client_data = {
95 let mut cd: Vec<(ClientId, ClientData)> = Vec::with_capacity(clients.len());
96
97 for client in clients {
98 let Some(monitor) = client.monitor else {
99 continue;
100 };
101 if workspace_data.find_by_first(&client.workspace.id).is_some() {
102 cd.push((
103 to_client_id(&client.address),
104 ClientData {
105 x: client.at.0,
106 y: client.at.1,
107 width: client.size.0,
108 height: client.size.1,
109 class: client.class.clone(),
110 workspace: client.workspace.id,
111 monitor,
112 focus_history_id: client.focus_history_id,
113 title: client.title.clone(),
114 floating: client.floating,
115 pid: client.pid,
116 enabled: false, },
118 ));
119 } else {
120 warn!(
121 "workspace {:?} not found for client {client:?}",
122 client.workspace
123 );
124 }
125 }
126 cd
127 };
128
129 workspace_data.sort_by(|a, b| a.0.cmp(&b.0));
130 monitor_data.sort_by(|a, b| a.0.cmp(&b.0));
131
132 let active_ws = Workspace::get_active()?.id;
133 let active_monitor = Monitor::get_active()?.id;
134 let active_client = Client::get_active()?.map(|a| (a.class.clone(), to_client_id(&a.address)));
135
136 Ok((
137 client_data,
138 workspace_data,
139 monitor_data,
140 active_client,
141 active_ws,
142 active_monitor,
143 ))
144}