Skip to content

Commit 2243ab9

Browse files
committed
state: Move shell behind RwLock
1 parent fbaa0a2 commit 2243ab9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2506
-2018
lines changed

src/backend/kms/mod.rs

+78-49
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ use crate::{
1111
utils::prelude::*,
1212
wayland::{
1313
handlers::screencopy::{submit_buffer, FrameHolder, SessionData},
14-
protocols::screencopy::{
15-
FailureReason, Frame as ScreencopyFrame, Session as ScreencopySession,
14+
protocols::{
15+
screencopy::{FailureReason, Frame as ScreencopyFrame, Session as ScreencopySession},
16+
workspace::WorkspaceUpdateGuard,
1617
},
1718
},
1819
};
@@ -76,6 +77,7 @@ use smithay::{
7677
relative_pointer::RelativePointerManagerState,
7778
seat::WaylandFocus,
7879
shm::{shm_format_to_fourcc, with_buffer_contents},
80+
xdg_activation::XdgActivationState,
7981
},
8082
};
8183
use tracing::{error, info, trace, warn};
@@ -202,7 +204,7 @@ pub fn init_backend(
202204
state.backend.kms().input_devices.remove(device.name());
203205
}
204206
state.process_input_event(event, true);
205-
for output in state.common.shell.outputs() {
207+
for output in state.common.shell.read().unwrap().outputs() {
206208
if let Err(err) = state.backend.kms().schedule_render(
207209
&state.common.event_loop_handle,
208210
output,
@@ -326,9 +328,13 @@ pub fn init_backend(
326328
state.common.config.read_outputs(
327329
&mut state.common.output_configuration_state,
328330
&mut state.backend,
329-
&mut state.common.shell,
331+
&mut state.common.shell.write().unwrap(),
330332
&state.common.event_loop_handle,
333+
&mut state.common.workspace_state.update(),
334+
&state.common.xdg_activation_state,
331335
);
336+
state.common.refresh();
337+
332338
for surface in state
333339
.backend
334340
.kms()
@@ -339,7 +345,7 @@ pub fn init_backend(
339345
surface.scheduled = false;
340346
surface.pending = false;
341347
}
342-
for output in state.common.shell.outputs() {
348+
for output in state.common.shell.read().unwrap().outputs() {
343349
if let Err(err) = state.backend.kms().schedule_render(
344350
&state.common.event_loop_handle,
345351
output,
@@ -601,7 +607,7 @@ impl State {
601607

602608
let outputs = device.enumerate_surfaces()?.added; // There are no removed outputs on newly added devices
603609
let mut wl_outputs = Vec::new();
604-
let mut w = self.common.shell.global_space().size.w;
610+
let mut w = self.common.shell.read().unwrap().global_space().size.w;
605611
{
606612
let backend = self.backend.kms();
607613
backend
@@ -701,9 +707,12 @@ impl State {
701707
self.common.config.read_outputs(
702708
&mut self.common.output_configuration_state,
703709
&mut self.backend,
704-
&mut self.common.shell,
710+
&mut *self.common.shell.write().unwrap(),
705711
&self.common.event_loop_handle,
712+
&mut self.common.workspace_state.update(),
713+
&self.common.xdg_activation_state,
706714
);
715+
self.common.refresh();
707716

708717
Ok(())
709718
}
@@ -720,7 +729,7 @@ impl State {
720729
let backend = self.backend.kms();
721730
if let Some(device) = backend.devices.get_mut(&drm_node) {
722731
let changes = device.enumerate_surfaces()?;
723-
let mut w = self.common.shell.global_space().size.w;
732+
let mut w = self.common.shell.read().unwrap().global_space().size.w;
724733
for crtc in changes.removed {
725734
if let Some(pos) = device
726735
.non_desktop_connectors
@@ -831,18 +840,23 @@ impl State {
831840
self.common
832841
.output_configuration_state
833842
.add_heads(outputs_added.iter());
834-
self.common.config.read_outputs(
835-
&mut self.common.output_configuration_state,
836-
&mut self.backend,
837-
&mut self.common.shell,
838-
&self.common.event_loop_handle,
839-
);
840-
// Don't remove the outputs, before potentially new ones have been initialized.
841-
// reading a new config means outputs might become enabled, that were previously disabled.
842-
// If we have 0 outputs at some point, we won't quit, but shell doesn't know where to move
843-
// windows and workspaces to.
844-
for output in outputs_removed {
845-
self.common.shell.remove_output(&output);
843+
{
844+
self.common.config.read_outputs(
845+
&mut self.common.output_configuration_state,
846+
&mut self.backend,
847+
&mut *self.common.shell.write().unwrap(),
848+
&self.common.event_loop_handle,
849+
&mut self.common.workspace_state.update(),
850+
&self.common.xdg_activation_state,
851+
);
852+
self.common.refresh();
853+
// Don't remove the outputs, before potentially new ones have been initialized.
854+
// reading a new config means outputs might become enabled, that were previously disabled.
855+
// If we have 0 outputs at some point, we won't quit, but shell doesn't know where to move
856+
// windows and workspaces to.
857+
for output in outputs_removed {
858+
self.common.remove_output(&output);
859+
}
846860
}
847861

848862
{
@@ -889,14 +903,17 @@ impl State {
889903

890904
if self.backend.kms().session.is_active() {
891905
for output in outputs_removed {
892-
self.common.shell.remove_output(&output);
906+
self.common.remove_output(&output);
893907
}
894908
self.common.config.read_outputs(
895909
&mut self.common.output_configuration_state,
896910
&mut self.backend,
897-
&mut self.common.shell,
911+
&mut *self.common.shell.write().unwrap(),
898912
&self.common.event_loop_handle,
913+
&mut self.common.workspace_state.update(),
914+
&self.common.xdg_activation_state,
899915
);
916+
self.common.refresh();
900917
} else {
901918
self.common.output_configuration_state.update();
902919
}
@@ -1178,30 +1195,33 @@ impl Surface {
11781195
);
11791196
}
11801197

1181-
let (previous_workspace, workspace) = state.shell.workspaces.active(&self.output);
1182-
let (previous_idx, idx) = state.shell.workspaces.active_num(&self.output);
1183-
let previous_workspace = previous_workspace
1184-
.zip(previous_idx)
1185-
.map(|((w, start), idx)| (w.handle, idx, start));
1186-
let workspace = (workspace.handle, idx);
1187-
1188-
let mut elements = workspace_elements(
1189-
Some(&render_node),
1190-
&mut renderer,
1191-
&state.shell,
1192-
&state.config,
1193-
&state.theme,
1194-
state.clock.now(),
1195-
&self.output,
1196-
previous_workspace,
1197-
workspace,
1198-
CursorMode::All,
1199-
&mut Some(&mut self.fps),
1200-
false,
1201-
)
1202-
.map_err(|err| {
1203-
anyhow::format_err!("Failed to accumulate elements for rendering: {:?}", err)
1204-
})?;
1198+
let mut elements = {
1199+
let shell = state.shell.read().unwrap();
1200+
let (previous_workspace, workspace) = shell.workspaces.active(&self.output);
1201+
let (previous_idx, idx) = shell.workspaces.active_num(&self.output);
1202+
let previous_workspace = previous_workspace
1203+
.zip(previous_idx)
1204+
.map(|((w, start), idx)| (w.handle, idx, start));
1205+
let workspace = (workspace.handle, idx);
1206+
1207+
workspace_elements(
1208+
Some(&render_node),
1209+
&mut renderer,
1210+
&*shell,
1211+
&state.config,
1212+
&state.theme,
1213+
state.clock.now(),
1214+
&self.output,
1215+
previous_workspace,
1216+
workspace,
1217+
CursorMode::All,
1218+
&mut Some(&mut self.fps),
1219+
false,
1220+
)
1221+
.map_err(|err| {
1222+
anyhow::format_err!("Failed to accumulate elements for rendering: {:?}", err)
1223+
})?
1224+
};
12051225
self.fps.elements();
12061226

12071227
let frames: Vec<(
@@ -1490,6 +1510,8 @@ impl KmsState {
14901510
shell: &mut Shell,
14911511
test_only: bool,
14921512
loop_handle: &LoopHandle<'_, State>,
1513+
workspace_state: &mut WorkspaceUpdateGuard<'_, State>,
1514+
xdg_activation_state: &XdgActivationState,
14931515
) -> Result<(), anyhow::Error> {
14941516
let recreated = if let Some(device) = self
14951517
.devices
@@ -1509,7 +1531,12 @@ impl KmsState {
15091531

15101532
if !output_config.enabled {
15111533
if !test_only {
1512-
shell.remove_output(output);
1534+
shell.workspaces.remove_output(
1535+
output,
1536+
shell.seats.iter(),
1537+
workspace_state,
1538+
xdg_activation_state,
1539+
);
15131540
if surface.surface.take().is_some() {
15141541
// just drop it
15151542
surface.pending = false;
@@ -1608,7 +1635,9 @@ impl KmsState {
16081635
surface.surface = Some(target);
16091636
true
16101637
};
1611-
shell.add_output(output);
1638+
shell
1639+
.workspaces
1640+
.add_output(output, workspace_state, xdg_activation_state);
16121641
res
16131642
} else {
16141643
false
@@ -1748,7 +1777,7 @@ impl KmsState {
17481777
&surface.output,
17491778
backend.primary_node,
17501779
target_node,
1751-
&common.shell,
1780+
&*common.shell.read().unwrap(),
17521781
);
17531782

17541783
let result = if render_node != target_node {

src/backend/mod.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,26 @@ pub fn init_backend_auto(
4545
let output = state
4646
.common
4747
.shell
48+
.read()
49+
.unwrap()
4850
.outputs()
4951
.next()
50-
.with_context(|| "Backend initialized without output")?;
52+
.with_context(|| "Backend initialized without output")
53+
.cloned()?;
5154
let initial_seat = crate::shell::create_seat(
5255
dh,
5356
&mut state.common.seat_state,
54-
output,
57+
&output,
5558
&state.common.config,
5659
"seat-0".into(),
5760
);
58-
state.common.shell.seats.add_seat(initial_seat);
61+
state
62+
.common
63+
.shell
64+
.write()
65+
.unwrap()
66+
.seats
67+
.add_seat(initial_seat);
5968
}
6069
res
6170
}

src/backend/winit.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl WinitState {
6363
surface.clone(),
6464
&mut self.damage_tracker,
6565
age,
66-
&state.shell,
66+
&*state.shell.read().unwrap(),
6767
&state.config,
6868
&state.theme,
6969
state.clock.now(),
@@ -201,7 +201,7 @@ pub fn init_backend(
201201
}
202202
PumpStatus::Exit(_) => {
203203
let output = state.backend.winit().output.clone();
204-
state.common.shell.remove_output(&output);
204+
state.common.remove_output(&output);
205205
if let Some(token) = token.take() {
206206
event_loop_handle.remove(token);
207207
}
@@ -226,13 +226,21 @@ pub fn init_backend(
226226
.common
227227
.output_configuration_state
228228
.add_heads(std::iter::once(&output));
229-
state.common.shell.add_output(&output);
230-
state.common.config.read_outputs(
231-
&mut state.common.output_configuration_state,
232-
&mut state.backend,
233-
&mut state.common.shell,
234-
&state.common.event_loop_handle,
235-
);
229+
{
230+
state.common.add_output(&output);
231+
let mut shell = state.common.shell.write().unwrap();
232+
state.common.config.read_outputs(
233+
&mut state.common.output_configuration_state,
234+
&mut state.backend,
235+
&mut *shell,
236+
&state.common.event_loop_handle,
237+
&mut state.common.workspace_state.update(),
238+
&state.common.xdg_activation_state,
239+
);
240+
241+
std::mem::drop(shell);
242+
state.common.refresh();
243+
}
236244
state.launch_xwayland(None);
237245

238246
Ok(())
@@ -299,7 +307,7 @@ impl State {
299307
// here we can handle special cases for winit inputs
300308
match event {
301309
WinitEvent::Focus(true) => {
302-
for seat in self.common.shell.seats.iter() {
310+
for seat in self.common.shell.read().unwrap().seats.iter() {
303311
let devices = seat.user_data().get::<Devices>().unwrap();
304312
if devices.has_device(&WinitVirtualDevice) {
305313
seat.set_active_output(&self.backend.winit().output);

src/backend/x11.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ impl Surface {
222222
buffer.clone(),
223223
&mut self.damage_tracker,
224224
age as usize,
225-
&state.shell,
225+
&*state.shell.read().unwrap(),
226226
&state.config,
227227
&state.theme,
228228
state.clock.now(),
@@ -364,13 +364,21 @@ pub fn init_backend(
364364
.common
365365
.output_configuration_state
366366
.add_heads(std::iter::once(&output));
367-
state.common.shell.add_output(&output);
368-
state.common.config.read_outputs(
369-
&mut state.common.output_configuration_state,
370-
&mut state.backend,
371-
&mut state.common.shell,
372-
&state.common.event_loop_handle,
373-
);
367+
{
368+
state.common.add_output(&output);
369+
let mut shell = state.common.shell.write().unwrap();
370+
state.common.config.read_outputs(
371+
&mut state.common.output_configuration_state,
372+
&mut state.backend,
373+
&mut *shell,
374+
&state.common.event_loop_handle,
375+
&mut state.common.workspace_state.update(),
376+
&state.common.xdg_activation_state,
377+
);
378+
379+
std::mem::drop(shell);
380+
state.common.refresh();
381+
}
374382
state.launch_xwayland(None);
375383

376384
event_loop
@@ -395,7 +403,7 @@ pub fn init_backend(
395403
.surfaces
396404
.retain(|s| s.window.id() != window_id);
397405
for output in outputs_removed.into_iter() {
398-
state.common.shell.remove_output(&output);
406+
state.common.remove_output(&output);
399407
}
400408
}
401409
X11Event::Resized {
@@ -504,7 +512,7 @@ impl State {
504512
.unwrap();
505513

506514
let device = event.device();
507-
for seat in self.common.shell.seats.iter() {
515+
for seat in self.common.shell.read().unwrap().seats.iter() {
508516
let devices = seat.user_data().get::<Devices>().unwrap();
509517
if devices.has_device(&device) {
510518
seat.set_active_output(&output);
@@ -518,7 +526,7 @@ impl State {
518526

519527
self.process_input_event(event, false);
520528
// TODO actually figure out the output
521-
for output in self.common.shell.outputs() {
529+
for output in self.common.shell.read().unwrap().outputs() {
522530
self.backend.x11().schedule_render(output);
523531
}
524532
}

0 commit comments

Comments
 (0)