wayland.compositor: user UserDataMap to store per-surface data
This commit is contained in:
parent
0712bdefec
commit
c604a48dce
|
@ -28,7 +28,7 @@ use smithay::{
|
|||
};
|
||||
|
||||
use crate::shaders;
|
||||
use crate::shell::{MyCompositorToken, MyWindowMap};
|
||||
use crate::shell::{MyCompositorToken, MyWindowMap, SurfaceData};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Vertex {
|
||||
|
@ -299,70 +299,77 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
|
|||
location,
|
||||
|_surface, attributes, role, &(mut x, mut y)| {
|
||||
// Pull a new buffer if available
|
||||
if attributes.user_data.texture.is_none() {
|
||||
if let Some(buffer) = attributes.user_data.buffer.take() {
|
||||
if let Ok(m) = self.texture_from_buffer(buffer.clone()) {
|
||||
// release the buffer if it was an SHM buffer
|
||||
#[cfg(feature = "egl")]
|
||||
{
|
||||
if m.images.is_none() {
|
||||
if let Some(data) = attributes.user_data.get_mut::<SurfaceData>() {
|
||||
if data.texture.is_none() {
|
||||
if let Some(buffer) = data.buffer.take() {
|
||||
if let Ok(m) = self.texture_from_buffer(buffer.clone()) {
|
||||
// release the buffer if it was an SHM buffer
|
||||
#[cfg(feature = "egl")]
|
||||
{
|
||||
if m.images.is_none() {
|
||||
buffer.release();
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "egl"))]
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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 ?
|
||||
if attributes.user_data.texture.is_some() {
|
||||
// if yes, also process the children
|
||||
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
|
||||
x += subdata.location.0;
|
||||
y += subdata.location.1;
|
||||
// Now, should we be drawn ?
|
||||
if data.texture.is_some() {
|
||||
// if yes, also process the children
|
||||
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
|
||||
x += subdata.location.0;
|
||||
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 {
|
||||
// we are not display, so our children are neither
|
||||
// we are not displayed, so our children are neither
|
||||
TraversalAction::SkipChildren
|
||||
}
|
||||
},
|
||||
|_surface, attributes, role, &(mut x, mut y)| {
|
||||
if let Some(ref metadata) = attributes.user_data.texture {
|
||||
// we need to re-extract the subsurface offset, as the previous closure
|
||||
// only passes it to our children
|
||||
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
|
||||
x += subdata.location.0;
|
||||
y += subdata.location.1;
|
||||
if let Some(ref data) = attributes.user_data.get::<SurfaceData>() {
|
||||
if let Some(ref metadata) = data.texture {
|
||||
// we need to re-extract the subsurface offset, as the previous closure
|
||||
// only passes it to our children
|
||||
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
|
||||
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,
|
||||
|
|
|
@ -36,18 +36,17 @@ define_roles!(Roles =>
|
|||
[ CursorImage, CursorImageRole ]
|
||||
);
|
||||
|
||||
pub type MyWindowMap =
|
||||
WindowMap<SurfaceData, Roles, (), (), fn(&SurfaceAttributes<SurfaceData>) -> Option<(i32, i32)>>;
|
||||
pub type MyWindowMap = WindowMap<Roles, (), (), fn(&SurfaceAttributes) -> Option<(i32, i32)>>;
|
||||
|
||||
pub type MyCompositorToken = CompositorToken<SurfaceData, Roles>;
|
||||
pub type MyCompositorToken = CompositorToken<Roles>;
|
||||
|
||||
pub fn init_shell(
|
||||
display: &mut Display,
|
||||
log: ::slog::Logger,
|
||||
) -> (
|
||||
CompositorToken<SurfaceData, Roles>,
|
||||
Arc<Mutex<XdgShellState<SurfaceData, Roles, ()>>>,
|
||||
Arc<Mutex<WlShellState<SurfaceData, Roles, ()>>>,
|
||||
CompositorToken<Roles>,
|
||||
Arc<Mutex<XdgShellState<Roles, ()>>>,
|
||||
Arc<Mutex<WlShellState<Roles, ()>>>,
|
||||
Rc<RefCell<MyWindowMap>>,
|
||||
) {
|
||||
// Create the compositor
|
||||
|
@ -63,7 +62,7 @@ pub fn init_shell(
|
|||
);
|
||||
|
||||
// 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,
|
||||
get_size as _,
|
||||
)));
|
||||
|
@ -105,7 +104,7 @@ pub fn init_shell(
|
|||
let (wl_shell_state, _) = wl_shell_init(
|
||||
display,
|
||||
compositor_token,
|
||||
move |req: ShellRequest<_, _, ()>| {
|
||||
move |req: ShellRequest<_, ()>| {
|
||||
if let ShellRequest::SetKind {
|
||||
surface,
|
||||
kind: ShellSurfaceKind::Toplevel,
|
||||
|
@ -135,31 +134,34 @@ pub struct SurfaceData {
|
|||
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
|
||||
token.with_surface_data(surface, |attributes| {
|
||||
attributes.user_data.insert_if_missing(|| SurfaceData::default());
|
||||
match attributes.buffer.take() {
|
||||
Some(Some((buffer, (_x, _y)))) => {
|
||||
// new contents
|
||||
// TODO: handle hotspot coordinates
|
||||
attributes.user_data.buffer = Some(buffer);
|
||||
attributes.user_data.texture = None;
|
||||
let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();
|
||||
data.buffer = Some(buffer);
|
||||
data.texture = None;
|
||||
}
|
||||
Some(None) => {
|
||||
// erase the contents
|
||||
attributes.user_data.buffer = None;
|
||||
attributes.user_data.texture = None;
|
||||
let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();
|
||||
data.buffer = None;
|
||||
data.texture = None;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn get_size(attrs: &SurfaceAttributes<SurfaceData>) -> Option<(i32, i32)> {
|
||||
attrs
|
||||
.user_data
|
||||
.texture
|
||||
.as_ref()
|
||||
.map(|ref meta| meta.dimensions)
|
||||
.map(|(x, y)| (x as i32, y as i32))
|
||||
fn get_size(attrs: &SurfaceAttributes) -> Option<(i32, i32)> {
|
||||
attrs.user_data.get::<SurfaceData>().and_then(|data| {
|
||||
data.texture
|
||||
.as_ref()
|
||||
.map(|ref meta| meta.dimensions)
|
||||
.map(|(x, y)| (x as i32, y as i32))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ use smithay::{
|
|||
|
||||
use crate::glium_drawer::GliumDrawer;
|
||||
use crate::input_handler::AnvilInputHandler;
|
||||
use crate::shell::{init_shell, MyWindowMap, Roles, SurfaceData};
|
||||
use crate::shell::{init_shell, MyWindowMap, Roles};
|
||||
|
||||
pub struct SessionFd(RawFd);
|
||||
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> {
|
||||
compositor_token: CompositorToken<SurfaceData, Roles>,
|
||||
compositor_token: CompositorToken<Roles>,
|
||||
#[cfg(feature = "egl")]
|
||||
active_egl_context: Rc<RefCell<Option<EGLDisplay>>>,
|
||||
session: AutoSession,
|
||||
|
@ -522,7 +522,7 @@ impl<S: SessionNotifier, Data: 'static> UdevHandler for UdevHandlerImpl<S, Data>
|
|||
}
|
||||
|
||||
pub struct DrmHandlerImpl {
|
||||
compositor_token: CompositorToken<SurfaceData, Roles>,
|
||||
compositor_token: CompositorToken<Roles>,
|
||||
backends: Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<RenderSurface>>>>,
|
||||
window_map: Rc<RefCell<MyWindowMap>>,
|
||||
pointer_location: Rc<RefCell<(f64, f64)>>,
|
||||
|
|
|
@ -12,14 +12,13 @@ use smithay::{
|
|||
},
|
||||
};
|
||||
|
||||
pub enum Kind<U, R, SD, D> {
|
||||
Xdg(ToplevelSurface<U, R, SD>),
|
||||
Wl(ShellSurface<U, R, D>),
|
||||
pub enum Kind<R, SD, D> {
|
||||
Xdg(ToplevelSurface<R, SD>),
|
||||
Wl(ShellSurface<R, D>),
|
||||
}
|
||||
|
||||
impl<U, R, SD, D> Kind<U, R, SD, D>
|
||||
impl<R, SD, D> Kind<R, SD, D>
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
|
||||
SD: 'static,
|
||||
D: 'static,
|
||||
|
@ -38,15 +37,14 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
struct Window<U, R, SD, D> {
|
||||
struct Window<R, SD, D> {
|
||||
location: (i32, i32),
|
||||
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
|
||||
U: 'static,
|
||||
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
|
||||
SD: 'static,
|
||||
D: 'static,
|
||||
|
@ -55,11 +53,11 @@ where
|
|||
fn matching<F>(
|
||||
&self,
|
||||
point: (f64, f64),
|
||||
ctoken: CompositorToken<U, R>,
|
||||
ctoken: CompositorToken<R>,
|
||||
get_size: F,
|
||||
) -> Option<(wl_surface::WlSurface, (f64, f64))>
|
||||
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)) {
|
||||
return None;
|
||||
|
@ -101,9 +99,9 @@ where
|
|||
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
|
||||
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>,
|
||||
F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
|
||||
{
|
||||
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);
|
||||
|
@ -148,21 +146,20 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub struct WindowMap<U, R, SD, D, F> {
|
||||
ctoken: CompositorToken<U, R>,
|
||||
windows: Vec<Window<U, R, SD, D>>,
|
||||
pub struct WindowMap<R, SD, D, F> {
|
||||
ctoken: CompositorToken<R>,
|
||||
windows: Vec<Window<R, SD, D>>,
|
||||
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
|
||||
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>,
|
||||
U: 'static,
|
||||
F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
|
||||
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
|
||||
SD: '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 {
|
||||
ctoken,
|
||||
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 {
|
||||
location,
|
||||
surface: Rectangle {
|
||||
|
@ -216,7 +213,7 @@ where
|
|||
|
||||
pub fn with_windows_from_bottom_to_top<Func>(&self, mut f: Func)
|
||||
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() {
|
||||
f(&w.toplevel, w.location)
|
||||
|
|
|
@ -300,7 +300,6 @@ impl Drop for EGLImages {
|
|||
}
|
||||
}
|
||||
}
|
||||
println!("RELEASING EGL BUFFER");
|
||||
self.buffer.release();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,15 +15,14 @@ use super::{
|
|||
* wl_compositor
|
||||
*/
|
||||
|
||||
pub(crate) fn implement_compositor<U, R, Impl>(
|
||||
pub(crate) fn implement_compositor<R, Impl>(
|
||||
compositor: NewResource<wl_compositor::WlCompositor>,
|
||||
log: ::slog::Logger,
|
||||
implem: Rc<RefCell<Impl>>,
|
||||
) -> wl_compositor::WlCompositor
|
||||
where
|
||||
U: 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(
|
||||
move |request, _compositor| match request {
|
||||
|
@ -47,34 +46,33 @@ where
|
|||
*/
|
||||
|
||||
// Internal implementation data of surfaces
|
||||
pub(crate) struct SurfaceImplem<U, R> {
|
||||
pub(crate) struct SurfaceImplem<R> {
|
||||
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> {
|
||||
fn make<Impl>(log: ::slog::Logger, implem: Rc<RefCell<Impl>>) -> SurfaceImplem<U, R>
|
||||
impl<R> SurfaceImplem<R> {
|
||||
fn make<Impl>(log: ::slog::Logger, implem: Rc<RefCell<Impl>>) -> SurfaceImplem<R>
|
||||
where
|
||||
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<U, R>) + 'static,
|
||||
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static,
|
||||
{
|
||||
SurfaceImplem { log, implem }
|
||||
}
|
||||
}
|
||||
|
||||
impl<U, R> SurfaceImplem<U, R>
|
||||
impl<R> SurfaceImplem<R>
|
||||
where
|
||||
U: 'static,
|
||||
R: 'static,
|
||||
{
|
||||
fn receive_surface_request(&mut self, req: wl_surface::Request, surface: wl_surface::WlSurface) {
|
||||
match req {
|
||||
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))))
|
||||
});
|
||||
}
|
||||
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 })
|
||||
});
|
||||
}
|
||||
|
@ -88,14 +86,14 @@ where
|
|||
let attributes_mutex = r.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap();
|
||||
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 } => {
|
||||
let attributes = region.map(|r| {
|
||||
let attributes_mutex = r.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap();
|
||||
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 => {
|
||||
let mut user_impl = self.implem.borrow_mut();
|
||||
|
@ -103,13 +101,13 @@ where
|
|||
(&mut *user_impl)(SurfaceEvent::Commit, surface, CompositorToken::make());
|
||||
}
|
||||
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 } => {
|
||||
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 } => {
|
||||
SurfaceData::<U, R>::with_data(&surface, |d| {
|
||||
SurfaceData::<R>::with_data(&surface, |d| {
|
||||
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>,
|
||||
log: ::slog::Logger,
|
||||
implem: Rc<RefCell<Impl>>,
|
||||
) -> wl_surface::WlSurface
|
||||
where
|
||||
U: 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 mut implem = SurfaceImplem::make(log, implem);
|
||||
move |req, surface| implem.receive_surface_request(req, surface)
|
||||
},
|
||||
Some(|surface| SurfaceData::<U, R>::cleanup(&surface)),
|
||||
SurfaceData::<U, R>::new(),
|
||||
Some(|surface| SurfaceData::<R>::cleanup(&surface)),
|
||||
SurfaceData::<R>::new(),
|
||||
);
|
||||
SurfaceData::<U, R>::init(&surface);
|
||||
SurfaceData::<R>::init(&surface);
|
||||
surface
|
||||
}
|
||||
|
||||
|
@ -176,24 +173,23 @@ fn implement_region(region: NewResource<wl_region::WlRegion>) -> wl_region::WlRe
|
|||
* wl_subcompositor
|
||||
*/
|
||||
|
||||
pub(crate) fn implement_subcompositor<U, R>(
|
||||
pub(crate) fn implement_subcompositor<R>(
|
||||
subcompositor: NewResource<wl_subcompositor::WlSubcompositor>,
|
||||
) -> wl_subcompositor::WlSubcompositor
|
||||
where
|
||||
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||
U: 'static,
|
||||
{
|
||||
subcompositor.implement_closure(
|
||||
move |request, subcompositor| match request {
|
||||
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(
|
||||
wl_subcompositor::Error::BadSurface as u32,
|
||||
"Surface already has a role.".into(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
implement_subsurface::<U, R>(id, surface.clone());
|
||||
implement_subsurface::<R>(id, surface.clone());
|
||||
}
|
||||
wl_subcompositor::Request::Destroy => {}
|
||||
_ => unreachable!(),
|
||||
|
@ -207,36 +203,34 @@ where
|
|||
* 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
|
||||
F: FnOnce(&mut SubsurfaceRole),
|
||||
U: 'static,
|
||||
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||
{
|
||||
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?!");
|
||||
}
|
||||
|
||||
fn implement_subsurface<U, R>(
|
||||
fn implement_subsurface<R>(
|
||||
subsurface: NewResource<wl_subsurface::WlSubsurface>,
|
||||
surface: wl_surface::WlSurface,
|
||||
) -> wl_subsurface::WlSubsurface
|
||||
where
|
||||
U: 'static,
|
||||
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||
{
|
||||
subsurface.implement_closure(
|
||||
|request, subsurface| {
|
||||
match request {
|
||||
wl_subsurface::Request::SetPosition { x, y } => {
|
||||
with_subsurface_attributes::<U, R, _>(&subsurface, |attrs| {
|
||||
with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
|
||||
attrs.location = (x, y);
|
||||
})
|
||||
}
|
||||
wl_subsurface::Request::PlaceAbove { sibling } => {
|
||||
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(
|
||||
wl_subsurface::Error::BadSurface as u32,
|
||||
"Provided surface is not a sibling or parent.".into(),
|
||||
|
@ -245,20 +239,18 @@ where
|
|||
}
|
||||
wl_subsurface::Request::PlaceBelow { sibling } => {
|
||||
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(
|
||||
wl_subsurface::Error::BadSurface as u32,
|
||||
"Provided surface is not a sibling or parent.".into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
wl_subsurface::Request::SetSync => {
|
||||
with_subsurface_attributes::<U, R, _>(&subsurface, |attrs| {
|
||||
attrs.sync = true;
|
||||
})
|
||||
}
|
||||
wl_subsurface::Request::SetSync => with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
|
||||
attrs.sync = true;
|
||||
}),
|
||||
wl_subsurface::Request::SetDesync => {
|
||||
with_subsurface_attributes::<U, R, _>(&subsurface, |attrs| {
|
||||
with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
|
||||
attrs.sync = false;
|
||||
})
|
||||
}
|
||||
|
@ -268,18 +260,17 @@ where
|
|||
_ => unreachable!(),
|
||||
}
|
||||
},
|
||||
Some(|subsurface| destroy_subsurface::<U, R>(&subsurface)),
|
||||
Some(|subsurface| destroy_subsurface::<R>(&subsurface)),
|
||||
surface,
|
||||
)
|
||||
}
|
||||
|
||||
fn destroy_subsurface<U, R>(subsurface: &wl_subsurface::WlSubsurface)
|
||||
fn destroy_subsurface<R>(subsurface: &wl_subsurface::WlSubsurface)
|
||||
where
|
||||
U: 'static,
|
||||
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||
{
|
||||
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap();
|
||||
if surface.as_ref().is_alive() {
|
||||
SurfaceData::<U, R>::unset_parent(&surface);
|
||||
SurfaceData::<R>::unset_parent(&surface);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,14 +32,6 @@
|
|||
//! # #[macro_use] extern crate smithay;
|
||||
//! 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
|
||||
//! define_roles!(MyRoles);
|
||||
//!
|
||||
|
@ -47,7 +39,7 @@
|
|||
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
|
||||
//! # let mut display = wayland_server::Display::new(event_loop.handle());
|
||||
//! // Call the init function:
|
||||
//! let (token, _, _) = compositor_init::<MyData, MyRoles, _, _>(
|
||||
//! let (token, _, _) = compositor_init::<MyRoles, _, _>(
|
||||
//! &mut display,
|
||||
//! |request, surface, compositor_token| {
|
||||
//! /*
|
||||
|
@ -112,8 +104,7 @@ pub enum Damage {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone, Default)]
|
||||
struct Marker<U, R> {
|
||||
_u: ::std::marker::PhantomData<U>,
|
||||
struct Marker<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
|
||||
/// processing them two times.
|
||||
pub struct SurfaceAttributes<U> {
|
||||
pub struct SurfaceAttributes {
|
||||
/// Buffer defining the contents of the surface
|
||||
///
|
||||
/// The tuple represent the coordinates of this buffer
|
||||
|
@ -164,11 +155,11 @@ pub struct SurfaceAttributes<U> {
|
|||
/// User-controlled data
|
||||
///
|
||||
/// 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> {
|
||||
fn default() -> SurfaceAttributes<U> {
|
||||
impl Default for SurfaceAttributes {
|
||||
fn default() -> SurfaceAttributes {
|
||||
SurfaceAttributes {
|
||||
buffer: None,
|
||||
buffer_scale: 1,
|
||||
|
@ -176,7 +167,7 @@ impl<U: Default> Default for SurfaceAttributes<U> {
|
|||
opaque_region: None,
|
||||
input_region: None,
|
||||
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)
|
||||
/// and [`wl_region`](wayland_server::protocol::wl_region) managed
|
||||
/// by the `CompositorGlobal` that provided it.
|
||||
pub struct CompositorToken<U, R> {
|
||||
_data: ::std::marker::PhantomData<*mut U>,
|
||||
pub struct CompositorToken<R> {
|
||||
_role: ::std::marker::PhantomData<*mut R>,
|
||||
}
|
||||
|
||||
// we implement them manually because #[derive(..)] would require
|
||||
// U: Clone and R: Clone
|
||||
impl<U, R> Copy for CompositorToken<U, R> {}
|
||||
impl<U, R> Clone for CompositorToken<U, R> {
|
||||
fn clone(&self) -> CompositorToken<U, R> {
|
||||
// we implement them manually because #[derive(..)] would require R: Clone
|
||||
impl<R> Copy for CompositorToken<R> {}
|
||||
impl<R> Clone for CompositorToken<R> {
|
||||
fn clone(&self) -> CompositorToken<R> {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<U, R> Send for CompositorToken<U, R> {}
|
||||
unsafe impl<U, R> Sync for CompositorToken<U, R> {}
|
||||
unsafe impl<R> Send for CompositorToken<R> {}
|
||||
unsafe impl<R> Sync for CompositorToken<R> {}
|
||||
|
||||
impl<U, R> CompositorToken<U, R> {
|
||||
pub(crate) fn make() -> CompositorToken<U, R> {
|
||||
impl<R> CompositorToken<R> {
|
||||
pub(crate) fn make() -> CompositorToken<R> {
|
||||
CompositorToken {
|
||||
_data: ::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
|
||||
///
|
||||
/// 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).
|
||||
pub fn with_surface_data<F, T>(&self, surface: &WlSurface, f: F) -> T
|
||||
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
|
||||
U: 'static,
|
||||
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||
{
|
||||
/// Access the data of a surface tree from bottom to top
|
||||
|
@ -319,11 +306,11 @@ where
|
|||
processor: F2,
|
||||
post_filter: F3,
|
||||
) where
|
||||
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
|
||||
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T),
|
||||
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool,
|
||||
F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
|
||||
F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
|
||||
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
|
||||
|
@ -340,11 +327,11 @@ where
|
|||
processor: F2,
|
||||
post_filter: F3,
|
||||
) where
|
||||
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
|
||||
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T),
|
||||
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool,
|
||||
F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
|
||||
F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
|
||||
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
|
||||
|
@ -354,7 +341,7 @@ where
|
|||
/// If the surface is not managed by the `CompositorGlobal` that provided this token, this
|
||||
/// will panic (having more than one compositor is not supported).
|
||||
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
|
||||
|
@ -362,17 +349,17 @@ where
|
|||
/// If the surface is not managed by the `CompositorGlobal` that provided this token, this
|
||||
/// will panic (having more than one compositor is not supported).
|
||||
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
|
||||
///
|
||||
/// If the surface is not managed by the `CompositorGlobal` that provided this token, this
|
||||
/// will panic (having more than one compositor is not supported).
|
||||
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
|
||||
|
@ -383,7 +370,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
|
|||
where
|
||||
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
|
||||
|
@ -397,7 +384,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
|
|||
R: Role<RoleData>,
|
||||
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
|
||||
|
@ -410,7 +397,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
|
|||
where
|
||||
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
|
||||
|
@ -424,7 +411,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
|
|||
R: Role<RoleData>,
|
||||
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
|
||||
|
@ -437,7 +424,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
|
|||
where
|
||||
R: Role<RoleData>,
|
||||
{
|
||||
SurfaceData::<U, R>::remove_role::<RoleData>(surface)
|
||||
SurfaceData::<R>::remove_role::<RoleData>(surface)
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// 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,
|
||||
implem: Impl,
|
||||
logger: L,
|
||||
) -> (
|
||||
CompositorToken<U, R>,
|
||||
CompositorToken<R>,
|
||||
Global<wl_compositor::WlCompositor>,
|
||||
Global<wl_subcompositor::WlSubcompositor>,
|
||||
)
|
||||
where
|
||||
L: Into<Option<::slog::Logger>>,
|
||||
U: Default + '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 implem = Rc::new(RefCell::new(implem));
|
||||
|
||||
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| {
|
||||
self::handlers::implement_subcompositor::<U, R>(new_subcompositor);
|
||||
self::handlers::implement_subcompositor::<R>(new_subcompositor);
|
||||
});
|
||||
|
||||
(CompositorToken::make(), compositor, subcompositor)
|
||||
|
|
|
@ -15,11 +15,11 @@ use wayland_server::protocol::wl_surface::WlSurface;
|
|||
///
|
||||
/// Each node also appears within its children list, to allow relative placement
|
||||
/// between them.
|
||||
pub struct SurfaceData<U, R> {
|
||||
pub struct SurfaceData<R> {
|
||||
parent: Option<WlSurface>,
|
||||
children: Vec<WlSurface>,
|
||||
role: R,
|
||||
attributes: SurfaceAttributes<U>,
|
||||
attributes: SurfaceAttributes,
|
||||
}
|
||||
|
||||
pub enum Location {
|
||||
|
@ -37,8 +37,8 @@ pub enum TraversalAction<T> {
|
|||
Break,
|
||||
}
|
||||
|
||||
impl<U: Default, R: Default> SurfaceData<U, R> {
|
||||
pub fn new() -> Mutex<SurfaceData<U, R>> {
|
||||
impl<R: Default> SurfaceData<R> {
|
||||
pub fn new() -> Mutex<SurfaceData<R>> {
|
||||
Mutex::new(SurfaceData {
|
||||
parent: None,
|
||||
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
|
||||
U: 'static,
|
||||
R: 'static,
|
||||
{
|
||||
/// Initializes the surface, must be called at creation for state coherence
|
||||
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();
|
||||
debug_assert!(my_data.children.len() == 0);
|
||||
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
|
||||
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();
|
||||
if let Some(old_parent) = my_data.parent.take() {
|
||||
// We had a parent, lets unregister ourselves from it
|
||||
let old_parent_mutex = old_parent
|
||||
.as_ref()
|
||||
.user_data::<Mutex<SurfaceData<U, R>>>()
|
||||
.unwrap();
|
||||
let old_parent_mutex = old_parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
|
||||
let mut old_parent_guard = old_parent_mutex.lock().unwrap();
|
||||
old_parent_guard
|
||||
.children
|
||||
|
@ -82,17 +78,17 @@ where
|
|||
if child.as_ref().equals(surface.as_ref()) {
|
||||
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();
|
||||
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 {
|
||||
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();
|
||||
<R as RoleType>::has_role(&data_guard.role)
|
||||
}
|
||||
|
@ -103,7 +99,7 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
|
|||
R: Role<RoleData>,
|
||||
{
|
||||
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();
|
||||
<R as Role<RoleData>>::has(&data_guard.role)
|
||||
}
|
||||
|
@ -115,7 +111,7 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
|
|||
RoleData: Default,
|
||||
{
|
||||
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();
|
||||
<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>,
|
||||
{
|
||||
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();
|
||||
<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>,
|
||||
{
|
||||
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();
|
||||
<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,
|
||||
{
|
||||
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 data = <R as Role<RoleData>>::data_mut(&mut data_guard.role)?;
|
||||
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
|
||||
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();
|
||||
if let Some(ref parent) = b_guard.parent {
|
||||
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
|
||||
{
|
||||
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();
|
||||
// if surface already has a role, it cannot become a subsurface
|
||||
<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
|
||||
{
|
||||
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();
|
||||
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) {
|
||||
debug_assert!(child.as_ref().is_alive());
|
||||
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 old_parent = child_guard.parent.take();
|
||||
if old_parent.is_some() {
|
||||
|
@ -225,10 +221,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
|
|||
};
|
||||
// unregister from our parent
|
||||
if let Some(old_parent) = old_parent {
|
||||
let parent_mutex = old_parent
|
||||
.as_ref()
|
||||
.user_data::<Mutex<SurfaceData<U, R>>>()
|
||||
.unwrap();
|
||||
let parent_mutex = old_parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
|
||||
let mut parent_guard = parent_mutex.lock().unwrap();
|
||||
parent_guard
|
||||
.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
|
||||
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();
|
||||
child_guard.parent.as_ref().cloned()
|
||||
}
|
||||
|
||||
/// Retrieve the children surface (if any) of this surface
|
||||
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();
|
||||
parent_guard
|
||||
.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`.
|
||||
pub fn reorder(surface: &WlSurface, to: Location, relative_to: &WlSurface) -> Result<(), ()> {
|
||||
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();
|
||||
data_guard.parent.as_ref().cloned().unwrap()
|
||||
};
|
||||
|
@ -274,7 +267,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
|
|||
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 my_index = index_of(surface, &parent_guard.children).unwrap();
|
||||
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
|
||||
///
|
||||
/// Note that an internal lock is taken during access of this data,
|
||||
/// so the tree cannot be manipulated at the same time
|
||||
pub fn with_data<T, F>(surface: &WlSurface, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut SurfaceAttributes<U>) -> T,
|
||||
F: FnOnce(&mut SurfaceAttributes) -> T,
|
||||
{
|
||||
let data_mutex = surface
|
||||
.as_ref()
|
||||
.user_data::<Mutex<SurfaceData<U, R>>>()
|
||||
.user_data::<Mutex<SurfaceData<R>>>()
|
||||
.expect("Accessing the data of foreign surfaces is not supported.");
|
||||
let mut data_guard = data_mutex.lock().unwrap();
|
||||
f(&mut data_guard.attributes)
|
||||
|
@ -332,9 +325,9 @@ impl<U: 'static, R: 'static> SurfaceData<U, R> {
|
|||
mut post_filter: F3,
|
||||
reverse: bool,
|
||||
) where
|
||||
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
|
||||
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T),
|
||||
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool,
|
||||
F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
|
||||
F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
|
||||
F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool,
|
||||
{
|
||||
Self::map(
|
||||
surface,
|
||||
|
@ -356,11 +349,11 @@ impl<U: 'static, R: 'static> SurfaceData<U, R> {
|
|||
reverse: bool,
|
||||
) -> bool
|
||||
where
|
||||
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
|
||||
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T),
|
||||
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool,
|
||||
F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
|
||||
F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
|
||||
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 data_guard = &mut *data_guard;
|
||||
// call the filter on ourselves
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::wayland::{
|
|||
|
||||
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>,
|
||||
current_focus: Option<wl_surface::WlSurface>,
|
||||
pending_offers: Vec<wl_data_offer::WlDataOffer>,
|
||||
|
@ -21,19 +21,19 @@ pub(crate) struct DnDGrab<U, R> {
|
|||
icon: Option<wl_surface::WlSurface>,
|
||||
origin: wl_surface::WlSurface,
|
||||
callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
seat: Seat,
|
||||
}
|
||||
|
||||
impl<U: 'static, R: Role<DnDIconRole> + 'static> DnDGrab<U, R> {
|
||||
impl<R: Role<DnDIconRole> + 'static> DnDGrab<R> {
|
||||
pub(crate) fn new(
|
||||
source: Option<wl_data_source::WlDataSource>,
|
||||
origin: wl_surface::WlSurface,
|
||||
seat: Seat,
|
||||
icon: Option<wl_surface::WlSurface>,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>,
|
||||
) -> DnDGrab<U, R> {
|
||||
) -> DnDGrab<R> {
|
||||
DnDGrab {
|
||||
data_source: source,
|
||||
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(
|
||||
&mut self,
|
||||
_handle: &mut PointerInnerHandle<'_>,
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
//! # fn main(){
|
||||
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
|
||||
//! # 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_data_device(
|
||||
//! &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
|
||||
/// chosen (and thus the drag'n'drop should abort on drop), return
|
||||
/// [`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,
|
||||
callback: C,
|
||||
action_choice: F,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
logger: L,
|
||||
) -> Global<wl_data_device_manager::WlDataDeviceManager>
|
||||
where
|
||||
F: FnMut(DndAction, DndAction) -> DndAction + 'static,
|
||||
C: FnMut(DataDeviceEvent) + 'static,
|
||||
R: Role<DnDIconRole> + 'static,
|
||||
U: 'static,
|
||||
L: Into<Option<::slog::Logger>>,
|
||||
{
|
||||
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>,
|
||||
callback: Rc<RefCell<C>>,
|
||||
action_choice: Rc<RefCell<F>>,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
log: ::slog::Logger,
|
||||
) -> wl_data_device_manager::WlDataDeviceManager
|
||||
where
|
||||
F: FnMut(DndAction, DndAction) -> DndAction + 'static,
|
||||
C: FnMut(DataDeviceEvent) + 'static,
|
||||
R: Role<DnDIconRole> + 'static,
|
||||
U: 'static,
|
||||
{
|
||||
use self::wl_data_device_manager::Request;
|
||||
new_ddm.implement_closure(
|
||||
|
@ -429,19 +427,18 @@ struct DataDeviceData {
|
|||
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>,
|
||||
seat: Seat,
|
||||
callback: Rc<RefCell<C>>,
|
||||
action_choice: Rc<RefCell<F>>,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
log: ::slog::Logger,
|
||||
) -> wl_data_device::WlDataDevice
|
||||
where
|
||||
F: FnMut(DndAction, DndAction) -> DndAction + 'static,
|
||||
C: FnMut(DataDeviceEvent) + 'static,
|
||||
R: Role<DnDIconRole> + 'static,
|
||||
U: 'static,
|
||||
{
|
||||
use self::wl_data_device::Request;
|
||||
let dd_data = DataDeviceData {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
//! # fn main(){
|
||||
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
|
||||
//! # 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:
|
||||
//! let (seat, seat_global) = Seat::new(
|
||||
//! &mut display, // the display
|
||||
|
@ -121,14 +121,13 @@ impl Seat {
|
|||
/// You are provided with the state token to retrieve it (allowing
|
||||
/// you to add or remove capabilities from it), and the global handle,
|
||||
/// in case you want to remove it.
|
||||
pub fn new<U, R, L>(
|
||||
pub fn new<R, L>(
|
||||
display: &mut Display,
|
||||
name: String,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
logger: L,
|
||||
) -> (Seat, Global<wl_seat::WlSeat>)
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<CursorImageRole> + 'static,
|
||||
L: Into<Option<::slog::Logger>>,
|
||||
{
|
||||
|
@ -194,7 +193,7 @@ impl Seat {
|
|||
/// # fn main(){
|
||||
/// # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
|
||||
/// # 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(
|
||||
/// # &mut display,
|
||||
/// # "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
|
||||
U: 'static,
|
||||
R: Role<CursorImageRole> + '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>,
|
||||
arc: Rc<SeatRc>,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
) -> wl_seat::WlSeat
|
||||
where
|
||||
R: Role<CursorImageRole> + 'static,
|
||||
U: 'static,
|
||||
{
|
||||
let dest_arc = arc.clone();
|
||||
new_seat.implement_closure(
|
||||
|
|
|
@ -46,9 +46,8 @@ struct 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
|
||||
U: 'static,
|
||||
R: Role<CursorImageRole> + '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
|
||||
R: Role<CursorImageRole> + 'static,
|
||||
U: 'static,
|
||||
F: FnMut(CursorImageStatus) + 'static,
|
||||
{
|
||||
PointerHandle {
|
||||
|
@ -525,14 +523,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn implement_pointer<U, R>(
|
||||
pub(crate) fn implement_pointer<R>(
|
||||
new_pointer: NewResource<WlPointer>,
|
||||
handle: Option<&PointerHandle>,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
) -> WlPointer
|
||||
where
|
||||
R: Role<CursorImageRole> + 'static,
|
||||
U: 'static,
|
||||
{
|
||||
let inner = handle.map(|h| h.inner.clone());
|
||||
let destructor = match inner.clone() {
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
//! # fn main() {
|
||||
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
|
||||
//! # 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,
|
||||
//! # |_, _, _| {},
|
||||
//! # None
|
||||
|
@ -62,7 +62,7 @@
|
|||
//! // token from the compositor implementation
|
||||
//! compositor_token,
|
||||
//! // your implementation
|
||||
//! |event: ShellRequest<_, _, MyShellSurfaceData>| { /* ... */ },
|
||||
//! |event: ShellRequest<_, MyShellSurfaceData>| { /* ... */ },
|
||||
//! None // put a logger if you want
|
||||
//! );
|
||||
//!
|
||||
|
@ -97,16 +97,15 @@ pub struct ShellSurfaceRole<D: 'static> {
|
|||
}
|
||||
|
||||
/// A handle to a shell surface
|
||||
pub struct ShellSurface<U, R, D> {
|
||||
pub struct ShellSurface<R, D> {
|
||||
wl_surface: wl_surface::WlSurface,
|
||||
shell_surface: wl_shell_surface::WlShellSurface,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
_d: ::std::marker::PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<U, R, D> ShellSurface<U, R, D>
|
||||
impl<R, D> ShellSurface<R, D>
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<ShellSurfaceRole<D>> + 'static,
|
||||
D: 'static,
|
||||
{
|
||||
|
@ -235,13 +234,13 @@ pub enum ShellSurfaceKind {
|
|||
}
|
||||
|
||||
/// 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
|
||||
///
|
||||
/// by default it has no kind and this should not be displayed
|
||||
NewShellSurface {
|
||||
/// The created surface
|
||||
surface: ShellSurface<U, R, D>,
|
||||
surface: ShellSurface<R, D>,
|
||||
},
|
||||
/// A pong event
|
||||
///
|
||||
|
@ -249,14 +248,14 @@ pub enum ShellRequest<U, R, D> {
|
|||
/// event, smithay has already checked that the responded serial was valid.
|
||||
Pong {
|
||||
/// The surface that sent the pong
|
||||
surface: ShellSurface<U, R, D>,
|
||||
surface: ShellSurface<R, D>,
|
||||
},
|
||||
/// Start of an interactive move
|
||||
///
|
||||
/// The surface requests that an interactive move is started on it
|
||||
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: u32,
|
||||
/// 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
|
||||
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: u32,
|
||||
/// Seat associated with the resize
|
||||
|
@ -278,7 +277,7 @@ pub enum ShellRequest<U, R, D> {
|
|||
/// The surface changed its kind
|
||||
SetKind {
|
||||
/// The surface
|
||||
surface: ShellSurface<U, R, D>,
|
||||
surface: ShellSurface<R, D>,
|
||||
/// Its new kind
|
||||
kind: ShellSurfaceKind,
|
||||
},
|
||||
|
@ -288,13 +287,12 @@ pub enum ShellRequest<U, R, D> {
|
|||
///
|
||||
/// This state allows you to retrieve a list of surfaces
|
||||
/// currently known to the shell global.
|
||||
pub struct ShellState<U, R, D> {
|
||||
known_surfaces: Vec<ShellSurface<U, R, D>>,
|
||||
pub struct ShellState<R, D> {
|
||||
known_surfaces: Vec<ShellSurface<R, D>>,
|
||||
}
|
||||
|
||||
impl<U, R, D> ShellState<U, R, D>
|
||||
impl<R, D> ShellState<R, D>
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<ShellSurfaceRole<D>> + 'static,
|
||||
D: 'static,
|
||||
{
|
||||
|
@ -304,24 +302,23 @@ where
|
|||
}
|
||||
|
||||
/// 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[..]
|
||||
}
|
||||
}
|
||||
|
||||
/// 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,
|
||||
ctoken: CompositorToken<U, R>,
|
||||
ctoken: CompositorToken<R>,
|
||||
implementation: Impl,
|
||||
logger: L,
|
||||
) -> (Arc<Mutex<ShellState<U, R, D>>>, Global<wl_shell::WlShell>)
|
||||
) -> (Arc<Mutex<ShellState<R, D>>>, Global<wl_shell::WlShell>)
|
||||
where
|
||||
U: 'static,
|
||||
D: Default + 'static,
|
||||
R: Role<ShellSurfaceRole<D>> + 'static,
|
||||
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);
|
||||
|
||||
|
|
|
@ -13,16 +13,15 @@ use crate::wayland::compositor::{roles::Role, CompositorToken};
|
|||
|
||||
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>,
|
||||
ctoken: CompositorToken<U, R>,
|
||||
ctoken: CompositorToken<R>,
|
||||
implementation: Rc<RefCell<Impl>>,
|
||||
state: Arc<Mutex<ShellState<U, R, D>>>,
|
||||
state: Arc<Mutex<ShellState<R, D>>>,
|
||||
) where
|
||||
U: 'static,
|
||||
D: Default + 'static,
|
||||
R: Role<ShellSurfaceRole<D>> + 'static,
|
||||
Impl: FnMut(ShellRequest<U, R, D>) + 'static,
|
||||
Impl: FnMut(ShellRequest<R, D>) + 'static,
|
||||
{
|
||||
shell.implement_closure(
|
||||
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,
|
||||
token: CompositorToken<U, R>,
|
||||
) -> ShellSurface<U, R, SD>
|
||||
token: CompositorToken<R>,
|
||||
) -> ShellSurface<R, SD>
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<ShellSurfaceRole<SD>> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = shell_surface
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
ShellSurface {
|
||||
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,
|
||||
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>,
|
||||
surface: wl_surface::WlSurface,
|
||||
implementation: Rc<RefCell<Impl>>,
|
||||
ctoken: CompositorToken<U, R>,
|
||||
state: Arc<Mutex<ShellState<U, R, SD>>>,
|
||||
ctoken: CompositorToken<R>,
|
||||
state: Arc<Mutex<ShellState<R, SD>>>,
|
||||
) -> wl_shell_surface::WlShellSurface
|
||||
where
|
||||
U: 'static,
|
||||
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;
|
||||
shell_surface.implement_closure(
|
||||
move |req, shell_surface| {
|
||||
let data = shell_surface
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
let mut user_impl = implementation.borrow_mut();
|
||||
match req {
|
||||
|
@ -196,7 +193,7 @@ where
|
|||
Some(|shell_surface: wl_shell_surface::WlShellSurface| {
|
||||
let data = shell_surface
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
data.state.lock().unwrap().cleanup_surfaces();
|
||||
}),
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
//! use smithay::wayland::shell::xdg::{xdg_shell_init, XdgSurfaceRole, XdgRequest};
|
||||
//! use wayland_protocols::unstable::xdg_shell::v6::server::zxdg_shell_v6::ZxdgShellV6;
|
||||
//! # use wayland_server::protocol::{wl_seat, wl_output};
|
||||
//! # #[derive(Default)] struct MySurfaceData;
|
||||
//!
|
||||
//! // define the roles type. You need to integrate the XdgSurface role:
|
||||
//! define_roles!(MyRoles =>
|
||||
|
@ -51,7 +50,7 @@
|
|||
//! # fn main() {
|
||||
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
|
||||
//! # 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,
|
||||
//! # |_, _, _| {},
|
||||
//! # None
|
||||
|
@ -61,7 +60,7 @@
|
|||
//! // token from the compositor implementation
|
||||
//! compositor_token,
|
||||
//! // your implementation
|
||||
//! |event: XdgRequest<_, _, MyShellData>| { /* ... */ },
|
||||
//! |event: XdgRequest<_, MyShellData>| { /* ... */ },
|
||||
//! 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,
|
||||
compositor_token: CompositorToken<U, R>,
|
||||
user_impl: Rc<RefCell<dyn FnMut(XdgRequest<U, R, SD>)>>,
|
||||
shell_state: Arc<Mutex<ShellState<U, R, SD>>>,
|
||||
compositor_token: CompositorToken<R>,
|
||||
user_impl: Rc<RefCell<dyn FnMut(XdgRequest<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 {
|
||||
ShellData {
|
||||
log: self.log.clone(),
|
||||
|
@ -278,22 +277,21 @@ impl<U, R, SD> Clone for ShellData<U, R, SD> {
|
|||
}
|
||||
|
||||
/// 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,
|
||||
ctoken: CompositorToken<U, R>,
|
||||
ctoken: CompositorToken<R>,
|
||||
implementation: Impl,
|
||||
logger: L,
|
||||
) -> (
|
||||
Arc<Mutex<ShellState<U, R, SD>>>,
|
||||
Arc<Mutex<ShellState<R, SD>>>,
|
||||
Global<xdg_wm_base::XdgWmBase>,
|
||||
Global<zxdg_shell_v6::ZxdgShellV6>,
|
||||
)
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: Default + 'static,
|
||||
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 shell_state = Arc::new(Mutex::new(ShellState {
|
||||
|
@ -325,24 +323,23 @@ where
|
|||
///
|
||||
/// This state allows you to retrieve a list of surfaces
|
||||
/// currently known to the shell global.
|
||||
pub struct ShellState<U, R, SD> {
|
||||
known_toplevels: Vec<ToplevelSurface<U, R, SD>>,
|
||||
known_popups: Vec<PopupSurface<U, R, SD>>,
|
||||
pub struct ShellState<R, SD> {
|
||||
known_toplevels: Vec<ToplevelSurface<R, SD>>,
|
||||
known_popups: Vec<PopupSurface<R, SD>>,
|
||||
}
|
||||
|
||||
impl<U, R, SD> ShellState<U, R, SD>
|
||||
impl<R, SD> ShellState<R, SD>
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
/// 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[..]
|
||||
}
|
||||
|
||||
/// 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[..]
|
||||
}
|
||||
}
|
||||
|
@ -378,15 +375,14 @@ fn make_shell_client_data<SD: Default>() -> ShellClientData<SD> {
|
|||
///
|
||||
/// You can use this handle to access a storage for any
|
||||
/// client-specific data you wish to associate with it.
|
||||
pub struct ShellClient<U, R, SD> {
|
||||
pub struct ShellClient<R, SD> {
|
||||
kind: ShellClientKind,
|
||||
_token: CompositorToken<U, R>,
|
||||
_token: CompositorToken<R>,
|
||||
_data: ::std::marker::PhantomData<*mut SD>,
|
||||
}
|
||||
|
||||
impl<U, R, SD> ShellClient<U, R, SD>
|
||||
impl<R, SD> ShellClient<R, SD>
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
|
@ -427,7 +423,7 @@ where
|
|||
ShellClientKind::Xdg(ref shell) => {
|
||||
let user_data = shell
|
||||
.as_ref()
|
||||
.user_data::<self::xdg_handlers::ShellUserData<U, R, SD>>()
|
||||
.user_data::<self::xdg_handlers::ShellUserData<R, SD>>()
|
||||
.unwrap();
|
||||
let mut guard = user_data.client_data.lock().unwrap();
|
||||
if guard.pending_ping == 0 {
|
||||
|
@ -439,7 +435,7 @@ where
|
|||
ShellClientKind::ZxdgV6(ref shell) => {
|
||||
let user_data = shell
|
||||
.as_ref()
|
||||
.user_data::<self::zxdgv6_handlers::ShellUserData<U, R, SD>>()
|
||||
.user_data::<self::zxdgv6_handlers::ShellUserData<R, SD>>()
|
||||
.unwrap();
|
||||
let mut guard = user_data.client_data.lock().unwrap();
|
||||
if guard.pending_ping == 0 {
|
||||
|
@ -464,7 +460,7 @@ where
|
|||
ShellClientKind::Xdg(ref shell) => {
|
||||
let data = shell
|
||||
.as_ref()
|
||||
.user_data::<self::xdg_handlers::ShellUserData<U, R, SD>>()
|
||||
.user_data::<self::xdg_handlers::ShellUserData<R, SD>>()
|
||||
.unwrap();
|
||||
let mut guard = data.client_data.lock().unwrap();
|
||||
Ok(f(&mut guard.data))
|
||||
|
@ -472,7 +468,7 @@ where
|
|||
ShellClientKind::ZxdgV6(ref shell) => {
|
||||
let data = shell
|
||||
.as_ref()
|
||||
.user_data::<self::zxdgv6_handlers::ShellUserData<U, R, SD>>()
|
||||
.user_data::<self::zxdgv6_handlers::ShellUserData<R, SD>>()
|
||||
.unwrap();
|
||||
let mut guard = data.client_data.lock().unwrap();
|
||||
Ok(f(&mut guard.data))
|
||||
|
@ -487,16 +483,15 @@ pub(crate) enum ToplevelKind {
|
|||
}
|
||||
|
||||
/// A handle to a toplevel surface
|
||||
pub struct ToplevelSurface<U, R, SD> {
|
||||
pub struct ToplevelSurface<R, SD> {
|
||||
wl_surface: wl_surface::WlSurface,
|
||||
shell_surface: ToplevelKind,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
_shell_data: ::std::marker::PhantomData<SD>,
|
||||
}
|
||||
|
||||
impl<U, R, SD> ToplevelSurface<U, R, SD>
|
||||
impl<R, SD> ToplevelSurface<R, SD>
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
|
@ -517,7 +512,7 @@ where
|
|||
/// Retrieve the shell client owning this toplevel surface
|
||||
///
|
||||
/// 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() {
|
||||
return None;
|
||||
}
|
||||
|
@ -526,14 +521,14 @@ where
|
|||
ToplevelKind::Xdg(ref s) => {
|
||||
let data = s
|
||||
.as_ref()
|
||||
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
ShellClientKind::Xdg(data.wm_base.clone())
|
||||
}
|
||||
ToplevelKind::ZxdgV6(ref s) => {
|
||||
let data = s
|
||||
.as_ref()
|
||||
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
ShellClientKind::ZxdgV6(data.shell.clone())
|
||||
}
|
||||
|
@ -554,8 +549,8 @@ where
|
|||
return;
|
||||
}
|
||||
match self.shell_surface {
|
||||
ToplevelKind::Xdg(ref s) => self::xdg_handlers::send_toplevel_configure::<U, R, SD>(s, cfg),
|
||||
ToplevelKind::ZxdgV6(ref s) => self::zxdgv6_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::<R, SD>(s, cfg),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -580,7 +575,7 @@ where
|
|||
ToplevelKind::Xdg(ref s) => {
|
||||
let data = s
|
||||
.as_ref()
|
||||
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
data.xdg_surface.as_ref().post_error(
|
||||
xdg_surface::Error::NotConstructed as u32,
|
||||
|
@ -590,7 +585,7 @@ where
|
|||
ToplevelKind::ZxdgV6(ref s) => {
|
||||
let data = s
|
||||
.as_ref()
|
||||
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
data.xdg_surface.as_ref().post_error(
|
||||
zxdg_surface_v6::Error::NotConstructed as u32,
|
||||
|
@ -647,16 +642,15 @@ pub(crate) enum PopupKind {
|
|||
///
|
||||
/// This is an unified abstraction over the popup surfaces
|
||||
/// of both `wl_shell` and `xdg_shell`.
|
||||
pub struct PopupSurface<U, R, SD> {
|
||||
pub struct PopupSurface<R, SD> {
|
||||
wl_surface: wl_surface::WlSurface,
|
||||
shell_surface: PopupKind,
|
||||
token: CompositorToken<U, R>,
|
||||
token: CompositorToken<R>,
|
||||
_shell_data: ::std::marker::PhantomData<SD>,
|
||||
}
|
||||
|
||||
impl<U, R, SD> PopupSurface<U, R, SD>
|
||||
impl<R, SD> PopupSurface<R, SD>
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
|
@ -677,7 +671,7 @@ where
|
|||
/// Retrieve the shell client owning this popup surface
|
||||
///
|
||||
/// 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() {
|
||||
return None;
|
||||
}
|
||||
|
@ -686,14 +680,14 @@ where
|
|||
PopupKind::Xdg(ref p) => {
|
||||
let data = p
|
||||
.as_ref()
|
||||
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
ShellClientKind::Xdg(data.wm_base.clone())
|
||||
}
|
||||
PopupKind::ZxdgV6(ref p) => {
|
||||
let data = p
|
||||
.as_ref()
|
||||
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
ShellClientKind::ZxdgV6(data.shell.clone())
|
||||
}
|
||||
|
@ -715,10 +709,10 @@ where
|
|||
}
|
||||
match self.shell_surface {
|
||||
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) => {
|
||||
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) => {
|
||||
let data = s
|
||||
.as_ref()
|
||||
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
data.xdg_surface.as_ref().post_error(
|
||||
xdg_surface::Error::NotConstructed as u32,
|
||||
|
@ -754,7 +748,7 @@ where
|
|||
PopupKind::ZxdgV6(ref s) => {
|
||||
let data = s
|
||||
.as_ref()
|
||||
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
data.xdg_surface.as_ref().post_error(
|
||||
zxdg_surface_v6::Error::NotConstructed as u32,
|
||||
|
@ -843,11 +837,11 @@ pub struct PopupConfigure {
|
|||
/// for you directly.
|
||||
///
|
||||
/// 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
|
||||
NewClient {
|
||||
/// the client
|
||||
client: ShellClient<U, R, SD>,
|
||||
client: ShellClient<R, SD>,
|
||||
},
|
||||
/// 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.
|
||||
ClientPong {
|
||||
/// the client
|
||||
client: ShellClient<U, R, SD>,
|
||||
client: ShellClient<R, SD>,
|
||||
},
|
||||
/// A new toplevel surface was created
|
||||
///
|
||||
|
@ -863,7 +857,7 @@ pub enum XdgRequest<U, R, SD> {
|
|||
/// client as to how its window should be
|
||||
NewToplevel {
|
||||
/// the surface
|
||||
surface: ToplevelSurface<U, R, SD>,
|
||||
surface: ToplevelSurface<R, SD>,
|
||||
},
|
||||
/// A new popup surface was created
|
||||
///
|
||||
|
@ -871,12 +865,12 @@ pub enum XdgRequest<U, R, SD> {
|
|||
/// client as to how its popup should be
|
||||
NewPopup {
|
||||
/// the surface
|
||||
surface: PopupSurface<U, R, SD>,
|
||||
surface: PopupSurface<R, SD>,
|
||||
},
|
||||
/// The client requested the start of an interactive move for this surface
|
||||
Move {
|
||||
/// the surface
|
||||
surface: ToplevelSurface<U, R, SD>,
|
||||
surface: ToplevelSurface<R, SD>,
|
||||
/// the seat associated to this move
|
||||
seat: wl_seat::WlSeat,
|
||||
/// 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
|
||||
Resize {
|
||||
/// The surface
|
||||
surface: ToplevelSurface<U, R, SD>,
|
||||
surface: ToplevelSurface<R, SD>,
|
||||
/// The seat associated with this resize
|
||||
seat: wl_seat::WlSeat,
|
||||
/// The grab serial
|
||||
|
@ -899,7 +893,7 @@ pub enum XdgRequest<U, R, SD> {
|
|||
/// the grab area.
|
||||
Grab {
|
||||
/// The surface
|
||||
surface: PopupSurface<U, R, SD>,
|
||||
surface: PopupSurface<R, SD>,
|
||||
/// The seat to grab
|
||||
seat: wl_seat::WlSeat,
|
||||
/// The grab serial
|
||||
|
@ -908,29 +902,29 @@ pub enum XdgRequest<U, R, SD> {
|
|||
/// A toplevel surface requested to be maximized
|
||||
Maximize {
|
||||
/// The surface
|
||||
surface: ToplevelSurface<U, R, SD>,
|
||||
surface: ToplevelSurface<R, SD>,
|
||||
},
|
||||
/// A toplevel surface requested to stop being maximized
|
||||
UnMaximize {
|
||||
/// The surface
|
||||
surface: ToplevelSurface<U, R, SD>,
|
||||
surface: ToplevelSurface<R, SD>,
|
||||
},
|
||||
/// A toplevel surface requested to be set fullscreen
|
||||
Fullscreen {
|
||||
/// The surface
|
||||
surface: ToplevelSurface<U, R, SD>,
|
||||
surface: ToplevelSurface<R, SD>,
|
||||
/// The output (if any) on which the fullscreen is requested
|
||||
output: Option<wl_output::WlOutput>,
|
||||
},
|
||||
/// A toplevel surface request to stop being fullscreen
|
||||
UnFullscreen {
|
||||
/// The surface
|
||||
surface: ToplevelSurface<U, R, SD>,
|
||||
surface: ToplevelSurface<R, SD>,
|
||||
},
|
||||
/// A toplevel surface requested to be minimized
|
||||
Minimize {
|
||||
/// 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
|
||||
///
|
||||
|
@ -938,7 +932,7 @@ pub enum XdgRequest<U, R, SD> {
|
|||
/// control of the window (maximize/minimize/close/move/etc...).
|
||||
ShowWindowMenu {
|
||||
/// The surface
|
||||
surface: ToplevelSurface<U, R, SD>,
|
||||
surface: ToplevelSurface<R, SD>,
|
||||
/// The seat associated with this input grab
|
||||
seat: wl_seat::WlSeat,
|
||||
/// the grab serial
|
||||
|
|
|
@ -14,17 +14,16 @@ use super::{
|
|||
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_data: &ShellData<U, R, SD>,
|
||||
shell_data: &ShellData<R, SD>,
|
||||
) -> xdg_wm_base::XdgWmBase
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: Default + 'static,
|
||||
{
|
||||
let shell = shell.implement_closure(
|
||||
wm_implementation::<U, R, SD>,
|
||||
wm_implementation::<R, SD>,
|
||||
None::<fn(_)>,
|
||||
ShellUserData {
|
||||
shell_data: shell_data.clone(),
|
||||
|
@ -42,15 +41,15 @@ where
|
|||
* xdg_shell
|
||||
*/
|
||||
|
||||
pub(crate) struct ShellUserData<U, R, SD> {
|
||||
shell_data: ShellData<U, R, SD>,
|
||||
pub(crate) struct ShellUserData<R, SD> {
|
||||
shell_data: ShellData<R, 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,
|
||||
token: CompositorToken<U, R>,
|
||||
) -> ShellClient<U, R, SD> {
|
||||
token: CompositorToken<R>,
|
||||
) -> ShellClient<R, SD> {
|
||||
ShellClient {
|
||||
kind: super::ShellClientKind::Xdg(resource.clone()),
|
||||
_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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + '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 {
|
||||
xdg_wm_base::Request::Destroy => {
|
||||
// all is handled by destructor
|
||||
|
@ -92,8 +90,8 @@ where
|
|||
return;
|
||||
}
|
||||
id.implement_closure(
|
||||
xdg_surface_implementation::<U, R, SD>,
|
||||
Some(destroy_surface::<U, R, SD>),
|
||||
xdg_surface_implementation::<R, SD>,
|
||||
Some(destroy_surface::<R, SD>),
|
||||
XdgSurfaceUserData {
|
||||
shell_data: data.shell_data.clone(),
|
||||
wl_surface: surface,
|
||||
|
@ -188,22 +186,18 @@ fn implement_positioner(
|
|||
* xdg_surface
|
||||
*/
|
||||
|
||||
struct XdgSurfaceUserData<U, R, SD> {
|
||||
shell_data: ShellData<U, R, SD>,
|
||||
struct XdgSurfaceUserData<R, SD> {
|
||||
shell_data: ShellData<R, SD>,
|
||||
wl_surface: wl_surface::WlSurface,
|
||||
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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = surface
|
||||
.as_ref()
|
||||
.user_data::<XdgSurfaceUserData<U, R, SD>>()
|
||||
.unwrap();
|
||||
let data = surface.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
|
||||
if !data.wl_surface.as_ref().is_alive() {
|
||||
// the wl_surface is destroyed, this means the client is not
|
||||
// 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?!");
|
||||
}
|
||||
|
||||
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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = xdg_surface
|
||||
.as_ref()
|
||||
.user_data::<XdgSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<XdgSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
match request {
|
||||
xdg_surface::Request::Destroy => {
|
||||
|
@ -253,8 +246,8 @@ where
|
|||
})
|
||||
.expect("xdg_surface exists but surface has not shell_surface role?!");
|
||||
let toplevel = id.implement_closure(
|
||||
toplevel_implementation::<U, R, SD>,
|
||||
Some(destroy_toplevel::<U, R, SD>),
|
||||
toplevel_implementation::<R, SD>,
|
||||
Some(destroy_toplevel::<R, SD>),
|
||||
ShellSurfaceUserData {
|
||||
shell_data: data.shell_data.clone(),
|
||||
wl_surface: data.wl_surface.clone(),
|
||||
|
@ -285,10 +278,7 @@ where
|
|||
.unwrap();
|
||||
|
||||
let parent_surface = parent.map(|parent| {
|
||||
let parent_data = parent
|
||||
.as_ref()
|
||||
.user_data::<XdgSurfaceUserData<U, R, SD>>()
|
||||
.unwrap();
|
||||
let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
|
||||
parent_data.wl_surface.clone()
|
||||
});
|
||||
data.shell_data
|
||||
|
@ -301,8 +291,8 @@ where
|
|||
})
|
||||
.expect("xdg_surface exists but surface has not shell_surface role?!");
|
||||
let popup = id.implement_closure(
|
||||
xg_popup_implementation::<U, R, SD>,
|
||||
Some(destroy_popup::<U, R, SD>),
|
||||
xg_popup_implementation::<R, SD>,
|
||||
Some(destroy_popup::<R, SD>),
|
||||
ShellSurfaceUserData {
|
||||
shell_data: data.shell_data.clone(),
|
||||
wl_surface: data.wl_surface.clone(),
|
||||
|
@ -360,27 +350,26 @@ where
|
|||
* xdg_toplevel
|
||||
*/
|
||||
|
||||
pub(crate) struct ShellSurfaceUserData<U, R, SD> {
|
||||
pub(crate) shell_data: ShellData<U, R, SD>,
|
||||
pub(crate) struct ShellSurfaceUserData<R, SD> {
|
||||
pub(crate) shell_data: ShellData<R, SD>,
|
||||
pub(crate) wl_surface: wl_surface::WlSurface,
|
||||
pub(crate) wm_base: xdg_wm_base::XdgWmBase,
|
||||
pub(crate) xdg_surface: xdg_surface::XdgSurface,
|
||||
}
|
||||
|
||||
// Utility functions allowing to factor out a lot of the upcoming logic
|
||||
fn with_surface_toplevel_data<U, R, SD, F>(
|
||||
shell_data: &ShellData<U, R, SD>,
|
||||
fn with_surface_toplevel_data<R, SD, F>(
|
||||
shell_data: &ShellData<R, SD>,
|
||||
toplevel: &xdg_toplevel::XdgToplevel,
|
||||
f: F,
|
||||
) where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
F: FnOnce(&mut ToplevelState),
|
||||
{
|
||||
let toplevel_data = toplevel
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
shell_data
|
||||
.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?!");
|
||||
}
|
||||
|
||||
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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = resource
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
let (width, height) = configure.size.unwrap_or((0, 0));
|
||||
// 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?!");
|
||||
}
|
||||
|
||||
fn make_toplevel_handle<U: 'static, R: 'static, SD: 'static>(
|
||||
fn make_toplevel_handle<R: 'static, SD: 'static>(
|
||||
resource: &xdg_toplevel::XdgToplevel,
|
||||
) -> super::ToplevelSurface<U, R, SD> {
|
||||
) -> super::ToplevelSurface<R, SD> {
|
||||
let data = resource
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
super::ToplevelSurface {
|
||||
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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = toplevel
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
match request {
|
||||
xdg_toplevel::Request::Destroy => {
|
||||
|
@ -455,7 +442,7 @@ where
|
|||
toplevel_data.parent = parent.map(|toplevel_surface_parent| {
|
||||
toplevel_surface_parent
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap()
|
||||
.wl_surface
|
||||
.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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = toplevel
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
if !data.wl_surface.as_ref().is_alive() {
|
||||
// the wl_surface is destroyed, this means the client is not
|
||||
|
@ -580,15 +566,14 @@ where
|
|||
* 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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = resource
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
let (x, y) = configure.position;
|
||||
let (width, height) = configure.size;
|
||||
|
@ -602,12 +587,10 @@ where
|
|||
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
|
||||
}
|
||||
|
||||
fn make_popup_handle<U: 'static, R: 'static, SD: 'static>(
|
||||
resource: &xdg_popup::XdgPopup,
|
||||
) -> super::PopupSurface<U, R, SD> {
|
||||
fn make_popup_handle<R: 'static, SD: 'static>(resource: &xdg_popup::XdgPopup) -> super::PopupSurface<R, SD> {
|
||||
let data = resource
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
super::PopupSurface {
|
||||
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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = popup
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.unwrap();
|
||||
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
|
||||
match request {
|
||||
xdg_popup::Request::Destroy => {
|
||||
// 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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = popup
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.unwrap();
|
||||
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
|
||||
if !data.wl_surface.as_ref().is_alive() {
|
||||
// the wl_surface is destroyed, this means the client is not
|
||||
// trying to change the role but it's a cleanup (possibly a
|
||||
|
|
|
@ -17,17 +17,16 @@ use super::{
|
|||
XdgSurfacePendingState, XdgSurfaceRole,
|
||||
};
|
||||
|
||||
pub(crate) fn implement_shell<U, R, SD>(
|
||||
pub(crate) fn implement_shell<R, SD>(
|
||||
shell: NewResource<zxdg_shell_v6::ZxdgShellV6>,
|
||||
shell_data: &ShellData<U, R, SD>,
|
||||
shell_data: &ShellData<R, SD>,
|
||||
) -> zxdg_shell_v6::ZxdgShellV6
|
||||
where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: Default + 'static,
|
||||
{
|
||||
let shell = shell.implement_closure(
|
||||
shell_implementation::<U, R, SD>,
|
||||
shell_implementation::<R, SD>,
|
||||
None::<fn(_)>,
|
||||
ShellUserData {
|
||||
shell_data: shell_data.clone(),
|
||||
|
@ -45,15 +44,15 @@ where
|
|||
* xdg_shell
|
||||
*/
|
||||
|
||||
pub(crate) struct ShellUserData<U, R, SD> {
|
||||
shell_data: ShellData<U, R, SD>,
|
||||
pub(crate) struct ShellUserData<R, SD> {
|
||||
shell_data: ShellData<R, 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,
|
||||
token: CompositorToken<U, R>,
|
||||
) -> ShellClient<U, R, SD> {
|
||||
token: CompositorToken<R>,
|
||||
) -> ShellClient<R, SD> {
|
||||
ShellClient {
|
||||
kind: super::ShellClientKind::ZxdgV6(resource.clone()),
|
||||
_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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + '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 {
|
||||
zxdg_shell_v6::Request::Destroy => {
|
||||
// all is handled by destructor
|
||||
|
@ -95,8 +93,8 @@ where
|
|||
return;
|
||||
}
|
||||
id.implement_closure(
|
||||
xdg_surface_implementation::<U, R, SD>,
|
||||
Some(destroy_surface::<U, R, SD>),
|
||||
xdg_surface_implementation::<R, SD>,
|
||||
Some(destroy_surface::<R, SD>),
|
||||
XdgSurfaceUserData {
|
||||
shell_data: data.shell_data.clone(),
|
||||
wl_surface: surface.clone(),
|
||||
|
@ -205,22 +203,18 @@ fn implement_positioner(
|
|||
* xdg_surface
|
||||
*/
|
||||
|
||||
struct XdgSurfaceUserData<U, R, SD> {
|
||||
shell_data: ShellData<U, R, SD>,
|
||||
struct XdgSurfaceUserData<R, SD> {
|
||||
shell_data: ShellData<R, SD>,
|
||||
wl_surface: wl_surface::WlSurface,
|
||||
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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = surface
|
||||
.as_ref()
|
||||
.user_data::<XdgSurfaceUserData<U, R, SD>>()
|
||||
.unwrap();
|
||||
let data = surface.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
|
||||
if !data.wl_surface.as_ref().is_alive() {
|
||||
// the wl_surface is destroyed, this means the client is not
|
||||
// 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?!");
|
||||
}
|
||||
|
||||
fn xdg_surface_implementation<U, R, SD>(
|
||||
fn xdg_surface_implementation<R, SD>(
|
||||
request: zxdg_surface_v6::Request,
|
||||
xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6,
|
||||
) where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = xdg_surface
|
||||
.as_ref()
|
||||
.user_data::<XdgSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<XdgSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
match request {
|
||||
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?!");
|
||||
let toplevel = id.implement_closure(
|
||||
toplevel_implementation::<U, R, SD>,
|
||||
Some(destroy_toplevel::<U, R, SD>),
|
||||
toplevel_implementation::<R, SD>,
|
||||
Some(destroy_toplevel::<R, SD>),
|
||||
ShellSurfaceUserData {
|
||||
shell_data: data.shell_data.clone(),
|
||||
wl_surface: data.wl_surface.clone(),
|
||||
|
@ -303,10 +296,7 @@ fn xdg_surface_implementation<U, R, SD>(
|
|||
.user_data::<RefCell<PositionerState>>()
|
||||
.unwrap();
|
||||
|
||||
let parent_data = parent
|
||||
.as_ref()
|
||||
.user_data::<XdgSurfaceUserData<U, R, SD>>()
|
||||
.unwrap();
|
||||
let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
|
||||
data.shell_data
|
||||
.compositor_token
|
||||
.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?!");
|
||||
let popup = id.implement_closure(
|
||||
popup_implementation::<U, R, SD>,
|
||||
Some(destroy_popup::<U, R, SD>),
|
||||
popup_implementation::<R, SD>,
|
||||
Some(destroy_popup::<R, SD>),
|
||||
ShellSurfaceUserData {
|
||||
shell_data: data.shell_data.clone(),
|
||||
wl_surface: data.wl_surface.clone(),
|
||||
|
@ -376,24 +366,23 @@ fn xdg_surface_implementation<U, R, SD>(
|
|||
* xdg_toplevel
|
||||
*/
|
||||
|
||||
pub struct ShellSurfaceUserData<U, R, SD> {
|
||||
pub(crate) shell_data: ShellData<U, R, SD>,
|
||||
pub struct ShellSurfaceUserData<R, SD> {
|
||||
pub(crate) shell_data: ShellData<R, SD>,
|
||||
pub(crate) wl_surface: wl_surface::WlSurface,
|
||||
pub(crate) shell: zxdg_shell_v6::ZxdgShellV6,
|
||||
pub(crate) xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6,
|
||||
}
|
||||
|
||||
// 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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
F: FnOnce(&mut ToplevelState),
|
||||
{
|
||||
let data = toplevel
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
data.shell_data
|
||||
.compositor_token
|
||||
|
@ -404,17 +393,16 @@ where
|
|||
.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,
|
||||
configure: ToplevelConfigure,
|
||||
) where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = resource
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
let (width, height) = configure.size.unwrap_or((0, 0));
|
||||
// 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?!");
|
||||
}
|
||||
|
||||
fn make_toplevel_handle<U: 'static, R: 'static, SD: 'static>(
|
||||
fn make_toplevel_handle<R: 'static, SD: 'static>(
|
||||
resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
|
||||
) -> super::ToplevelSurface<U, R, SD> {
|
||||
) -> super::ToplevelSurface<R, SD> {
|
||||
let data = resource
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
super::ToplevelSurface {
|
||||
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,
|
||||
toplevel: zxdg_toplevel_v6::ZxdgToplevelV6,
|
||||
) where
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = toplevel
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
match request {
|
||||
zxdg_toplevel_v6::Request::Destroy => {
|
||||
// all it done by the destructor
|
||||
}
|
||||
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| {
|
||||
let parent_data = toplevel_surface_parent
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
parent_data.wl_surface.clone()
|
||||
})
|
||||
});
|
||||
}
|
||||
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;
|
||||
});
|
||||
}
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
@ -520,12 +507,12 @@ fn toplevel_implementation<U, R, SD>(
|
|||
});
|
||||
}
|
||||
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);
|
||||
});
|
||||
}
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
@ -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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = toplevel
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
if !data.wl_surface.as_ref().is_alive() {
|
||||
// the wl_surface is destroyed, this means the client is not
|
||||
|
@ -597,15 +583,14 @@ where
|
|||
* 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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = resource
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
let (x, y) = configure.position;
|
||||
let (width, height) = configure.size;
|
||||
|
@ -619,12 +604,12 @@ where
|
|||
.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,
|
||||
) -> super::PopupSurface<U, R, SD> {
|
||||
) -> super::PopupSurface<R, SD> {
|
||||
let data = resource
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.user_data::<ShellSurfaceUserData<R, SD>>()
|
||||
.unwrap();
|
||||
super::PopupSurface {
|
||||
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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = popup
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.unwrap();
|
||||
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
|
||||
match request {
|
||||
zxdg_popup_v6::Request::Destroy => {
|
||||
// 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
|
||||
U: 'static,
|
||||
R: Role<XdgSurfaceRole> + 'static,
|
||||
SD: 'static,
|
||||
{
|
||||
let data = popup
|
||||
.as_ref()
|
||||
.user_data::<ShellSurfaceUserData<U, R, SD>>()
|
||||
.unwrap();
|
||||
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
|
||||
if !data.wl_surface.as_ref().is_alive() {
|
||||
// the wl_surface is destroyed, this means the client is not
|
||||
// trying to change the role but it's a cleanup (possibly a
|
||||
|
|
Loading…
Reference in New Issue