1
0
Fork 0
forked from wry/wry

autocommit 2022-01-03 18:56:52 CET

This commit is contained in:
Julian Orth 2022-01-03 18:56:52 +01:00
parent fc887b339e
commit 30376c595c
39 changed files with 3157 additions and 309 deletions

View file

@ -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(())
}