Skip to content

Commit

Permalink
state: Move shell behind RwLock
Browse files Browse the repository at this point in the history
  • Loading branch information
Drakulix committed Apr 16, 2024
1 parent 647deb8 commit 5d5a510
Show file tree
Hide file tree
Showing 45 changed files with 2,633 additions and 2,073 deletions.
127 changes: 78 additions & 49 deletions src/backend/kms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ use crate::{
utils::prelude::*,
wayland::{
handlers::screencopy::{submit_buffer, FrameHolder, SessionData},
protocols::screencopy::{
FailureReason, Frame as ScreencopyFrame, Session as ScreencopySession,
protocols::{
screencopy::{FailureReason, Frame as ScreencopyFrame, Session as ScreencopySession},
workspace::WorkspaceUpdateGuard,
},
},
};
Expand Down Expand Up @@ -76,6 +77,7 @@ use smithay::{
relative_pointer::RelativePointerManagerState,
seat::WaylandFocus,
shm::{shm_format_to_fourcc, with_buffer_contents},
xdg_activation::XdgActivationState,
},
};
use tracing::{error, info, trace, warn};
Expand Down Expand Up @@ -202,7 +204,7 @@ pub fn init_backend(
state.backend.kms().input_devices.remove(device.name());
}
state.process_input_event(event, true);
for output in state.common.shell.outputs() {
for output in state.common.shell.read().unwrap().outputs() {
if let Err(err) = state.backend.kms().schedule_render(
&state.common.event_loop_handle,
output,
Expand Down Expand Up @@ -326,9 +328,13 @@ pub fn init_backend(
state.common.config.read_outputs(
&mut state.common.output_configuration_state,
&mut state.backend,
&mut state.common.shell,
&mut state.common.shell.write().unwrap(),
&state.common.event_loop_handle,
&mut state.common.workspace_state.update(),
&state.common.xdg_activation_state,
);
state.common.refresh();

for surface in state
.backend
.kms()
Expand All @@ -339,7 +345,7 @@ pub fn init_backend(
surface.scheduled = false;
surface.pending = false;
}
for output in state.common.shell.outputs() {
for output in state.common.shell.read().unwrap().outputs() {
if let Err(err) = state.backend.kms().schedule_render(
&state.common.event_loop_handle,
output,
Expand Down Expand Up @@ -601,7 +607,7 @@ impl State {

let outputs = device.enumerate_surfaces()?.added; // There are no removed outputs on newly added devices
let mut wl_outputs = Vec::new();
let mut w = self.common.shell.global_space().size.w;
let mut w = self.common.shell.read().unwrap().global_space().size.w;
{
let backend = self.backend.kms();
backend
Expand Down Expand Up @@ -701,9 +707,12 @@ impl State {
self.common.config.read_outputs(
&mut self.common.output_configuration_state,
&mut self.backend,
&mut self.common.shell,
&mut *self.common.shell.write().unwrap(),
&self.common.event_loop_handle,
&mut self.common.workspace_state.update(),
&self.common.xdg_activation_state,
);
self.common.refresh();

Ok(())
}
Expand All @@ -720,7 +729,7 @@ impl State {
let backend = self.backend.kms();
if let Some(device) = backend.devices.get_mut(&drm_node) {
let changes = device.enumerate_surfaces()?;
let mut w = self.common.shell.global_space().size.w;
let mut w = self.common.shell.read().unwrap().global_space().size.w;
for crtc in changes.removed {
if let Some(pos) = device
.non_desktop_connectors
Expand Down Expand Up @@ -831,18 +840,23 @@ impl State {
self.common
.output_configuration_state
.add_heads(outputs_added.iter());
self.common.config.read_outputs(
&mut self.common.output_configuration_state,
&mut self.backend,
&mut self.common.shell,
&self.common.event_loop_handle,
);
// Don't remove the outputs, before potentially new ones have been initialized.
// reading a new config means outputs might become enabled, that were previously disabled.
// If we have 0 outputs at some point, we won't quit, but shell doesn't know where to move
// windows and workspaces to.
for output in outputs_removed {
self.common.shell.remove_output(&output);
{
self.common.config.read_outputs(
&mut self.common.output_configuration_state,
&mut self.backend,
&mut *self.common.shell.write().unwrap(),
&self.common.event_loop_handle,
&mut self.common.workspace_state.update(),
&self.common.xdg_activation_state,
);
self.common.refresh();
// Don't remove the outputs, before potentially new ones have been initialized.
// reading a new config means outputs might become enabled, that were previously disabled.
// If we have 0 outputs at some point, we won't quit, but shell doesn't know where to move
// windows and workspaces to.
for output in outputs_removed {
self.common.remove_output(&output);
}
}

{
Expand Down Expand Up @@ -889,14 +903,17 @@ impl State {

if self.backend.kms().session.is_active() {
for output in outputs_removed {
self.common.shell.remove_output(&output);
self.common.remove_output(&output);
}
self.common.config.read_outputs(
&mut self.common.output_configuration_state,
&mut self.backend,
&mut self.common.shell,
&mut *self.common.shell.write().unwrap(),
&self.common.event_loop_handle,
&mut self.common.workspace_state.update(),
&self.common.xdg_activation_state,
);
self.common.refresh();
} else {
self.common.output_configuration_state.update();
}
Expand Down Expand Up @@ -1178,30 +1195,33 @@ impl Surface {
);
}

let (previous_workspace, workspace) = state.shell.workspaces.active(&self.output);
let (previous_idx, idx) = state.shell.workspaces.active_num(&self.output);
let previous_workspace = previous_workspace
.zip(previous_idx)
.map(|((w, start), idx)| (w.handle, idx, start));
let workspace = (workspace.handle, idx);

let mut elements = workspace_elements(
Some(&render_node),
&mut renderer,
&state.shell,
&state.config,
&state.theme,
state.clock.now(),
&self.output,
previous_workspace,
workspace,
CursorMode::All,
&mut Some(&mut self.fps),
false,
)
.map_err(|err| {
anyhow::format_err!("Failed to accumulate elements for rendering: {:?}", err)
})?;
let mut elements = {
let shell = state.shell.read().unwrap();
let (previous_workspace, workspace) = shell.workspaces.active(&self.output);
let (previous_idx, idx) = shell.workspaces.active_num(&self.output);
let previous_workspace = previous_workspace
.zip(previous_idx)
.map(|((w, start), idx)| (w.handle, idx, start));
let workspace = (workspace.handle, idx);

workspace_elements(
Some(&render_node),
&mut renderer,
&*shell,
&state.config,
&state.theme,
state.clock.now(),
&self.output,
previous_workspace,
workspace,
CursorMode::All,
&mut Some(&mut self.fps),
false,
)
.map_err(|err| {
anyhow::format_err!("Failed to accumulate elements for rendering: {:?}", err)
})?
};
self.fps.elements();

let frames: Vec<(
Expand Down Expand Up @@ -1490,6 +1510,8 @@ impl KmsState {
shell: &mut Shell,
test_only: bool,
loop_handle: &LoopHandle<'_, State>,
workspace_state: &mut WorkspaceUpdateGuard<'_, State>,
xdg_activation_state: &XdgActivationState,
) -> Result<(), anyhow::Error> {
let recreated = if let Some(device) = self
.devices
Expand All @@ -1509,7 +1531,12 @@ impl KmsState {

if !output_config.enabled {
if !test_only {
shell.remove_output(output);
shell.workspaces.remove_output(
output,
shell.seats.iter(),
workspace_state,
xdg_activation_state,
);
if surface.surface.take().is_some() {
// just drop it
surface.pending = false;
Expand Down Expand Up @@ -1608,7 +1635,9 @@ impl KmsState {
surface.surface = Some(target);
true
};
shell.add_output(output);
shell
.workspaces
.add_output(output, workspace_state, xdg_activation_state);
res
} else {
false
Expand Down Expand Up @@ -1748,7 +1777,7 @@ impl KmsState {
&surface.output,
backend.primary_node,
target_node,
&common.shell,
&*common.shell.read().unwrap(),
);

let result = if render_node != target_node {
Expand Down
15 changes: 12 additions & 3 deletions src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,26 @@ pub fn init_backend_auto(
let output = state
.common
.shell
.read()
.unwrap()
.outputs()
.next()
.with_context(|| "Backend initialized without output")?;
.with_context(|| "Backend initialized without output")
.cloned()?;
let initial_seat = crate::shell::create_seat(
dh,
&mut state.common.seat_state,
output,
&output,
&state.common.config,
"seat-0".into(),
);
state.common.shell.seats.add_seat(initial_seat);
state
.common
.shell
.write()
.unwrap()
.seats
.add_seat(initial_seat);
}
res
}
28 changes: 18 additions & 10 deletions src/backend/winit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl WinitState {
surface.clone(),
&mut self.damage_tracker,
age,
&state.shell,
&*state.shell.read().unwrap(),
&state.config,
&state.theme,
state.clock.now(),
Expand Down Expand Up @@ -201,7 +201,7 @@ pub fn init_backend(
}
PumpStatus::Exit(_) => {
let output = state.backend.winit().output.clone();
state.common.shell.remove_output(&output);
state.common.remove_output(&output);
if let Some(token) = token.take() {
event_loop_handle.remove(token);
}
Expand All @@ -226,13 +226,21 @@ pub fn init_backend(
.common
.output_configuration_state
.add_heads(std::iter::once(&output));
state.common.shell.add_output(&output);
state.common.config.read_outputs(
&mut state.common.output_configuration_state,
&mut state.backend,
&mut state.common.shell,
&state.common.event_loop_handle,
);
{
state.common.add_output(&output);
let mut shell = state.common.shell.write().unwrap();
state.common.config.read_outputs(
&mut state.common.output_configuration_state,
&mut state.backend,
&mut *shell,
&state.common.event_loop_handle,
&mut state.common.workspace_state.update(),
&state.common.xdg_activation_state,
);

std::mem::drop(shell);
state.common.refresh();
}
state.launch_xwayland(None);

Ok(())
Expand Down Expand Up @@ -299,7 +307,7 @@ impl State {
// here we can handle special cases for winit inputs
match event {
WinitEvent::Focus(true) => {
for seat in self.common.shell.seats.iter() {
for seat in self.common.shell.read().unwrap().seats.iter() {
let devices = seat.user_data().get::<Devices>().unwrap();
if devices.has_device(&WinitVirtualDevice) {
seat.set_active_output(&self.backend.winit().output);
Expand Down
30 changes: 19 additions & 11 deletions src/backend/x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ impl Surface {
buffer.clone(),
&mut self.damage_tracker,
age as usize,
&state.shell,
&*state.shell.read().unwrap(),
&state.config,
&state.theme,
state.clock.now(),
Expand Down Expand Up @@ -364,13 +364,21 @@ pub fn init_backend(
.common
.output_configuration_state
.add_heads(std::iter::once(&output));
state.common.shell.add_output(&output);
state.common.config.read_outputs(
&mut state.common.output_configuration_state,
&mut state.backend,
&mut state.common.shell,
&state.common.event_loop_handle,
);
{
state.common.add_output(&output);
let mut shell = state.common.shell.write().unwrap();
state.common.config.read_outputs(
&mut state.common.output_configuration_state,
&mut state.backend,
&mut *shell,
&state.common.event_loop_handle,
&mut state.common.workspace_state.update(),
&state.common.xdg_activation_state,
);

std::mem::drop(shell);
state.common.refresh();
}
state.launch_xwayland(None);

event_loop
Expand All @@ -395,7 +403,7 @@ pub fn init_backend(
.surfaces
.retain(|s| s.window.id() != window_id);
for output in outputs_removed.into_iter() {
state.common.shell.remove_output(&output);
state.common.remove_output(&output);
}
}
X11Event::Resized {
Expand Down Expand Up @@ -504,7 +512,7 @@ impl State {
.unwrap();

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

self.process_input_event(event, false);
// TODO actually figure out the output
for output in self.common.shell.outputs() {
for output in self.common.shell.read().unwrap().outputs() {
self.backend.x11().schedule_render(output);
}
}
Expand Down
Loading

0 comments on commit 5d5a510

Please sign in to comment.