Skip to content

Commit 80b043f

Browse files
committed
chore: handle when monitor is dead
this time we also need to send close event
1 parent b7de074 commit 80b043f

File tree

6 files changed

+84
-6
lines changed

6 files changed

+84
-6
lines changed

iced_sessionlock/src/event.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub enum WindowEvent {
9494
y: f64,
9595
},
9696
Refresh,
97+
Closed,
9798
ThemeChanged(iced::theme::Mode),
9899
}
99100

@@ -108,6 +109,7 @@ impl From<&DispatchMessage> for WindowEvent {
108109
fn from(value: &DispatchMessage) -> Self {
109110
match value {
110111
DispatchMessage::RequestRefresh { .. } => WindowEvent::Refresh,
112+
DispatchMessage::Closed => WindowEvent::Closed,
111113
DispatchMessage::MouseEnter {
112114
surface_x: x,
113115
surface_y: y,

iced_sessionlock/src/multi_window.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,6 @@ where
278278
self
279279
}
280280

281-
#[allow(unused)]
282281
fn remove_compositor(&mut self) {
283282
self.compositor = None;
284283
self.clipboard = SessionLockClipboard::unconnected();
@@ -314,7 +313,9 @@ where
314313
IcedSessionLockEvent::Window(WindowEvent::Refresh) => {
315314
self.handle_refresh_event(ev, session_lock_id)
316315
}
317-
316+
IcedSessionLockEvent::Window(WindowEvent::Closed) => {
317+
self.handle_closed_event(session_lock_id)
318+
}
318319
IcedSessionLockEvent::Window(window_event) => {
319320
self.handle_window_event(session_lock_id, window_event)
320321
}
@@ -488,6 +489,28 @@ where
488489
},
489490
}
490491
}
492+
493+
fn handle_closed_event(&mut self, session_lock_id: Option<SessionLockId>) {
494+
let Some(session_lock_id) = session_lock_id else {
495+
return;
496+
};
497+
let Some(iced_id) = self.window_manager.get_iced_id(session_lock_id) else {
498+
return;
499+
};
500+
self.cached_layer_dimensions.remove(&iced_id);
501+
self.window_manager.remove(iced_id);
502+
self.user_interfaces.remove(&iced_id);
503+
self.runtime
504+
.broadcast(iced_futures::subscription::Event::Interaction {
505+
window: iced_id,
506+
event: IcedEvent::Window(IcedWindowEvent::Closed),
507+
status: iced_core::event::Status::Ignored,
508+
});
509+
if self.window_manager.is_empty() {
510+
self.remove_compositor();
511+
}
512+
}
513+
491514
fn handle_window_event(&mut self, session_lock_id: Option<SessionLockId>, event: WindowEvent) {
492515
let id_and_window = if let Some(layer_shell_id) = session_lock_id {
493516
self.window_manager.get_mut_alias(layer_shell_id)

iced_sessionlock/src/multi_window/window_manager.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,18 @@ where
5656
entries: BTreeMap::new(),
5757
}
5858
}
59-
59+
pub fn remove(&mut self, id: IcedId) {
60+
let remove_alias = self
61+
.aliases
62+
.iter()
63+
.find(|(_, oriid)| **oriid == id)
64+
.map(|(layid, _)| *layid);
65+
if let Some(oriid) = remove_alias {
66+
self.aliases.remove(&oriid);
67+
}
68+
self.back_aliases.remove(&id);
69+
self.entries.remove(&id);
70+
}
6071
#[allow(clippy::too_many_arguments)]
6172
pub fn insert(
6273
&mut self,
@@ -108,7 +119,11 @@ where
108119
Some((id, self.get_mut(id)?))
109120
}
110121

111-
pub fn get_iced_id(&self, id: IcedId) -> Option<SessionId> {
122+
pub fn get_iced_id(&self, id: SessionId) -> Option<IcedId> {
123+
self.aliases.get(&id).copied()
124+
}
125+
126+
pub fn get_session_id(&self, id: IcedId) -> Option<SessionId> {
112127
self.back_aliases.get(&id).copied()
113128
}
114129

layershellev/src/lib.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,7 @@ pub struct WindowState<T> {
879879
use_display_handle: bool,
880880
repeat_delay: Option<KeyboardTokenState>,
881881
to_remove_tokens: Vec<RegistrationToken>,
882+
closed_ids: Vec<id::Id>,
882883

883884
to_be_released_key: Option<VirtualKeyRelease>,
884885

@@ -1361,6 +1362,7 @@ impl<T> Default for WindowState<T> {
13611362
repeat_delay: None,
13621363
to_remove_tokens: Vec::new(),
13631364
to_be_released_key: None,
1365+
closed_ids: Vec::new(),
13641366

13651367
last_wloutput: None,
13661368
last_unit_index: 0,
@@ -1530,7 +1532,12 @@ impl<T: 'static> Dispatch<wl_registry::WlRegistry, ()> for WindowState<T> {
15301532
state.last_wloutput.take();
15311533
}
15321534
state.outputs.retain(|x| x.0 != name);
1533-
state.units.retain(|unit| unit.wl_surface.is_alive());
1535+
let removed_states = state
1536+
.units
1537+
.extract_if(.., |unit| !unit.wl_surface.is_alive());
1538+
for deleled in removed_states.into_iter() {
1539+
state.closed_ids.push(deleled.id);
1540+
}
15341541
}
15351542

15361543
_ => {}
@@ -3280,6 +3287,18 @@ impl<T: 'static> WindowState<T> {
32803287
window_state.remove_shell(id);
32813288
}
32823289

3290+
// NOTE: this is for those closed because wl_output is dead.
3291+
let closed_ids = window_state.closed_ids.clone();
3292+
for id in closed_ids {
3293+
window_state.handle_event(
3294+
&mut *event_handler,
3295+
LayerShellEvent::RequestMessages(&DispatchMessage::Closed),
3296+
Some(id),
3297+
);
3298+
}
3299+
window_state.closed_ids.clear();
3300+
3301+
32833302
for idx in 0..window_state.units.len() {
32843303
let unit = &mut window_state.units[idx];
32853304
let (width, height) = unit.size;

sessionlockev/src/events.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ pub enum DispatchMessage {
267267
scale_float: f64,
268268
scale_u32: u32,
269269
},
270+
// because wlouput is dead, the window is closed
271+
Closed,
270272
}
271273

272274
impl From<DispatchMessageInner> for DispatchMessage {

sessionlockev/src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ pub struct WindowState<T> {
508508
// settings:
509509
to_remove_tokens: Vec<RegistrationToken>,
510510
repeat_delay: Option<KeyboardTokenState>,
511+
closed_ids: Vec<id::Id>,
511512

512513
// keyboard
513514
use_display_handle: bool,
@@ -631,6 +632,7 @@ impl<T> Default for WindowState<T> {
631632

632633
to_remove_tokens: Vec::new(),
633634
repeat_delay: None,
635+
closed_ids: Vec::new(),
634636

635637
use_display_handle: false,
636638

@@ -761,7 +763,12 @@ impl<T: 'static> Dispatch<wl_registry::WlRegistry, ()> for WindowState<T> {
761763
}
762764
wl_registry::Event::GlobalRemove { name } => {
763765
state.outputs.retain(|x| x.0 != name);
764-
state.units.retain(|unit| unit.wl_surface.is_alive());
766+
let removed_states = state
767+
.units
768+
.extract_if(.., |unit| !unit.wl_surface.is_alive());
769+
for deleled in removed_states.into_iter() {
770+
state.closed_ids.push(deleled.id);
771+
}
765772
}
766773

767774
_ => {}
@@ -1729,6 +1736,16 @@ impl<T: 'static> WindowState<T> {
17291736
break;
17301737
}
17311738
}
1739+
let closed_ids = window_state.closed_ids.clone();
1740+
for id in closed_ids {
1741+
window_state.handle_event(
1742+
&mut *event_handler,
1743+
SessionLockEvent::RequestMessages(&DispatchMessage::Closed),
1744+
Some(id),
1745+
);
1746+
}
1747+
window_state.closed_ids.clear();
1748+
17321749
for idx in 0..window_state.units.len() {
17331750
let unit = &mut window_state.units[idx];
17341751
let (width, height) = unit.size;

0 commit comments

Comments
 (0)