Skip to content

Commit cd2e179

Browse files
committed
fix: it exit if no units when single mode
1 parent 4a98f35 commit cd2e179

File tree

2 files changed

+62
-13
lines changed

2 files changed

+62
-13
lines changed

layershellev/src/lib.rs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ use strtoshape::str_to_shape;
132132
use waycrate_xkbkeycode::xkb_keyboard::ElementState;
133133
use waycrate_xkbkeycode::xkb_keyboard::RepeatInfo;
134134

135+
use wayland_client::protocol::wl_surface;
135136
use wayland_client::{
136137
ConnectError, Connection, Dispatch, DispatchError, EventQueue, Proxy, QueueHandle, WEnum,
137138
delegate_noop,
@@ -1610,17 +1611,20 @@ impl<T: 'static> Dispatch<wl_registry::WlRegistry, ()> for WindowState<T> {
16101611
{
16111612
state.last_wloutput.take();
16121613
}
1613-
16141614
let outputs_removed = state.outputs.extract_if(.., |o| o.0 == name);
16151615
for output_removed in outputs_removed {
16161616
state
16171617
.xdg_info_cache
16181618
.retain(|info| info.0.id() != output_removed.1.id());
16191619
}
16201620

1621-
let removed_states = state
1622-
.units
1623-
.extract_if(.., |unit| !unit.wl_surface.is_alive());
1621+
let removed_states = state.units.extract_if(.., |unit| {
1622+
!unit.wl_surface.is_alive()
1623+
|| unit
1624+
.wl_output
1625+
.as_ref()
1626+
.is_some_and(|o| !state.outputs.iter().any(|(_, storage)| storage == o))
1627+
});
16241628
for deleled in removed_states.into_iter() {
16251629
state.closed_ids.push(deleled.id);
16261630
}
@@ -2352,6 +2356,40 @@ impl<T> Dispatch<wp_fractional_scale_v1::WpFractionalScaleV1, ()> for WindowStat
23522356
}
23532357
}
23542358
}
2359+
impl<T> Dispatch<WlSurface, ()> for WindowState<T> {
2360+
fn event(
2361+
state: &mut Self,
2362+
proxy: &WlSurface,
2363+
event: <WlSurface as Proxy>::Event,
2364+
_data: &(),
2365+
_conn: &Connection,
2366+
_qhandle: &QueueHandle<Self>,
2367+
) {
2368+
let Some(unit) = state
2369+
.units
2370+
.iter_mut()
2371+
.find(|unit| unit.wl_surface == *proxy)
2372+
else {
2373+
return;
2374+
};
2375+
match event {
2376+
wl_surface::Event::Enter { output } => {
2377+
unit.wl_output.replace(output);
2378+
}
2379+
wl_surface::Event::Leave { output } => {
2380+
if !matches!(unit.shell, Shell::LayerShell(..))
2381+
&& unit
2382+
.wl_output
2383+
.as_ref()
2384+
.is_some_and(|i_output| i_output == &output)
2385+
{
2386+
unit.wl_output.take();
2387+
}
2388+
}
2389+
_ => {}
2390+
}
2391+
}
2392+
}
23552393

23562394
#[derive(Default)]
23572395
pub struct TextInputData {
@@ -2503,7 +2541,6 @@ impl<T> Dispatch<WlCallback, (id::Id, PresentAvailableState)> for WindowState<T>
25032541
}
25042542

25052543
delegate_noop!(@<T> WindowState<T>: ignore WlCompositor); // WlCompositor is need to create a surface
2506-
delegate_noop!(@<T> WindowState<T>: ignore WlSurface); // surface is the base needed to show buffer
25072544
delegate_noop!(@<T> WindowState<T>: ignore WlOutput); // output is need to place layer_shell, although here
25082545
// it is not used
25092546
delegate_noop!(@<T> WindowState<T>: ignore WlShm); // shm is used to create buffer pool
@@ -3374,6 +3411,10 @@ impl<T: 'static> WindowState<T> {
33743411
);
33753412
}
33763413
window_state.closed_ids.clear();
3414+
if window_state.units.is_empty() && !window_state.is_allscreens() {
3415+
signal.stop();
3416+
return true;
3417+
}
33773418

