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,
|
use super::{CompositorHandler, Damage, Handler as UserHandler, Rectangle, RectangleKind,
|
||||||
SubsurfaceAttributes};
|
SubsurfaceAttributes};
|
||||||
use super::region::RegionData;
|
use super::region::RegionData;
|
||||||
use super::tree::SurfaceData;
|
use super::tree::{Location, SurfaceData};
|
||||||
use wayland_server::{Client, Destroy, EventLoopHandle, Resource};
|
use wayland_server::{Client, Destroy, EventLoopHandle, Resource};
|
||||||
use wayland_server::protocol::{wl_buffer, wl_callback, wl_compositor, wl_output, wl_region,
|
use wayland_server::protocol::{wl_buffer, wl_callback, wl_compositor, wl_output, wl_region,
|
||||||
wl_subcompositor, wl_subsurface, wl_surface};
|
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> {
|
impl<U, H> wl_subsurface::Handler for CompositorHandler<U, H> {
|
||||||
fn set_position(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface,
|
fn set_position(&mut self, _: &mut EventLoopHandle, _: &Client,
|
||||||
x: i32, y: i32) {
|
subsurface: &wl_subsurface::WlSubsurface, x: i32, y: i32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
with_subsurface_attributes::<U, _>(resource, |attrs| {
|
with_subsurface_attributes::<U, _>(subsurface, |attrs| {
|
||||||
attrs.x = x;
|
attrs.x = x;
|
||||||
attrs.y = y;
|
attrs.y = y;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn place_above(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface,
|
fn place_above(&mut self, _: &mut EventLoopHandle, _: &Client,
|
||||||
sibling: &wl_surface::WlSurface) {
|
subsurface: &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) {
|
|
||||||
unsafe {
|
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 {
|
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
|
/// Access the data of a surface tree
|
||||||
///
|
///
|
||||||
/// The provided closure is called successively on the surface and all its child subsurfaces,
|
/// 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
|
/// If the surface is not managed by the CompositorGlobal that provided this token, this
|
||||||
/// will panic (having more than one compositor is not supported).
|
/// will panic (having more than one compositor is not supported).
|
||||||
|
|
|
@ -43,6 +43,11 @@ pub enum RoleStatus {
|
||||||
HasRole,
|
HasRole,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Location {
|
||||||
|
Before,
|
||||||
|
After,
|
||||||
|
}
|
||||||
|
|
||||||
impl<U: Default> SurfaceData<U> {
|
impl<U: Default> SurfaceData<U> {
|
||||||
fn new() -> SurfaceData<U> {
|
fn new() -> SurfaceData<U> {
|
||||||
SurfaceData {
|
SurfaceData {
|
||||||
|
@ -191,6 +196,54 @@ impl<U> SurfaceData<U> {
|
||||||
child_guard.parent.as_ref().map(|p| p.clone_unchecked())
|
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
|
/// Access the attributes associated with a surface
|
||||||
///
|
///
|
||||||
/// Note that an internal lock is taken during access of this data,
|
/// Note that an internal lock is taken during access of this data,
|
||||||
|
|
Loading…
Reference in New Issue