shell: Using parking_lot's RwLock for fairness guarantees

This commit is contained in:
Victoria Brekenfeld 2025-05-20 17:41:27 +02:00 committed by Victoria Brekenfeld
parent 8194be30c6
commit 465813c1c5
42 changed files with 247 additions and 396 deletions

View file

@ -12,7 +12,7 @@ impl A11yHandler for State {
}
fn request_screen_magnifier(&mut self, enabled: bool) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if shell
.zoom_state()

View file

@ -173,7 +173,7 @@ impl CompositorHandler for State {
// handle initial configure events and map windows if necessary
let mapped = self.send_initial_configure_and_map(surface);
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
// schedule a new render
if let Some(output) = shell.visible_output_for_surface(surface) {
@ -277,7 +277,7 @@ impl CompositorHandler for State {
impl State {
fn send_initial_configure_and_map(&mut self, surface: &WlSurface) -> bool {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(pending) = shell
.pending_windows

View file

@ -114,14 +114,14 @@ pub fn unset_mode(mapped: &CosmicMapped, surface: &WlSurface) {
impl XdgDecorationHandler for State {
fn new_decoration(&mut self, toplevel: ToplevelSurface) {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
new_decoration(mapped, toplevel.wl_surface());
}
}
fn request_mode(&mut self, toplevel: ToplevelSurface, mode: XdgMode) {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
request_mode(mapped, toplevel.wl_surface(), mode);
} else {
@ -130,7 +130,7 @@ impl XdgDecorationHandler for State {
}
fn unset_mode(&mut self, toplevel: ToplevelSurface) {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
if let Some(mapped) = shell.element_for_surface(toplevel.wl_surface()) {
unset_mode(mapped, toplevel.wl_surface())
}
@ -143,7 +143,7 @@ impl KdeDecorationHandler for State {
}
fn new_decoration(&mut self, surface: &WlSurface, decoration: &OrgKdeKwinServerDecoration) {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
if let Some(mapped) = shell.element_for_surface(surface) {
let mode = new_decoration(mapped, surface);
decoration.mode(mode);
@ -157,7 +157,7 @@ impl KdeDecorationHandler for State {
mode: WEnum<KdeMode>,
) {
if let WEnum::Value(mode) = mode {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
// TODO: We need to store this value until it gets mapped and apply it then, if it is not mapped yet.
if let Some(mapped) = shell.element_for_surface(surface) {
request_mode(
@ -174,7 +174,7 @@ impl KdeDecorationHandler for State {
}
fn release(&mut self, _decoration: &OrgKdeKwinServerDecoration, surface: &WlSurface) {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
if let Some(mapped) = shell.element_for_surface(surface) {
unset_mode(mapped, surface)
}

View file

@ -42,20 +42,11 @@ impl FractionalScaleHandler for State {
self.common
.shell
.read()
.unwrap()
.visible_output_for_surface(&surface)
.cloned()
})
})
.unwrap_or_else(|| {
self.common
.shell
.read()
.unwrap()
.seats
.last_active()
.active_output()
});
.unwrap_or_else(|| self.common.shell.read().seats.last_active().active_output());
with_states(&surface, |states| {
with_fractional_scale(states, |fractional_scale| {

View file

@ -27,7 +27,6 @@ impl InputMethodHandler for State {
self.common
.shell
.read()
.unwrap()
.element_for_surface(parent)
.map(|e| e.geometry())
.unwrap_or_default()

View file

@ -26,7 +26,7 @@ impl WlrLayerShellHandler for State {
_layer: Layer,
namespace: String,
) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let seat = shell.seats.last_active().clone();
let output = wl_output
.as_ref()
@ -40,7 +40,7 @@ impl WlrLayerShellHandler for State {
}
fn new_popup(&mut self, _parent: WlrLayerSurface, popup: PopupSurface) {
self.common.shell.read().unwrap().unconstrain_popup(&popup);
self.common.shell.read().unconstrain_popup(&popup);
if popup.send_configure().is_ok() {
self.common
@ -51,7 +51,7 @@ impl WlrLayerShellHandler for State {
}
fn layer_destroyed(&mut self, surface: WlrLayerSurface) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let maybe_output = shell
.outputs()
.find(|o| {

View file

@ -22,7 +22,7 @@ impl OverlapNotifyHandler for State {
.layer_surfaces()
.find(|l| l.shell_surface() == &resource)
.and_then(|l| {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
let outputs = shell.outputs();
let ret = outputs.map(|o| layer_map_for_output(o)).find_map(|s| {
s.layer_for_surface(l.wl_surface(), WindowSurfaceType::ALL)
@ -34,14 +34,14 @@ impl OverlapNotifyHandler for State {
}
fn outputs(&self) -> impl Iterator<Item = Output> {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
shell.outputs().cloned().collect::<Vec<_>>().into_iter()
}
fn active_workspaces(
&self,
) -> impl Iterator<Item = crate::wayland::protocols::workspace::WorkspaceHandle> {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
shell
.workspaces
.sets

View file

@ -51,7 +51,7 @@ impl ScreencopyHandler for State {
.upgrade()
.and_then(|output| constraints_for_output(&output, &mut self.backend)),
ImageCaptureSourceData::Workspace(handle) => {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
let output = shell.workspaces.space_for_handle(&handle)?.output();
constraints_for_output(output, &mut self.backend)
}
@ -69,7 +69,6 @@ impl ScreencopyHandler for State {
.common
.shell
.read()
.unwrap()
.seats
.last_active()
.cursor_geometry((0.0, 0.0), self.common.clock.now())
@ -103,7 +102,7 @@ impl ScreencopyHandler for State {
output.add_session(session);
}
ImageCaptureSourceData::Workspace(handle) => {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let Some(workspace) = shell.workspaces.space_for_handle_mut(&handle) else {
session.stop();
return;
@ -132,14 +131,7 @@ impl ScreencopyHandler for State {
}
fn new_cursor_session(&mut self, session: CursorSession) {
let (pointer_loc, pointer_size, hotspot) = {
let seat = self
.common
.shell
.read()
.unwrap()
.seats
.last_active()
.clone();
let seat = self.common.shell.read().seats.last_active().clone();
let pointer = seat.get_pointer().unwrap();
let pointer_loc = pointer.current_location().to_i32_round().as_global();
@ -194,7 +186,7 @@ impl ScreencopyHandler for State {
output.add_cursor_session(session);
}
ImageCaptureSourceData::Workspace(handle) => {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let Some(workspace) = shell.workspaces.space_for_handle_mut(&handle) else {
return;
};
@ -225,7 +217,7 @@ impl ScreencopyHandler for State {
workspace.add_cursor_session(session);
}
ImageCaptureSourceData::Toplevel(mut toplevel) => {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
if let Some(element) = shell.element_for_surface(&toplevel) {
if element.has_active_window(&toplevel) {
if let Some(workspace) = shell.space_for(element) {
@ -277,19 +269,12 @@ impl ScreencopyHandler for State {
return;
}
let seat = self
.common
.shell
.read()
.unwrap()
.seats
.last_active()
.clone();
let seat = self.common.shell.read().seats.last_active().clone();
render_cursor_to_buffer(self, &session, frame, &seat);
}
fn frame_aborted(&mut self, frame: FrameRef) {
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
for mut output in shell.outputs().cloned() {
output.remove_frame(&frame);
}
@ -307,7 +292,6 @@ impl ScreencopyHandler for State {
.common
.shell
.write()
.unwrap()
.workspaces
.space_for_handle_mut(&handle)
{
@ -331,7 +315,6 @@ impl ScreencopyHandler for State {
.common
.shell
.write()
.unwrap()
.workspaces
.space_for_handle_mut(&handle)
{

View file

@ -209,7 +209,7 @@ pub fn render_workspace_to_buffer(
frame: Frame,
handle: WorkspaceHandle,
) {
let shell = state.common.shell.read().unwrap();
let shell = state.common.shell.read();
let Some(workspace) = shell.workspaces.space_for_handle(&handle) else {
return;
};
@ -509,7 +509,7 @@ pub fn render_window_to_buffer(
.map(Into::<WindowCaptureElement<R>>::into),
);
let shell = common.shell.read().unwrap();
let shell = common.shell.read();
let seat = shell.seats.last_active().clone();
let location = if let Some(mapped) = shell.element_for_surface(window) {
mapped.cursor_position(&seat).and_then(|mut p| {

View file

@ -18,7 +18,7 @@ impl SessionLockHandler for State {
}
fn lock(&mut self, locker: SessionLocker) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
// Reject lock if sesion lock exists and is still valid
if let Some(session_lock) = shell.session_lock.as_ref() {
@ -45,7 +45,7 @@ impl SessionLockHandler for State {
}
fn unlock(&mut self) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
shell.session_lock = None;
for output in shell.outputs() {
@ -54,7 +54,7 @@ impl SessionLockHandler for State {
}
fn new_surface(&mut self, lock_surface: LockSurface, wl_output: WlOutput) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(session_lock) = &mut shell.session_lock {
if let Some(output) = Output::from_resource(&wl_output) {
lock_surface.with_pending_state(|states| {

View file

@ -34,7 +34,7 @@ impl ToplevelManagementHandler for State {
) {
self.unminimize(dh, window);
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
for output in shell.outputs().cloned().collect::<Vec<_>>().iter() {
let maybe = shell
.workspaces
@ -120,7 +120,7 @@ impl ToplevelManagementHandler for State {
to_handle: WorkspaceHandle,
_output: Output,
) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mut mapped) = shell.element_for_surface(window).cloned() {
if let Some(from_workspace) = shell.space_for_mut(&mapped) {
// If window is part of a stack, remove it and map it outside the stack
@ -168,7 +168,7 @@ impl ToplevelManagementHandler for State {
window: &<Self as ToplevelInfoHandler>::Window,
output: Option<Output>,
) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let seat = shell.seats.last_active().clone();
if let Some(mapped) = shell.element_for_surface(window).cloned() {
if let Some((output, workspace)) =
@ -195,7 +195,7 @@ impl ToplevelManagementHandler for State {
_dh: &DisplayHandle,
window: &<Self as ToplevelInfoHandler>::Window,
) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(window).cloned() {
if let Some(workspace) = shell.space_for_mut(&mapped) {
if let Some((layer, previous_workspace)) = workspace.unfullscreen_request(window) {
@ -219,7 +219,7 @@ impl ToplevelManagementHandler for State {
}
fn maximize(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(window).cloned() {
let seat = shell.seats.last_active().clone();
shell.maximize_request(&mapped, &seat, true);
@ -227,14 +227,14 @@ impl ToplevelManagementHandler for State {
}
fn unmaximize(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(window).cloned() {
shell.unmaximize_request(&mapped);
}
}
fn minimize(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(window).cloned() {
if !mapped.is_stack() || &mapped.active_window() == window {
shell.minimize_request(&mapped);
@ -243,7 +243,7 @@ impl ToplevelManagementHandler for State {
}
fn unminimize(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(window).cloned() {
let seat = shell.seats.last_active().clone();
shell.unminimize_request(&mapped, &seat);
@ -258,7 +258,7 @@ impl ToplevelManagementHandler for State {
return;
}
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(window).cloned() {
let seat = shell.seats.last_active().clone();
shell.toggle_sticky(&seat, &mapped);
@ -274,7 +274,7 @@ impl ToplevelManagementHandler for State {
return;
}
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(window).cloned() {
let seat = shell.seats.last_active().clone();
shell.toggle_sticky(&seat, &mapped);

View file

@ -22,7 +22,7 @@ impl WorkspaceHandler for State {
for request in requests.into_iter() {
match request {
Request::Activate(handle) => {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let maybe = shell.workspaces.iter().find_map(|(o, set)| {
set.workspaces
.iter()
@ -41,7 +41,7 @@ impl WorkspaceHandler for State {
}
}
Request::SetTilingState { workspace, state } => {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let seat = shell.seats.last_active().clone();
if let Some(workspace) = shell.workspaces.space_for_handle_mut(&workspace) {
let mut guard = self.common.workspace_state.update();
@ -56,7 +56,7 @@ impl WorkspaceHandler for State {
}
}
Request::SetPin { workspace, pinned } => {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(workspace) = shell.workspaces.space_for_handle_mut(&workspace) {
workspace.pinned = pinned;
let mut update = self.common.workspace_state.update();
@ -78,7 +78,7 @@ impl WorkspaceHandler for State {
if axis != 0 {
continue;
}
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let mut update = self.common.workspace_state.update();
shell.workspaces.move_workspace(
&workspace,
@ -95,7 +95,7 @@ impl WorkspaceHandler for State {
if axis != 0 {
continue;
}
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let mut update = self.common.workspace_state.update();
shell.workspaces.move_workspace(
&workspace,

View file

@ -43,7 +43,7 @@ impl XdgActivationHandler for State {
{
if let Some(seat) = data.serial.and_then(|(_, seat)| Seat::from_resource(&seat)) {
let output = seat.active_output();
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let workspace = shell.active_space_mut(&output).unwrap();
let handle = workspace.handle;
data.user_data
@ -86,7 +86,7 @@ impl XdgActivationHandler for State {
if valid {
let output = seat.active_output();
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let workspace = shell.active_space_mut(&output).unwrap();
let handle = workspace.handle;
data.user_data
@ -107,7 +107,7 @@ impl XdgActivationHandler for State {
surface: WlSurface,
) {
if let Some(context) = token_data.user_data.get::<ActivationContext>() {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(element) = shell.element_for_surface(&surface).cloned() {
match context {
ActivationContext::UrgentOnly => {

View file

@ -45,7 +45,7 @@ impl XdgShellHandler for State {
}
fn new_toplevel(&mut self, surface: ToplevelSurface) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let seat = shell.seats.last_active().clone();
let window = CosmicSurface::from(surface);
shell.pending_windows.push(PendingWindow {
@ -65,11 +65,7 @@ impl XdgShellHandler for State {
if surface.get_parent_surface().is_some() {
// let other shells deal with their popups
self.common
.shell
.read()
.unwrap()
.unconstrain_popup(&surface);
self.common.shell.read().unconstrain_popup(&surface);
if surface.send_configure().is_ok() {
self.common
@ -83,14 +79,9 @@ impl XdgShellHandler for State {
fn grab(&mut self, surface: PopupSurface, seat: WlSeat, serial: Serial) {
let seat = Seat::from_resource(&seat).unwrap();
let kind = PopupKind::Xdg(surface);
let maybe_root = find_popup_root_surface(&kind).ok().and_then(|root| {
self.common
.shell
.read()
.unwrap()
.element_for_surface(&root)
.cloned()
});
let maybe_root = find_popup_root_surface(&kind)
.ok()
.and_then(|root| self.common.shell.read().element_for_surface(&root).cloned());
if let Some(root) = maybe_root {
let target = root.into();
@ -149,11 +140,7 @@ impl XdgShellHandler for State {
state.positioner = positioner;
});
self.common
.shell
.read()
.unwrap()
.unconstrain_popup(&surface);
self.common.shell.read().unconstrain_popup(&surface);
surface.send_repositioned(token);
if let Err(err) = surface.send_configure() {
warn!(
@ -165,7 +152,7 @@ impl XdgShellHandler for State {
fn move_request(&mut self, surface: ToplevelSurface, seat: WlSeat, serial: Serial) {
let seat = Seat::from_resource(&seat).unwrap();
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some((grab, focus)) = shell.move_request(
surface.wl_surface(),
&seat,
@ -195,7 +182,7 @@ impl XdgShellHandler for State {
edges: xdg_toplevel::ResizeEdge,
) {
let seat = Seat::from_resource(&seat).unwrap();
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some((grab, focus)) = shell.resize_request(
surface.wl_surface(),
&seat,
@ -216,7 +203,7 @@ impl XdgShellHandler for State {
}
fn minimize_request(&mut self, surface: ToplevelSurface) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(surface.wl_surface()).cloned() {
if !mapped.is_stack()
|| mapped.active_window().wl_surface().as_deref() == Some(surface.wl_surface())
@ -227,7 +214,7 @@ impl XdgShellHandler for State {
}
fn maximize_request(&mut self, surface: ToplevelSurface) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(surface.wl_surface()).cloned() {
let seat = shell.seats.last_active().clone();
shell.maximize_request(&mapped, &seat, true)
@ -241,7 +228,7 @@ impl XdgShellHandler for State {
}
fn unmaximize_request(&mut self, surface: ToplevelSurface) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(surface.wl_surface()).cloned() {
shell.unmaximize_request(&mapped);
} else if let Some(pending) = shell
@ -254,7 +241,7 @@ impl XdgShellHandler for State {
}
fn fullscreen_request(&mut self, surface: ToplevelSurface, output: Option<WlOutput>) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let seat = shell.seats.last_active().clone();
let Some(focused_output) = seat.focused_output() else {
return;
@ -373,7 +360,7 @@ impl XdgShellHandler for State {
}
fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
if let Some(mapped) = shell.element_for_surface(surface.wl_surface()).cloned() {
if let Some(workspace) = shell.space_for_mut(&mapped) {
let (window, _) = mapped
@ -408,7 +395,7 @@ impl XdgShellHandler for State {
fn toplevel_destroyed(&mut self, surface: ToplevelSurface) {
let (output, clients) = {
let mut shell = self.common.shell.write().unwrap();
let mut shell = self.common.shell.write();
let seat = shell.seats.last_active().clone();
shell.unmap_surface(
surface.wl_surface(),
@ -457,7 +444,7 @@ impl XdgShellHandler for State {
.unwrap_or_default()
.loc;
let shell = self.common.shell.read().unwrap();
let shell = self.common.shell.read();
let res = shell.menu_request(
surface.wl_surface(),
&seat,

View file

@ -12,7 +12,6 @@ impl XWaylandKeyboardGrabHandler for State {
.common
.shell
.read()
.unwrap()
.workspaces
.spaces()
.find_map(|x| x.element_for_surface(surface).cloned())?;