wayland.compositor: user UserDataMap to store per-surface data

This commit is contained in:
Victor Berger 2019-04-23 22:46:11 +02:00 committed by Victor Berger
parent 0712bdefec
commit c604a48dce
17 changed files with 431 additions and 525 deletions

View File

@ -28,7 +28,7 @@ use smithay::{
}; };
use crate::shaders; use crate::shaders;
use crate::shell::{MyCompositorToken, MyWindowMap}; use crate::shell::{MyCompositorToken, MyWindowMap, SurfaceData};
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct Vertex { struct Vertex {
@ -299,70 +299,77 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
location, location,
|_surface, attributes, role, &(mut x, mut y)| { |_surface, attributes, role, &(mut x, mut y)| {
// Pull a new buffer if available // Pull a new buffer if available
if attributes.user_data.texture.is_none() { if let Some(data) = attributes.user_data.get_mut::<SurfaceData>() {
if let Some(buffer) = attributes.user_data.buffer.take() { if data.texture.is_none() {
if let Ok(m) = self.texture_from_buffer(buffer.clone()) { if let Some(buffer) = data.buffer.take() {
// release the buffer if it was an SHM buffer if let Ok(m) = self.texture_from_buffer(buffer.clone()) {
#[cfg(feature = "egl")] // release the buffer if it was an SHM buffer
{ #[cfg(feature = "egl")]
if m.images.is_none() { {
if m.images.is_none() {
buffer.release();
}
}
#[cfg(not(feature = "egl"))]
{
buffer.release(); buffer.release();
} }
}
#[cfg(not(feature = "egl"))] data.texture = Some(m);
{ } else {
// there was an error reading the buffer, release it, we
// already logged the error
buffer.release(); buffer.release();
} }
attributes.user_data.texture = Some(m);
} else {
// there was an error reading the buffer, release it, we
// already logged the error
buffer.release();
} }
} }
} // Now, should we be drawn ?
// Now, should we be drawn ? if data.texture.is_some() {
if attributes.user_data.texture.is_some() { // if yes, also process the children
// if yes, also process the children if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) { x += subdata.location.0;
x += subdata.location.0; y += subdata.location.1;
y += subdata.location.1; }
TraversalAction::DoChildren((x, y))
} else {
// we are not displayed, so our children are neither
TraversalAction::SkipChildren
} }
TraversalAction::DoChildren((x, y))
} else { } else {
// we are not display, so our children are neither // we are not displayed, so our children are neither
TraversalAction::SkipChildren TraversalAction::SkipChildren
} }
}, },
|_surface, attributes, role, &(mut x, mut y)| { |_surface, attributes, role, &(mut x, mut y)| {
if let Some(ref metadata) = attributes.user_data.texture { if let Some(ref data) = attributes.user_data.get::<SurfaceData>() {
// we need to re-extract the subsurface offset, as the previous closure if let Some(ref metadata) = data.texture {
// only passes it to our children // we need to re-extract the subsurface offset, as the previous closure
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) { // only passes it to our children
x += subdata.location.0; if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
y += subdata.location.1; x += subdata.location.0;
y += subdata.location.1;
}
self.render_texture(
frame,
&metadata.texture,
metadata.fragment,
metadata.y_inverted,
metadata.dimensions,
(x, y),
screen_dimensions,
::glium::Blend {
color: ::glium::BlendingFunction::Addition {
source: ::glium::LinearBlendingFactor::One,
destination: ::glium::LinearBlendingFactor::OneMinusSourceAlpha,
},
alpha: ::glium::BlendingFunction::Addition {
source: ::glium::LinearBlendingFactor::One,
destination: ::glium::LinearBlendingFactor::OneMinusSourceAlpha,
},
..Default::default()
},
);
} }
self.render_texture(
frame,
&metadata.texture,
metadata.fragment,
metadata.y_inverted,
metadata.dimensions,
(x, y),
screen_dimensions,
::glium::Blend {
color: ::glium::BlendingFunction::Addition {
source: ::glium::LinearBlendingFactor::One,
destination: ::glium::LinearBlendingFactor::OneMinusSourceAlpha,
},
alpha: ::glium::BlendingFunction::Addition {
source: ::glium::LinearBlendingFactor::One,
destination: ::glium::LinearBlendingFactor::OneMinusSourceAlpha,
},
..Default::default()
},
);
} }
}, },
|_, _, _, _| true, |_, _, _, _| true,

View File

