diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 48bd28d2..12c3e27a 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -25,11 +25,14 @@ use { NodeSeatState, SeatId, WlSeatGlobal, }, wl_surface::{ - cursor::CursorSurface, wl_subsurface::WlSubsurface, + cursor::CursorSurface, + wl_subsurface::{PendingSubsurfaceData, WlSubsurface}, wp_fractional_scale_v1::WpFractionalScaleV1, - wp_tearing_control_v1::WpTearingControlV1, wp_viewport::WpViewport, - x_surface::XSurface, xdg_surface::XdgSurfaceError, - zwlr_layer_surface_v1::ZwlrLayerSurfaceV1Error, + wp_tearing_control_v1::WpTearingControlV1, + wp_viewport::WpViewport, + x_surface::XSurface, + xdg_surface::{PendingXdgSurfaceData, XdgSurfaceError}, + zwlr_layer_surface_v1::{PendingLayerSurfaceData, ZwlrLayerSurfaceV1Error}, }, wp_content_type_v1::ContentType, wp_presentation_feedback::WpPresentationFeedback, @@ -281,6 +284,9 @@ struct PendingState { xwayland_serial: Option, tearing: Option, content_type: Option>, + subsurface: Option>, + xdg_surface: Option>, + layer_surface: Option>, } #[derive(Default)] diff --git a/src/ifs/wl_surface/wl_subsurface.rs b/src/ifs/wl_surface/wl_subsurface.rs index c54a6a29..039c3f23 100644 --- a/src/ifs/wl_surface/wl_subsurface.rs +++ b/src/ifs/wl_surface/wl_subsurface.rs @@ -12,11 +12,12 @@ use { buffd::{MsgParser, MsgParserError}, linkedlist::LinkedNode, numcell::NumCell, + option_ext::OptionExt, }, wire::{wl_subsurface::*, WlSubsurfaceId}, }, std::{ - cell::{Cell, RefCell}, + cell::{Cell, RefCell, RefMut}, ops::Deref, rc::Rc, }, @@ -37,14 +38,13 @@ pub struct WlSubsurface { sync_ancestor: Cell, node: RefCell>>, depth: NumCell, - pending: PendingSubsurfaceData, pub tracker: Tracker, } #[derive(Default)] -struct PendingSubsurfaceData { - node: RefCell>>, - position: Cell>, +pub struct PendingSubsurfaceData { + node: Option>, + position: Option<(i32, i32)>, } fn update_children_sync(surface: &WlSubsurface, sync: bool) { @@ -92,11 +92,16 @@ impl WlSubsurface { sync_ancestor: Cell::new(false), node: RefCell::new(None), depth: NumCell::new(0), - pending: Default::default(), tracker: Default::default(), } } + fn pending(&self) -> RefMut> { + RefMut::map(self.surface.pending.borrow_mut(), |m| { + m.subsurface.get_or_insert_default_ext() + }) + } + pub fn install(self: &Rc) -> Result<(), WlSubsurfaceError> { if self.surface.id == self.parent.id { return Err(WlSubsurfaceError::OwnParent(self.surface.id)); @@ -128,7 +133,7 @@ impl WlSubsurface { sub_surface: self.clone(), }) }; - *self.pending.node.borrow_mut() = Some(node); + self.pending().node = Some(node); self.surface.set_toplevel(self.parent.toplevel.get()); self.sync_ancestor.set(sync_ancestor); self.depth.set(depth); @@ -140,7 +145,7 @@ impl WlSubsurface { fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSubsurfaceError> { let _req: Destroy = self.surface.client.parse(self, parser)?; self.surface.unset_ext(); - *self.pending.node.borrow_mut() = None; + self.surface.pending.borrow_mut().subsurface.take(); *self.node.borrow_mut() = None; { let mut children = self.parent.children.borrow_mut(); @@ -164,7 +169,7 @@ impl WlSubsurface { fn set_position(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSubsurfaceError> { let req: SetPosition = self.surface.client.parse(self, parser)?; - self.pending.position.set(Some((req.x, req.y))); + self.pending().position = Some((req.x, req.y)); Ok(()) } @@ -188,7 +193,7 @@ impl WlSubsurface { Some(s) => s, _ => return Err(WlSubsurfaceError::NotASibling(sibling, self.surface.id)), }; - let node = match sibling.pending.node.borrow().deref() { + let node = match &sibling.pending().node { Some(n) => n.to_ref(), _ => match sibling.node.borrow().deref() { Some(n) => n.to_ref(), @@ -200,7 +205,7 @@ impl WlSubsurface { _ => node.prepend(element), } }; - self.pending.node.borrow_mut().replace(node); + self.pending().node.replace(node); } Ok(()) } @@ -256,7 +261,6 @@ object_base! { impl Object for WlSubsurface { fn break_loops(&self) { - *self.pending.node.borrow_mut() = None; *self.node.borrow_mut() = None; } } @@ -272,15 +276,17 @@ impl SurfaceExt for WlSubsurface { CommitAction::ContinueCommit } - fn after_apply_commit(self: Rc, _pending: &mut PendingState) { - if let Some(v) = self.pending.node.take() { - v.pending.set(false); - self.node.borrow_mut().replace(v); - } - if let Some((x, y)) = self.pending.position.take() { - self.position - .set(self.surface.buffer_abs_pos.get().at_point(x, y)); - self.parent.need_extents_update.set(true); + fn after_apply_commit(self: Rc, pending: &mut PendingState) { + if let Some(pending) = &mut pending.subsurface { + if let Some(v) = pending.node.take() { + v.pending.set(false); + self.node.borrow_mut().replace(v); + } + if let Some((x, y)) = pending.position.take() { + self.position + .set(self.surface.buffer_abs_pos.get().at_point(x, y)); + self.parent.need_extents_update.set(true); + } } } diff --git a/src/ifs/wl_surface/xdg_surface.rs b/src/ifs/wl_surface/xdg_surface.rs index 83fbb4e7..4563ab21 100644 --- a/src/ifs/wl_surface/xdg_surface.rs +++ b/src/ifs/wl_surface/xdg_surface.rs @@ -23,10 +23,15 @@ use { clonecell::CloneCell, copyhashmap::CopyHashMap, numcell::NumCell, + option_ext::OptionExt, }, wire::{xdg_surface::*, WlSurfaceId, XdgPopupId, XdgSurfaceId}, }, - std::{cell::Cell, fmt::Debug, rc::Rc}, + std::{ + cell::{Cell, RefMut}, + fmt::Debug, + rc::Rc, + }, thiserror::Error, }; @@ -65,14 +70,13 @@ pub struct XdgSurface { pub absolute_desired_extents: Cell, ext: CloneCell>>, popups: CopyHashMap>, - pending: PendingXdgSurfaceData, pub workspace: CloneCell>>, pub tracker: Tracker, } #[derive(Default, Debug)] -struct PendingXdgSurfaceData { - geometry: Cell>, +pub struct PendingXdgSurfaceData { + geometry: Option, } pub trait XdgSurfaceExt: Debug { @@ -103,7 +107,6 @@ impl XdgSurface { absolute_desired_extents: Cell::new(Default::default()), ext: Default::default(), popups: Default::default(), - pending: Default::default(), workspace: Default::default(), tracker: Default::default(), } @@ -270,6 +273,12 @@ impl XdgSurface { Ok(()) } + fn pending(&self) -> RefMut> { + RefMut::map(self.surface.pending.borrow_mut(), |p| { + p.xdg_surface.get_or_insert_default_ext() + }) + } + fn set_window_geometry(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgSurfaceError> { let req: SetWindowGeometry = self.surface.client.parse(self, parser)?; if req.height == 0 && req.width == 0 { @@ -280,7 +289,7 @@ impl XdgSurface { return Err(XdgSurfaceError::NonPositiveWidthHeight); } let extents = Rect::new_sized(req.x, req.y, req.width, req.height).unwrap(); - self.pending.geometry.set(Some(extents)); + self.pending().geometry = Some(extents); Ok(()) } @@ -359,7 +368,7 @@ dedicated_add_obj!(XdgSurface, XdgSurfaceId, xdg_surfaces); impl SurfaceExt for XdgSurface { fn before_apply_commit( self: Rc, - _pending: &mut PendingState, + pending: &mut PendingState, ) -> Result<(), WlSurfaceError> { { let ase = self.acked_serial.get(); @@ -373,9 +382,11 @@ impl SurfaceExt for XdgSurface { } } } - if let Some(geometry) = self.pending.geometry.take() { - self.geometry.set(Some(geometry)); - self.update_extents(); + if let Some(pending) = &mut pending.xdg_surface { + if let Some(geometry) = pending.geometry.take() { + self.geometry.set(Some(geometry)); + self.update_extents(); + } } Ok(()) } diff --git a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs index 4eaf585d..09509342 100644 --- a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs +++ b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs @@ -17,10 +17,16 @@ use { cell_ext::CellExt, linkedlist::LinkedNode, numcell::NumCell, + option_ext::OptionExt, }, wire::{zwlr_layer_surface_v1::*, WlSurfaceId, ZwlrLayerSurfaceV1Id}, }, - std::{cell::Cell, ops::Deref, rc::Rc}, + std::{ + cell::{Cell, RefMut}, + mem, + ops::Deref, + rc::Rc, + }, thiserror::Error, }; @@ -48,7 +54,6 @@ pub struct ZwlrLayerSurfaceV1 { pos: Cell, mapped: Cell, layer: Cell, - pending: Pending, requested_serial: NumCell, acked_serial: Cell>, size: Cell<(i32, i32)>, @@ -61,14 +66,14 @@ pub struct ZwlrLayerSurfaceV1 { } #[derive(Default)] -struct Pending { - size: Cell>, - anchor: Cell>, - exclusive_zone: Cell>, - margin: Cell>, - keyboard_interactivity: Cell>, - layer: Cell>, - any: Cell, +pub struct PendingLayerSurfaceData { + size: Option<(i32, i32)>, + anchor: Option, + exclusive_zone: Option, + margin: Option<(i32, i32, i32, i32)>, + keyboard_interactivity: Option, + layer: Option, + any: bool, } impl ZwlrLayerSurfaceV1 { @@ -93,7 +98,6 @@ impl ZwlrLayerSurfaceV1 { pos: Default::default(), mapped: Cell::new(false), layer: Cell::new(layer), - pending: Default::default(), requested_serial: Default::default(), acked_serial: Cell::new(None), size: Cell::new((0, 0)), @@ -129,15 +133,20 @@ impl ZwlrLayerSurfaceV1 { self.client.event(Closed { self_id: self.id }); } + fn pending(&self) -> RefMut> { + RefMut::map(self.surface.pending.borrow_mut(), |m| { + m.layer_surface.get_or_insert_default_ext() + }) + } + fn set_size(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { let req: SetSize = self.client.parse(self, parser)?; if req.width > u16::MAX as u32 || req.height > u16::MAX as u32 { return Err(ZwlrLayerSurfaceV1Error::ExcessiveSize); } - self.pending - .size - .set(Some((req.width as _, req.height as _))); - self.pending.any.set(true); + let mut pending = self.pending(); + pending.size = Some((req.width as _, req.height as _)); + pending.any = true; Ok(()) } @@ -146,24 +155,25 @@ impl ZwlrLayerSurfaceV1 { if req.anchor & !(LEFT | RIGHT | TOP | BOTTOM) != 0 { return Err(ZwlrLayerSurfaceV1Error::UnknownAnchor(req.anchor)); } - self.pending.anchor.set(Some(req.anchor)); - self.pending.any.set(true); + let mut pending = self.pending(); + pending.anchor = Some(req.anchor); + pending.any = true; Ok(()) } fn set_exclusive_zone(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { let req: SetExclusiveZone = self.client.parse(self, parser)?; - self.pending.exclusive_zone.set(Some(req.zone)); - self.pending.any.set(true); + let mut pending = self.pending(); + pending.exclusive_zone = Some(req.zone); + pending.any = true; Ok(()) } fn set_margin(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { let req: SetMargin = self.client.parse(self, parser)?; - self.pending - .margin - .set(Some((req.top, req.right, req.bottom, req.left))); - self.pending.any.set(true); + let mut pending = self.pending(); + pending.margin = Some((req.top, req.right, req.bottom, req.left)); + pending.any = true; Ok(()) } @@ -177,10 +187,9 @@ impl ZwlrLayerSurfaceV1 { req.keyboard_interactivity, )); } - self.pending - .keyboard_interactivity - .set(Some(req.keyboard_interactivity)); - self.pending.any.set(true); + let mut pending = self.pending(); + pending.keyboard_interactivity = Some(req.keyboard_interactivity); + pending.any = true; Ok(()) } @@ -208,29 +217,31 @@ impl ZwlrLayerSurfaceV1 { if req.layer > OVERLAY { return Err(ZwlrLayerSurfaceV1Error::UnknownLayer(req.layer)); } - self.pending.layer.set(Some(req.layer)); - self.pending.any.set(true); + let mut pending = self.pending(); + pending.layer = Some(req.layer); + pending.any = true; Ok(()) } - fn pre_commit(&self) -> Result<(), ZwlrLayerSurfaceV1Error> { - let mut send_configure = self.pending.any.replace(false); - if let Some(size) = self.pending.size.take() { + fn pre_commit(&self, pending: &mut PendingState) -> Result<(), ZwlrLayerSurfaceV1Error> { + let pending = pending.layer_surface.get_or_insert_default_ext(); + let mut send_configure = mem::replace(&mut pending.any, false); + if let Some(size) = pending.size.take() { self.size.set(size); } - if let Some(anchor) = self.pending.anchor.take() { + if let Some(anchor) = pending.anchor.take() { self.anchor.set(anchor); } - if let Some(ez) = self.pending.exclusive_zone.take() { + if let Some(ez) = pending.exclusive_zone.take() { self.exclusive_zone.set(ez); } - if let Some(margin) = self.pending.margin.take() { + if let Some(margin) = pending.margin.take() { self.margin.set(margin); } - if let Some(ki) = self.pending.keyboard_interactivity.take() { + if let Some(ki) = pending.keyboard_interactivity.take() { self.keyboard_interactivity.set(ki); } - if let Some(layer) = self.pending.layer.take() { + if let Some(layer) = pending.layer.take() { self.layer.set(layer); } { @@ -313,9 +324,9 @@ impl ZwlrLayerSurfaceV1 { impl SurfaceExt for ZwlrLayerSurfaceV1 { fn before_apply_commit( self: Rc, - _pending: &mut PendingState, + pending: &mut PendingState, ) -> Result<(), WlSurfaceError> { - self.deref().pre_commit()?; + self.deref().pre_commit(pending)?; Ok(()) }