Implement wl_subsurface.place_{above,below}.
This commit is contained in:
parent
1e960af5f2
commit
a5ae27be84
|
@ -1,7 +1,7 @@
|
|||
use super::{CompositorHandler, Damage, Handler as UserHandler, Rectangle, RectangleKind,
|
||||
SubsurfaceAttributes};
|
||||
use super::region::RegionData;
|
||||
use super::tree::SurfaceData;
|
||||
use super::tree::{Location, SurfaceData};
|
||||
use wayland_server::{Client, Destroy, EventLoopHandle, Resource};
|
||||
use wayland_server::protocol::{wl_buffer, wl_callback, wl_compositor, wl_output, wl_region,
|
||||
wl_subcompositor, wl_subsurface, wl_surface};
|
||||
|
@ -227,31 +227,43 @@ unsafe fn with_subsurface_attributes<U, F>(subsurface: &wl_subsurface::WlSubsurf
|
|||
}
|
||||
|
||||
impl<U, H> wl_subsurface::Handler for CompositorHandler<U, H> {
|
||||
fn set_position(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface,
|
||||
x: i32, y: i32) {
|
||||
fn set_position(&mut self, _: &mut EventLoopHandle, _: &Client,
|
||||
subsurface: &wl_subsurface::WlSubsurface, x: i32, y: i32) {
|
||||
unsafe {
|
||||
with_subsurface_attributes::<U, _>(resource, |attrs| {
|
||||
with_subsurface_attributes::<U, _>(subsurface, |attrs| {
|
||||
attrs.x = x;
|
||||
attrs.y = y;
|
||||
});
|
||||
}
|
||||
}
|
||||
fn place_above(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface,
|
||||
sibling: &wl_surface::WlSurface) {
|
||||
unimplemented!()
|
||||
}
|
||||
fn place_below(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface,
|
||||
sibling: &wl_surface::WlSurface) {
|
||||
unimplemented!()
|
||||
}
|
||||
fn set_sync(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface) {
|
||||
fn place_above(&mut self, _: &mut EventLoopHandle, _: &Client,
|
||||
subsurface: &wl_subsurface::WlSubsurface, sibling: &wl_surface::WlSurface) {
|
||||
unsafe {
|
||||
with_subsurface_attributes::<U, _>(resource, |attrs| { attrs.sync = true; });
|
||||
let ptr = subsurface.get_user_data();
|
||||
let surface = &*(ptr as *mut wl_surface::WlSurface);
|
||||
if let Err(()) = SurfaceData::<U>::reorder(surface, Location::After, sibling) {
|
||||
subsurface.post_error(wl_subsurface::Error::BadSurface as u32, "Provided surface is not a sibling or parent.".into());
|
||||
}
|
||||
}
|
||||
}
|
||||
fn set_desync(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface) {
|
||||
fn place_below(&mut self, _: &mut EventLoopHandle, _: &Client,
|
||||
subsurface: &wl_subsurface::WlSubsurface, sibling: &wl_surface::WlSurface) {
|
||||
unsafe {
|
||||
with_subsurface_attributes::<U, _>(resource, |attrs| { attrs.sync = false; });
|
||||
let ptr = subsurface.get_user_data();
|
||||
let surface = &*(ptr as *mut wl_surface::WlSurface);
|
||||
if let Err(()) = SurfaceData::<U>::reorder(surface, Location::Before, sibling) {
|
||||
subsurface.post_error(wl_subsurface::Error::BadSurface as u32, "Provided surface is not a sibling or parent.".into());
|
||||
}
|
||||
}
|
||||
}
|
||||
fn set_sync(&mut self, _: &mut EventLoopHandle, _: &Client, subsurface: &wl_subsurface::WlSubsurface) {
|
||||
unsafe {
|
||||
with_subsurface_attributes::<U, _>(subsurface, |attrs| { attrs.sync = true; });
|
||||
}
|
||||
}
|
||||
fn set_desync(&mut self, _: &mut EventLoopHandle, _: &Client, subsurface: &wl_subsurface::WlSubsurface) {
|
||||
unsafe {
|
||||
with_subsurface_attributes::<U, _>(subsurface, |attrs| { attrs.sync = false; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,7 +192,8 @@ impl<U: Send + 'static, H: Handler + Send + 'static> CompositorToken<U, H> {
|
|||
/// Access the data of a surface tree
|
||||
///
|
||||
/// The provided closure is called successively on the surface and all its child subsurfaces,
|
||||
/// in a depth-first order.
|
||||
/// in a depth-first order. This matches the order in which the surfaces are supposed to be
|
||||
/// drawn: top-most last.
|
||||
///
|
||||
/// If the surface is not managed by the CompositorGlobal that provided this token, this
|
||||
/// will panic (having more than one compositor is not supported).
|
||||
|
|
|
@ -43,6 +43,11 @@ pub enum RoleStatus {
|
|||
HasRole,
|
||||
}
|
||||
|
||||
pub enum Location {
|
||||
Before,
|
||||
After,
|
||||
}
|
||||
|
||||
impl<U: Default> SurfaceData<U> {
|
||||
fn new() -> SurfaceData<U> {
|
||||
SurfaceData {
|
||||
|
@ -191,6 +196,54 @@ impl<U> SurfaceData<U> {
|
|||
child_guard.parent.as_ref().map(|p| p.clone_unchecked())
|
||||
}
|
||||
|
||||
/// Reorders a surface relative to one of its sibling
|
||||
///
|
||||
/// Fails if `relative_to` is not a sibling or parent of `surface`.
|
||||
pub unsafe fn reorder(surface: &wl_surface::WlSurface, to: Location,
|
||||
relative_to: &wl_surface::WlSurface)
|
||||
-> Result<(), ()> {
|
||||
let parent = {
|
||||
let data_mutex = Self::get_data(surface);
|
||||
let data_guard = data_mutex.lock().unwrap();
|
||||
data_guard
|
||||
.parent
|
||||
.as_ref()
|
||||
.map(|p| p.clone_unchecked())
|
||||
.unwrap()
|
||||
};
|
||||
if parent.equals(relative_to) {
|
||||
// TODO: handle positioning relative to parent
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn index_of(surface: &wl_surface::WlSurface, slice: &[wl_surface::WlSurface]) -> Option<usize> {
|
||||
for (i, s) in slice.iter().enumerate() {
|
||||
if s.equals(surface) {
|
||||
return Some(i);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
let parent_mutex = Self::get_data(&parent);
|
||||
let mut parent_guard = parent_mutex.lock().unwrap();
|
||||
let my_index = index_of(surface, &parent_guard.children).unwrap();
|
||||
let mut other_index = match index_of(surface, &parent_guard.children) {
|
||||
Some(idx) => idx,
|
||||
None => return Err(()),
|
||||
};
|
||||
let me = parent_guard.children.remove(my_index);
|
||||
if my_index < other_index {
|
||||
other_index -= 1;
|
||||
}
|
||||
let new_index = match to {
|
||||
Location::Before => other_index,
|
||||
Location::After => other_index + 1,
|
||||
};
|
||||
parent_guard.children.insert(new_index, me);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Access the attributes associated with a surface
|
||||
///
|
||||
/// Note that an internal lock is taken during access of this data,
|
||||
|
|
Loading…
Reference in New Issue