@ -36,18 +36,17 @@ define_roles!(Roles =>
[ CursorImage, CursorImageRole ] [ CursorImage, CursorImageRole ]
); );
pub type MyWindowMap = pub type MyWindowMap = WindowMap<Roles, (), (), fn(&SurfaceAttributes) -> Option<(i32, i32)>>;
WindowMap<SurfaceData, Roles, (), (), fn(&SurfaceAttributes<SurfaceData>) -> Option<(i32, i32)>>;
pub type MyCompositorToken = CompositorToken<SurfaceData, Roles>; pub type MyCompositorToken = CompositorToken<Roles>;
pub fn init_shell( pub fn init_shell(
display: &mut Display, display: &mut Display,
log: ::slog::Logger, log: ::slog::Logger,
) -> ( ) -> (
CompositorToken<SurfaceData, Roles>, CompositorToken<Roles>,
Arc<Mutex<XdgShellState<SurfaceData, Roles, ()>>>, Arc<Mutex<XdgShellState<Roles, ()>>>,
Arc<Mutex<WlShellState<SurfaceData, Roles, ()>>>, Arc<Mutex<WlShellState<Roles, ()>>>,
Rc<RefCell<MyWindowMap>>, Rc<RefCell<MyWindowMap>>,
) { ) {
// Create the compositor // Create the compositor
@ -63,7 +62,7 @@ pub fn init_shell(
); );
// Init a window map, to track the location of our windows // Init a window map, to track the location of our windows
let window_map = Rc::new(RefCell::new(WindowMap::<_, _, (), (), _>::new( let window_map = Rc::new(RefCell::new(WindowMap::<_, (), (), _>::new(
compositor_token, compositor_token,
get_size as _, get_size as _,
))); )));
@ -105,7 +104,7 @@ pub fn init_shell(
let (wl_shell_state, _) = wl_shell_init( let (wl_shell_state, _) = wl_shell_init(
display, display,
compositor_token, compositor_token,
move |req: ShellRequest<_, _, ()>| { move |req: ShellRequest<_, ()>| {
if let ShellRequest::SetKind { if let ShellRequest::SetKind {
surface, surface,
kind: ShellSurfaceKind::Toplevel, kind: ShellSurfaceKind::Toplevel,
@ -135,31 +134,34 @@ pub struct SurfaceData {
pub texture: Option<crate::glium_drawer::TextureMetadata>, pub texture: Option<crate::glium_drawer::TextureMetadata>,
} }
fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<SurfaceData, Roles>) { fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<Roles>) {
// we retrieve the contents of the associated buffer and copy it // we retrieve the contents of the associated buffer and copy it
token.with_surface_data(surface, |attributes| { token.with_surface_data(surface, |attributes| {
attributes.user_data.insert_if_missing(|| SurfaceData::default());
match attributes.buffer.take() { match attributes.buffer.take() {
Some(Some((buffer, (_x, _y)))) => { Some(Some((buffer, (_x, _y)))) => {
// new contents // new contents
// TODO: handle hotspot coordinates // TODO: handle hotspot coordinates
attributes.user_data.buffer = Some(buffer); let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();
attributes.user_data.texture = None; data.buffer = Some(buffer);
data.texture = None;
} }
Some(None) => { Some(None) => {
// erase the contents // erase the contents
attributes.user_data.buffer = None; let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();
attributes.user_data.texture = None; data.buffer = None;
data.texture = None;
} }
None => {} None => {}
} }
}); });
} }
fn get_size(attrs: &SurfaceAttributes<SurfaceData>) -> Option<(i32, i32)> { fn get_size(attrs: &SurfaceAttributes) -> Option<(i32, i32)> {
attrs attrs.user_data.get::<SurfaceData>().and_then(|data| {
.user_data data.texture
.texture .as_ref()
.as_ref() .map(|ref meta| meta.dimensions)
.map(|ref meta| meta.dimensions) .map(|(x, y)| (x as i32, y as i32))
.map(|(x, y)| (x as i32, y as i32)) })
} }

View File

@ -63,7 +63,7 @@ use smithay::{
use crate::glium_drawer::GliumDrawer; use crate::glium_drawer::GliumDrawer;
use crate::input_handler::AnvilInputHandler; use crate::input_handler::AnvilInputHandler;
use crate::shell::{init_shell, MyWindowMap, Roles, SurfaceData}; use crate::shell::{init_shell, MyWindowMap, Roles};
pub struct SessionFd(RawFd); pub struct SessionFd(RawFd);
impl AsRawFd for SessionFd { impl AsRawFd for SessionFd {
@ -272,7 +272,7 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger
} }
struct UdevHandlerImpl<S: SessionNotifier, Data: 'static> { struct UdevHandlerImpl<S: SessionNotifier, Data: 'static> {
compositor_token: CompositorToken<SurfaceData, Roles>, compositor_token: CompositorToken<Roles>,
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
active_egl_context: Rc<RefCell<Option<EGLDisplay>>>, active_egl_context: Rc<RefCell<Option<EGLDisplay>>>,
session: AutoSession, session: AutoSession,
@ -522,7 +522,7 @@ impl<S: SessionNotifier, Data: 'static> UdevHandler for UdevHandlerImpl<S, Data>
} }
pub struct DrmHandlerImpl { pub struct DrmHandlerImpl {
compositor_token: CompositorToken<SurfaceData, Roles>, compositor_token: CompositorToken<Roles>,
backends: Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<RenderSurface>>>>, backends: Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<RenderSurface>>>>,
window_map: Rc<RefCell<MyWindowMap>>, window_map: Rc<RefCell<MyWindowMap>>,
pointer_location: Rc<RefCell<(f64, f64)>>, pointer_location: Rc<RefCell<(f64, f64)>>,

View File

@ -12,14 +12,13 @@ use smithay::{
}, },
}; };
pub enum Kind<U, R, SD, D> { pub enum Kind<R, SD, D> {
Xdg(ToplevelSurface<U, R, SD>), Xdg(ToplevelSurface<R, SD>),
Wl(ShellSurface<U, R, D>), Wl(ShellSurface<R, D>),
} }
impl<U, R, SD, D> Kind<U, R, SD, D> impl<R, SD, D> Kind<R, SD, D>
where where
U: 'static,
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static, R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
SD: 'static, SD: 'static,
D: 'static, D: 'static,
@ -38,15 +37,14 @@ where
} }
} }
struct Window<U, R, SD, D> { struct Window<R, SD, D> {
location: (i32, i32), location: (i32, i32),
surface: Rectangle, surface: Rectangle,
toplevel: Kind<U, R, SD, D>, toplevel: Kind<R, SD, D>,
} }
impl<U, R, SD, D> Window<U, R, SD, D> impl<R, SD, D> Window<R, SD, D>
where where
U: 'static,
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static, R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
SD: 'static, SD: 'static,
D: 'static, D: 'static,
@ -55,11 +53,11 @@ where
fn matching<F>( fn matching<F>(
&self, &self,
point: (f64, f64), point: (f64, f64),
ctoken: CompositorToken<U, R>, ctoken: CompositorToken<R>,
get_size: F, get_size: F,
) -> Option<(wl_surface::WlSurface, (f64, f64))> ) -> Option<(wl_surface::WlSurface, (f64, f64))>
where where
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>, F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
{ {
if !self.surface.contains((point.0 as i32, point.1 as i32)) { if !self.surface.contains((point.0 as i32, point.1 as i32)) {
return None; return None;
@ -101,9 +99,9 @@ where
found.into_inner() found.into_inner()
} }
fn self_update<F>(&mut self, ctoken: CompositorToken<U, R>, get_size: F) fn self_update<F>(&mut self, ctoken: CompositorToken<R>, get_size: F)
where where
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>, F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
{ {
let (base_x, base_y) = self.location; let (base_x, base_y) = self.location;
let (mut min_x, mut min_y, mut max_x, mut max_y) = (base_x, base_y, base_x, base_y); let (mut min_x, mut min_y, mut max_x, mut max_y) = (base_x, base_y, base_x, base_y);
@ -148,21 +146,20 @@ where
} }
} }
pub struct WindowMap<U, R, SD, D, F> { pub struct WindowMap<R, SD, D, F> {
ctoken: CompositorToken<U, R>, ctoken: CompositorToken<R>,
windows: Vec<Window<U, R, SD, D>>, windows: Vec<Window<R, SD, D>>,
get_size: F, get_size: F,
} }
impl<U, R, SD, D, F> WindowMap<U, R, SD, D, F> impl<R, SD, D, F> WindowMap<R, SD, D, F>
where where
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>, F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
U: 'static,
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static, R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
SD: 'static, SD: 'static,
D: 'static, D: 'static,
{ {
pub fn new(ctoken: CompositorToken<U, R>, get_size: F) -> WindowMap<U, R, D, SD, F> { pub fn new(ctoken: CompositorToken<R>, get_size: F) -> WindowMap<R, D, SD, F> {
WindowMap { WindowMap {
ctoken, ctoken,
windows: Vec::new(), windows: Vec::new(),
@ -170,7 +167,7 @@ where
} }
} }
pub fn insert(&mut self, toplevel: Kind<U, R, SD, D>, location: (i32, i32)) { pub fn insert(&mut self, toplevel: Kind<R, SD, D>, location: (i32, i32)) {
let mut window = Window { let mut window = Window {
location, location,
surface: Rectangle { surface: Rectangle {
@ -216,7 +213,7 @@ where
pub fn with_windows_from_bottom_to_top<Func>(&self, mut f: Func) pub fn with_windows_from_bottom_to_top<Func>(&self, mut f: Func)
where where
Func: FnMut(&Kind<U, R, SD, D>, (i32, i32)), Func: FnMut(&Kind<R, SD, D>, (i32, i32)),
{ {
for w in self.windows.iter().rev() { for w in self.windows.iter().rev() {
f(&w.toplevel, w.location) f(&w.toplevel, w.location)

View File

@ -300,7 +300,6 @@ impl Drop for EGLImages {
} }
} }
} }
println!("RELEASING EGL BUFFER");
self.buffer.release(); self.buffer.release();
} }
} }

View File

@ -15,15 +15,14 @@ use super::{
* wl_compositor * wl_compositor
*/ */
pub(crate) fn implement_compositor<U, R, Impl>( pub(crate) fn implement_compositor<R, Impl>(
compositor: NewResource<wl_compositor::WlCompositor>, compositor: NewResource<wl_compositor::WlCompositor>,
log: ::slog::Logger, log: ::slog::Logger,
implem: Rc<RefCell<Impl>>, implem: Rc<RefCell<Impl>>,
) -> wl_compositor::WlCompositor ) -> wl_compositor::WlCompositor
where where
U: Default + 'static,
R: Default + 'static, R: Default + 'static,
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<U, R>) + 'static, Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static,
{ {
compositor.implement_closure( compositor.implement_closure(
move |request, _compositor| match request { move |request, _compositor| match request {
@ -47,34 +46,33 @@ where
*/ */
// Internal implementation data of surfaces // Internal implementation data of surfaces
pub(crate) struct SurfaceImplem<U, R> { pub(crate) struct SurfaceImplem<R> {
log: ::slog::Logger, log: ::slog::Logger,
implem: Rc<RefCell<dyn FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<U, R>)>>, implem: Rc<RefCell<dyn FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>)>>,
} }
impl<U, R> SurfaceImplem<U, R> { impl<R> SurfaceImplem<R> {
fn make<Impl>(log: ::slog::Logger, implem: Rc<RefCell<Impl>>) -> SurfaceImplem<U, R> fn make<Impl>(log: ::slog::Logger, implem: Rc<RefCell<Impl>>) -> SurfaceImplem<R>
where where
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<U, R>) + 'static, Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static,
{ {
SurfaceImplem { log, implem } SurfaceImplem { log, implem }
} }
} }
impl<U, R> SurfaceImplem<U, R> impl<R> SurfaceImplem<R>
where where
U: 'static,
R: 'static, R: 'static,
{ {
fn receive_surface_request(&mut self, req: wl_surface::Request, surface: wl_surface::WlSurface) { fn receive_surface_request(&mut self, req: wl_surface::Request, surface: wl_surface::WlSurface) {
match req { match req {
wl_surface::Request::Attach { buffer, x, y } => { wl_surface::Request::Attach { buffer, x, y } => {
SurfaceData::<U, R>::with_data(&surface, |d| { SurfaceData::<R>::with_data(&surface, |d| {
d.buffer = Some(buffer.map(|b| (b.clone(), (x, y)))) d.buffer = Some(buffer.map(|b| (b.clone(), (x, y))))
}); });
} }
wl_surface::Request::Damage { x, y, width, height } => { wl_surface::Request::Damage { x, y, width, height } => {
SurfaceData::<U, R>::with_data(&surface, |d| { SurfaceData::<R>::with_data(&surface, |d| {
d.damage = Damage::Surface(Rectangle { x, y, width, height }) d.damage = Damage::Surface(Rectangle { x, y, width, height })
}); });
} }
@ -88,14 +86,14 @@ where
let attributes_mutex = r.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap(); let attributes_mutex = r.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap();
attributes_mutex.lock().unwrap().clone() attributes_mutex.lock().unwrap().clone()
}); });
SurfaceData::<U, R>::with_data(&surface, |d| d.opaque_region = attributes); SurfaceData::<R>::with_data(&surface, |d| d.opaque_region = attributes);
} }
wl_surface::Request::SetInputRegion { region } => { wl_surface::Request::SetInputRegion { region } => {
let attributes = region.map(|r| { let attributes = region.map(|r| {
let attributes_mutex = r.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap(); let attributes_mutex = r.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap();
attributes_mutex.lock().unwrap().clone() attributes_mutex.lock().unwrap().clone()
}); });
SurfaceData::<U, R>::with_data(&surface, |d| d.input_region = attributes); SurfaceData::<R>::with_data(&surface, |d| d.input_region = attributes);
} }
wl_surface::Request::Commit => { wl_surface::Request::Commit => {
let mut user_impl = self.implem.borrow_mut(); let mut user_impl = self.implem.borrow_mut();
@ -103,13 +101,13 @@ where
(&mut *user_impl)(SurfaceEvent::Commit, surface, CompositorToken::make()); (&mut *user_impl)(SurfaceEvent::Commit, surface, CompositorToken::make());
} }
wl_surface::Request::SetBufferTransform { transform } => { wl_surface::Request::SetBufferTransform { transform } => {
SurfaceData::<U, R>::with_data(&surface, |d| d.buffer_transform = transform); SurfaceData::<R>::with_data(&surface, |d| d.buffer_transform = transform);
} }
wl_surface::Request::SetBufferScale { scale } => { wl_surface::Request::SetBufferScale { scale } => {
SurfaceData::<U, R>::with_data(&surface, |d| d.buffer_scale = scale); SurfaceData::<R>::with_data(&surface, |d| d.buffer_scale = scale);
} }
wl_surface::Request::DamageBuffer { x, y, width, height } => { wl_surface::Request::DamageBuffer { x, y, width, height } => {
SurfaceData::<U, R>::with_data(&surface, |d| { SurfaceData::<R>::with_data(&surface, |d| {
d.damage = Damage::Buffer(Rectangle { x, y, width, height }) d.damage = Damage::Buffer(Rectangle { x, y, width, height })
}); });
} }
@ -121,25 +119,24 @@ where
} }
} }
fn implement_surface<U, R, Impl>( fn implement_surface<R, Impl>(
surface: NewResource<wl_surface::WlSurface>, surface: NewResource<wl_surface::WlSurface>,
log: ::slog::Logger, log: ::slog::Logger,
implem: Rc<RefCell<Impl>>, implem: Rc<RefCell<Impl>>,
) -> wl_surface::WlSurface ) -> wl_surface::WlSurface
where where
U: Default + 'static,
R: Default + 'static, R: Default + 'static,
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<U, R>) + 'static, Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static,
{ {
let surface = surface.implement_closure( let surface = surface.implement_closure(
{ {
let mut implem = SurfaceImplem::make(log, implem); let mut implem = SurfaceImplem::make(log, implem);
move |req, surface| implem.receive_surface_request(req, surface) move |req, surface| implem.receive_surface_request(req, surface)
}, },
Some(|surface| SurfaceData::<U, R>::cleanup(&surface)), Some(|surface| SurfaceData::<R>::cleanup(&surface)),
SurfaceData::<U, R>::new(), SurfaceData::<R>::new(),
); );
SurfaceData::<U, R>::init(&surface); SurfaceData::<R>::init(&surface);
surface surface
} }
@ -176,24 +173,23 @@ fn implement_region(region: NewResource<wl_region::WlRegion>) -> wl_region::WlRe
* wl_subcompositor * wl_subcompositor
*/ */
pub(crate) fn implement_subcompositor<U, R>( pub(crate) fn implement_subcompositor<R>(
subcompositor: NewResource<wl_subcompositor::WlSubcompositor>, subcompositor: NewResource<wl_subcompositor::WlSubcompositor>,
) -> wl_subcompositor::WlSubcompositor ) -> wl_subcompositor::WlSubcompositor
where where
R: RoleType + Role<SubsurfaceRole> + 'static, R: RoleType + Role<SubsurfaceRole> + 'static,
U: 'static,
{ {
subcompositor.implement_closure( subcompositor.implement_closure(
move |request, subcompositor| match request { move |request, subcompositor| match request {
wl_subcompositor::Request::GetSubsurface { id, surface, parent } => { wl_subcompositor::Request::GetSubsurface { id, surface, parent } => {
if let Err(()) = SurfaceData::<U, R>::set_parent(&surface, &parent) { if let Err(()) = SurfaceData::<R>::set_parent(&surface, &parent) {
subcompositor.as_ref().post_error( subcompositor.as_ref().post_error(
wl_subcompositor::Error::BadSurface as u32, wl_subcompositor::Error::BadSurface as u32,
"Surface already has a role.".into(), "Surface already has a role.".into(),
); );
return; return;
} }
implement_subsurface::<U, R>(id, surface.clone()); implement_subsurface::<R>(id, surface.clone());
} }
wl_subcompositor::Request::Destroy => {} wl_subcompositor::Request::Destroy => {}
_ => unreachable!(), _ => unreachable!(),
@ -207,36 +203,34 @@ where
* wl_subsurface * wl_subsurface
*/ */
fn with_subsurface_attributes<U, R, F>(subsurface: &wl_subsurface::WlSubsurface, f: F) fn with_subsurface_attributes<R, F>(subsurface: &wl_subsurface::WlSubsurface, f: F)
where where
F: FnOnce(&mut SubsurfaceRole), F: FnOnce(&mut SubsurfaceRole),
U: 'static,
R: RoleType + Role<SubsurfaceRole> + 'static, R: RoleType + Role<SubsurfaceRole> + 'static,
{ {
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap(); let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap();
SurfaceData::<U, R>::with_role_data::<SubsurfaceRole, _, _>(surface, |d| f(d)) SurfaceData::<R>::with_role_data::<SubsurfaceRole, _, _>(surface, |d| f(d))
.expect("The surface does not have a subsurface role while it has a wl_subsurface?!"); .expect("The surface does not have a subsurface role while it has a wl_subsurface?!");
} }
fn implement_subsurface<U, R>( fn implement_subsurface<R>(
subsurface: NewResource<wl_subsurface::WlSubsurface>, subsurface: NewResource<wl_subsurface::WlSubsurface>,
surface: wl_surface::WlSurface, surface: wl_surface::WlSurface,
) -> wl_subsurface::WlSubsurface ) -> wl_subsurface::WlSubsurface
where where
U: 'static,
R: RoleType + Role<SubsurfaceRole> + 'static, R: RoleType + Role<SubsurfaceRole> + 'static,
{ {
subsurface.implement_closure( subsurface.implement_closure(
|request, subsurface| { |request, subsurface| {
match request { match request {
wl_subsurface::Request::SetPosition { x, y } => { wl_subsurface::Request::SetPosition { x, y } => {
with_subsurface_attributes::<U, R, _>(&subsurface, |attrs| { with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
attrs.location = (x, y); attrs.location = (x, y);
}) })
} }
wl_subsurface::Request::PlaceAbove { sibling } => { wl_subsurface::Request::PlaceAbove { sibling } => {
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap(); let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap();
if let Err(()) = SurfaceData::<U, R>::reorder(surface, Location::After, &sibling) { if let Err(()) = SurfaceData::<R>::reorder(surface, Location::After, &sibling) {
subsurface.as_ref().post_error( subsurface.as_ref().post_error(
wl_subsurface::Error::BadSurface as u32, wl_subsurface::Error::BadSurface as u32,
"Provided surface is not a sibling or parent.".into(), "Provided surface is not a sibling or parent.".into(),
@ -245,20 +239,18 @@ where
} }
wl_subsurface::Request::PlaceBelow { sibling } => { wl_subsurface::Request::PlaceBelow { sibling } => {
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap(); let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap();
if let Err(()) = SurfaceData::<U, R>::reorder(surface, Location::Before, &sibling) { if let Err(()) = SurfaceData::<R>::reorder(surface, Location::Before, &sibling) {
subsurface.as_ref().post_error( subsurface.as_ref().post_error(
wl_subsurface::Error::BadSurface as u32, wl_subsurface::Error::BadSurface as u32,
"Provided surface is not a sibling or parent.".into(), "Provided surface is not a sibling or parent.".into(),
) )
} }
} }
wl_subsurface::Request::SetSync => { wl_subsurface::Request::SetSync => with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
with_subsurface_attributes::<U, R, _>(&subsurface, |attrs| { attrs.sync = true;
attrs.sync = true; }),
})
}
wl_subsurface::Request::SetDesync => { wl_subsurface::Request::SetDesync => {
with_subsurface_attributes::<U, R, _>(&subsurface, |attrs| { with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
attrs.sync = false; attrs.sync = false;
}) })
} }
@ -268,18 +260,17 @@ where
_ => unreachable!(), _ => unreachable!(),
} }
}, },
Some(|subsurface| destroy_subsurface::<U, R>(&subsurface)), Some(|subsurface| destroy_subsurface::<R>(&subsurface)),
surface, surface,
) )
} }
fn destroy_subsurface<U, R>(subsurface: &wl_subsurface::WlSubsurface) fn destroy_subsurface<R>(subsurface: &wl_subsurface::WlSubsurface)
where where
U: 'static,
R: RoleType + Role<SubsurfaceRole> + 'static, R: RoleType + Role<SubsurfaceRole> + 'static,
{ {
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap(); let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap();
if surface.as_ref().is_alive() { if surface.as_ref().is_alive() {
SurfaceData::<U, R>::unset_parent(&surface); SurfaceData::<R>::unset_parent(&surface);
} }
} }

View File

@ -32,14 +32,6 @@
//! # #[macro_use] extern crate smithay; //! # #[macro_use] extern crate smithay;
//! use smithay::wayland::compositor::compositor_init; //! use smithay::wayland::compositor::compositor_init;
//! //!
//! // Define some user data to be associated with the surfaces.
//! // It must implement the Default trait, which will represent the state of a surface which
//! // has just been created.
//! #[derive(Default)]
//! struct MyData {
//! // whatever you need here
//! }
//!
//! // Declare the roles enum //! // Declare the roles enum
//! define_roles!(MyRoles); //! define_roles!(MyRoles);
//! //!
@ -47,7 +39,7 @@
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
//! # let mut display = wayland_server::Display::new(event_loop.handle()); //! # let mut display = wayland_server::Display::new(event_loop.handle());
//! // Call the init function: //! // Call the init function:
//! let (token, _, _) = compositor_init::<MyData, MyRoles, _, _>( //! let (token, _, _) = compositor_init::<MyRoles, _, _>(
//! &mut display, //! &mut display,
//! |request, surface, compositor_token| { //! |request, surface, compositor_token| {
//! /* //! /*
@ -112,8 +104,7 @@ pub enum Damage {
} }
#[derive(Copy, Clone, Default)] #[derive(Copy, Clone, Default)]
struct Marker<U, R> { struct Marker<R> {
_u: ::std::marker::PhantomData<U>,
_r: ::std::marker::PhantomData<R>, _r: ::std::marker::PhantomData<R>,
} }
@ -125,7 +116,7 @@ struct Marker<U, R> {
/// ///
/// You are responsible for setting those values as you see fit to avoid /// You are responsible for setting those values as you see fit to avoid
/// processing them two times. /// processing them two times.
pub struct SurfaceAttributes<U> { pub struct SurfaceAttributes {
/// Buffer defining the contents of the surface /// Buffer defining the contents of the surface
/// ///
/// The tuple represent the coordinates of this buffer /// The tuple represent the coordinates of this buffer
@ -164,11 +155,11 @@ pub struct SurfaceAttributes<U> {
/// User-controlled data /// User-controlled data
/// ///
/// This is your field to host whatever you need. /// This is your field to host whatever you need.
pub user_data: U, pub user_data: ::wayland_commons::utils::UserDataMap,
} }
impl<U: Default> Default for SurfaceAttributes<U> { impl Default for SurfaceAttributes {
fn default() -> SurfaceAttributes<U> { fn default() -> SurfaceAttributes {
SurfaceAttributes { SurfaceAttributes {
buffer: None, buffer: None,
buffer_scale: 1, buffer_scale: 1,
@ -176,7 +167,7 @@ impl<U: Default> Default for SurfaceAttributes<U> {
opaque_region: None, opaque_region: None,
input_region: None, input_region: None,
damage: Damage::Full, damage: Damage::Full,
user_data: Default::default(), user_data: ::wayland_commons::utils::UserDataMap::new(),
} }
} }
} }
@ -239,33 +230,30 @@ impl Default for RegionAttributes {
/// access data associated with the [`wl_surface`](wayland_server::protocol::wl_surface) /// access data associated with the [`wl_surface`](wayland_server::protocol::wl_surface)
/// and [`wl_region`](wayland_server::protocol::wl_region) managed /// and [`wl_region`](wayland_server::protocol::wl_region) managed
/// by the `CompositorGlobal` that provided it. /// by the `CompositorGlobal` that provided it.
pub struct CompositorToken<U, R> { pub struct CompositorToken<R> {
_data: ::std::marker::PhantomData<*mut U>,
_role: ::std::marker::PhantomData<*mut R>, _role: ::std::marker::PhantomData<*mut R>,
} }
// we implement them manually because #[derive(..)] would require // we implement them manually because #[derive(..)] would require R: Clone
// U: Clone and R: Clone impl<R> Copy for CompositorToken<R> {}
impl<U, R> Copy for CompositorToken<U, R> {} impl<R> Clone for CompositorToken<R> {
impl<U, R> Clone for CompositorToken<U, R> { fn clone(&self) -> CompositorToken<R> {
fn clone(&self) -> CompositorToken<U, R> {
*self *self
} }
} }
unsafe impl<U, R> Send for CompositorToken<U, R> {} unsafe impl<R> Send for CompositorToken<R> {}
unsafe impl<U, R> Sync for CompositorToken<U, R> {} unsafe impl<R> Sync for CompositorToken<R> {}
impl<U, R> CompositorToken<U, R> { impl<R> CompositorToken<R> {
pub(crate) fn make() -> CompositorToken<U, R> { pub(crate) fn make() -> CompositorToken<R> {
CompositorToken { CompositorToken {
_data: ::std::marker::PhantomData,
_role: ::std::marker::PhantomData, _role: ::std::marker::PhantomData,
} }
} }
} }
impl<U: 'static, R: 'static> CompositorToken<U, R> { impl<R: 'static> CompositorToken<R> {
/// Access the data of a surface /// Access the data of a surface
/// ///
/// The closure will be called with the contents of the data associated with this surface. /// The closure will be called with the contents of the data associated with this surface.
@ -274,15 +262,14 @@ impl<U: 'static, R: 'static> CompositorToken<U, R> {
/// will panic (having more than one compositor is not supported). /// will panic (having more than one compositor is not supported).
pub fn with_surface_data<F, T>(&self, surface: &WlSurface, f: F) -> T pub fn with_surface_data<F, T>(&self, surface: &WlSurface, f: F) -> T
where where
F: FnOnce(&mut SurfaceAttributes<U>) -> T, F: FnOnce(&mut SurfaceAttributes) -> T,
{ {
SurfaceData::<U, R>::with_data(surface, f) SurfaceData::<R>::with_data(surface, f)
} }
} }
impl<U, R> CompositorToken<U, R> impl<R> CompositorToken<R>
where where
U: 'static,
R: RoleType + Role<SubsurfaceRole> + 'static, R: RoleType + Role<SubsurfaceRole> + 'static,
{ {
/// Access the data of a surface tree from bottom to top /// Access the data of a surface tree from bottom to top
@ -319,11 +306,11 @@ where
processor: F2, processor: F2,
post_filter: F3, post_filter: F3,
) where ) where
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>, F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T), F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool, F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool,
{ {
SurfaceData::<U, R>::map_tree(surface, &initial, filter, processor, post_filter, false); SurfaceData::<R>::map_tree(surface, &initial, filter, processor, post_filter, false);
} }
/// Access the data of a surface tree from top to bottom /// Access the data of a surface tree from top to bottom
@ -340,11 +327,11 @@ where
processor: F2, processor: F2,
post_filter: F3, post_filter: F3,
) where ) where
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>, F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T), F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool, F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool,
{ {
SurfaceData::<U, R>::map_tree(surface, &initial, filter, processor, post_filter, true); SurfaceData::<R>::map_tree(surface, &initial, filter, processor, post_filter, true);
} }
/// Retrieve the parent of this surface /// Retrieve the parent of this surface
@ -354,7 +341,7 @@ where
/// 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).
pub fn get_parent(&self, surface: &WlSurface) -> Option<WlSurface> { pub fn get_parent(&self, surface: &WlSurface) -> Option<WlSurface> {
SurfaceData::<U, R>::get_parent(surface) SurfaceData::<R>::get_parent(surface)
} }
/// Retrieve the children of this surface /// Retrieve the children of this surface
@ -362,17 +349,17 @@ where
/// 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).
pub fn get_children(&self, surface: &WlSurface) -> Vec<WlSurface> { pub fn get_children(&self, surface: &WlSurface) -> Vec<WlSurface> {
SurfaceData::<U, R>::get_children(surface) SurfaceData::<R>::get_children(surface)
} }
} }
impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> { impl<R: RoleType + 'static> CompositorToken<R> {
/// Check whether this surface as a role or not /// Check whether this surface as a role or not
/// ///
/// 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).
pub fn has_a_role(&self, surface: &WlSurface) -> bool { pub fn has_a_role(&self, surface: &WlSurface) -> bool {
SurfaceData::<U, R>::has_a_role(surface) SurfaceData::<R>::has_a_role(surface)
} }
/// Check whether this surface as a specific role /// Check whether this surface as a specific role
@ -383,7 +370,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
where where
R: Role<RoleData>, R: Role<RoleData>,
{ {
SurfaceData::<U, R>::has_role::<RoleData>(surface) SurfaceData::<R>::has_role::<RoleData>(surface)
} }
/// Register that this surface has given role with default data /// Register that this surface has given role with default data
@ -397,7 +384,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
R: Role<RoleData>, R: Role<RoleData>,
RoleData: Default, RoleData: Default,
{ {
SurfaceData::<U, R>::give_role::<RoleData>(surface) SurfaceData::<R>::give_role::<RoleData>(surface)
} }
/// Register that this surface has given role with given data /// Register that this surface has given role with given data
@ -410,7 +397,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
where where
R: Role<RoleData>, R: Role<RoleData>,
{ {
SurfaceData::<U, R>::give_role_with::<RoleData>(surface, data) SurfaceData::<R>::give_role_with::<RoleData>(surface, data)
} }
/// Access the role data of a surface /// Access the role data of a surface
@ -424,7 +411,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
R: Role<RoleData>, R: Role<RoleData>,
F: FnOnce(&mut RoleData) -> T, F: FnOnce(&mut RoleData) -> T,
{ {
SurfaceData::<U, R>::with_role_data::<RoleData, _, _>(surface, f) SurfaceData::<R>::with_role_data::<RoleData, _, _>(surface, f)
} }
/// Register that this surface does not have a role any longer and retrieve the data /// Register that this surface does not have a role any longer and retrieve the data
@ -437,7 +424,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
where where
R: Role<RoleData>, R: Role<RoleData>,
{ {
SurfaceData::<U, R>::remove_role::<RoleData>(surface) SurfaceData::<R>::remove_role::<RoleData>(surface)
} }
/// Retrieve the metadata associated with a `wl_region` /// Retrieve the metadata associated with a `wl_region`
@ -461,30 +448,29 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
/// ///
/// It also returns the two global handles, in case you wish to remove these /// It also returns the two global handles, in case you wish to remove these
/// globals from the event loop in the future. /// globals from the event loop in the future.
pub fn compositor_init<U, R, Impl, L>( pub fn compositor_init<R, Impl, L>(
display: &mut Display, display: &mut Display,
implem: Impl, implem: Impl,
logger: L, logger: L,
) -> ( ) -> (
CompositorToken<U, R>, CompositorToken<R>,
Global<wl_compositor::WlCompositor>, Global<wl_compositor::WlCompositor>,
Global<wl_subcompositor::WlSubcompositor>, Global<wl_subcompositor::WlSubcompositor>,
) )
where where
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
U: Default + 'static,
R: Default + RoleType + Role<SubsurfaceRole> + 'static, R: Default + RoleType + Role<SubsurfaceRole> + 'static,
Impl: FnMut(SurfaceEvent, WlSurface, CompositorToken<U, R>) + 'static, Impl: FnMut(SurfaceEvent, WlSurface, CompositorToken<R>) + 'static,
{ {
let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "compositor_handler")); let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "compositor_handler"));
let implem = Rc::new(RefCell::new(implem)); let implem = Rc::new(RefCell::new(implem));
let compositor = display.create_global(4, move |new_compositor, _version| { let compositor = display.create_global(4, move |new_compositor, _version| {
self::handlers::implement_compositor::<U, R, Impl>(new_compositor, log.clone(), implem.clone()); self::handlers::implement_compositor::<R, Impl>(new_compositor, log.clone(), implem.clone());
}); });
let subcompositor = display.create_global(1, move |new_subcompositor, _version| { let subcompositor = display.create_global(1, move |new_subcompositor, _version| {
self::handlers::implement_subcompositor::<U, R>(new_subcompositor); self::handlers::implement_subcompositor::<R>(new_subcompositor);
}); });
(CompositorToken::make(), compositor, subcompositor) (CompositorToken::make(), compositor, subcompositor)

View File

@ -15,11 +15,11 @@ use wayland_server::protocol::wl_surface::WlSurface;
/// ///
/// Each node also appears within its children list, to allow relative placement /// Each node also appears within its children list, to allow relative placement
/// between them. /// between them.
pub struct SurfaceData<U, R> { pub struct SurfaceData<R> {
parent: Option<WlSurface>, parent: Option<WlSurface>,
children: Vec<WlSurface>, children: Vec<WlSurface>,
role: R, role: R,
attributes: SurfaceAttributes<U>, attributes: SurfaceAttributes,
} }
pub enum Location { pub enum Location {
@ -37,8 +37,8 @@ pub enum TraversalAction<T> {
Break, Break,
} }
impl<U: Default, R: Default> SurfaceData<U, R> { impl<R: Default> SurfaceData<R> {
pub fn new() -> Mutex<SurfaceData<U, R>> { pub fn new() -> Mutex<SurfaceData<R>> {
Mutex::new(SurfaceData { Mutex::new(SurfaceData {
parent: None, parent: None,
children: vec![], children: vec![],
@ -48,14 +48,13 @@ impl<U: Default, R: Default> SurfaceData<U, R> {
} }
} }
impl<U, R> SurfaceData<U, R> impl<R> SurfaceData<R>
where where
U: 'static,
R: 'static, R: 'static,
{ {
/// Initializes the surface, must be called at creation for state coherence /// Initializes the surface, must be called at creation for state coherence
pub fn init(surface: &WlSurface) { pub fn init(surface: &WlSurface) {
let my_data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let my_data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut my_data = my_data_mutex.lock().unwrap(); let mut my_data = my_data_mutex.lock().unwrap();
debug_assert!(my_data.children.len() == 0); debug_assert!(my_data.children.len() == 0);
my_data.children.push(surface.clone()); my_data.children.push(surface.clone());
@ -63,14 +62,11 @@ where
/// Cleans the `as_ref().user_data` of that surface, must be called when it is destroyed /// Cleans the `as_ref().user_data` of that surface, must be called when it is destroyed
pub fn cleanup(surface: &WlSurface) { pub fn cleanup(surface: &WlSurface) {
let my_data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let my_data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut my_data = my_data_mutex.lock().unwrap(); let mut my_data = my_data_mutex.lock().unwrap();
if let Some(old_parent) = my_data.parent.take() { if let Some(old_parent) = my_data.parent.take() {
// We had a parent, lets unregister ourselves from it // We had a parent, lets unregister ourselves from it
let old_parent_mutex = old_parent let old_parent_mutex = old_parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
.as_ref()
.user_data::<Mutex<SurfaceData<U, R>>>()
.unwrap();
let mut old_parent_guard = old_parent_mutex.lock().unwrap(); let mut old_parent_guard = old_parent_mutex.lock().unwrap();
old_parent_guard old_parent_guard
.children .children
@ -82,17 +78,17 @@ where
if child.as_ref().equals(surface.as_ref()) { if child.as_ref().equals(surface.as_ref()) {
continue; continue;
} }
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut child_guard = child_mutex.lock().unwrap(); let mut child_guard = child_mutex.lock().unwrap();
child_guard.parent = None; child_guard.parent = None;
} }
} }
} }
impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> { impl<R: RoleType + 'static> SurfaceData<R> {
pub fn has_a_role(surface: &WlSurface) -> bool { pub fn has_a_role(surface: &WlSurface) -> bool {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let data_guard = data_mutex.lock().unwrap(); let data_guard = data_mutex.lock().unwrap();
<R as RoleType>::has_role(&data_guard.role) <R as RoleType>::has_role(&data_guard.role)
} }
@ -103,7 +99,7 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
R: Role<RoleData>, R: Role<RoleData>,
{ {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let data_guard = data_mutex.lock().unwrap(); let data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::has(&data_guard.role) <R as Role<RoleData>>::has(&data_guard.role)
} }
@ -115,7 +111,7 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
RoleData: Default, RoleData: Default,
{ {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::set(&mut data_guard.role) <R as Role<RoleData>>::set(&mut data_guard.role)
} }
@ -128,7 +124,7 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
R: Role<RoleData>, R: Role<RoleData>,
{ {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::set_with(&mut data_guard.role, data) <R as Role<RoleData>>::set_with(&mut data_guard.role, data)
} }
@ -142,7 +138,7 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
R: Role<RoleData>, R: Role<RoleData>,
{ {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::unset(&mut data_guard.role) <R as Role<RoleData>>::unset(&mut data_guard.role)
} }
@ -154,17 +150,17 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
F: FnOnce(&mut RoleData) -> T, F: FnOnce(&mut RoleData) -> T,
{ {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
let data = <R as Role<RoleData>>::data_mut(&mut data_guard.role)?; let data = <R as Role<RoleData>>::data_mut(&mut data_guard.role)?;
Ok(f(data)) Ok(f(data))
} }
} }
impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R> { impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> {
/// Checks if the first surface is an ancestor of the second /// Checks if the first surface is an ancestor of the second
pub fn is_ancestor(a: &WlSurface, b: &WlSurface) -> bool { pub fn is_ancestor(a: &WlSurface, b: &WlSurface) -> bool {
let b_mutex = b.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let b_mutex = b.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let b_guard = b_mutex.lock().unwrap(); let b_guard = b_mutex.lock().unwrap();
if let Some(ref parent) = b_guard.parent { if let Some(ref parent) = b_guard.parent {
if parent.as_ref().equals(a.as_ref()) { if parent.as_ref().equals(a.as_ref()) {
@ -191,7 +187,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
// change child's parent // change child's parent
{ {
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut child_guard = child_mutex.lock().unwrap(); let mut child_guard = child_mutex.lock().unwrap();
// if surface already has a role, it cannot become a subsurface // if surface already has a role, it cannot become a subsurface
<R as Role<SubsurfaceRole>>::set(&mut child_guard.role)?; <R as Role<SubsurfaceRole>>::set(&mut child_guard.role)?;
@ -200,7 +196,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
} }
// register child to new parent // register child to new parent
{ {
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut parent_guard = parent_mutex.lock().unwrap(); let mut parent_guard = parent_mutex.lock().unwrap();
parent_guard.children.push(child.clone()) parent_guard.children.push(child.clone())
} }
@ -213,7 +209,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
pub fn unset_parent(child: &WlSurface) { pub fn unset_parent(child: &WlSurface) {
debug_assert!(child.as_ref().is_alive()); debug_assert!(child.as_ref().is_alive());
let old_parent = { let old_parent = {
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut child_guard = child_mutex.lock().unwrap(); let mut child_guard = child_mutex.lock().unwrap();
let old_parent = child_guard.parent.take(); let old_parent = child_guard.parent.take();
if old_parent.is_some() { if old_parent.is_some() {
@ -225,10 +221,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
}; };
// unregister from our parent // unregister from our parent
if let Some(old_parent) = old_parent { if let Some(old_parent) = old_parent {
let parent_mutex = old_parent let parent_mutex = old_parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
.as_ref()
.user_data::<Mutex<SurfaceData<U, R>>>()
.unwrap();
let mut parent_guard = parent_mutex.lock().unwrap(); let mut parent_guard = parent_mutex.lock().unwrap();
parent_guard parent_guard
.children .children
@ -238,14 +231,14 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
/// Retrieve the parent surface (if any) of this surface /// Retrieve the parent surface (if any) of this surface
pub fn get_parent(child: &WlSurface) -> Option<WlSurface> { pub fn get_parent(child: &WlSurface) -> Option<WlSurface> {
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let child_guard = child_mutex.lock().unwrap(); let child_guard = child_mutex.lock().unwrap();
child_guard.parent.as_ref().cloned() child_guard.parent.as_ref().cloned()
} }
/// Retrieve the children surface (if any) of this surface /// Retrieve the children surface (if any) of this surface
pub fn get_children(parent: &WlSurface) -> Vec<WlSurface> { pub fn get_children(parent: &WlSurface) -> Vec<WlSurface> {
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let parent_guard = parent_mutex.lock().unwrap(); let parent_guard = parent_mutex.lock().unwrap();
parent_guard parent_guard
.children .children
@ -260,7 +253,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
/// Fails if `relative_to` is not a sibling or parent of `surface`. /// Fails if `relative_to` is not a sibling or parent of `surface`.
pub fn reorder(surface: &WlSurface, to: Location, relative_to: &WlSurface) -> Result<(), ()> { pub fn reorder(surface: &WlSurface, to: Location, relative_to: &WlSurface) -> Result<(), ()> {
let parent = { let parent = {
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let data_guard = data_mutex.lock().unwrap(); let data_guard = data_mutex.lock().unwrap();
data_guard.parent.as_ref().cloned().unwrap() data_guard.parent.as_ref().cloned().unwrap()
}; };
@ -274,7 +267,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
None None
} }
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut parent_guard = parent_mutex.lock().unwrap(); let mut parent_guard = parent_mutex.lock().unwrap();
let my_index = index_of(surface, &parent_guard.children).unwrap(); let my_index = index_of(surface, &parent_guard.children).unwrap();
let mut other_index = match index_of(relative_to, &parent_guard.children) { let mut other_index = match index_of(relative_to, &parent_guard.children) {
@ -294,18 +287,18 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
} }
} }
impl<U: 'static, R: 'static> SurfaceData<U, R> { impl<R: 'static> SurfaceData<R> {
/// 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,
/// so the tree cannot be manipulated at the same time /// so the tree cannot be manipulated at the same time
pub fn with_data<T, F>(surface: &WlSurface, f: F) -> T pub fn with_data<T, F>(surface: &WlSurface, f: F) -> T
where where
F: FnOnce(&mut SurfaceAttributes<U>) -> T, F: FnOnce(&mut SurfaceAttributes) -> T,
{ {
let data_mutex = surface let data_mutex = surface
.as_ref() .as_ref()
.user_data::<Mutex<SurfaceData<U, R>>>() .user_data::<Mutex<SurfaceData<R>>>()
.expect("Accessing the data of foreign surfaces is not supported."); .expect("Accessing the data of foreign surfaces is not supported.");
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
f(&mut data_guard.attributes) f(&mut data_guard.attributes)
@ -332,9 +325,9 @@ impl<U: 'static, R: 'static> SurfaceData<U, R> {
mut post_filter: F3, mut post_filter: F3,
reverse: bool, reverse: bool,
) where ) where
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>, F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T), F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool, F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool,
{ {
Self::map( Self::map(
surface, surface,
@ -356,11 +349,11 @@ impl<U: 'static, R: 'static> SurfaceData<U, R> {
reverse: bool, reverse: bool,
) -> bool ) -> bool
where where
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>, F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T), F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool, F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool,
{ {
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap(); let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
let data_guard = &mut *data_guard; let data_guard = &mut *data_guard;
// call the filter on ourselves // call the filter on ourselves

View File

@ -13,7 +13,7 @@ use crate::wayland::{
use super::{with_source_metadata, DataDeviceData, DnDIconRole, SeatData}; use super::{with_source_metadata, DataDeviceData, DnDIconRole, SeatData};
pub(crate) struct DnDGrab<U, R> { pub(crate) struct DnDGrab<R> {
data_source: Option<wl_data_source::WlDataSource>, data_source: Option<wl_data_source::WlDataSource>,
current_focus: Option<wl_surface::WlSurface>, current_focus: Option<wl_surface::WlSurface>,
pending_offers: Vec<wl_data_offer::WlDataOffer>, pending_offers: Vec<wl_data_offer::WlDataOffer>,
@ -21,19 +21,19 @@ pub(crate) struct DnDGrab<U, R> {
icon: Option<wl_surface::WlSurface>, icon: Option<wl_surface::WlSurface>,
origin: wl_surface::WlSurface, origin: wl_surface::WlSurface,
callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>, callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>,
token: CompositorToken<U, R>, token: CompositorToken<R>,
seat: Seat, seat: Seat,
} }
impl<U: 'static, R: Role<DnDIconRole> + 'static> DnDGrab<U, R> { impl<R: Role<DnDIconRole> + 'static> DnDGrab<R> {
pub(crate) fn new( pub(crate) fn new(
source: Option<wl_data_source::WlDataSource>, source: Option<wl_data_source::WlDataSource>,
origin: wl_surface::WlSurface, origin: wl_surface::WlSurface,
seat: Seat, seat: Seat,
icon: Option<wl_surface::WlSurface>, icon: Option<wl_surface::WlSurface>,
token: CompositorToken<U, R>, token: CompositorToken<R>,
callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>, callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>,
) -> DnDGrab<U, R> { ) -> DnDGrab<R> {
DnDGrab { DnDGrab {
data_source: source, data_source: source,
current_focus: None, current_focus: None,
@ -48,7 +48,7 @@ impl<U: 'static, R: Role<DnDIconRole> + 'static> DnDGrab<U, R> {
} }
} }
impl<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> { impl<R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<R> {
fn motion( fn motion(
&mut self, &mut self,
_handle: &mut PointerInnerHandle<'_>, _handle: &mut PointerInnerHandle<'_>,

View File

@ -43,7 +43,7 @@
//! # fn main(){ //! # fn main(){
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
//! # let mut display = wayland_server::Display::new(event_loop.handle()); //! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = compositor_init::<(), Roles, _, _>(&mut display, |_, _, _| {}, None); //! # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None);
//! // init the data device: //! // init the data device:
//! init_data_device( //! init_data_device(
//! &mut display, // the display //! &mut display, // the display
@ -286,18 +286,17 @@ impl SeatData {
/// and the second argument is the preferred action reported by the target. If no action should be /// and the second argument is the preferred action reported by the target. If no action should be
/// chosen (and thus the drag'n'drop should abort on drop), return /// chosen (and thus the drag'n'drop should abort on drop), return
/// [`DndAction::empty()`](wayland_server::protocol::wl_data_device_manager::DndAction::empty). /// [`DndAction::empty()`](wayland_server::protocol::wl_data_device_manager::DndAction::empty).
pub fn init_data_device<F, C, U, R, L>( pub fn init_data_device<F, C, R, L>(
display: &mut Display, display: &mut Display,
callback: C, callback: C,
action_choice: F, action_choice: F,
token: CompositorToken<U, R>, token: CompositorToken<R>,
logger: L, logger: L,
) -> Global<wl_data_device_manager::WlDataDeviceManager> ) -> Global<wl_data_device_manager::WlDataDeviceManager>
where where
F: FnMut(DndAction, DndAction) -> DndAction + 'static, F: FnMut(DndAction, DndAction) -> DndAction + 'static,
C: FnMut(DataDeviceEvent) + 'static, C: FnMut(DataDeviceEvent) + 'static,
R: Role<DnDIconRole> + 'static, R: Role<DnDIconRole> + 'static,
U: 'static,
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
{ {
let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "data_device_mgr")); let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "data_device_mgr"));
@ -378,18 +377,17 @@ where
} }
} }
fn implement_ddm<F, C, U, R>( fn implement_ddm<F, C, R>(
new_ddm: NewResource<wl_data_device_manager::WlDataDeviceManager>, new_ddm: NewResource<wl_data_device_manager::WlDataDeviceManager>,
callback: Rc<RefCell<C>>, callback: Rc<RefCell<C>>,
action_choice: Rc<RefCell<F>>, action_choice: Rc<RefCell<F>>,
token: CompositorToken<U, R>, token: CompositorToken<R>,
log: ::slog::Logger, log: ::slog::Logger,
) -> wl_data_device_manager::WlDataDeviceManager ) -> wl_data_device_manager::WlDataDeviceManager
where where
F: FnMut(DndAction, DndAction) -> DndAction + 'static, F: FnMut(DndAction, DndAction) -> DndAction + 'static,
C: FnMut(DataDeviceEvent) + 'static, C: FnMut(DataDeviceEvent) + 'static,
R: Role<DnDIconRole> + 'static, R: Role<DnDIconRole> + 'static,
U: 'static,
{ {
use self::wl_data_device_manager::Request; use self::wl_data_device_manager::Request;
new_ddm.implement_closure( new_ddm.implement_closure(
@ -429,19 +427,18 @@ struct DataDeviceData {
action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> DndAction + 'static>>, action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> DndAction + 'static>>,
} }
fn implement_data_device<F, C, U, R>( fn implement_data_device<F, C, R>(
new_dd: NewResource<wl_data_device::WlDataDevice>, new_dd: NewResource<wl_data_device::WlDataDevice>,
seat: Seat, seat: Seat,
callback: Rc<RefCell<C>>, callback: Rc<RefCell<C>>,
action_choice: Rc<RefCell<F>>, action_choice: Rc<RefCell<F>>,
token: CompositorToken<U, R>, token: CompositorToken<R>,
log: ::slog::Logger, log: ::slog::Logger,
) -> wl_data_device::WlDataDevice ) -> wl_data_device::WlDataDevice
where where
F: FnMut(DndAction, DndAction) -> DndAction + 'static, F: FnMut(DndAction, DndAction) -> DndAction + 'static,
C: FnMut(DataDeviceEvent) + 'static, C: FnMut(DataDeviceEvent) + 'static,
R: Role<DnDIconRole> + 'static, R: Role<DnDIconRole> + 'static,
U: 'static,
{ {
use self::wl_data_device::Request; use self::wl_data_device::Request;
let dd_data = DataDeviceData { let dd_data = DataDeviceData {

View File

@ -20,7 +20,7 @@
//! # fn main(){ //! # fn main(){
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
//! # let mut display = wayland_server::Display::new(event_loop.handle()); //! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = compositor_init::<(), Roles, _, _>(&mut display, |_, _, _| {}, None); //! # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None);
//! // insert the seat: //! // insert the seat:
//! let (seat, seat_global) = Seat::new( //! let (seat, seat_global) = Seat::new(
//! &mut display, // the display //! &mut display, // the display
@ -121,14 +121,13 @@ impl Seat {
/// You are provided with the state token to retrieve it (allowing /// You are provided with the state token to retrieve it (allowing
/// you to add or remove capabilities from it), and the global handle, /// you to add or remove capabilities from it), and the global handle,
/// in case you want to remove it. /// in case you want to remove it.
pub fn new<U, R, L>( pub fn new<R, L>(
display: &mut Display, display: &mut Display,
name: String, name: String,
token: CompositorToken<U, R>, token: CompositorToken<R>,
logger: L, logger: L,
) -> (Seat, Global<wl_seat::WlSeat>) ) -> (Seat, Global<wl_seat::WlSeat>)
where where
U: 'static,
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + 'static,
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
{ {
@ -194,7 +193,7 @@ impl Seat {
/// # fn main(){ /// # fn main(){
/// # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); /// # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
/// # let mut display = wayland_server::Display::new(event_loop.handle()); /// # let mut display = wayland_server::Display::new(event_loop.handle());
/// # let (compositor_token, _, _) = compositor_init::<(), Roles, _, _>(&mut display, |_, _, _| {}, None); /// # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None);
/// # let (mut seat, seat_global) = Seat::new( /// # let (mut seat, seat_global) = Seat::new(
/// # &mut display, /// # &mut display,
/// # "seat-0".into(), /// # "seat-0".into(),
@ -207,9 +206,8 @@ impl Seat {
/// ); /// );
/// # } /// # }
/// ``` /// ```
pub fn add_pointer<U, R, F>(&mut self, token: CompositorToken<U, R>, cb: F) -> PointerHandle pub fn add_pointer<R, F>(&mut self, token: CompositorToken<R>, cb: F) -> PointerHandle
where where
U: 'static,
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + 'static,
F: FnMut(CursorImageStatus) + 'static, F: FnMut(CursorImageStatus) + 'static,
{ {
@ -336,14 +334,13 @@ impl ::std::cmp::PartialEq for Seat {
} }
} }
fn implement_seat<U, R>( fn implement_seat<R>(
new_seat: NewResource<wl_seat::WlSeat>, new_seat: NewResource<wl_seat::WlSeat>,
arc: Rc<SeatRc>, arc: Rc<SeatRc>,
token: CompositorToken<U, R>, token: CompositorToken<R>,
) -> wl_seat::WlSeat ) -> wl_seat::WlSeat
where where
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + 'static,
U: 'static,
{ {
let dest_arc = arc.clone(); let dest_arc = arc.clone();
new_seat.implement_closure( new_seat.implement_closure(

View File

@ -46,9 +46,8 @@ struct PointerInternal {
} }
impl PointerInternal { impl PointerInternal {
fn new<F, U, R>(token: CompositorToken<U, R>, mut cb: F) -> PointerInternal fn new<F, R>(token: CompositorToken<R>, mut cb: F) -> PointerInternal
where where
U: 'static,
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + 'static,
F: FnMut(CursorImageStatus) + 'static, F: FnMut(CursorImageStatus) + 'static,
{ {
@ -514,10 +513,9 @@ impl AxisFrame {
} }
} }
pub(crate) fn create_pointer_handler<F, U, R>(token: CompositorToken<U, R>, cb: F) -> PointerHandle pub(crate) fn create_pointer_handler<F, R>(token: CompositorToken<R>, cb: F) -> PointerHandle
where where
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + 'static,
U: 'static,
F: FnMut(CursorImageStatus) + 'static, F: FnMut(CursorImageStatus) + 'static,
{ {
PointerHandle { PointerHandle {
@ -525,14 +523,13 @@ where
} }
} }
pub(crate) fn implement_pointer<U, R>( pub(crate) fn implement_pointer<R>(
new_pointer: NewResource<WlPointer>, new_pointer: NewResource<WlPointer>,
handle: Option<&PointerHandle>, handle: Option<&PointerHandle>,
token: CompositorToken<U, R>, token: CompositorToken<R>,
) -> WlPointer ) -> WlPointer
where where
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + 'static,
U: 'static,
{ {
let inner = handle.map(|h| h.inner.clone()); let inner = handle.map(|h| h.inner.clone());
let destructor = match inner.clone() { let destructor = match inner.clone() {

View File

@ -52,7 +52,7 @@
//! # fn main() { //! # fn main() {
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
//! # let mut display = wayland_server::Display::new(event_loop.handle()); //! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<(), MyRoles, _, _>( //! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<MyRoles, _, _>(
//! # &mut display, //! # &mut display,
//! # |_, _, _| {}, //! # |_, _, _| {},
//! # None //! # None
@ -62,7 +62,7 @@
//! // token from the compositor implementation //! // token from the compositor implementation
//! compositor_token, //! compositor_token,
//! // your implementation //! // your implementation
//! |event: ShellRequest<_, _, MyShellSurfaceData>| { /* ... */ }, //! |event: ShellRequest<_, MyShellSurfaceData>| { /* ... */ },
//! None // put a logger if you want //! None // put a logger if you want
//! ); //! );
//! //!
@ -97,16 +97,15 @@ pub struct ShellSurfaceRole<D: 'static> {
} }
/// A handle to a shell surface /// A handle to a shell surface
pub struct ShellSurface<U, R, D> { pub struct ShellSurface<R, D> {
wl_surface: wl_surface::WlSurface, wl_surface: wl_surface::WlSurface,
shell_surface: wl_shell_surface::WlShellSurface, shell_surface: wl_shell_surface::WlShellSurface,
token: CompositorToken<U, R>, token: CompositorToken<R>,
_d: ::std::marker::PhantomData<D>, _d: ::std::marker::PhantomData<D>,
} }
impl<U, R, D> ShellSurface<U, R, D> impl<R, D> ShellSurface<R, D>
where where
U: 'static,
R: Role<ShellSurfaceRole<D>> + 'static, R: Role<ShellSurfaceRole<D>> + 'static,
D: 'static, D: 'static,
{ {
@ -235,13 +234,13 @@ pub enum ShellSurfaceKind {
} }
/// A request triggered by a `wl_shell_surface` /// A request triggered by a `wl_shell_surface`
pub enum ShellRequest<U, R, D> { pub enum ShellRequest<R, D> {
/// A new shell surface was created /// A new shell surface was created
/// ///
/// by default it has no kind and this should not be displayed /// by default it has no kind and this should not be displayed
NewShellSurface { NewShellSurface {
/// The created surface /// The created surface
surface: ShellSurface<U, R, D>, surface: ShellSurface<R, D>,
}, },
/// A pong event /// A pong event
/// ///
@ -249,14 +248,14 @@ pub enum ShellRequest<U, R, D> {
/// event, smithay has already checked that the responded serial was valid. /// event, smithay has already checked that the responded serial was valid.
Pong { Pong {
/// The surface that sent the pong /// The surface that sent the pong
surface: ShellSurface<U, R, D>, surface: ShellSurface<R, D>,
}, },
/// Start of an interactive move /// Start of an interactive move
/// ///
/// The surface requests that an interactive move is started on it /// The surface requests that an interactive move is started on it
Move { Move {
/// The surface requesting the move /// The surface requesting the move
surface: ShellSurface<U, R, D>, surface: ShellSurface<R, D>,
/// Serial of the implicit grab that initiated the move /// Serial of the implicit grab that initiated the move
serial: u32, serial: u32,
/// Seat associated with the move /// Seat associated with the move
@ -267,7 +266,7 @@ pub enum ShellRequest<U, R, D> {
/// The surface requests that an interactive resize is started on it /// The surface requests that an interactive resize is started on it
Resize { Resize {
/// The surface requesting the resize /// The surface requesting the resize
surface: ShellSurface<U, R, D>, surface: ShellSurface<R, D>,
/// Serial of the implicit grab that initiated the resize /// Serial of the implicit grab that initiated the resize
serial: u32, serial: u32,
/// Seat associated with the resize /// Seat associated with the resize
@ -278,7 +277,7 @@ pub enum ShellRequest<U, R, D> {
/// The surface changed its kind /// The surface changed its kind
SetKind { SetKind {
/// The surface /// The surface
surface: ShellSurface<U, R, D>, surface: ShellSurface<R, D>,
/// Its new kind /// Its new kind
kind: ShellSurfaceKind, kind: ShellSurfaceKind,
}, },
@ -288,13 +287,12 @@ pub enum ShellRequest<U, R, D> {
/// ///
/// This state allows you to retrieve a list of surfaces /// This state allows you to retrieve a list of surfaces
/// currently known to the shell global. /// currently known to the shell global.
pub struct ShellState<U, R, D> { pub struct ShellState<R, D> {
known_surfaces: Vec<ShellSurface<U, R, D>>, known_surfaces: Vec<ShellSurface<R, D>>,
} }
impl<U, R, D> ShellState<U, R, D> impl<R, D> ShellState<R, D>
where where
U: 'static,
R: Role<ShellSurfaceRole<D>> + 'static, R: Role<ShellSurfaceRole<D>> + 'static,
D: 'static, D: 'static,
{ {
@ -304,24 +302,23 @@ where
} }
/// Access all the shell surfaces known by this handler /// Access all the shell surfaces known by this handler
pub fn surfaces(&self) -> &[ShellSurface<U, R, D>] { pub fn surfaces(&self) -> &[ShellSurface<R, D>] {
&self.known_surfaces[..] &self.known_surfaces[..]
} }
} }
/// Create a new `wl_shell` global /// Create a new `wl_shell` global
pub fn wl_shell_init<U, R, D, L, Impl>( pub fn wl_shell_init<R, D, L, Impl>(
display: &mut Display, display: &mut Display,
ctoken: CompositorToken<U, R>, ctoken: CompositorToken<R>,
implementation: Impl, implementation: Impl,
logger: L, logger: L,
) -> (Arc<Mutex<ShellState<U, R, D>>>, Global<wl_shell::WlShell>) ) -> (Arc<Mutex<ShellState<R, D>>>, Global<wl_shell::WlShell>)
where where
U: 'static,
D: Default + 'static, D: Default + 'static,
R: Role<ShellSurfaceRole<D>> + 'static, R: Role<ShellSurfaceRole<D>> + 'static,
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
Impl: FnMut(ShellRequest<U, R, D>) + 'static, Impl: FnMut(ShellRequest<R, D>) + 'static,
{ {
let _log = crate::slog_or_stdlog(logger); let _log = crate::slog_or_stdlog(logger);

View File

@ -13,16 +13,15 @@ use crate::wayland::compositor::{roles::Role, CompositorToken};
use super::{ShellRequest, ShellState, ShellSurface, ShellSurfaceKind, ShellSurfaceRole}; use super::{ShellRequest, ShellState, ShellSurface, ShellSurfaceKind, ShellSurfaceRole};
pub(crate) fn implement_shell<U, R, D, Impl>( pub(crate) fn implement_shell<R, D, Impl>(
shell: NewResource<wl_shell::WlShell>, shell: NewResource<wl_shell::WlShell>,
ctoken: CompositorToken<U, R>, ctoken: CompositorToken<R>,
implementation: Rc<RefCell<Impl>>, implementation: Rc<RefCell<Impl>>,
state: Arc<Mutex<ShellState<U, R, D>>>, state: Arc<Mutex<ShellState<R, D>>>,
) where ) where
U: 'static,
D: Default + 'static, D: Default + 'static,
R: Role<ShellSurfaceRole<D>> + 'static, R: Role<ShellSurfaceRole<D>> + 'static,
Impl: FnMut(ShellRequest<U, R, D>) + 'static, Impl: FnMut(ShellRequest<R, D>) + 'static,
{ {
shell.implement_closure( shell.implement_closure(
move |req, shell| { move |req, shell| {
@ -59,18 +58,17 @@ pub(crate) fn implement_shell<U, R, D, Impl>(
); );
} }
fn make_handle<U, R, SD>( fn make_handle<R, SD>(
shell_surface: &wl_shell_surface::WlShellSurface, shell_surface: &wl_shell_surface::WlShellSurface,
token: CompositorToken<U, R>, token: CompositorToken<R>,
) -> ShellSurface<U, R, SD> ) -> ShellSurface<R, SD>
where where
U: 'static,
R: Role<ShellSurfaceRole<SD>> + 'static, R: Role<ShellSurfaceRole<SD>> + 'static,
SD: 'static, SD: 'static,
{ {
let data = shell_surface let data = shell_surface
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
ShellSurface { ShellSurface {
wl_surface: data.surface.clone(), wl_surface: data.surface.clone(),
@ -80,30 +78,29 @@ where
} }
} }
pub(crate) struct ShellSurfaceUserData<U, R, SD> { pub(crate) struct ShellSurfaceUserData<R, SD> {
surface: wl_surface::WlSurface, surface: wl_surface::WlSurface,
state: Arc<Mutex<ShellState<U, R, SD>>>, state: Arc<Mutex<ShellState<R, SD>>>,
} }
fn implement_shell_surface<U, R, Impl, SD>( fn implement_shell_surface<R, Impl, SD>(
shell_surface: NewResource<wl_shell_surface::WlShellSurface>, shell_surface: NewResource<wl_shell_surface::WlShellSurface>,
surface: wl_surface::WlSurface, surface: wl_surface::WlSurface,
implementation: Rc<RefCell<Impl>>, implementation: Rc<RefCell<Impl>>,
ctoken: CompositorToken<U, R>, ctoken: CompositorToken<R>,
state: Arc<Mutex<ShellState<U, R, SD>>>, state: Arc<Mutex<ShellState<R, SD>>>,
) -> wl_shell_surface::WlShellSurface ) -> wl_shell_surface::WlShellSurface
where where
U: 'static,
SD: 'static, SD: 'static,
R: Role<ShellSurfaceRole<SD>> + 'static, R: Role<ShellSurfaceRole<SD>> + 'static,
Impl: FnMut(ShellRequest<U, R, SD>) + 'static, Impl: FnMut(ShellRequest<R, SD>) + 'static,
{ {
use self::wl_shell_surface::Request; use self::wl_shell_surface::Request;
shell_surface.implement_closure( shell_surface.implement_closure(
move |req, shell_surface| { move |req, shell_surface| {
let data = shell_surface let data = shell_surface
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
let mut user_impl = implementation.borrow_mut(); let mut user_impl = implementation.borrow_mut();
match req { match req {
@ -196,7 +193,7 @@ where
Some(|shell_surface: wl_shell_surface::WlShellSurface| { Some(|shell_surface: wl_shell_surface::WlShellSurface| {
let data = shell_surface let data = shell_surface
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
data.state.lock().unwrap().cleanup_surfaces(); data.state.lock().unwrap().cleanup_surfaces();
}), }),

View File

@ -35,7 +35,6 @@
//! use smithay::wayland::shell::xdg::{xdg_shell_init, XdgSurfaceRole, XdgRequest}; //! use smithay::wayland::shell::xdg::{xdg_shell_init, XdgSurfaceRole, XdgRequest};
//! use wayland_protocols::unstable::xdg_shell::v6::server::zxdg_shell_v6::ZxdgShellV6; //! use wayland_protocols::unstable::xdg_shell::v6::server::zxdg_shell_v6::ZxdgShellV6;
//! # use wayland_server::protocol::{wl_seat, wl_output}; //! # use wayland_server::protocol::{wl_seat, wl_output};
//! # #[derive(Default)] struct MySurfaceData;
//! //!
//! // define the roles type. You need to integrate the XdgSurface role: //! // define the roles type. You need to integrate the XdgSurface role:
//! define_roles!(MyRoles => //! define_roles!(MyRoles =>
@ -51,7 +50,7 @@
//! # fn main() { //! # fn main() {
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
//! # let mut display = wayland_server::Display::new(event_loop.handle()); //! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<(), MyRoles, _, _>( //! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<MyRoles, _, _>(
//! # &mut display, //! # &mut display,
//! # |_, _, _| {}, //! # |_, _, _| {},
//! # None //! # None
@ -61,7 +60,7 @@
//! // token from the compositor implementation //! // token from the compositor implementation
//! compositor_token, //! compositor_token,
//! // your implementation //! // your implementation
//! |event: XdgRequest<_, _, MyShellData>| { /* ... */ }, //! |event: XdgRequest<_, MyShellData>| { /* ... */ },
//! None // put a logger if you want //! None // put a logger if you want
//! ); //! );
//! //!
@ -259,14 +258,14 @@ impl Default for XdgSurfacePendingState {
} }
} }
pub(crate) struct ShellData<U, R, SD> { pub(crate) struct ShellData<R, SD> {
log: ::slog::Logger, log: ::slog::Logger,
compositor_token: CompositorToken<U, R>, compositor_token: CompositorToken<R>,
user_impl: Rc<RefCell<dyn FnMut(XdgRequest<U, R, SD>)>>, user_impl: Rc<RefCell<dyn FnMut(XdgRequest<R, SD>)>>,
shell_state: Arc<Mutex<ShellState<U, R, SD>>>, shell_state: Arc<Mutex<ShellState<R, SD>>>,
} }
impl<U, R, SD> Clone for ShellData<U, R, SD> { impl<R, SD> Clone for ShellData<R, SD> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
ShellData { ShellData {
log: self.log.clone(), log: self.log.clone(),
@ -278,22 +277,21 @@ impl<U, R, SD> Clone for ShellData<U, R, SD> {
} }
/// Create a new `xdg_shell` globals /// Create a new `xdg_shell` globals
pub fn xdg_shell_init<U, R, SD, L, Impl>( pub fn xdg_shell_init<R, SD, L, Impl>(
display: &mut Display, display: &mut Display,
ctoken: CompositorToken<U, R>, ctoken: CompositorToken<R>,
implementation: Impl, implementation: Impl,
logger: L, logger: L,
) -> ( ) -> (
Arc<Mutex<ShellState<U, R, SD>>>, Arc<Mutex<ShellState<R, SD>>>,
Global<xdg_wm_base::XdgWmBase>, Global<xdg_wm_base::XdgWmBase>,
Global<zxdg_shell_v6::ZxdgShellV6>, Global<zxdg_shell_v6::ZxdgShellV6>,
) )
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: Default + 'static, SD: Default + 'static,
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
Impl: FnMut(XdgRequest<U, R, SD>) + 'static, Impl: FnMut(XdgRequest<R, SD>) + 'static,
{ {
let log = crate::slog_or_stdlog(logger); let log = crate::slog_or_stdlog(logger);
let shell_state = Arc::new(Mutex::new(ShellState { let shell_state = Arc::new(Mutex::new(ShellState {
@ -325,24 +323,23 @@ where
/// ///
/// This state allows you to retrieve a list of surfaces /// This state allows you to retrieve a list of surfaces
/// currently known to the shell global. /// currently known to the shell global.
pub struct ShellState<U, R, SD> { pub struct ShellState<R, SD> {
known_toplevels: Vec<ToplevelSurface<U, R, SD>>, known_toplevels: Vec<ToplevelSurface<R, SD>>,
known_popups: Vec<PopupSurface<U, R, SD>>, known_popups: Vec<PopupSurface<R, SD>>,
} }
impl<U, R, SD> ShellState<U, R, SD> impl<R, SD> ShellState<R, SD>
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
/// Access all the shell surfaces known by this handler /// Access all the shell surfaces known by this handler
pub fn toplevel_surfaces(&self) -> &[ToplevelSurface<U, R, SD>] { pub fn toplevel_surfaces(&self) -> &[ToplevelSurface<R, SD>] {
&self.known_toplevels[..] &self.known_toplevels[..]
} }
/// Access all the popup surfaces known by this handler /// Access all the popup surfaces known by this handler
pub fn popup_surfaces(&self) -> &[PopupSurface<U, R, SD>] { pub fn popup_surfaces(&self) -> &[PopupSurface<R, SD>] {
&self.known_popups[..] &self.known_popups[..]
} }
} }
@ -378,15 +375,14 @@ fn make_shell_client_data<SD: Default>() -> ShellClientData<SD> {
/// ///
/// You can use this handle to access a storage for any /// You can use this handle to access a storage for any
/// client-specific data you wish to associate with it. /// client-specific data you wish to associate with it.
pub struct ShellClient<U, R, SD> { pub struct ShellClient<R, SD> {
kind: ShellClientKind, kind: ShellClientKind,
_token: CompositorToken<U, R>, _token: CompositorToken<R>,
_data: ::std::marker::PhantomData<*mut SD>, _data: ::std::marker::PhantomData<*mut SD>,
} }
impl<U, R, SD> ShellClient<U, R, SD> impl<R, SD> ShellClient<R, SD>
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
@ -427,7 +423,7 @@ where
ShellClientKind::Xdg(ref shell) => { ShellClientKind::Xdg(ref shell) => {
let user_data = shell let user_data = shell
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellUserData<U, R, SD>>() .user_data::<self::xdg_handlers::ShellUserData<R, SD>>()
.unwrap(); .unwrap();
let mut guard = user_data.client_data.lock().unwrap(); let mut guard = user_data.client_data.lock().unwrap();
if guard.pending_ping == 0 { if guard.pending_ping == 0 {
@ -439,7 +435,7 @@ where
ShellClientKind::ZxdgV6(ref shell) => { ShellClientKind::ZxdgV6(ref shell) => {
let user_data = shell let user_data = shell
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellUserData<U, R, SD>>() .user_data::<self::zxdgv6_handlers::ShellUserData<R, SD>>()
.unwrap(); .unwrap();
let mut guard = user_data.client_data.lock().unwrap(); let mut guard = user_data.client_data.lock().unwrap();
if guard.pending_ping == 0 { if guard.pending_ping == 0 {
@ -464,7 +460,7 @@ where
ShellClientKind::Xdg(ref shell) => { ShellClientKind::Xdg(ref shell) => {
let data = shell let data = shell
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellUserData<U, R, SD>>() .user_data::<self::xdg_handlers::ShellUserData<R, SD>>()
.unwrap(); .unwrap();
let mut guard = data.client_data.lock().unwrap(); let mut guard = data.client_data.lock().unwrap();
Ok(f(&mut guard.data)) Ok(f(&mut guard.data))
@ -472,7 +468,7 @@ where
ShellClientKind::ZxdgV6(ref shell) => { ShellClientKind::ZxdgV6(ref shell) => {
let data = shell let data = shell
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellUserData<U, R, SD>>() .user_data::<self::zxdgv6_handlers::ShellUserData<R, SD>>()
.unwrap(); .unwrap();
let mut guard = data.client_data.lock().unwrap(); let mut guard = data.client_data.lock().unwrap();
Ok(f(&mut guard.data)) Ok(f(&mut guard.data))
@ -487,16 +483,15 @@ pub(crate) enum ToplevelKind {
} }
/// A handle to a toplevel surface /// A handle to a toplevel surface
pub struct ToplevelSurface<U, R, SD> { pub struct ToplevelSurface<R, SD> {
wl_surface: wl_surface::WlSurface, wl_surface: wl_surface::WlSurface,
shell_surface: ToplevelKind, shell_surface: ToplevelKind,
token: CompositorToken<U, R>, token: CompositorToken<R>,
_shell_data: ::std::marker::PhantomData<SD>, _shell_data: ::std::marker::PhantomData<SD>,
} }
impl<U, R, SD> ToplevelSurface<U, R, SD> impl<R, SD> ToplevelSurface<R, SD>
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
@ -517,7 +512,7 @@ where
/// Retrieve the shell client owning this toplevel surface /// Retrieve the shell client owning this toplevel surface
/// ///
/// Returns `None` if the surface does actually no longer exist. /// Returns `None` if the surface does actually no longer exist.
pub fn client(&self) -> Option<ShellClient<U, R, SD>> { pub fn client(&self) -> Option<ShellClient<R, SD>> {
if !self.alive() { if !self.alive() {
return None; return None;
} }
@ -526,14 +521,14 @@ where
ToplevelKind::Xdg(ref s) => { ToplevelKind::Xdg(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>() .user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
ShellClientKind::Xdg(data.wm_base.clone()) ShellClientKind::Xdg(data.wm_base.clone())
} }
ToplevelKind::ZxdgV6(ref s) => { ToplevelKind::ZxdgV6(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>() .user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
ShellClientKind::ZxdgV6(data.shell.clone()) ShellClientKind::ZxdgV6(data.shell.clone())
} }
@ -554,8 +549,8 @@ where
return; return;
} }
match self.shell_surface { match self.shell_surface {
ToplevelKind::Xdg(ref s) => self::xdg_handlers::send_toplevel_configure::<U, R, SD>(s, cfg), ToplevelKind::Xdg(ref s) => self::xdg_handlers::send_toplevel_configure::<R, SD>(s, cfg),
ToplevelKind::ZxdgV6(ref s) => self::zxdgv6_handlers::send_toplevel_configure::<U, R, SD>(s, cfg), ToplevelKind::ZxdgV6(ref s) => self::zxdgv6_handlers::send_toplevel_configure::<R, SD>(s, cfg),
} }
} }
@ -580,7 +575,7 @@ where
ToplevelKind::Xdg(ref s) => { ToplevelKind::Xdg(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>() .user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
data.xdg_surface.as_ref().post_error( data.xdg_surface.as_ref().post_error(
xdg_surface::Error::NotConstructed as u32, xdg_surface::Error::NotConstructed as u32,
@ -590,7 +585,7 @@ where
ToplevelKind::ZxdgV6(ref s) => { ToplevelKind::ZxdgV6(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>() .user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
data.xdg_surface.as_ref().post_error( data.xdg_surface.as_ref().post_error(
zxdg_surface_v6::Error::NotConstructed as u32, zxdg_surface_v6::Error::NotConstructed as u32,
@ -647,16 +642,15 @@ pub(crate) enum PopupKind {
/// ///
/// This is an unified abstraction over the popup surfaces /// This is an unified abstraction over the popup surfaces
/// of both `wl_shell` and `xdg_shell`. /// of both `wl_shell` and `xdg_shell`.
pub struct PopupSurface<U, R, SD> { pub struct PopupSurface<R, SD> {
wl_surface: wl_surface::WlSurface, wl_surface: wl_surface::WlSurface,
shell_surface: PopupKind, shell_surface: PopupKind,
token: CompositorToken<U, R>, token: CompositorToken<R>,
_shell_data: ::std::marker::PhantomData<SD>, _shell_data: ::std::marker::PhantomData<SD>,
} }
impl<U, R, SD> PopupSurface<U, R, SD> impl<R, SD> PopupSurface<R, SD>
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
@ -677,7 +671,7 @@ where
/// Retrieve the shell client owning this popup surface /// Retrieve the shell client owning this popup surface
/// ///
/// Returns `None` if the surface does actually no longer exist. /// Returns `None` if the surface does actually no longer exist.
pub fn client(&self) -> Option<ShellClient<U, R, SD>> { pub fn client(&self) -> Option<ShellClient<R, SD>> {
if !self.alive() { if !self.alive() {
return None; return None;
} }
@ -686,14 +680,14 @@ where
PopupKind::Xdg(ref p) => { PopupKind::Xdg(ref p) => {
let data = p let data = p
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>() .user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
ShellClientKind::Xdg(data.wm_base.clone()) ShellClientKind::Xdg(data.wm_base.clone())
} }
PopupKind::ZxdgV6(ref p) => { PopupKind::ZxdgV6(ref p) => {
let data = p let data = p
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>() .user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
ShellClientKind::ZxdgV6(data.shell.clone()) ShellClientKind::ZxdgV6(data.shell.clone())
} }
@ -715,10 +709,10 @@ where
} }
match self.shell_surface { match self.shell_surface {
PopupKind::Xdg(ref p) => { PopupKind::Xdg(ref p) => {
self::xdg_handlers::send_popup_configure::<U, R, SD>(p, cfg); self::xdg_handlers::send_popup_configure::<R, SD>(p, cfg);
} }
PopupKind::ZxdgV6(ref p) => { PopupKind::ZxdgV6(ref p) => {
self::zxdgv6_handlers::send_popup_configure::<U, R, SD>(p, cfg); self::zxdgv6_handlers::send_popup_configure::<R, SD>(p, cfg);
} }
} }
} }
@ -744,7 +738,7 @@ where
PopupKind::Xdg(ref s) => { PopupKind::Xdg(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>() .user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
data.xdg_surface.as_ref().post_error( data.xdg_surface.as_ref().post_error(
xdg_surface::Error::NotConstructed as u32, xdg_surface::Error::NotConstructed as u32,
@ -754,7 +748,7 @@ where
PopupKind::ZxdgV6(ref s) => { PopupKind::ZxdgV6(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>() .user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
data.xdg_surface.as_ref().post_error( data.xdg_surface.as_ref().post_error(
zxdg_surface_v6::Error::NotConstructed as u32, zxdg_surface_v6::Error::NotConstructed as u32,
@ -843,11 +837,11 @@ pub struct PopupConfigure {
/// for you directly. /// for you directly.
/// ///
/// Depending on what you want to do, you might ignore some of them /// Depending on what you want to do, you might ignore some of them
pub enum XdgRequest<U, R, SD> { pub enum XdgRequest<R, SD> {
/// A new shell client was instantiated /// A new shell client was instantiated
NewClient { NewClient {
/// the client /// the client
client: ShellClient<U, R, SD>, client: ShellClient<R, SD>,
}, },
/// The pong for a pending ping of this shell client was received /// The pong for a pending ping of this shell client was received
/// ///
@ -855,7 +849,7 @@ pub enum XdgRequest<U, R, SD> {
/// from the pending ping. /// from the pending ping.
ClientPong { ClientPong {
/// the client /// the client
client: ShellClient<U, R, SD>, client: ShellClient<R, SD>,
}, },
/// A new toplevel surface was created /// A new toplevel surface was created
/// ///
@ -863,7 +857,7 @@ pub enum XdgRequest<U, R, SD> {
/// client as to how its window should be /// client as to how its window should be
NewToplevel { NewToplevel {
/// the surface /// the surface
surface: ToplevelSurface<U, R, SD>, surface: ToplevelSurface<R, SD>,
}, },
/// A new popup surface was created /// A new popup surface was created
/// ///
@ -871,12 +865,12 @@ pub enum XdgRequest<U, R, SD> {
/// client as to how its popup should be /// client as to how its popup should be
NewPopup { NewPopup {
/// the surface /// the surface
surface: PopupSurface<U, R, SD>, surface: PopupSurface<R, SD>,
}, },
/// The client requested the start of an interactive move for this surface /// The client requested the start of an interactive move for this surface
Move { Move {
/// the surface /// the surface
surface: ToplevelSurface<U, R, SD>, surface: ToplevelSurface<R, SD>,
/// the seat associated to this move /// the seat associated to this move
seat: wl_seat::WlSeat, seat: wl_seat::WlSeat,
/// the grab serial /// the grab serial
@ -885,7 +879,7 @@ pub enum XdgRequest<U, R, SD> {
/// The client requested the start of an interactive resize for this surface /// The client requested the start of an interactive resize for this surface
Resize { Resize {
/// The surface /// The surface
surface: ToplevelSurface<U, R, SD>, surface: ToplevelSurface<R, SD>,
/// The seat associated with this resize /// The seat associated with this resize
seat: wl_seat::WlSeat, seat: wl_seat::WlSeat,
/// The grab serial /// The grab serial
@ -899,7 +893,7 @@ pub enum XdgRequest<U, R, SD> {
/// the grab area. /// the grab area.
Grab { Grab {
/// The surface /// The surface
surface: PopupSurface<U, R, SD>, surface: PopupSurface<R, SD>,
/// The seat to grab /// The seat to grab
seat: wl_seat::WlSeat, seat: wl_seat::WlSeat,
/// The grab serial /// The grab serial
@ -908,29 +902,29 @@ pub enum XdgRequest<U, R, SD> {
/// A toplevel surface requested to be maximized /// A toplevel surface requested to be maximized
Maximize { Maximize {
/// The surface /// The surface
surface: ToplevelSurface<U, R, SD>, surface: ToplevelSurface<R, SD>,
}, },
/// A toplevel surface requested to stop being maximized /// A toplevel surface requested to stop being maximized
UnMaximize { UnMaximize {
/// The surface /// The surface
surface: ToplevelSurface<U, R, SD>, surface: ToplevelSurface<R, SD>,
}, },
/// A toplevel surface requested to be set fullscreen /// A toplevel surface requested to be set fullscreen
Fullscreen { Fullscreen {
/// The surface /// The surface
surface: ToplevelSurface<U, R, SD>, surface: ToplevelSurface<R, SD>,
/// The output (if any) on which the fullscreen is requested /// The output (if any) on which the fullscreen is requested
output: Option<wl_output::WlOutput>, output: Option<wl_output::WlOutput>,
}, },
/// A toplevel surface request to stop being fullscreen /// A toplevel surface request to stop being fullscreen
UnFullscreen { UnFullscreen {
/// The surface /// The surface
surface: ToplevelSurface<U, R, SD>, surface: ToplevelSurface<R, SD>,
}, },
/// A toplevel surface requested to be minimized /// A toplevel surface requested to be minimized
Minimize { Minimize {
/// The surface /// The surface
surface: ToplevelSurface<U, R, SD>, surface: ToplevelSurface<R, SD>,
}, },
/// The client requests the window menu to be displayed on this surface at this location /// The client requests the window menu to be displayed on this surface at this location
/// ///
@ -938,7 +932,7 @@ pub enum XdgRequest<U, R, SD> {
/// control of the window (maximize/minimize/close/move/etc...). /// control of the window (maximize/minimize/close/move/etc...).
ShowWindowMenu { ShowWindowMenu {
/// The surface /// The surface
surface: ToplevelSurface<U, R, SD>, surface: ToplevelSurface<R, SD>,
/// The seat associated with this input grab /// The seat associated with this input grab
seat: wl_seat::WlSeat, seat: wl_seat::WlSeat,
/// the grab serial /// the grab serial

View File

@ -14,17 +14,16 @@ use super::{
XdgSurfacePendingState, XdgSurfaceRole, XdgSurfacePendingState, XdgSurfaceRole,
}; };
pub(crate) fn implement_wm_base<U, R, SD>( pub(crate) fn implement_wm_base<R, SD>(
shell: NewResource<xdg_wm_base::XdgWmBase>, shell: NewResource<xdg_wm_base::XdgWmBase>,
shell_data: &ShellData<U, R, SD>, shell_data: &ShellData<R, SD>,
) -> xdg_wm_base::XdgWmBase ) -> xdg_wm_base::XdgWmBase
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: Default + 'static, SD: Default + 'static,
{ {
let shell = shell.implement_closure( let shell = shell.implement_closure(
wm_implementation::<U, R, SD>, wm_implementation::<R, SD>,
None::<fn(_)>, None::<fn(_)>,
ShellUserData { ShellUserData {
shell_data: shell_data.clone(), shell_data: shell_data.clone(),
@ -42,15 +41,15 @@ where
* xdg_shell * xdg_shell
*/ */
pub(crate) struct ShellUserData<U, R, SD> { pub(crate) struct ShellUserData<R, SD> {
shell_data: ShellData<U, R, SD>, shell_data: ShellData<R, SD>,
pub(crate) client_data: Mutex<ShellClientData<SD>>, pub(crate) client_data: Mutex<ShellClientData<SD>>,
} }
pub(crate) fn make_shell_client<U, R, SD>( pub(crate) fn make_shell_client<R, SD>(
resource: &xdg_wm_base::XdgWmBase, resource: &xdg_wm_base::XdgWmBase,
token: CompositorToken<U, R>, token: CompositorToken<R>,
) -> ShellClient<U, R, SD> { ) -> ShellClient<R, SD> {
ShellClient { ShellClient {
kind: super::ShellClientKind::Xdg(resource.clone()), kind: super::ShellClientKind::Xdg(resource.clone()),
_token: token, _token: token,
@ -58,13 +57,12 @@ pub(crate) fn make_shell_client<U, R, SD>(
} }
} }
fn wm_implementation<U, R, SD>(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWmBase) fn wm_implementation<R, SD>(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWmBase)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = shell.as_ref().user_data::<ShellUserData<U, R, SD>>().unwrap(); let data = shell.as_ref().user_data::<ShellUserData<R, SD>>().unwrap();
match request { match request {
xdg_wm_base::Request::Destroy => { xdg_wm_base::Request::Destroy => {
// all is handled by destructor // all is handled by destructor
@ -92,8 +90,8 @@ where
return; return;
} }
id.implement_closure( id.implement_closure(
xdg_surface_implementation::<U, R, SD>, xdg_surface_implementation::<R, SD>,
Some(destroy_surface::<U, R, SD>), Some(destroy_surface::<R, SD>),
XdgSurfaceUserData { XdgSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: surface, wl_surface: surface,
@ -188,22 +186,18 @@ fn implement_positioner(
* xdg_surface * xdg_surface
*/ */
struct XdgSurfaceUserData<U, R, SD> { struct XdgSurfaceUserData<R, SD> {
shell_data: ShellData<U, R, SD>, shell_data: ShellData<R, SD>,
wl_surface: wl_surface::WlSurface, wl_surface: wl_surface::WlSurface,
wm_base: xdg_wm_base::XdgWmBase, wm_base: xdg_wm_base::XdgWmBase,
} }
fn destroy_surface<U, R, SD>(surface: xdg_surface::XdgSurface) fn destroy_surface<R, SD>(surface: xdg_surface::XdgSurface)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = surface let data = surface.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
.as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a // trying to change the role but it's a cleanup (possibly a
@ -225,15 +219,14 @@ where
.expect("xdg_surface exists but surface has not shell_surface role?!"); .expect("xdg_surface exists but surface has not shell_surface role?!");
} }
fn xdg_surface_implementation<U, R, SD>(request: xdg_surface::Request, xdg_surface: xdg_surface::XdgSurface) fn xdg_surface_implementation<R, SD>(request: xdg_surface::Request, xdg_surface: xdg_surface::XdgSurface)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = xdg_surface let data = xdg_surface
.as_ref() .as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>() .user_data::<XdgSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
match request { match request {
xdg_surface::Request::Destroy => { xdg_surface::Request::Destroy => {
@ -253,8 +246,8 @@ where
}) })
.expect("xdg_surface exists but surface has not shell_surface role?!"); .expect("xdg_surface exists but surface has not shell_surface role?!");
let toplevel = id.implement_closure( let toplevel = id.implement_closure(
toplevel_implementation::<U, R, SD>, toplevel_implementation::<R, SD>,
Some(destroy_toplevel::<U, R, SD>), Some(destroy_toplevel::<R, SD>),
ShellSurfaceUserData { ShellSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -285,10 +278,7 @@ where
.unwrap(); .unwrap();
let parent_surface = parent.map(|parent| { let parent_surface = parent.map(|parent| {
let parent_data = parent let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
.as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>()
.unwrap();
parent_data.wl_surface.clone() parent_data.wl_surface.clone()
}); });
data.shell_data data.shell_data
@ -301,8 +291,8 @@ where
}) })
.expect("xdg_surface exists but surface has not shell_surface role?!"); .expect("xdg_surface exists but surface has not shell_surface role?!");
let popup = id.implement_closure( let popup = id.implement_closure(
xg_popup_implementation::<U, R, SD>, xg_popup_implementation::<R, SD>,
Some(destroy_popup::<U, R, SD>), Some(destroy_popup::<R, SD>),
ShellSurfaceUserData { ShellSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -360,27 +350,26 @@ where
* xdg_toplevel * xdg_toplevel
*/ */
pub(crate) struct ShellSurfaceUserData<U, R, SD> { pub(crate) struct ShellSurfaceUserData<R, SD> {
pub(crate) shell_data: ShellData<U, R, SD>, pub(crate) shell_data: ShellData<R, SD>,
pub(crate) wl_surface: wl_surface::WlSurface, pub(crate) wl_surface: wl_surface::WlSurface,
pub(crate) wm_base: xdg_wm_base::XdgWmBase, pub(crate) wm_base: xdg_wm_base::XdgWmBase,
pub(crate) xdg_surface: xdg_surface::XdgSurface, pub(crate) xdg_surface: xdg_surface::XdgSurface,
} }
// Utility functions allowing to factor out a lot of the upcoming logic // Utility functions allowing to factor out a lot of the upcoming logic
fn with_surface_toplevel_data<U, R, SD, F>( fn with_surface_toplevel_data<R, SD, F>(
shell_data: &ShellData<U, R, SD>, shell_data: &ShellData<R, SD>,
toplevel: &xdg_toplevel::XdgToplevel, toplevel: &xdg_toplevel::XdgToplevel,
f: F, f: F,
) where ) where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
F: FnOnce(&mut ToplevelState), F: FnOnce(&mut ToplevelState),
{ {
let toplevel_data = toplevel let toplevel_data = toplevel
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
shell_data shell_data
.compositor_token .compositor_token
@ -391,15 +380,14 @@ fn with_surface_toplevel_data<U, R, SD, F>(
.expect("xdg_toplevel exists but surface has not shell_surface role?!"); .expect("xdg_toplevel exists but surface has not shell_surface role?!");
} }
pub fn send_toplevel_configure<U, R, SD>(resource: &xdg_toplevel::XdgToplevel, configure: ToplevelConfigure) pub fn send_toplevel_configure<R, SD>(resource: &xdg_toplevel::XdgToplevel, configure: ToplevelConfigure)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = resource let data = resource
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
let (width, height) = configure.size.unwrap_or((0, 0)); let (width, height) = configure.size.unwrap_or((0, 0));
// convert the Vec<State> (which is really a Vec<u32>) into Vec<u8> // convert the Vec<State> (which is really a Vec<u32>) into Vec<u8>
@ -421,12 +409,12 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!"); .expect("xdg_toplevel exists but surface has not shell_surface role?!");
} }
fn make_toplevel_handle<U: 'static, R: 'static, SD: 'static>( fn make_toplevel_handle<R: 'static, SD: 'static>(
resource: &xdg_toplevel::XdgToplevel, resource: &xdg_toplevel::XdgToplevel,
) -> super::ToplevelSurface<U, R, SD> { ) -> super::ToplevelSurface<R, SD> {
let data = resource let data = resource
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
super::ToplevelSurface { super::ToplevelSurface {
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -436,15 +424,14 @@ fn make_toplevel_handle<U: 'static, R: 'static, SD: 'static>(
} }
} }
fn toplevel_implementation<U, R, SD>(request: xdg_toplevel::Request, toplevel: xdg_toplevel::XdgToplevel) fn toplevel_implementation<R, SD>(request: xdg_toplevel::Request, toplevel: xdg_toplevel::XdgToplevel)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = toplevel let data = toplevel
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
match request { match request {
xdg_toplevel::Request::Destroy => { xdg_toplevel::Request::Destroy => {
@ -455,7 +442,7 @@ where
toplevel_data.parent = parent.map(|toplevel_surface_parent| { toplevel_data.parent = parent.map(|toplevel_surface_parent| {
toplevel_surface_parent toplevel_surface_parent
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap() .unwrap()
.wl_surface .wl_surface
.clone() .clone()
@ -544,15 +531,14 @@ where
} }
} }
fn destroy_toplevel<U, R, SD>(toplevel: xdg_toplevel::XdgToplevel) fn destroy_toplevel<R, SD>(toplevel: xdg_toplevel::XdgToplevel)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = toplevel let data = toplevel
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
@ -580,15 +566,14 @@ where
* xdg_popup * xdg_popup
*/ */
pub(crate) fn send_popup_configure<U, R, SD>(resource: &xdg_popup::XdgPopup, configure: PopupConfigure) pub(crate) fn send_popup_configure<R, SD>(resource: &xdg_popup::XdgPopup, configure: PopupConfigure)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = resource let data = resource
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
let (x, y) = configure.position; let (x, y) = configure.position;
let (width, height) = configure.size; let (width, height) = configure.size;
@ -602,12 +587,10 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!"); .expect("xdg_toplevel exists but surface has not shell_surface role?!");
} }
fn make_popup_handle<U: 'static, R: 'static, SD: 'static>( fn make_popup_handle<R: 'static, SD: 'static>(resource: &xdg_popup::XdgPopup) -> super::PopupSurface<R, SD> {
resource: &xdg_popup::XdgPopup,
) -> super::PopupSurface<U, R, SD> {
let data = resource let data = resource
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
super::PopupSurface { super::PopupSurface {
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -617,16 +600,12 @@ fn make_popup_handle<U: 'static, R: 'static, SD: 'static>(
} }
} }
fn xg_popup_implementation<U, R, SD>(request: xdg_popup::Request, popup: xdg_popup::XdgPopup) fn xg_popup_implementation<R, SD>(request: xdg_popup::Request, popup: xdg_popup::XdgPopup)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = popup let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.unwrap();
match request { match request {
xdg_popup::Request::Destroy => { xdg_popup::Request::Destroy => {
// all is handled by our destructor // all is handled by our destructor
@ -644,16 +623,12 @@ where
} }
} }
fn destroy_popup<U, R, SD>(popup: xdg_popup::XdgPopup) fn destroy_popup<R, SD>(popup: xdg_popup::XdgPopup)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = popup let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a // trying to change the role but it's a cleanup (possibly a

View File

@ -17,17 +17,16 @@ use super::{
XdgSurfacePendingState, XdgSurfaceRole, XdgSurfacePendingState, XdgSurfaceRole,
}; };
pub(crate) fn implement_shell<U, R, SD>( pub(crate) fn implement_shell<R, SD>(
shell: NewResource<zxdg_shell_v6::ZxdgShellV6>, shell: NewResource<zxdg_shell_v6::ZxdgShellV6>,
shell_data: &ShellData<U, R, SD>, shell_data: &ShellData<R, SD>,
) -> zxdg_shell_v6::ZxdgShellV6 ) -> zxdg_shell_v6::ZxdgShellV6
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: Default + 'static, SD: Default + 'static,
{ {
let shell = shell.implement_closure( let shell = shell.implement_closure(
shell_implementation::<U, R, SD>, shell_implementation::<R, SD>,
None::<fn(_)>, None::<fn(_)>,
ShellUserData { ShellUserData {
shell_data: shell_data.clone(), shell_data: shell_data.clone(),
@ -45,15 +44,15 @@ where
* xdg_shell * xdg_shell
*/ */
pub(crate) struct ShellUserData<U, R, SD> { pub(crate) struct ShellUserData<R, SD> {
shell_data: ShellData<U, R, SD>, shell_data: ShellData<R, SD>,
pub(crate) client_data: Mutex<ShellClientData<SD>>, pub(crate) client_data: Mutex<ShellClientData<SD>>,
} }
pub(crate) fn make_shell_client<U, R, SD>( pub(crate) fn make_shell_client<R, SD>(
resource: &zxdg_shell_v6::ZxdgShellV6, resource: &zxdg_shell_v6::ZxdgShellV6,
token: CompositorToken<U, R>, token: CompositorToken<R>,
) -> ShellClient<U, R, SD> { ) -> ShellClient<R, SD> {
ShellClient { ShellClient {
kind: super::ShellClientKind::ZxdgV6(resource.clone()), kind: super::ShellClientKind::ZxdgV6(resource.clone()),
_token: token, _token: token,
@ -61,13 +60,12 @@ pub(crate) fn make_shell_client<U, R, SD>(
} }
} }
fn shell_implementation<U, R, SD>(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6::ZxdgShellV6) fn shell_implementation<R, SD>(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6::ZxdgShellV6)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = shell.as_ref().user_data::<ShellUserData<U, R, SD>>().unwrap(); let data = shell.as_ref().user_data::<ShellUserData<R, SD>>().unwrap();
match request { match request {
zxdg_shell_v6::Request::Destroy => { zxdg_shell_v6::Request::Destroy => {
// all is handled by destructor // all is handled by destructor
@ -95,8 +93,8 @@ where
return; return;
} }
id.implement_closure( id.implement_closure(
xdg_surface_implementation::<U, R, SD>, xdg_surface_implementation::<R, SD>,
Some(destroy_surface::<U, R, SD>), Some(destroy_surface::<R, SD>),
XdgSurfaceUserData { XdgSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: surface.clone(), wl_surface: surface.clone(),
@ -205,22 +203,18 @@ fn implement_positioner(
* xdg_surface * xdg_surface
*/ */
struct XdgSurfaceUserData<U, R, SD> { struct XdgSurfaceUserData<R, SD> {
shell_data: ShellData<U, R, SD>, shell_data: ShellData<R, SD>,
wl_surface: wl_surface::WlSurface, wl_surface: wl_surface::WlSurface,
shell: zxdg_shell_v6::ZxdgShellV6, shell: zxdg_shell_v6::ZxdgShellV6,
} }
fn destroy_surface<U, R, SD>(surface: zxdg_surface_v6::ZxdgSurfaceV6) fn destroy_surface<R, SD>(surface: zxdg_surface_v6::ZxdgSurfaceV6)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = surface let data = surface.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
.as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a // trying to change the role but it's a cleanup (possibly a
@ -242,17 +236,16 @@ where
.expect("xdg_surface exists but surface has not shell_surface role?!"); .expect("xdg_surface exists but surface has not shell_surface role?!");
} }
fn xdg_surface_implementation<U, R, SD>( fn xdg_surface_implementation<R, SD>(
request: zxdg_surface_v6::Request, request: zxdg_surface_v6::Request,
xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6, xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6,
) where ) where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = xdg_surface let data = xdg_surface
.as_ref() .as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>() .user_data::<XdgSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
match request { match request {
zxdg_surface_v6::Request::Destroy => { zxdg_surface_v6::Request::Destroy => {
@ -272,8 +265,8 @@ fn xdg_surface_implementation<U, R, SD>(
}) })
.expect("xdg_surface exists but surface has not shell_surface role?!"); .expect("xdg_surface exists but surface has not shell_surface role?!");
let toplevel = id.implement_closure( let toplevel = id.implement_closure(
toplevel_implementation::<U, R, SD>, toplevel_implementation::<R, SD>,
Some(destroy_toplevel::<U, R, SD>), Some(destroy_toplevel::<R, SD>),
ShellSurfaceUserData { ShellSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -303,10 +296,7 @@ fn xdg_surface_implementation<U, R, SD>(
.user_data::<RefCell<PositionerState>>() .user_data::<RefCell<PositionerState>>()
.unwrap(); .unwrap();
let parent_data = parent let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
.as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>()
.unwrap();
data.shell_data data.shell_data
.compositor_token .compositor_token
.with_role_data::<XdgSurfaceRole, _, _>(&data.wl_surface, |data| { .with_role_data::<XdgSurfaceRole, _, _>(&data.wl_surface, |data| {
@ -317,8 +307,8 @@ fn xdg_surface_implementation<U, R, SD>(
}) })
.expect("xdg_surface exists but surface has not shell_surface role?!"); .expect("xdg_surface exists but surface has not shell_surface role?!");
let popup = id.implement_closure( let popup = id.implement_closure(
popup_implementation::<U, R, SD>, popup_implementation::<R, SD>,
Some(destroy_popup::<U, R, SD>), Some(destroy_popup::<R, SD>),
ShellSurfaceUserData { ShellSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -376,24 +366,23 @@ fn xdg_surface_implementation<U, R, SD>(
* xdg_toplevel * xdg_toplevel
*/ */
pub struct ShellSurfaceUserData<U, R, SD> { pub struct ShellSurfaceUserData<R, SD> {
pub(crate) shell_data: ShellData<U, R, SD>, pub(crate) shell_data: ShellData<R, SD>,
pub(crate) wl_surface: wl_surface::WlSurface, pub(crate) wl_surface: wl_surface::WlSurface,
pub(crate) shell: zxdg_shell_v6::ZxdgShellV6, pub(crate) shell: zxdg_shell_v6::ZxdgShellV6,
pub(crate) xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6, pub(crate) xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6,
} }
// Utility functions allowing to factor out a lot of the upcoming logic // Utility functions allowing to factor out a lot of the upcoming logic
fn with_surface_toplevel_data<U, R, SD, F>(toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F) fn with_surface_toplevel_data<R, SD, F>(toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
F: FnOnce(&mut ToplevelState), F: FnOnce(&mut ToplevelState),
{ {
let data = toplevel let data = toplevel
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
data.shell_data data.shell_data
.compositor_token .compositor_token
@ -404,17 +393,16 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!"); .expect("xdg_toplevel exists but surface has not shell_surface role?!");
} }
pub fn send_toplevel_configure<U, R, SD>( pub fn send_toplevel_configure<R, SD>(
resource: &zxdg_toplevel_v6::ZxdgToplevelV6, resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
configure: ToplevelConfigure, configure: ToplevelConfigure,
) where ) where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = resource let data = resource
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
let (width, height) = configure.size.unwrap_or((0, 0)); let (width, height) = configure.size.unwrap_or((0, 0));
// convert the Vec<State> (which is really a Vec<u32>) into Vec<u8> // convert the Vec<State> (which is really a Vec<u32>) into Vec<u8>
@ -436,12 +424,12 @@ pub fn send_toplevel_configure<U, R, SD>(
.expect("xdg_toplevel exists but surface has not shell_surface role?!"); .expect("xdg_toplevel exists but surface has not shell_surface role?!");
} }
fn make_toplevel_handle<U: 'static, R: 'static, SD: 'static>( fn make_toplevel_handle<R: 'static, SD: 'static>(
resource: &zxdg_toplevel_v6::ZxdgToplevelV6, resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
) -> super::ToplevelSurface<U, R, SD> { ) -> super::ToplevelSurface<R, SD> {
let data = resource let data = resource
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
super::ToplevelSurface { super::ToplevelSurface {
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -451,40 +439,39 @@ fn make_toplevel_handle<U: 'static, R: 'static, SD: 'static>(
} }
} }
fn toplevel_implementation<U, R, SD>( fn toplevel_implementation<R, SD>(
request: zxdg_toplevel_v6::Request, request: zxdg_toplevel_v6::Request,
toplevel: zxdg_toplevel_v6::ZxdgToplevelV6, toplevel: zxdg_toplevel_v6::ZxdgToplevelV6,
) where ) where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = toplevel let data = toplevel
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
match request { match request {
zxdg_toplevel_v6::Request::Destroy => { zxdg_toplevel_v6::Request::Destroy => {
// all it done by the destructor // all it done by the destructor
} }
zxdg_toplevel_v6::Request::SetParent { parent } => { zxdg_toplevel_v6::Request::SetParent { parent } => {
with_surface_toplevel_data::<U, R, SD, _>(&toplevel, |toplevel_data| { with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
toplevel_data.parent = parent.map(|toplevel_surface_parent| { toplevel_data.parent = parent.map(|toplevel_surface_parent| {
let parent_data = toplevel_surface_parent let parent_data = toplevel_surface_parent
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
parent_data.wl_surface.clone() parent_data.wl_surface.clone()
}) })
}); });
} }
zxdg_toplevel_v6::Request::SetTitle { title } => { zxdg_toplevel_v6::Request::SetTitle { title } => {
with_surface_toplevel_data::<U, R, SD, _>(&toplevel, |toplevel_data| { with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
toplevel_data.title = title; toplevel_data.title = title;
}); });
} }
zxdg_toplevel_v6::Request::SetAppId { app_id } => { zxdg_toplevel_v6::Request::SetAppId { app_id } => {
with_surface_toplevel_data::<U, R, SD, _>(&toplevel, |toplevel_data| { with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
toplevel_data.app_id = app_id; toplevel_data.app_id = app_id;
}); });
} }
@ -520,12 +507,12 @@ fn toplevel_implementation<U, R, SD>(
}); });
} }
zxdg_toplevel_v6::Request::SetMaxSize { width, height } => { zxdg_toplevel_v6::Request::SetMaxSize { width, height } => {
with_surface_toplevel_data::<U, R, SD, _>(&toplevel, |toplevel_data| { with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
toplevel_data.max_size = (width, height); toplevel_data.max_size = (width, height);
}); });
} }
zxdg_toplevel_v6::Request::SetMinSize { width, height } => { zxdg_toplevel_v6::Request::SetMinSize { width, height } => {
with_surface_toplevel_data::<U, R, SD, _>(&toplevel, |toplevel_data| { with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
toplevel_data.max_size = (width, height); toplevel_data.max_size = (width, height);
}); });
} }
@ -561,15 +548,14 @@ fn toplevel_implementation<U, R, SD>(
} }
} }
fn destroy_toplevel<U, R, SD>(toplevel: zxdg_toplevel_v6::ZxdgToplevelV6) fn destroy_toplevel<R, SD>(toplevel: zxdg_toplevel_v6::ZxdgToplevelV6)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = toplevel let data = toplevel
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
@ -597,15 +583,14 @@ where
* xdg_popup * xdg_popup
*/ */
pub(crate) fn send_popup_configure<U, R, SD>(resource: &zxdg_popup_v6::ZxdgPopupV6, configure: PopupConfigure) pub(crate) fn send_popup_configure<R, SD>(resource: &zxdg_popup_v6::ZxdgPopupV6, configure: PopupConfigure)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = resource let data = resource
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
let (x, y) = configure.position; let (x, y) = configure.position;
let (width, height) = configure.size; let (width, height) = configure.size;
@ -619,12 +604,12 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!"); .expect("xdg_toplevel exists but surface has not shell_surface role?!");
} }
fn make_popup_handle<U: 'static, R: 'static, SD: 'static>( fn make_popup_handle<R: 'static, SD: 'static>(
resource: &zxdg_popup_v6::ZxdgPopupV6, resource: &zxdg_popup_v6::ZxdgPopupV6,
) -> super::PopupSurface<U, R, SD> { ) -> super::PopupSurface<R, SD> {
let data = resource let data = resource
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>() .user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap(); .unwrap();
super::PopupSurface { super::PopupSurface {
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -634,16 +619,12 @@ fn make_popup_handle<U: 'static, R: 'static, SD: 'static>(
} }
} }
fn popup_implementation<U, R, SD>(request: zxdg_popup_v6::Request, popup: zxdg_popup_v6::ZxdgPopupV6) fn popup_implementation<R, SD>(request: zxdg_popup_v6::Request, popup: zxdg_popup_v6::ZxdgPopupV6)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = popup let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.unwrap();
match request { match request {
zxdg_popup_v6::Request::Destroy => { zxdg_popup_v6::Request::Destroy => {
// all is handled by our destructor // all is handled by our destructor
@ -661,16 +642,12 @@ where
} }
} }
fn destroy_popup<U, R, SD>(popup: zxdg_popup_v6::ZxdgPopupV6) fn destroy_popup<R, SD>(popup: zxdg_popup_v6::ZxdgPopupV6)
where where
U: 'static,
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
SD: 'static, SD: 'static,
{ {
let data = popup let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a // trying to change the role but it's a cleanup (possibly a