33783419
for idx in 0..window_state.units.len() {
33793420
let unit = &mut window_state.units[idx];

sessionlockev/src/lib.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ impl rwh_06::HasDisplayHandle for WindowWrapper {
309309
pub struct WindowStateUnit<T> {
310310
id: id::Id,
311311
display: WlDisplay,
312+
wl_output: wl_output::WlOutput,
312313
wl_surface: WlSurface,
313314
size: (u32, u32),
314315
buffer: Option<WlBuffer>,
@@ -793,9 +794,14 @@ impl<T: 'static> Dispatch<wl_registry::WlRegistry, ()> for WindowState<T> {
793794
}
794795
wl_registry::Event::GlobalRemove { name } => {
795796
state.outputs.retain(|x| x.0 != name);
796-
let removed_states = state
797-
.units
798-
.extract_if(.., |unit| !unit.wl_surface.is_alive());
797+
798+
let removed_states = state.units.extract_if(.., |unit| {
799+
!unit.wl_surface.is_alive()
800+
&& !state
801+
.outputs
802+
.iter()
803+
.any(|(_, storage)| storage == &unit.wl_output)
804+
});
799805
for deleled in removed_states.into_iter() {
800806
state.closed_ids.push(deleled.id);
801807
}
@@ -1465,11 +1471,11 @@ impl<T: 'static> WindowState<T> {
14651471
let lock_manager = globals.bind::<ExtSessionLockManagerV1, _, _>(&qh, 1..=1, ())?;
14661472
event_queue.blocking_dispatch(&mut self)?; // then make a dispatch
14671473
let lock = lock_manager.lock(&qh, ());
1468-
let displays = self.outputs.clone();
1469-
for (_, display) in displays.iter() {
1474+
let wl_outputs = self.outputs.clone();
1475+
for (_, wl_output) in wl_outputs.iter() {
14701476
let wl_surface = wmcompositer.create_surface(&qh, ()); // and create a surface. if two or more,
14711477
wl_surface.commit();
1472-
let session_lock_surface = lock.get_lock_surface(&wl_surface, display, &qh, ());
1478+
let session_lock_surface = lock.get_lock_surface(&wl_surface, wl_output, &qh, ());
14731479

14741480
// so during the init Configure of the shell, a buffer, atleast a buffer is needed.
14751481
// and if you need to reconfigure it, you need to commit the wl_surface again
@@ -1488,6 +1494,7 @@ impl<T: 'static> WindowState<T> {
14881494
id: id::Id::unique(),
14891495
display: connection.display(),
14901496
wl_surface,
1497+
wl_output: wl_output.clone(),
14911498
size: (0, 0),
14921499
buffer: None,
14931500
session_shell: session_lock_surface,
@@ -1637,11 +1644,11 @@ impl<T: 'static> WindowState<T> {
16371644
std::mem::swap(&mut messages, &mut window_state.message);
16381645
for msg in messages.iter() {
16391646
match msg {
1640-
(_, DispatchMessageInner::NewDisplay(display)) => {
1647+
(_, DispatchMessageInner::NewDisplay(wl_output)) => {
16411648
let wl_surface = wmcompositer.create_surface(&qh, ());
16421649
wl_surface.commit();
16431650
let session_lock_surface =
1644-
lock.get_lock_surface(&wl_surface, display, &qh, ());
1651+
lock.get_lock_surface(&wl_surface, wl_output, &qh, ());
16451652

16461653
let mut fractional_scale = None;
16471654
if let Some(ref fractional_scale_manager) = fractional_scale_manager {
@@ -1657,6 +1664,7 @@ impl<T: 'static> WindowState<T> {
16571664
window_state.push_window(WindowStateUnit {
16581665
id: id::Id::unique(),
16591666
display: connection.display(),
1667+
wl_output: wl_output.clone(),
16601668
wl_surface,
16611669
size: (0, 0),
16621670
buffer: None,

0 commit comments

Comments
 (0)