shell: Unify element_for_(x11_|wl_)surface

This commit is contained in:
Victoria Brekenfeld 2024-03-21 12:44:40 +01:00 • committed by Victoria Brekenfeld
parent dbe2a073ef
commit 6858238bd6
13 changed files with 56 additions and 105 deletions

View file

@ -711,7 +711,7 @@ impl Program for CosmicStackInternal {
if let Some(surface) = self.windows.lock().unwrap()[active].wl_surface() { if let Some(surface) = self.windows.lock().unwrap()[active].wl_surface() {
loop_handle.insert_idle(move |state| { loop_handle.insert_idle(move |state| {
if let Some(mapped) = 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)) = let position = if let Some((output, set)) =
state.common.shell.workspaces.sets.iter().find(|(_, 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() { if let Some(surface) = self.windows.lock().unwrap()[idx].wl_surface() {
loop_handle.insert_idle(move |state| { loop_handle.insert_idle(move |state| {
if let Some(mapped) = 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) { if let Some(workspace) = state.common.shell.space_for_mut(&mapped) {
let Some(elem_geo) = workspace.element_geometry(&mapped) else { let Some(elem_geo) = workspace.element_geometry(&mapped) else {

View file

@ -73,6 +73,18 @@ impl From<X11Surface> for CosmicSurface {
} }
} }
impl PartialEq<WlSurface> for CosmicSurface {
fn eq(&self, other: &WlSurface) -> bool {
self.wl_surface().map_or(false, |s| &s == other)
}
}
impl PartialEq<X11Surface> for CosmicSurface {
fn eq(&self, other: &X11Surface) -> bool {
self.x11_surface().map_or(false, |s| s == other)
}
}
#[derive(Default)] #[derive(Default)]
struct Minimized(AtomicBool); struct Minimized(AtomicBool);

View file

@ -289,7 +289,7 @@ impl Program for CosmicWindowInternal {
if let Some(surface) = self.window.wl_surface() { if let Some(surface) = self.window.wl_surface() {
loop_handle.insert_idle(move |state| { loop_handle.insert_idle(move |state| {
if let Some(mapped) = 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) state.common.shell.minimize_request(&mapped)
} }
@ -300,7 +300,7 @@ impl Program for CosmicWindowInternal {
if let Some(surface) = self.window.wl_surface() { if let Some(surface) = self.window.wl_surface() {
loop_handle.insert_idle(move |state| { loop_handle.insert_idle(move |state| {
if let Some(mapped) = 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(); let seat = state.common.last_active_seat().clone();
state.common.shell.maximize_toggle(&mapped, &seat) state.common.shell.maximize_toggle(&mapped, &seat)
@ -314,7 +314,7 @@ impl Program for CosmicWindowInternal {
if let Some(surface) = self.window.wl_surface() { if let Some(surface) = self.window.wl_surface() {
loop_handle.insert_idle(move |state| { loop_handle.insert_idle(move |state| {
if let Some(mapped) = 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)) = let position = if let Some((output, set)) =
state.common.shell.workspaces.sets.iter().find(|(_, set)| { state.common.shell.workspaces.sets.iter().find(|(_, set)| {

View file

@ -1467,7 +1467,10 @@ impl Shell {
} }
} }
pub fn element_for_surface(&self, surface: &CosmicSurface) -> Option<&CosmicMapped> { pub fn element_for_surface<S>(&self, surface: &S) -> Option<&CosmicMapped>
where
CosmicSurface: PartialEq<S>,
{
self.workspaces.sets.values().find_map(|set| { self.workspaces.sets.values().find_map(|set| {
set.minimized_windows set.minimized_windows
.iter() .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> { pub fn space_for(&self, mapped: &CosmicMapped) -> Option<&Workspace> {
self.workspaces.spaces().find(|workspace| { self.workspaces.spaces().find(|workspace| {
workspace.mapped().any(|m| m == mapped) workspace.mapped().any(|m| m == mapped)
@ -1819,7 +1789,7 @@ impl Shell {
let parent_is_sticky = if let Some(toplevel) = window.0.toplevel() { let parent_is_sticky = if let Some(toplevel) = window.0.toplevel() {
if let Some(parent) = toplevel.parent() { 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 state
.common .common
.shell .shell
@ -2315,7 +2285,7 @@ impl Shell {
if let Some(start_data) = if let Some(start_data) =
check_grab_preconditions(&seat, surface, serial, ReleaseMode::NoMouseButtons) 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 let (_, relative_loc) = mapped
.windows() .windows()
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface)) .find(|(w, _)| w.wl_surface().as_ref() == Some(surface))
@ -2434,9 +2404,7 @@ impl Shell {
let output = seat.active_output(); let output = seat.active_output();
if let Some(mut start_data) = check_grab_preconditions(&seat, surface, serial, release) { if let Some(mut start_data) = check_grab_preconditions(&seat, surface, serial, release) {
if let Some(mut old_mapped) = if let Some(mut old_mapped) = state.common.shell.element_for_surface(surface).cloned() {
state.common.shell.element_for_wl_surface(surface).cloned()
{
if old_mapped.is_minimized() { if old_mapped.is_minimized() {
return; return;
} }
@ -3063,7 +3031,7 @@ impl Shell {
if let Some(start_data) = if let Some(start_data) =
check_grab_preconditions(&seat, surface, serial, ReleaseMode::NoMouseButtons) 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) { if mapped.is_fullscreen(true) || mapped.is_maximized(true) {
return; return;
} }

View file

@ -44,7 +44,6 @@ use smithay::{
seat::WaylandFocus, seat::WaylandFocus,
xdg_activation::{XdgActivationState, XdgActivationToken}, xdg_activation::{XdgActivationState, XdgActivationToken},
}, },
xwayland::X11Surface,
}; };
use std::{ use std::{
collections::{HashMap, HashSet, VecDeque}, collections::{HashMap, HashSet, VecDeque},
@ -365,7 +364,7 @@ impl Workspace {
} }
pub fn commit(&mut self, surface: &WlSurface) { 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 mapped
.windows() .windows()
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface)) .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<S>(&self, surface: &S) -> Option<&CosmicMapped>
where
CosmicSurface: PartialEq<S>,
{
self.floating_layer self.floating_layer
.mapped() .mapped()
.chain(self.tiling_layer.mapped().map(|(w, _)| w)) .chain(self.tiling_layer.mapped().map(|(w, _)| w))
@ -491,25 +493,6 @@ impl Workspace {
.find(|e| e.windows().any(|(w, _)| &w == surface)) .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( pub fn element_under(
&mut self, &mut self,
location: Point<f64, Global>, location: Point<f64, Global>,

View file

@ -118,21 +118,13 @@ impl State {
impl XdgDecorationHandler for State { impl XdgDecorationHandler for State {
fn new_decoration(&mut self, toplevel: ToplevelSurface) { fn new_decoration(&mut self, toplevel: ToplevelSurface) {
if let Some(mapped) = self if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) {
.common
.shell
.element_for_wl_surface(toplevel.wl_surface())
{
State::new_decoration(mapped, toplevel.wl_surface()); State::new_decoration(mapped, toplevel.wl_surface());
} }
} }
fn request_mode(&mut self, toplevel: ToplevelSurface, mode: XdgMode) { fn request_mode(&mut self, toplevel: ToplevelSurface, mode: XdgMode) {
if let Some(mapped) = self if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) {
.common
.shell
.element_for_wl_surface(toplevel.wl_surface())
{
State::request_mode(mapped, toplevel.wl_surface(), mode); State::request_mode(mapped, toplevel.wl_surface(), mode);
} else { } else {
toplevel.with_pending_state(|state| state.decoration_mode = Some(mode)); 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) { fn unset_mode(&mut self, toplevel: ToplevelSurface) {
if let Some(mapped) = self if let Some(mapped) = self.common.shell.element_for_surface(toplevel.wl_surface()) {
.common
.shell
.element_for_wl_surface(toplevel.wl_surface())
{
State::unset_mode(mapped, 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) { 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); let mode = State::new_decoration(mapped, surface);
decoration.mode(mode); decoration.mode(mode);
} }
@ -170,7 +158,7 @@ impl KdeDecorationHandler for State {
) { ) {
if let WEnum::Value(mode) = mode { 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. // 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( State::request_mode(
mapped, mapped,
surface, surface,
@ -185,7 +173,7 @@ impl KdeDecorationHandler for State {
} }
fn release(&mut self, _decoration: &OrgKdeKwinServerDecoration, surface: &WlSurface) { 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) State::unset_mode(mapped, surface)
} }
} }

View file

@ -31,7 +31,7 @@ impl InputMethodHandler for State {
fn parent_geometry(&self, parent: &WlSurface) -> Rectangle<i32, smithay::utils::Logical> { fn parent_geometry(&self, parent: &WlSurface) -> Rectangle<i32, smithay::utils::Logical> {
self.common self.common
.shell .shell
.element_for_wl_surface(parent) .element_for_surface(parent)
.map(|e| e.geometry()) .map(|e| e.geometry())
.unwrap_or_default() .unwrap_or_default()
} }

View file

@ -965,7 +965,7 @@ pub fn render_window_to_buffer(
for seat in common.seats() { for seat in common.seats() {
if let Some(location) = { if let Some(location) = {
// we need to find the mapped element in that case // 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| { mapped.cursor_position(seat).and_then(|mut p| {
p -= mapped.active_window_offset().to_f64(); p -= mapped.active_window_offset().to_f64();
if p.x < 0. || p.y < 0. { if p.x < 0. || p.y < 0. {
@ -1174,7 +1174,7 @@ impl State {
pub fn schedule_window_session(&mut self, surface: &WlSurface) { pub fn schedule_window_session(&mut self, surface: &WlSurface) {
if let Some(element) = surface if let Some(element) = surface
.wl_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(); let active = element.active_window();
if active.wl_surface().as_ref() == Some(surface) { if active.wl_surface().as_ref() == Some(surface) {

View file

@ -105,7 +105,7 @@ impl XdgActivationHandler for State {
surface: WlSurface, surface: WlSurface,
) { ) {
if let Some(context) = token_data.user_data.get::<ActivationContext>() { if let Some(context) = token_data.user_data.get::<ActivationContext>() {
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 { match context {
ActivationContext::UrgentOnly => { ActivationContext::UrgentOnly => {
if let Some((workspace, _output)) = if let Some((workspace, _output)) =

View file

@ -76,7 +76,7 @@ impl XdgShellHandler for State {
let kind = PopupKind::Xdg(surface); let kind = PopupKind::Xdg(surface);
if let Some(root) = find_popup_root_surface(&kind) if let Some(root) = find_popup_root_surface(&kind)
.ok() .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 target = root.clone().into();
let ret = self let ret = self
@ -169,7 +169,7 @@ impl XdgShellHandler for State {
if let Some(mapped) = self if let Some(mapped) = self
.common .common
.shell .shell
.element_for_wl_surface(surface.wl_surface()) .element_for_surface(surface.wl_surface())
.cloned() .cloned()
{ {
if !mapped.is_stack() if !mapped.is_stack()
@ -184,7 +184,7 @@ impl XdgShellHandler for State {
if let Some(mapped) = self if let Some(mapped) = self
.common .common
.shell .shell
.element_for_wl_surface(surface.wl_surface()) .element_for_surface(surface.wl_surface())
.cloned() .cloned()
{ {
let seat = self.common.last_active_seat().clone(); let seat = self.common.last_active_seat().clone();
@ -196,7 +196,7 @@ impl XdgShellHandler for State {
if let Some(mapped) = self if let Some(mapped) = self
.common .common
.shell .shell
.element_for_wl_surface(surface.wl_surface()) .element_for_surface(surface.wl_surface())
.cloned() .cloned()
{ {
self.common.shell.unmaximize_request(&mapped); self.common.shell.unmaximize_request(&mapped);
@ -214,7 +214,7 @@ impl XdgShellHandler for State {
if let Some(mapped) = self if let Some(mapped) = self
.common .common
.shell .shell
.element_for_wl_surface(surface.wl_surface()) .element_for_surface(surface.wl_surface())
.cloned() .cloned()
{ {
let from = self let from = self
@ -351,7 +351,7 @@ impl XdgShellHandler for State {
if let Some(mapped) = self if let Some(mapped) = self
.common .common
.shell .shell
.element_for_wl_surface(surface.wl_surface()) .element_for_surface(surface.wl_surface())
.cloned() .cloned()
{ {
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) { if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {

View file

@ -29,7 +29,7 @@ use tracing::{trace, warn};
impl Shell { impl Shell {
pub fn unconstrain_popup(&self, surface: &PopupSurface) { pub fn unconstrain_popup(&self, surface: &PopupSurface) {
if let Some(parent) = get_popup_toplevel(&surface) { 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) = let (mut element_geo, output, is_tiled) =
if let Some(workspace) = self.space_for(elem) { if let Some(workspace) = self.space_for(elem) {
let Some(elem_geo) = workspace.element_geometry(elem) else { let Some(elem_geo) = workspace.element_geometry(elem) else {

View file

@ -13,7 +13,7 @@ impl XWaylandKeyboardGrabHandler for State {
.shell .shell
.workspaces .workspaces
.spaces() .spaces()
.find_map(|x| x.element_for_wl_surface(surface))?; .find_map(|x| x.element_for_surface(surface))?;
Some(KeyboardFocusTarget::Element(element.clone())) Some(KeyboardFocusTarget::Element(element.clone()))
} }
} }

View file

@ -156,7 +156,7 @@ impl XwmHandler for State {
} }
let startup_id = window.startup_id(); 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; return;
} }
@ -320,7 +320,7 @@ impl XwmHandler for State {
) { ) {
// We only allow floating X11 windows to resize themselves. Nothing else // We only allow floating X11 windows to resize themselves. Nothing else
let mut current_geo = window.geometry(); 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 let is_floating = self
.common .common
.shell .shell
@ -431,20 +431,20 @@ impl XwmHandler for State {
} }
fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) { 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(); let seat = self.common.last_active_seat().clone();
self.common.shell.maximize_request(&mapped, &seat); self.common.shell.maximize_request(&mapped, &seat);
} }
} }
fn unmaximize_request(&mut self, _xwm: XwmId, window: X11Surface) { 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); self.common.shell.unmaximize_request(&mapped);
} }
} }
fn minimize_request(&mut self, _xwm: XwmId, window: X11Surface) { 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) { if !mapped.is_stack() || mapped.active_window().is_window(&window) {
self.common.shell.minimize_request(&mapped); self.common.shell.minimize_request(&mapped);
} }
@ -452,7 +452,7 @@ impl XwmHandler for State {
} }
fn unminimize_request(&mut self, _xwm: XwmId, window: X11Surface) { 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(); let seat = self.common.last_active_seat().clone();
self.common.shell.unminimize_request(&mapped, &seat); self.common.shell.unminimize_request(&mapped, &seat);
if mapped.is_stack() { if mapped.is_stack() {
@ -466,7 +466,7 @@ impl XwmHandler for State {
fn fullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) { fn fullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) {
let seat = self.common.last_active_seat().clone(); 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 if let Some((output, handle)) = self
.common .common
.shell .shell
@ -506,7 +506,7 @@ impl XwmHandler for State {
} }
fn unfullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) { 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) { if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped let (window, _) = mapped
.windows() .windows()