autocommit 2022-01-03 18:56:52 CET
This commit is contained in:
parent
fc887b339e
commit
30376c595c
39 changed files with 3157 additions and 309 deletions
|
|
@ -1,8 +1,10 @@
|
|||
mod types;
|
||||
|
||||
use crate::ifs::wl_surface::{SubsurfaceData, SurfaceType, WlSurface};
|
||||
use crate::client::AddObj;
|
||||
use crate::ifs::wl_surface::{RoleData, StackElement, SubsurfaceData, SurfaceRole, WlSurface};
|
||||
use crate::object::{Interface, Object, ObjectId};
|
||||
use crate::utils::buffd::MsgParser;
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
pub use types::*;
|
||||
|
||||
|
|
@ -15,85 +17,211 @@ const SET_DESYNC: u32 = 5;
|
|||
|
||||
const BAD_SURFACE: u32 = 0;
|
||||
|
||||
const MAX_SUBSURFACE_DEPTH: u32 = 100;
|
||||
|
||||
pub struct WlSubsurface {
|
||||
id: ObjectId,
|
||||
surface: Rc<WlSurface>,
|
||||
pub(super) parent: Rc<WlSurface>,
|
||||
}
|
||||
|
||||
fn update_children_sync(surface: &Rc<WlSurface>, sync: bool) -> Result<(), WlSubsurfaceError> {
|
||||
let children = surface.children.borrow();
|
||||
if let Some(children) = &*children {
|
||||
for child in children.subsurfaces.values() {
|
||||
let mut data = child.role_data.borrow_mut();
|
||||
if let RoleData::Subsurface(data) = &mut *data {
|
||||
let was_sync = data.sync_ancestor || data.sync_requested;
|
||||
data.sync_ancestor = sync;
|
||||
let is_sync = data.sync_ancestor || data.sync_requested;
|
||||
if was_sync != is_sync {
|
||||
update_children_sync(child, sync);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_children_attach(
|
||||
surface: &Rc<WlSurface>,
|
||||
sync: bool,
|
||||
depth: u32,
|
||||
) -> Result<(), WlSubsurfaceError> {
|
||||
let children = surface.children.borrow();
|
||||
if let Some(children) = &*children {
|
||||
for child in children.subsurfaces.values() {
|
||||
let mut data = child.role_data.borrow_mut();
|
||||
if let RoleData::Subsurface(data) = &mut *data {
|
||||
data.depth = depth + 1;
|
||||
if data.depth > MAX_SUBSURFACE_DEPTH {
|
||||
return Err(WlSubsurfaceError::MaxDepthExceeded);
|
||||
}
|
||||
data.sync_ancestor = sync;
|
||||
let sync = data.sync_ancestor || data.sync_requested;
|
||||
update_children_attach(child, sync, depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl WlSubsurface {
|
||||
pub fn new(id: ObjectId, surface: &Rc<WlSurface>) -> Self {
|
||||
pub fn new(id: ObjectId, surface: &Rc<WlSurface>, parent: &Rc<WlSurface>) -> Self {
|
||||
Self {
|
||||
id,
|
||||
surface: surface.clone(),
|
||||
parent: parent.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install(self: &Rc<Self>, parent: &Rc<WlSurface>) -> Result<(), WlSubsurfaceError> {
|
||||
let old_ty = self.surface.ty.get();
|
||||
if !matches!(old_ty, SurfaceType::None | SurfaceType::Subsurface) {
|
||||
return Err(WlSubsurfaceError::IncompatibleType(self.surface.id, old_ty));
|
||||
}
|
||||
self.surface.ty.set(SurfaceType::Subsurface);
|
||||
let mut data = self.surface.subsurface_data.borrow_mut();
|
||||
if data.is_some() {
|
||||
return Err(WlSubsurfaceError::AlreadyAttached(self.surface.id));
|
||||
}
|
||||
if self.surface.id == parent.id {
|
||||
pub fn install(self: &Rc<Self>) -> Result<(), WlSubsurfaceError> {
|
||||
if self.surface.id == self.parent.id {
|
||||
return Err(WlSubsurfaceError::OwnParent(self.surface.id));
|
||||
}
|
||||
if self.surface.id == parent.get_root().id {
|
||||
return Err(WlSubsurfaceError::Ancestor(self.surface.id, parent.id));
|
||||
let old_ty = self.surface.role.get();
|
||||
if !matches!(old_ty, SurfaceRole::None | SurfaceRole::Subsurface) {
|
||||
return Err(WlSubsurfaceError::IncompatibleType(self.surface.id, old_ty));
|
||||
}
|
||||
self.surface.role.set(SurfaceRole::Subsurface);
|
||||
let mut data = self.surface.role_data.borrow_mut();
|
||||
if matches!(*data, RoleData::Subsurface(_)) {
|
||||
return Err(WlSubsurfaceError::AlreadyAttached(self.surface.id));
|
||||
}
|
||||
if self.surface.id == self.parent.get_root().id {
|
||||
return Err(WlSubsurfaceError::Ancestor(self.surface.id, self.parent.id));
|
||||
}
|
||||
let mut sync_ancestor = false;
|
||||
let mut depth = 1;
|
||||
{
|
||||
let data = parent.subsurface_data.borrow();
|
||||
if let Some(data) = data.as_ref() {
|
||||
let data = self.parent.role_data.borrow();
|
||||
if let RoleData::Subsurface(data) = &*data {
|
||||
sync_ancestor = data.sync_requested || data.sync_ancestor;
|
||||
depth = data.depth + 1;
|
||||
if depth >= MAX_SUBSURFACE_DEPTH {
|
||||
return Err(WlSubsurfaceError::MaxDepthExceeded);
|
||||
}
|
||||
}
|
||||
}
|
||||
*data = Some(Box::new(SubsurfaceData {
|
||||
let node = {
|
||||
let mut data = self.parent.children.borrow_mut();
|
||||
let data = data.get_or_insert_with(|| Default::default());
|
||||
data.subsurfaces
|
||||
.insert(self.surface.id, self.surface.clone());
|
||||
data.above.prepend(StackElement {
|
||||
pending: Cell::new(true),
|
||||
surface: self.surface.clone(),
|
||||
})
|
||||
};
|
||||
*data = RoleData::Subsurface(Box::new(SubsurfaceData {
|
||||
subsurface: self.clone(),
|
||||
parent: parent.clone(),
|
||||
x: 0,
|
||||
y: 0,
|
||||
sync_requested: false,
|
||||
sync_ancestor,
|
||||
pending: true,
|
||||
depth,
|
||||
node,
|
||||
pending: Default::default(),
|
||||
}));
|
||||
{
|
||||
let mut data = parent.children.borrow_mut();
|
||||
let data = data.get_or_insert_with(|| Default::default());
|
||||
data.pending_subsurfaces
|
||||
.insert(self.surface.id, self.surface.clone());
|
||||
}
|
||||
update_children_attach(&self.surface, sync_ancestor, depth)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
||||
let _req: Destroy = self.surface.client.parse(self, parser)?;
|
||||
*self.surface.role_data.borrow_mut() = RoleData::None;
|
||||
{
|
||||
let mut children = self.parent.children.borrow_mut();
|
||||
if let Some(children) = &mut *children {
|
||||
children.subsurfaces.remove(&self.surface.id);
|
||||
}
|
||||
}
|
||||
self.surface.client.remove_obj(self).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn set_position(&self, parser: MsgParser<'_, '_>) -> Result<(), SetPositionError> {
|
||||
let req: SetPosition = self.surface.client.parse(self, parser)?;
|
||||
let mut data = self.surface.role_data.borrow_mut();
|
||||
if let RoleData::Subsurface(data) = &mut *data {
|
||||
data.pending.position = Some((req.x, req.y));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn place(&self, sibling: ObjectId, above: bool) -> Result<(), PlacementError> {
|
||||
if sibling == self.surface.id {
|
||||
return Err(PlacementError::AboveSelf(sibling));
|
||||
}
|
||||
let mut data = self.surface.role_data.borrow_mut();
|
||||
let pdata = self.parent.children.borrow();
|
||||
if let (RoleData::Subsurface(data), Some(pdata)) = (&mut *data, &*pdata) {
|
||||
let element = StackElement {
|
||||
pending: Cell::new(true),
|
||||
surface: self.surface.clone(),
|
||||
};
|
||||
if sibling == self.parent.id {
|
||||
let node = match above {
|
||||
true => pdata.above.prepend(element),
|
||||
_ => pdata.below.append(element),
|
||||
};
|
||||
data.pending.node = Some(node);
|
||||
} else {
|
||||
let sibling = match pdata.subsurfaces.get(&sibling) {
|
||||
Some(s) => s,
|
||||
_ => return Err(PlacementError::NotASibling(sibling, self.surface.id)),
|
||||
};
|
||||
let sdata = sibling.role_data.borrow();
|
||||
if let RoleData::Subsurface(p) = &*sdata {
|
||||
let node = match &p.pending.node {
|
||||
Some(n) => n,
|
||||
_ => &p.node,
|
||||
};
|
||||
let node = match above {
|
||||
true => node.append(element),
|
||||
_ => node.prepend(element),
|
||||
};
|
||||
data.pending.node = Some(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn place_above(&self, parser: MsgParser<'_, '_>) -> Result<(), PlaceAboveError> {
|
||||
let req: PlaceAbove = self.surface.client.parse(self, parser)?;
|
||||
self.place(req.sibling, true)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn place_below(&self, parser: MsgParser<'_, '_>) -> Result<(), PlaceBelowError> {
|
||||
let req: PlaceBelow = self.surface.client.parse(self, parser)?;
|
||||
self.place(req.sibling, false)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_sync(&self, sync: bool) {
|
||||
let mut data = self.surface.role_data.borrow_mut();
|
||||
if let RoleData::Subsurface(data) = &mut *data {
|
||||
let was_sync = data.sync_requested || data.sync_ancestor;
|
||||
data.sync_requested = sync;
|
||||
let is_sync = data.sync_requested || data.sync_ancestor;
|
||||
if was_sync != is_sync {
|
||||
update_children_sync(&self.surface, is_sync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn set_sync(&self, parser: MsgParser<'_, '_>) -> Result<(), SetSyncError> {
|
||||
let _req: SetSync = self.surface.client.parse(self, parser)?;
|
||||
self.update_sync(true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn set_desync(&self, parser: MsgParser<'_, '_>) -> Result<(), SetDesyncError> {
|
||||
let _req: SetDesync = self.surface.client.parse(self, parser)?;
|
||||
self.update_sync(false);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue