session and seat management daemon
0

Configure Feed

Select the types of activity you want to include in your feed.

chore(seat): store device and client objects

authored by

r0chd and committed by
Tangled
(Jul 15, 2026, 9:38 AM +0300) 76ff95d7 4b35d940

+509 -9
+25
daemon/src/device.rs
··· 52 52 .ok_or_else(|| anyhow::anyhow!("device not found"))?; 53 53 54 54 let device_entity = devices.0[idx]; 55 + let device_id = world 56 + .get::<ecs::DeviceObjects>(device_entity) 57 + .and_then(|objects| { 58 + objects 59 + .0 60 + .iter() 61 + .find(|candidate| candidate.object == *object) 62 + .map(|candidate| candidate.id) 63 + }) 64 + .ok_or_else(|| anyhow::anyhow!("device object not found"))?; 55 65 remove_object(world, device_entity, object); 56 66 let device_path = device_path(world, device_entity)?; 57 67 log::debug!( ··· 61 71 seat_name 62 72 ); 63 73 74 + seat::notify_client_device_removed(world, client_entity, device_id); 75 + seat::notify_device_id_destroyed(world, device_entity, device_id); 76 + seat::remove_device_id_objects(world, device_entity, device_id); 64 77 if decrement_ref(world, device_entity) > 0 { 65 78 return Ok(()); 66 79 } ··· 77 90 if let Some(mut devices) = world.get_mut::<ecs::Devices>(client_entity) { 78 91 devices.0.remove(idx); 79 92 } 93 + seat::notify_device_destroyed(world, device_entity); 80 94 world.despawn(device_entity); 81 95 82 96 Ok(()) ··· 156 170 drm_set_master(&fd.0) 157 171 .map_err(|err| anyhow::anyhow!("Could not make device fd drm master: {err}"))?; 158 172 world.entity_mut(entity).insert(ecs::DeviceActive(true)); 173 + notify_active(world, entity, true); 159 174 } 160 175 DeviceKind::Evdev | DeviceKind::Hidraw => { 161 176 return Err(anyhow::anyhow!("device type cannot be activated")); 162 177 } 163 178 DeviceKind::Wscons => { 164 179 world.entity_mut(entity).insert(ecs::DeviceActive(true)); 180 + notify_active(world, entity, true); 165 181 } 166 182 } 167 183 ··· 209 225 } 210 226 211 227 world.entity_mut(entity).insert(ecs::DeviceActive(false)); 228 + notify_active(world, entity, false); 212 229 Ok(()) 230 + } 231 + 232 + fn notify_active(world: &world::World, entity: entity::Entity, active: bool) { 233 + if let Some(objects) = world.get::<ecs::SeatDeviceObjects>(entity) { 234 + for object in &objects.0 { 235 + object.object.send_active(u32::from(active)); 236 + } 237 + } 213 238 } 214 239 215 240 pub fn matches_path(world: &world::World, entity: entity::Entity, path: &path::Path) -> bool {
+20
daemon/src/ecs.rs
··· 1 + use crate::session_core_v1::{ 2 + session_core_seat, session_core_seat_client, session_core_seat_device, 3 + }; 1 4 use crate::session_management_v1::session_management_session; 2 5 use crate::{ 3 6 device, seat, seat_v1, session, session_core_session, session_core_user, session_core_v1, ··· 67 70 .spawn(( 68 71 SeatObject(object), 69 72 ClientPid(pid), 73 + ClientObjects(Vec::new()), 70 74 Devices(Vec::new()), 71 75 SeatState(seat::SeatState::New), 72 76 )) ··· 80 84 SeatMode(mode), 81 85 CurrentVt(current_vt), 82 86 SeatClients(Vec::new()), 87 + SeatObjects(Vec::new()), 83 88 )) 84 89 .id() 85 90 } ··· 96 101 world 97 102 .spawn(( 98 103 DeviceObjects(vec![DeviceObject { object, id }]), 104 + SeatDeviceObjects(Vec::new()), 99 105 DevicePath(path), 100 106 DeviceRefCount(1), 101 107 DeviceKind(kind), ··· 157 163 pub struct ClientPid(pub u32); 158 164 159 165 #[derive(Component)] 166 + pub struct ClientObjects(pub Vec<session_core_seat_client::SessionCoreSeatClient>); 167 + 168 + #[derive(Component)] 160 169 pub struct Devices(pub Vec<Entity>); 161 170 162 171 #[derive(Component)] 163 172 pub struct DeviceObjects(pub Vec<DeviceObject>); 164 173 174 + #[derive(Component)] 175 + pub struct SeatDeviceObjects(pub Vec<SeatDeviceObject>); 176 + 177 + pub struct SeatDeviceObject { 178 + pub object: session_core_seat_device::SessionCoreSeatDevice, 179 + pub id: u32, 180 + } 181 + 165 182 pub struct DeviceObject { 166 183 pub object: seat_v1::device::Device, 167 184 pub id: u32, ··· 199 216 200 217 #[derive(Component)] 201 218 pub struct SeatClients(pub Vec<Entity>); 219 + 220 + #[derive(Component)] 221 + pub struct SeatObjects(pub Vec<session_core_seat::SessionCoreSeat>); 202 222 203 223 #[derive(Component)] 204 224 pub struct ActiveClient(pub Entity);
+456 -7
daemon/src/seat.rs
··· 30 30 }) 31 31 } 32 32 33 + pub fn seat_entity_by_core_object( 34 + world: &world::World, 35 + entities: &[entity::Entity], 36 + object: &session_core_seat::SessionCoreSeat, 37 + ) -> Option<entity::Entity> { 38 + entities.iter().copied().find(|entity| { 39 + world 40 + .get::<ecs::SeatObjects>(*entity) 41 + .is_some_and(|objects| objects.0.iter().any(|candidate| candidate == object)) 42 + }) 43 + } 44 + 45 + pub fn seat_entity_by_name( 46 + world: &world::World, 47 + entities: &[entity::Entity], 48 + name: &str, 49 + ) -> Option<entity::Entity> { 50 + entities.iter().copied().find(|entity| { 51 + world 52 + .get::<ecs::SeatName>(*entity) 53 + .is_some_and(|seat_name| seat_name.0 == name) 54 + }) 55 + } 56 + 57 + pub fn client_entity_by_pid( 58 + world: &world::World, 59 + entities: &[entity::Entity], 60 + pid: u32, 61 + ) -> Option<entity::Entity> { 62 + entities.iter().copied().find(|entity| { 63 + world 64 + .get::<ecs::ClientPid>(*entity) 65 + .is_some_and(|client_pid| client_pid.0 == pid) 66 + }) 67 + } 68 + 69 + pub fn client_entity_by_core_object( 70 + world: &world::World, 71 + entities: &[entity::Entity], 72 + object: &session_core_seat_client::SessionCoreSeatClient, 73 + ) -> Option<entity::Entity> { 74 + entities.iter().copied().find(|entity| { 75 + world 76 + .get::<ecs::ClientObjects>(*entity) 77 + .is_some_and(|objects| objects.0.iter().any(|candidate| candidate == object)) 78 + }) 79 + } 80 + 33 81 pub fn client_entity_by_device_object( 34 82 world: &world::World, 35 83 entities: &[entity::Entity], ··· 45 93 }) 46 94 } 47 95 96 + pub fn device_entity_by_id( 97 + world: &world::World, 98 + client_entity: entity::Entity, 99 + device_id: u32, 100 + ) -> Option<entity::Entity> { 101 + world 102 + .get::<ecs::Devices>(client_entity)? 103 + .0 104 + .iter() 105 + .copied() 106 + .find(|device_entity| { 107 + world 108 + .get::<ecs::DeviceObjects>(*device_entity) 109 + .is_some_and(|objects| objects.0.iter().any(|object| object.id == device_id)) 110 + }) 111 + } 112 + 113 + pub fn device_entity_by_core_object( 114 + world: &world::World, 115 + client_entity: entity::Entity, 116 + object: &session_core_seat_device::SessionCoreSeatDevice, 117 + ) -> Option<entity::Entity> { 118 + world 119 + .get::<ecs::Devices>(client_entity)? 120 + .0 121 + .iter() 122 + .copied() 123 + .find(|device_entity| { 124 + world 125 + .get::<ecs::SeatDeviceObjects>(*device_entity) 126 + .is_some_and(|objects| { 127 + objects 128 + .0 129 + .iter() 130 + .any(|candidate| candidate.object == *object) 131 + }) 132 + }) 133 + } 134 + 135 + fn seat_mode_event(mode: ecs::SeatKind) -> session_core_v1::SeatMode { 136 + match mode { 137 + ecs::SeatKind::VtBound => session_core_v1::SeatMode::VtBound, 138 + ecs::SeatKind::NonVtBound => session_core_v1::SeatMode::NonVtBound, 139 + } 140 + } 141 + 142 + fn client_state_event(state: SeatState) -> session_core_v1::SeatClientState { 143 + match state { 144 + SeatState::New => session_core_v1::SeatClientState::New, 145 + SeatState::Enabled => session_core_v1::SeatClientState::Enabled, 146 + SeatState::PendingDisabled => session_core_v1::SeatClientState::PendingDisabled, 147 + SeatState::Disabled => session_core_v1::SeatClientState::Disabled, 148 + } 149 + } 150 + 151 + pub fn device_kind_event(kind: device::DeviceKind) -> session_core_v1::SeatDeviceKind { 152 + match kind { 153 + device::DeviceKind::Drm => session_core_v1::SeatDeviceKind::Drm, 154 + device::DeviceKind::Evdev => session_core_v1::SeatDeviceKind::Evdev, 155 + device::DeviceKind::Hidraw => session_core_v1::SeatDeviceKind::Hidraw, 156 + device::DeviceKind::Wscons => session_core_v1::SeatDeviceKind::Wscons, 157 + } 158 + } 159 + 160 + pub fn add_seat_object( 161 + world: &mut world::World, 162 + seat_entity: entity::Entity, 163 + object: session_core_seat::SessionCoreSeat, 164 + ) { 165 + if let Some(name) = world.get::<ecs::SeatName>(seat_entity) { 166 + object.send_seat(&name.0); 167 + } 168 + if let Some(mode) = world.get::<ecs::SeatMode>(seat_entity) { 169 + object.send_mode(seat_mode_event(mode.0)); 170 + } 171 + if let Some(vt) = world.get::<ecs::CurrentVt>(seat_entity) { 172 + object.send_current_vt(vt.0); 173 + } 174 + if let Some(clients) = world.get::<ecs::SeatClients>(seat_entity) { 175 + for client_entity in &clients.0 { 176 + if let Some(pid) = world.get::<ecs::ClientPid>(*client_entity) { 177 + object.send_client_added(pid.0); 178 + } 179 + } 180 + } 181 + object.send_done(); 182 + 183 + if let Some(mut objects) = world.get_mut::<ecs::SeatObjects>(seat_entity) { 184 + objects.0.push(object); 185 + } 186 + } 187 + 188 + pub fn add_client_object( 189 + world: &mut world::World, 190 + seat_entity: entity::Entity, 191 + client_entity: entity::Entity, 192 + object: session_core_seat_client::SessionCoreSeatClient, 193 + ) { 194 + if let Some(session) = world.get::<ecs::Session>(client_entity) { 195 + object.send_session(session.0.as_raw()); 196 + } 197 + if let Some(state) = world.get::<ecs::SeatState>(client_entity) { 198 + object.send_state(client_state_event(state.0)); 199 + } 200 + object.send_active(u32::from(is_active_client( 201 + world, 202 + seat_entity, 203 + client_entity, 204 + ))); 205 + object.send_next(u32::from( 206 + world 207 + .get::<ecs::NextClient>(seat_entity) 208 + .is_some_and(|next| next.0 == client_entity), 209 + )); 210 + if let Some(pid) = world.get::<ecs::ClientPid>(client_entity) { 211 + object.send_pid(pid.0); 212 + } 213 + if let Some(devices) = world.get::<ecs::Devices>(client_entity) { 214 + for device_entity in &devices.0 { 215 + if let Some(objects) = world.get::<ecs::DeviceObjects>(*device_entity) { 216 + for device_object in &objects.0 { 217 + object.send_device_added(device_object.id); 218 + } 219 + } 220 + } 221 + } 222 + object.send_done(); 223 + 224 + if let Some(mut objects) = world.get_mut::<ecs::ClientObjects>(client_entity) { 225 + objects.0.push(object); 226 + } 227 + } 228 + 229 + pub fn add_device_object( 230 + world: &mut world::World, 231 + device_entity: entity::Entity, 232 + device_id: u32, 233 + object: session_core_seat_device::SessionCoreSeatDevice, 234 + ) { 235 + object.send_device_id(device_id); 236 + if let Ok(path) = device::absolute_path_string(world, device_entity) { 237 + object.send_path(path); 238 + } 239 + if let Some(kind) = world.get::<ecs::DeviceKind>(device_entity) { 240 + object.send_kind(device_kind_event(kind.0)); 241 + } 242 + if let Some(active) = world.get::<ecs::DeviceActive>(device_entity) { 243 + object.send_active(u32::from(active.0)); 244 + } 245 + object.send_done(); 246 + 247 + if let Some(mut objects) = world.get_mut::<ecs::SeatDeviceObjects>(device_entity) { 248 + objects.0.push(ecs::SeatDeviceObject { 249 + object, 250 + id: device_id, 251 + }); 252 + } 253 + } 254 + 255 + fn notify_seat_client_added( 256 + world: &world::World, 257 + seat_entity: entity::Entity, 258 + client_entity: entity::Entity, 259 + ) { 260 + let Some(pid) = world.get::<ecs::ClientPid>(client_entity).map(|pid| pid.0) else { 261 + return; 262 + }; 263 + if let Some(objects) = world.get::<ecs::SeatObjects>(seat_entity) { 264 + for object in &objects.0 { 265 + object.send_client_added(pid); 266 + } 267 + } 268 + } 269 + 270 + fn notify_seat_current_vt(world: &world::World, seat_entity: entity::Entity) { 271 + let vt = world 272 + .get::<ecs::CurrentVt>(seat_entity) 273 + .map_or(0, |vt| vt.0); 274 + if let Some(objects) = world.get::<ecs::SeatObjects>(seat_entity) { 275 + for object in &objects.0 { 276 + object.send_current_vt(vt); 277 + } 278 + } 279 + } 280 + 281 + fn notify_client_state(world: &world::World, client_entity: entity::Entity) { 282 + let Some(state) = world 283 + .get::<ecs::SeatState>(client_entity) 284 + .map(|state| state.0) 285 + else { 286 + return; 287 + }; 288 + if let Some(objects) = world.get::<ecs::ClientObjects>(client_entity) { 289 + for object in &objects.0 { 290 + object.send_state(client_state_event(state)); 291 + } 292 + } 293 + } 294 + 295 + fn notify_client_active( 296 + world: &world::World, 297 + seat_entity: entity::Entity, 298 + client_entity: entity::Entity, 299 + ) { 300 + let active = u32::from(is_active_client(world, seat_entity, client_entity)); 301 + if let Some(objects) = world.get::<ecs::ClientObjects>(client_entity) { 302 + for object in &objects.0 { 303 + object.send_active(active); 304 + } 305 + } 306 + } 307 + 308 + fn notify_client_next(world: &world::World, client_entity: entity::Entity, next: bool) { 309 + if let Some(objects) = world.get::<ecs::ClientObjects>(client_entity) { 310 + for object in &objects.0 { 311 + object.send_next(u32::from(next)); 312 + } 313 + } 314 + } 315 + 316 + fn notify_client_device_added(world: &world::World, client_entity: entity::Entity, device_id: u32) { 317 + if let Some(objects) = world.get::<ecs::ClientObjects>(client_entity) { 318 + for object in &objects.0 { 319 + object.send_device_added(device_id); 320 + } 321 + } 322 + } 323 + 324 + pub fn notify_client_device_removed( 325 + world: &world::World, 326 + client_entity: entity::Entity, 327 + device_id: u32, 328 + ) { 329 + if let Some(objects) = world.get::<ecs::ClientObjects>(client_entity) { 330 + for object in &objects.0 { 331 + object.send_device_removed(device_id); 332 + } 333 + } 334 + } 335 + 336 + pub fn notify_client_destroyed(world: &world::World, client_entity: entity::Entity) { 337 + if let Some(objects) = world.get::<ecs::ClientObjects>(client_entity) { 338 + for object in &objects.0 { 339 + object.send_destroyed(); 340 + } 341 + } 342 + } 343 + 344 + pub fn notify_device_destroyed(world: &world::World, device_entity: entity::Entity) { 345 + if let Some(objects) = world.get::<ecs::SeatDeviceObjects>(device_entity) { 346 + for object in &objects.0 { 347 + object.object.send_destroyed(); 348 + } 349 + } 350 + } 351 + 352 + pub fn notify_device_id_destroyed( 353 + world: &world::World, 354 + device_entity: entity::Entity, 355 + device_id: u32, 356 + ) { 357 + if let Some(objects) = world.get::<ecs::SeatDeviceObjects>(device_entity) { 358 + for object in &objects.0 { 359 + if object.id == device_id { 360 + object.object.send_destroyed(); 361 + } 362 + } 363 + } 364 + } 365 + 366 + pub fn remove_device_object( 367 + world: &mut world::World, 368 + device_entity: entity::Entity, 369 + object: &session_core_seat_device::SessionCoreSeatDevice, 370 + ) { 371 + if let Some(mut objects) = world.get_mut::<ecs::SeatDeviceObjects>(device_entity) { 372 + objects.0.retain(|candidate| candidate.object != *object); 373 + } 374 + } 375 + 376 + pub fn remove_device_id_objects( 377 + world: &mut world::World, 378 + device_entity: entity::Entity, 379 + device_id: u32, 380 + ) { 381 + if let Some(mut objects) = world.get_mut::<ecs::SeatDeviceObjects>(device_entity) { 382 + objects.0.retain(|candidate| candidate.id != device_id); 383 + } 384 + } 385 + 386 + pub fn notify_device_removed( 387 + world: &world::World, 388 + client_entity: entity::Entity, 389 + device_entity: entity::Entity, 390 + ) { 391 + if let Some(objects) = world.get::<ecs::DeviceObjects>(device_entity) { 392 + for device_object in &objects.0 { 393 + notify_client_device_removed(world, client_entity, device_object.id); 394 + } 395 + } 396 + notify_device_destroyed(world, device_entity); 397 + } 398 + 48 399 pub fn add_client( 49 400 world: &mut world::World, 50 401 seat_entity: entity::Entity, ··· 140 491 world 141 492 .entity_mut(seat_entity) 142 493 .insert(ecs::ActiveClient(client_entity)); 494 + notify_seat_client_added(world, seat_entity, client_entity); 495 + notify_client_state(world, client_entity); 496 + notify_client_active(world, seat_entity, client_entity); 143 497 144 498 if let Some(object) = world.get::<ecs::SeatObject>(client_entity) { 145 499 object.0.send_enabled(); ··· 212 566 world 213 567 .entity_mut(seat_entity) 214 568 .insert(ecs::ActiveClient(client_entity)); 569 + notify_client_state(world, client_entity); 570 + notify_client_active(world, seat_entity, client_entity); 215 571 log::info!("Opened client {} on {}", session_id.as_raw(), seat_name); 216 572 217 573 Ok(()) ··· 240 596 world 241 597 .entity_mut(client_entity) 242 598 .insert(ecs::SeatState(SeatState::PendingDisabled)); 599 + notify_client_state(world, client_entity); 243 600 if let Some(object) = world.get::<ecs::SeatObject>(client_entity) { 244 601 object.0.send_disabled(); 245 602 } ··· 263 620 world 264 621 .entity_mut(client_entity) 265 622 .insert(ecs::SeatState(SeatState::Disabled)); 623 + notify_client_state(world, client_entity); 266 624 log::info!("Disabled client {} on {}", session_id.as_raw(), seat_name); 267 625 268 626 if !is_active_client(world, seat_entity, client_entity) { ··· 270 628 } 271 629 272 630 world.entity_mut(seat_entity).remove::<ecs::ActiveClient>(); 631 + notify_client_active(world, seat_entity, client_entity); 273 632 let _ = activate(world, seat_entity); 274 633 275 634 Ok(()) ··· 297 656 retained_devices.push(device_entity); 298 657 } 299 658 Ok(device::DeviceKind::Evdev | device::DeviceKind::Hidraw) => { 659 + notify_device_removed(world, client_entity, device_entity); 300 660 world.despawn(device_entity); 301 661 } 302 662 Err(err) => { ··· 375 735 world 376 736 .entity_mut(seat_entity) 377 737 .insert(ecs::NextClient(target)); 738 + notify_client_next(world, target, true); 378 739 disable_client(world, seat_entity, client_entity)?; 379 740 380 741 Ok(()) ··· 390 751 .is_some_and(|next_client| next_client.0 == client_entity) 391 752 { 392 753 world.entity_mut(seat_entity).remove::<ecs::NextClient>(); 754 + notify_client_next(world, client_entity, false); 393 755 } 394 756 395 757 let session_id = world ··· 407 769 let path = device::path_display(world, device_entity); 408 770 log::error!("Could not deactivate {path}: {err}"); 409 771 } 772 + notify_device_removed(world, client_entity, device_entity); 410 773 world.despawn(device_entity); 411 774 } 412 775 } ··· 417 780 let was_current = is_active_client(world, seat_entity, client_entity); 418 781 if was_current { 419 782 world.entity_mut(seat_entity).remove::<ecs::ActiveClient>(); 783 + notify_client_active(world, seat_entity, client_entity); 420 784 let _ = activate(world, seat_entity); 421 785 } 422 786 ··· 443 807 } 444 808 } 445 809 810 + notify_client_destroyed(world, client_entity); 446 811 world.despawn(client_entity); 447 812 448 813 log::info!( ··· 539 904 .copied() 540 905 { 541 906 device::add_object(world, old_device, device, device_id); 907 + notify_client_device_added(world, client_entity, device_id); 542 908 if let Err(err) = device::send_opened(world, old_device) { 543 909 log::error!("Could not send opened device event: {err}"); 544 910 } ··· 613 979 if let Some(mut devices) = world.get_mut::<ecs::Devices>(client_entity) { 614 980 devices.0.push(device_entity); 615 981 } 982 + notify_client_device_added(world, client_entity, device_id); 616 983 } 617 984 618 985 pub fn refresh_current_vts(world: &mut world::World, seat_entities: &[entity::Entity]) { ··· 623 990 624 991 match current_vt() { 625 992 Ok(vt) => { 993 + let changed = world 994 + .get::<ecs::CurrentVt>(seat_entity) 995 + .is_none_or(|current| current.0 != vt); 626 996 world.entity_mut(seat_entity).insert(ecs::CurrentVt(vt)); 997 + if changed { 998 + notify_seat_current_vt(world, seat_entity); 999 + } 627 1000 } 628 1001 Err(err) => log::error!("Could not query active VT: {err}"), 629 1002 } ··· 741 1114 let next_client = 742 1115 if let Some(next_client) = world.entity_mut(seat_entity).take::<ecs::NextClient>() { 743 1116 log::debug!("Activating next queued client on {seat_name}"); 1117 + notify_client_next(world, next_client.0, false); 744 1118 Some(next_client.0) 745 1119 } else { 746 1120 let clients = world ··· 819 1193 820 1194 terminal::Terminal::open(cur_vt)?.ack_release()?; 821 1195 world.entity_mut(seat_entity).insert(ecs::CurrentVt(0)); 1196 + notify_seat_current_vt(world, seat_entity); 822 1197 823 1198 Ok(()) 824 1199 } ··· 833 1208 world 834 1209 .entity_mut(seat_entity) 835 1210 .insert(ecs::CurrentVt(acquired_vt)); 1211 + notify_seat_current_vt(world, seat_entity); 836 1212 837 1213 if world.get::<ecs::ActiveClient>(seat_entity).is_none() { 838 1214 let has_clients = world ··· 1123 1499 { 1124 1500 fn event( 1125 1501 &mut self, 1126 - _object: &session_core_seat::SessionCoreSeat, 1502 + object: &session_core_seat::SessionCoreSeat, 1127 1503 event: <session_core_seat::SessionCoreSeat as hyprwire::Object>::Event<'_>, 1128 1504 ) { 1129 1505 match event { 1130 1506 session_core_seat::Event::GetClient { 1131 1507 session_core_seat_client, 1132 1508 pid, 1133 - } => {} 1134 - session_core_seat::Event::Destroy => {} 1509 + } => { 1510 + let Some(seat_entity) = 1511 + seat_entity_by_core_object(&self.world, &self.seat_entities, object) 1512 + else { 1513 + session_core_seat_client.send_destroyed(); 1514 + return; 1515 + }; 1516 + let Some(client_entity) = 1517 + client_entity_by_pid(&self.world, &self.client_entities, pid) 1518 + else { 1519 + session_core_seat_client.send_destroyed(); 1520 + return; 1521 + }; 1522 + if self 1523 + .world 1524 + .get::<ecs::SeatEntity>(client_entity) 1525 + .is_none_or(|seat| seat.0 != seat_entity) 1526 + { 1527 + session_core_seat_client.send_destroyed(); 1528 + return; 1529 + } 1530 + 1531 + add_client_object( 1532 + &mut self.world, 1533 + seat_entity, 1534 + client_entity, 1535 + session_core_seat_client, 1536 + ); 1537 + } 1538 + session_core_seat::Event::Destroy => { 1539 + if let Some(seat_entity) = 1540 + seat_entity_by_core_object(&self.world, &self.seat_entities, object) 1541 + && let Some(mut objects) = self.world.get_mut::<ecs::SeatObjects>(seat_entity) 1542 + { 1543 + objects.0.retain(|candidate| candidate != object); 1544 + } 1545 + } 1135 1546 } 1136 1547 } 1137 1548 } ··· 1141 1552 { 1142 1553 fn event( 1143 1554 &mut self, 1144 - _object: &session_core_seat_client::SessionCoreSeatClient, 1555 + object: &session_core_seat_client::SessionCoreSeatClient, 1145 1556 event: <session_core_seat_client::SessionCoreSeatClient as hyprwire::Object>::Event<'_>, 1146 1557 ) { 1147 1558 match event { 1148 1559 session_core_seat_client::Event::GetDevice { 1149 1560 session_core_seat_device, 1150 1561 device_id, 1151 - } => {} 1152 - session_core_seat_client::Event::Destroy => {} 1562 + } => { 1563 + let Some(client_entity) = 1564 + client_entity_by_core_object(&self.world, &self.client_entities, object) 1565 + else { 1566 + session_core_seat_device.send_destroyed(); 1567 + return; 1568 + }; 1569 + let Some(device_entity) = 1570 + device_entity_by_id(&self.world, client_entity, device_id) 1571 + else { 1572 + session_core_seat_device.send_destroyed(); 1573 + return; 1574 + }; 1575 + 1576 + add_device_object( 1577 + &mut self.world, 1578 + device_entity, 1579 + device_id, 1580 + session_core_seat_device, 1581 + ); 1582 + } 1583 + session_core_seat_client::Event::Destroy => { 1584 + if let Some(client_entity) = 1585 + client_entity_by_core_object(&self.world, &self.client_entities, object) 1586 + && let Some(mut objects) = 1587 + self.world.get_mut::<ecs::ClientObjects>(client_entity) 1588 + { 1589 + objects.0.retain(|candidate| candidate != object); 1590 + } 1591 + } 1153 1592 } 1154 1593 } 1155 1594 } ··· 1159 1598 { 1160 1599 fn event( 1161 1600 &mut self, 1162 - _object: &session_core_seat_device::SessionCoreSeatDevice, 1601 + object: &session_core_seat_device::SessionCoreSeatDevice, 1163 1602 event: <session_core_seat_device::SessionCoreSeatDevice as hyprwire::Object>::Event<'_>, 1164 1603 ) { 1165 1604 let session_core_seat_device::Event::Destroy = event; 1605 + let Some(client_entity) = self.client_entities.iter().copied().find(|client_entity| { 1606 + device_entity_by_core_object(&self.world, *client_entity, object).is_some() 1607 + }) else { 1608 + return; 1609 + }; 1610 + let Some(device_entity) = device_entity_by_core_object(&self.world, client_entity, object) 1611 + else { 1612 + return; 1613 + }; 1614 + remove_device_object(&mut self.world, device_entity, object); 1166 1615 } 1167 1616 }
+8 -2
daemon/src/session.rs
··· 917 917 } 918 918 session_core_manager::Event::GetSeat { 919 919 session_core_seat, 920 - seat: _, 920 + seat, 921 921 } => { 922 - session_core_seat.send_destroyed(); 922 + let Some(seat_entity) = 923 + seat::seat_entity_by_name(&self.world, &self.seat_entities, &seat) 924 + else { 925 + session_core_seat.send_destroyed(); 926 + return; 927 + }; 928 + seat::add_seat_object(&mut self.world, seat_entity, session_core_seat); 923 929 } 924 930 session_core_manager::Event::Destroy => { 925 931 self.info_managers.retain(|m| m != object);