From 6858238bd6572bd209c68c6eb61de704429499ad Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 21 Mar 2024 12:44:40 +0100 Subject: [PATCH] shell: Unify element_for_(x11_|wl_)surface --- src/shell/element/stack.rs | 4 +- src/shell/element/surface.rs | 12 +++++ src/shell/element/window.rs | 6 +-- src/shell/mod.rs | 48 ++++--------------- src/shell/workspace.rs | 27 ++--------- src/wayland/handlers/decoration.rs | 24 +++------- src/wayland/handlers/input_method.rs | 2 +- src/wayland/handlers/screencopy.rs | 4 +- src/wayland/handlers/xdg_activation.rs | 2 +- src/wayland/handlers/xdg_shell/mod.rs | 12 ++--- src/wayland/handlers/xdg_shell/popup.rs | 2 +- .../handlers/xwayland_keyboard_grab.rs | 2 +- src/xwayland.rs | 16 +++---- 13 files changed, 56 insertions(+), 105 deletions(-) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 361102a9..ca5b121d 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -711,7 +711,7 @@ impl Program for CosmicStackInternal { if let Some(surface) = self.windows.lock().unwrap()[active].wl_surface() { loop_handle.insert_idle(move |state| { if let Some(mapped) = - state.common.shell.element_for_wl_surface(&surface).cloned() + state.common.shell.element_for_surface(&surface).cloned() { let position = if let Some((output, set)) = state.common.shell.workspaces.sets.iter().find(|(_, set)| { @@ -757,7 +757,7 @@ impl Program for CosmicStackInternal { if let Some(surface) = self.windows.lock().unwrap()[idx].wl_surface() { loop_handle.insert_idle(move |state| { if let Some(mapped) = - state.common.shell.element_for_wl_surface(&surface).cloned() + state.common.shell.element_for_surface(&surface).cloned() { if let Some(workspace) = state.common.shell.space_for_mut(&mapped) { let Some(elem_geo) = workspace.element_geometry(&mapped) else { diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index b4072709..375ae512 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -73,6 +73,18 @@ impl From for CosmicSurface { } } +impl PartialEq for CosmicSurface { + fn eq(&self, other: &WlSurface) -> bool { + self.wl_surface().map_or(false, |s| &s == other) + } +} + +impl PartialEq for CosmicSurface { + fn eq(&self, other: &X11Surface) -> bool { + self.x11_surface().map_or(false, |s| s == other) + } +} + #[derive(Default)] struct Minimized(AtomicBool); diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 0528fffc..6961db8f 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -289,7 +289,7 @@ impl Program for CosmicWindowInternal { if let Some(surface) = self.window.wl_surface() { loop_handle.insert_idle(move |state| { if let Some(mapped) = - state.common.shell.element_for_wl_surface(&surface).cloned() + state.common.shell.element_for_surface(&surface).cloned() { state.common.shell.minimize_request(&mapped) } @@ -300,7 +300,7 @@ impl Program for CosmicWindowInternal { if let Some(surface) = self.window.wl_surface() { loop_handle.insert_idle(move |state| { if let Some(mapped) = - state.common.shell.element_for_wl_surface(&surface).cloned() + state.common.shell.element_for_surface(&surface).cloned() { let seat = state.common.last_active_seat().clone(); state.common.shell.maximize_toggle(&mapped, &seat) @@ -314,7 +314,7 @@ impl Program for CosmicWindowInternal { if let Some(surface) = self.window.wl_surface() { loop_handle.insert_idle(move |state| { if let Some(mapped) = - state.common.shell.element_for_wl_surface(&surface).cloned() + state.common.shell.element_for_surface(&surface).cloned() { let position = if let Some((output, set)) = state.common.shell.workspaces.sets.iter().find(|(_, set)| { diff --git a/src/shell/mod.rs b/src/shell/mod.rs index ce42ded3..7ed464dc 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1467,7 +1467,10 @@ impl Shell { } } - pub fn element_for_surface(&self, surface: &CosmicSurface) -> Option<&CosmicMapped> { + pub fn element_for_surface(&self, surface: &S) -> Option<&CosmicMapped> + where + CosmicSurface: PartialEq, + { self.workspaces.sets.values().find_map(|set| { set.minimized_windows .iter() @@ -1482,39 +1485,6 @@ impl Shell { }) } - pub fn element_for_wl_surface(&self, surface: &WlSurface) -> Option<&CosmicMapped> { - self.workspaces.sets.values().find_map(|set| { - set.minimized_windows - .iter() - .map(|w| &w.window) - .chain(set.sticky_layer.mapped()) - .find(|w| { - w.windows() - .any(|(s, _)| s.wl_surface().as_ref() == Some(surface)) - }) - .or_else(|| { - set.workspaces - .iter() - .find_map(|w| w.element_for_wl_surface(surface)) - }) - }) - } - - pub fn element_for_x11_surface(&self, surface: &X11Surface) -> Option<&CosmicMapped> { - self.workspaces.sets.values().find_map(|set| { - set.minimized_windows - .iter() - .map(|w| &w.window) - .chain(set.sticky_layer.mapped()) - .find(|w| w.windows().any(|(s, _)| s.x11_surface() == Some(surface))) - .or_else(|| { - set.workspaces - .iter() - .find_map(|w| w.element_for_x11_surface(surface)) - }) - }) - } - pub fn space_for(&self, mapped: &CosmicMapped) -> Option<&Workspace> { self.workspaces.spaces().find(|workspace| { workspace.mapped().any(|m| m == mapped) @@ -1819,7 +1789,7 @@ impl Shell { let parent_is_sticky = if let Some(toplevel) = window.0.toplevel() { if let Some(parent) = toplevel.parent() { - if let Some(elem) = state.common.shell.element_for_wl_surface(&parent) { + if let Some(elem) = state.common.shell.element_for_surface(&parent) { state .common .shell @@ -2315,7 +2285,7 @@ impl Shell { if let Some(start_data) = check_grab_preconditions(&seat, surface, serial, ReleaseMode::NoMouseButtons) { - if let Some(mapped) = state.common.shell.element_for_wl_surface(surface).cloned() { + if let Some(mapped) = state.common.shell.element_for_surface(surface).cloned() { let (_, relative_loc) = mapped .windows() .find(|(w, _)| w.wl_surface().as_ref() == Some(surface)) @@ -2434,9 +2404,7 @@ impl Shell { let output = seat.active_output(); if let Some(mut start_data) = check_grab_preconditions(&seat, surface, serial, release) { - if let Some(mut old_mapped) = - state.common.shell.element_for_wl_surface(surface).cloned() - { + if let Some(mut old_mapped) = state.common.shell.element_for_surface(surface).cloned() { if old_mapped.is_minimized() { return; } @@ -3063,7 +3031,7 @@ impl Shell { if let Some(start_data) = check_grab_preconditions(&seat, surface, serial, ReleaseMode::NoMouseButtons) { - if let Some(mapped) = state.common.shell.element_for_wl_surface(surface).cloned() { + if let Some(mapped) = state.common.shell.element_for_surface(surface).cloned() { if mapped.is_fullscreen(true) || mapped.is_maximized(true) { return; } diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 91231f15..aa4ff4ae 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -44,7 +44,6 @@ use smithay::{ seat::WaylandFocus, xdg_activation::{XdgActivationState, XdgActivationToken}, }, - xwayland::X11Surface, }; use std::{ collections::{HashMap, HashSet, VecDeque}, @@ -365,7 +364,7 @@ impl Workspace { } pub fn commit(&mut self, surface: &WlSurface) { - if let Some(mapped) = self.element_for_wl_surface(surface) { + if let Some(mapped) = self.element_for_surface(surface) { mapped .windows() .find(|(w, _)| w.wl_surface().as_ref() == Some(surface)) @@ -483,7 +482,10 @@ impl Workspace { } } - pub fn element_for_surface(&self, surface: &CosmicSurface) -> Option<&CosmicMapped> { + pub fn element_for_surface(&self, surface: &S) -> Option<&CosmicMapped> + where + CosmicSurface: PartialEq, + { self.floating_layer .mapped() .chain(self.tiling_layer.mapped().map(|(w, _)| w)) @@ -491,25 +493,6 @@ impl Workspace { .find(|e| e.windows().any(|(w, _)| &w == surface)) } - pub fn element_for_wl_surface(&self, surface: &WlSurface) -> Option<&CosmicMapped> { - self.floating_layer - .mapped() - .chain(self.tiling_layer.mapped().map(|(w, _)| w)) - .chain(self.minimized_windows.iter().map(|w| &w.window)) - .find(|e| { - e.windows() - .any(|(w, _)| w.wl_surface().as_ref() == Some(surface)) - }) - } - - pub fn element_for_x11_surface(&self, surface: &X11Surface) -> Option<&CosmicMapped> { - self.floating_layer - .mapped() - .chain(self.tiling_layer.mapped().map(|(w, _)| w)) - .chain(self.minimized_windows.iter().map(|w| &w.window)) - .find(|e| e.windows().any(|(w, _)| w.x11_surface() == Some(surface))) - } - pub fn element_under( &mut self, location: Point, diff --git a/src/wayland/handlers/decoration.rs b/src/wayland/handlers/decoration.rs index 6a085e9e..f1fd6ac3 100644 --- a/src/wayland/handlers/decoration.rs +++ b/src/wayland/handlers/decoration.rs @@ -118,21 +118,13 @@ impl State { impl XdgDecorationHandler for State { fn new_decoration(&mut self, toplevel: ToplevelSurface) { - if let Some(mapped) = self - .common - .shell - .element_for_wl_surface(toplevel.wl_surface()) - { + if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) { State::new_decoration(mapped, toplevel.wl_surface()); } } fn request_mode(&mut self, toplevel: ToplevelSurface, mode: XdgMode) { - if let Some(mapped) = self - .common - .shell - .element_for_wl_surface(toplevel.wl_surface()) - { + if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) { State::request_mode(mapped, toplevel.wl_surface(), mode); } else { toplevel.with_pending_state(|state| state.decoration_mode = Some(mode)); @@ -140,11 +132,7 @@ impl XdgDecorationHandler for State { } fn unset_mode(&mut self, toplevel: ToplevelSurface) { - if let Some(mapped) = self - .common - .shell - .element_for_wl_surface(toplevel.wl_surface()) - { + if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) { State::unset_mode(mapped, toplevel.wl_surface()) } } @@ -156,7 +144,7 @@ impl KdeDecorationHandler for State { } fn new_decoration(&mut self, surface: &WlSurface, decoration: &OrgKdeKwinServerDecoration) { - if let Some(mapped) = self.common.shell.element_for_wl_surface(surface) { + if let Some(mapped) = self.common.shell.element_for_surface(surface) { let mode = State::new_decoration(mapped, surface); decoration.mode(mode); } @@ -170,7 +158,7 @@ impl KdeDecorationHandler for State { ) { if let WEnum::Value(mode) = mode { // 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) = self.common.shell.element_for_wl_surface(surface) { + if let Some(mapped) = self.common.shell.element_for_surface(surface) { State::request_mode( mapped, surface, @@ -185,7 +173,7 @@ impl KdeDecorationHandler for State { } fn release(&mut self, _decoration: &OrgKdeKwinServerDecoration, surface: &WlSurface) { - if let Some(mapped) = self.common.shell.element_for_wl_surface(surface) { + if let Some(mapped) = self.common.shell.element_for_surface(surface) { State::unset_mode(mapped, surface) } } diff --git a/src/wayland/handlers/input_method.rs b/src/wayland/handlers/input_method.rs index c92c3438..28cc82f0 100644 --- a/src/wayland/handlers/input_method.rs +++ b/src/wayland/handlers/input_method.rs @@ -31,7 +31,7 @@ impl InputMethodHandler for State { fn parent_geometry(&self, parent: &WlSurface) -> Rectangle { self.common .shell - .element_for_wl_surface(parent) + .element_for_surface(parent) .map(|e| e.geometry()) .unwrap_or_default() } diff --git a/src/wayland/handlers/screencopy.rs b/src/wayland/handlers/screencopy.rs index a589c0f8..a6f5228a 100644 --- a/src/wayland/handlers/screencopy.rs +++ b/src/wayland/handlers/screencopy.rs @@ -965,7 +965,7 @@ pub fn render_window_to_buffer( for seat in common.seats() { if let Some(location) = { // we need to find the mapped element in that case - if let Some(mapped) = common.shell.element_for_surface(&window) { + if let Some(mapped) = common.shell.element_for_surface(window) { mapped.cursor_position(seat).and_then(|mut p| { p -= mapped.active_window_offset().to_f64(); if p.x < 0. || p.y < 0. { @@ -1174,7 +1174,7 @@ impl State { pub fn schedule_window_session(&mut self, surface: &WlSurface) { if let Some(element) = surface .wl_surface() - .and_then(|surface| self.common.shell.element_for_wl_surface(&surface).cloned()) + .and_then(|surface| self.common.shell.element_for_surface(&surface).cloned()) { let active = element.active_window(); if active.wl_surface().as_ref() == Some(surface) { diff --git a/src/wayland/handlers/xdg_activation.rs b/src/wayland/handlers/xdg_activation.rs index 9ff96090..c3a94e60 100644 --- a/src/wayland/handlers/xdg_activation.rs +++ b/src/wayland/handlers/xdg_activation.rs @@ -105,7 +105,7 @@ impl XdgActivationHandler for State { surface: WlSurface, ) { if let Some(context) = token_data.user_data.get::() { - if let Some(element) = self.common.shell.element_for_wl_surface(&surface).cloned() { + if let Some(element) = self.common.shell.element_for_surface(&surface).cloned() { match context { ActivationContext::UrgentOnly => { if let Some((workspace, _output)) = diff --git a/src/wayland/handlers/xdg_shell/mod.rs b/src/wayland/handlers/xdg_shell/mod.rs index e779c50c..0bdb20ca 100644 --- a/src/wayland/handlers/xdg_shell/mod.rs +++ b/src/wayland/handlers/xdg_shell/mod.rs @@ -76,7 +76,7 @@ impl XdgShellHandler for State { let kind = PopupKind::Xdg(surface); if let Some(root) = find_popup_root_surface(&kind) .ok() - .and_then(|root| self.common.shell.element_for_wl_surface(&root)) + .and_then(|root| self.common.shell.element_for_surface(&root)) { let target = root.clone().into(); let ret = self @@ -169,7 +169,7 @@ impl XdgShellHandler for State { if let Some(mapped) = self .common .shell - .element_for_wl_surface(surface.wl_surface()) + .element_for_surface(surface.wl_surface()) .cloned() { if !mapped.is_stack() @@ -184,7 +184,7 @@ impl XdgShellHandler for State { if let Some(mapped) = self .common .shell - .element_for_wl_surface(surface.wl_surface()) + .element_for_surface(surface.wl_surface()) .cloned() { let seat = self.common.last_active_seat().clone(); @@ -196,7 +196,7 @@ impl XdgShellHandler for State { if let Some(mapped) = self .common .shell - .element_for_wl_surface(surface.wl_surface()) + .element_for_surface(surface.wl_surface()) .cloned() { self.common.shell.unmaximize_request(&mapped); @@ -214,7 +214,7 @@ impl XdgShellHandler for State { if let Some(mapped) = self .common .shell - .element_for_wl_surface(surface.wl_surface()) + .element_for_surface(surface.wl_surface()) .cloned() { let from = self @@ -351,7 +351,7 @@ impl XdgShellHandler for State { if let Some(mapped) = self .common .shell - .element_for_wl_surface(surface.wl_surface()) + .element_for_surface(surface.wl_surface()) .cloned() { if let Some(workspace) = self.common.shell.space_for_mut(&mapped) { diff --git a/src/wayland/handlers/xdg_shell/popup.rs b/src/wayland/handlers/xdg_shell/popup.rs index 55f3e2df..6853874a 100644 --- a/src/wayland/handlers/xdg_shell/popup.rs +++ b/src/wayland/handlers/xdg_shell/popup.rs @@ -29,7 +29,7 @@ use tracing::{trace, warn}; impl Shell { pub fn unconstrain_popup(&self, surface: &PopupSurface) { if let Some(parent) = get_popup_toplevel(&surface) { - if let Some(elem) = self.element_for_wl_surface(&parent) { + if let Some(elem) = self.element_for_surface(&parent) { let (mut element_geo, output, is_tiled) = if let Some(workspace) = self.space_for(elem) { let Some(elem_geo) = workspace.element_geometry(elem) else { diff --git a/src/wayland/handlers/xwayland_keyboard_grab.rs b/src/wayland/handlers/xwayland_keyboard_grab.rs index ca1e4c82..69e42e07 100644 --- a/src/wayland/handlers/xwayland_keyboard_grab.rs +++ b/src/wayland/handlers/xwayland_keyboard_grab.rs @@ -13,7 +13,7 @@ impl XWaylandKeyboardGrabHandler for State { .shell .workspaces .spaces() - .find_map(|x| x.element_for_wl_surface(surface))?; + .find_map(|x| x.element_for_surface(surface))?; Some(KeyboardFocusTarget::Element(element.clone())) } } diff --git a/src/xwayland.rs b/src/xwayland.rs index 2d644e12..4cefe351 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -156,7 +156,7 @@ impl XwmHandler for State { } let startup_id = window.startup_id(); - if self.common.shell.element_for_x11_surface(&window).is_some() { + if self.common.shell.element_for_surface(&window).is_some() { return; } @@ -320,7 +320,7 @@ impl XwmHandler for State { ) { // We only allow floating X11 windows to resize themselves. Nothing else let mut current_geo = window.geometry(); - if let Some(mapped) = self.common.shell.element_for_x11_surface(&window) { + if let Some(mapped) = self.common.shell.element_for_surface(&window) { let is_floating = self .common .shell @@ -431,20 +431,20 @@ impl XwmHandler for State { } fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) { - if let Some(mapped) = self.common.shell.element_for_x11_surface(&window).cloned() { + if let Some(mapped) = self.common.shell.element_for_surface(&window).cloned() { let seat = self.common.last_active_seat().clone(); self.common.shell.maximize_request(&mapped, &seat); } } fn unmaximize_request(&mut self, _xwm: XwmId, window: X11Surface) { - if let Some(mapped) = self.common.shell.element_for_x11_surface(&window).cloned() { + if let Some(mapped) = self.common.shell.element_for_surface(&window).cloned() { self.common.shell.unmaximize_request(&mapped); } } fn minimize_request(&mut self, _xwm: XwmId, window: X11Surface) { - if let Some(mapped) = self.common.shell.element_for_x11_surface(&window).cloned() { + if let Some(mapped) = self.common.shell.element_for_surface(&window).cloned() { if !mapped.is_stack() || mapped.active_window().is_window(&window) { self.common.shell.minimize_request(&mapped); } @@ -452,7 +452,7 @@ impl XwmHandler for State { } fn unminimize_request(&mut self, _xwm: XwmId, window: X11Surface) { - if let Some(mut mapped) = self.common.shell.element_for_x11_surface(&window).cloned() { + if let Some(mut mapped) = self.common.shell.element_for_surface(&window).cloned() { let seat = self.common.last_active_seat().clone(); self.common.shell.unminimize_request(&mapped, &seat); if mapped.is_stack() { @@ -466,7 +466,7 @@ impl XwmHandler for State { fn fullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) { let seat = self.common.last_active_seat().clone(); - if let Some(mapped) = self.common.shell.element_for_x11_surface(&window).cloned() { + if let Some(mapped) = self.common.shell.element_for_surface(&window).cloned() { if let Some((output, handle)) = self .common .shell @@ -506,7 +506,7 @@ impl XwmHandler for State { } fn unfullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) { - if let Some(mapped) = self.common.shell.element_for_x11_surface(&window).cloned() { + if let Some(mapped) = self.common.shell.element_for_surface(&window).cloned() { if let Some(workspace) = self.common.shell.space_for_mut(&mapped) { let (window, _) = mapped .windows()