Update wayland-rs to 0.25 (#171)

Update wayland-rs to 0.25 and calloop to 0.5

Co-authored-by: Victor Berger <victor.berger@m4x.org>
This commit is contained in:
Jonas Platte 2020-04-05 19:01:08 +02:00 committed by GitHub
parent fbe20d6c1f
commit b8c20ebf30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 1241 additions and 1008 deletions

View File

@ -11,10 +11,10 @@ edition = "2018"
members = [ "anvil" ] members = [ "anvil" ]
[dependencies] [dependencies]
wayland-server = { version = "0.23.4", optional = true } wayland-server = { version = "0.25.0", optional = true }
wayland-commons = { version = "0.23.4", optional = true } wayland-commons = { version = "0.25.0", optional = true }
wayland-sys = { version = "0.23.4", optional = true } wayland-sys = { version = "0.25.0", optional = true }
calloop = "0.4.2" calloop = "0.5.1"
bitflags = "1" bitflags = "1"
nix = "0.13" nix = "0.13"
xkbcommon = "0.4.0" xkbcommon = "0.4.0"
@ -31,7 +31,7 @@ input = { version = "0.4.1", optional = true }
udev = { version = "0.2.0", optional = true } udev = { version = "0.2.0", optional = true }
dbus = { version = "0.8", optional = true } dbus = { version = "0.8", optional = true }
systemd = { version = "0.4.0", optional = true } systemd = { version = "0.4.0", optional = true }
wayland-protocols = { version = "0.23.4", features = ["unstable_protocols", "server"], optional = true } wayland-protocols = { version = "0.25.0", features = ["unstable_protocols", "server"], optional = true }
image = { version = "0.21.0", optional = true } image = { version = "0.21.0", optional = true }
error-chain = "0.12.0" error-chain = "0.12.0"
lazy_static = "1.0.0" lazy_static = "1.0.0"
@ -44,7 +44,7 @@ gl_generator = { version = "0.10", optional = true }
[features] [features]
default = ["backend_winit", "backend_drm_legacy", "backend_drm_gbm", "backend_drm_egl", "backend_libinput", "backend_udev", "backend_session", "renderer_glium", "xwayland", "wayland_frontend"] default = ["backend_winit", "backend_drm_legacy", "backend_drm_gbm", "backend_drm_egl", "backend_libinput", "backend_udev", "backend_session", "renderer_glium", "xwayland", "wayland_frontend"]
backend_winit = ["winit", "wayland-server/dlopen", "wayland-client/dlopen", "backend_egl", "renderer_gl", "native_lib"] backend_winit = ["winit", "wayland-server/dlopen", "wayland-client/dlopen", "backend_egl", "renderer_gl", "use_system_lib"]
backend_drm = ["drm"] backend_drm = ["drm"]
backend_drm_legacy = ["backend_drm"] backend_drm_legacy = ["backend_drm"]
backend_drm_gbm = ["backend_drm", "gbm", "image"] backend_drm_gbm = ["backend_drm", "gbm", "image"]
@ -56,7 +56,7 @@ backend_udev = ["udev"]
backend_session_logind = ["dbus", "systemd", "backend_session"] backend_session_logind = ["dbus", "systemd", "backend_session"]
renderer_gl = ["gl_generator"] renderer_gl = ["gl_generator"]
renderer_glium = ["renderer_gl", "glium"] renderer_glium = ["renderer_gl", "glium"]
native_lib = ["wayland_frontend", "wayland-sys", "wayland-server/native_lib"] use_system_lib = ["wayland_frontend", "wayland-sys", "wayland-server/use_system_lib"]
wayland_frontend = ["wayland-server", "wayland-commons", "wayland-protocols"] wayland_frontend = ["wayland-server", "wayland-commons", "wayland-protocols"]
xwayland = ["wayland_frontend"] xwayland = ["wayland_frontend"]

View File

@ -12,7 +12,7 @@ slog-term = "2.3"
slog-async = "2.2" slog-async = "2.2"
rand = "0.6" rand = "0.6"
glium = { version = "0.23.0", default-features = false } glium = { version = "0.23.0", default-features = false }
wayland-server = "0.23" wayland-server = "0.25.0"
xkbcommon = "0.4.0" xkbcommon = "0.4.0"
bitflags = "1.2.1" bitflags = "1.2.1"
@ -26,7 +26,7 @@ gl_generator = "0.10"
[features] [features]
default = [ "winit", "egl", "udev" ] default = [ "winit", "egl", "udev" ]
egl = [ "smithay/native_lib" ] egl = [ "smithay/use_system_lib" ]
winit = [ "smithay/backend_winit" ] winit = [ "smithay/backend_winit" ]
udev = [ "smithay/backend_libinput", "smithay/backend_drm_legacy", "smithay/backend_drm_gbm", "smithay/backend_drm_egl", "smithay/backend_udev", "smithay/backend_session" ] udev = [ "smithay/backend_libinput", "smithay/backend_drm_legacy", "smithay/backend_drm_gbm", "smithay/backend_drm_egl", "smithay/backend_udev", "smithay/backend_session" ]
logind = [ "smithay/backend_session_logind" ] logind = [ "smithay/backend_session_logind" ]

View File

@ -299,7 +299,8 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
location, location,
|_surface, attributes, role, &(mut x, mut y)| { |_surface, attributes, role, &(mut x, mut y)| {
// Pull a new buffer if available // Pull a new buffer if available
if let Some(data) = attributes.user_data.get_mut::<SurfaceData>() { if let Some(data) = attributes.user_data.get::<RefCell<SurfaceData>>() {
let mut data = data.borrow_mut();
if data.texture.is_none() { if data.texture.is_none() {
if let Some(buffer) = data.buffer.take() { if let Some(buffer) = data.buffer.take() {
if let Ok(m) = self.texture_from_buffer(buffer.clone()) { if let Ok(m) = self.texture_from_buffer(buffer.clone()) {
@ -341,8 +342,8 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
} }
}, },
|_surface, attributes, role, &(mut x, mut y)| { |_surface, attributes, role, &(mut x, mut y)| {
if let Some(ref data) = attributes.user_data.get::<SurfaceData>() { if let Some(ref data) = attributes.user_data.get::<RefCell<SurfaceData>>() {
if let Some(ref metadata) = data.texture { if let Some(ref metadata) = data.borrow().texture {
// we need to re-extract the subsurface offset, as the previous closure // we need to re-extract the subsurface offset, as the previous closure
// only passes it to our children // only passes it to our children
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) { if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {

View File

@ -8,7 +8,7 @@ extern crate slog;
extern crate smithay; extern crate smithay;
use slog::Drain; use slog::Drain;
use smithay::reexports::{calloop::EventLoop, wayland_server::Display}; use smithay::reexports::{calloop::{EventLoop, generic::Generic, mio::Interest}, wayland_server::Display};
#[macro_use] #[macro_use]
mod shaders; mod shaders;
@ -30,6 +30,20 @@ static POSSIBLE_BACKENDS: &[&str] = &[
"--tty-udev : Run anvil as a tty udev client (requires root if without logind).", "--tty-udev : Run anvil as a tty udev client (requires root if without logind).",
]; ];
pub struct AnvilState {
pub need_wayland_dispatch: bool,
pub running: bool,
}
impl Default for AnvilState {
fn default() -> AnvilState {
AnvilState {
need_wayland_dispatch: false,
running: true,
}
}
}
fn main() { fn main() {
// A logger facility, here we use the terminal here // A logger facility, here we use the terminal here
let log = slog::Logger::root( let log = slog::Logger::root(
@ -37,8 +51,16 @@ fn main() {
o!(), o!(),
); );
let mut event_loop = EventLoop::<()>::new().unwrap(); let mut event_loop = EventLoop::<AnvilState>::new().unwrap();
let mut display = Display::new(event_loop.handle()); let mut display = Display::new();
// Glue for event dispatching
let mut wayland_event_source = Generic::from_raw_fd(display.get_poll_fd());
wayland_event_source.set_interest(Interest::READABLE);
let _wayland_source = event_loop.handle().insert_source(
wayland_event_source,
|_, state: &mut AnvilState| { state.need_wayland_dispatch = true; }
);
let arg = ::std::env::args().nth(1); let arg = ::std::env::args().nth(1);
match arg.as_ref().map(|s| &s[..]) { match arg.as_ref().map(|s| &s[..]) {

View File

@ -187,7 +187,7 @@ impl PointerGrab for ResizeSurfaceGrab {
let (min_size, max_size) = let (min_size, max_size) =
self.ctoken self.ctoken
.with_surface_data(self.toplevel.get_surface().unwrap(), |attrs| { .with_surface_data(self.toplevel.get_surface().unwrap(), |attrs| {
let data = attrs.user_data.get::<SurfaceData>().unwrap(); let data = attrs.user_data.get::<RefCell<SurfaceData>>().unwrap().borrow();
(data.min_size, data.max_size) (data.min_size, data.max_size)
}); });
@ -245,7 +245,7 @@ impl PointerGrab for ResizeSurfaceGrab {
self.ctoken self.ctoken
.with_surface_data(self.toplevel.get_surface().unwrap(), |attrs| { .with_surface_data(self.toplevel.get_surface().unwrap(), |attrs| {
let data = attrs.user_data.get_mut::<SurfaceData>().unwrap(); let mut data = attrs.user_data.get::<RefCell<SurfaceData>>().unwrap().borrow_mut();
if let ResizeState::Resizing(resize_data) = data.resize_state { if let ResizeState::Resizing(resize_data) = data.resize_state {
data.resize_state = ResizeState::WaitingForFinalAck(resize_data, serial); data.resize_state = ResizeState::WaitingForFinalAck(resize_data, serial);
} else { } else {
@ -255,7 +255,7 @@ impl PointerGrab for ResizeSurfaceGrab {
} else { } else {
self.ctoken self.ctoken
.with_surface_data(self.toplevel.get_surface().unwrap(), |attrs| { .with_surface_data(self.toplevel.get_surface().unwrap(), |attrs| {
let data = attrs.user_data.get_mut::<SurfaceData>().unwrap(); let mut data = attrs.user_data.get::<RefCell<SurfaceData>>().unwrap().borrow_mut();
if let ResizeState::Resizing(resize_data) = data.resize_state { if let ResizeState::Resizing(resize_data) = data.resize_state {
data.resize_state = ResizeState::WaitingForCommit(resize_data); data.resize_state = ResizeState::WaitingForCommit(resize_data);
} else { } else {
@ -298,9 +298,10 @@ pub fn init_shell(
let window_map = window_map.as_ref().unwrap(); let window_map = window_map.as_ref().unwrap();
surface_commit(&surface, ctoken, &buffer_utils, &*window_map) surface_commit(&surface, ctoken, &buffer_utils, &*window_map)
} }
SurfaceEvent::Frame { callback } => callback SurfaceEvent::Frame { callback } => {
.implement_closure(|_, _| unreachable!(), None::<fn(_)>, ()) callback.quick_assign(|_, _, _| unreachable!());
.done(0), callback.done(0)
}
}, },
log.clone(), log.clone(),
); );
@ -413,7 +414,7 @@ pub fn init_shell(
let initial_window_size = (geometry.width, geometry.height); let initial_window_size = (geometry.width, geometry.height);
compositor_token.with_surface_data(surface.get_surface().unwrap(), move |attrs| { compositor_token.with_surface_data(surface.get_surface().unwrap(), move |attrs| {
attrs.user_data.get_mut::<SurfaceData>().unwrap().resize_state = attrs.user_data.get::<RefCell<SurfaceData>>().unwrap().borrow_mut().resize_state =
ResizeState::Resizing(ResizeData { ResizeState::Resizing(ResizeData {
edges: edges.into(), edges: edges.into(),
initial_window_location, initial_window_location,
@ -434,8 +435,8 @@ pub fn init_shell(
} }
XdgRequest::AckConfigure { surface, .. } => { XdgRequest::AckConfigure { surface, .. } => {
let waiting_for_serial = compositor_token.with_surface_data(&surface, |attrs| { let waiting_for_serial = compositor_token.with_surface_data(&surface, |attrs| {
if let Some(data) = attrs.user_data.get_mut::<SurfaceData>() { if let Some(data) = attrs.user_data.get::<RefCell<SurfaceData>>() {
if let ResizeState::WaitingForFinalAck(_, serial) = data.resize_state { if let ResizeState::WaitingForFinalAck(_, serial) = data.borrow().resize_state {
return Some(serial); return Some(serial);
} }
} }
@ -452,7 +453,7 @@ pub fn init_shell(
if acked { if acked {
compositor_token.with_surface_data(&surface, |attrs| { compositor_token.with_surface_data(&surface, |attrs| {
let data = attrs.user_data.get_mut::<SurfaceData>().unwrap(); let mut data = attrs.user_data.get::<RefCell<SurfaceData>>().unwrap().borrow_mut();
if let ResizeState::WaitingForFinalAck(resize_data, _) = data.resize_state { if let ResizeState::WaitingForFinalAck(resize_data, _) = data.resize_state {
data.resize_state = ResizeState::WaitingForCommit(resize_data); data.resize_state = ResizeState::WaitingForCommit(resize_data);
} else { } else {
@ -565,7 +566,7 @@ pub fn init_shell(
let initial_window_size = (geometry.width, geometry.height); let initial_window_size = (geometry.width, geometry.height);
compositor_token.with_surface_data(surface.get_surface().unwrap(), move |attrs| { compositor_token.with_surface_data(surface.get_surface().unwrap(), move |attrs| {
attrs.user_data.get_mut::<SurfaceData>().unwrap().resize_state = attrs.user_data.get::<RefCell<SurfaceData>>().unwrap().borrow_mut().resize_state =
ResizeState::Resizing(ResizeData { ResizeState::Resizing(ResizeData {
edges: edges.into(), edges: edges.into(),
initial_window_location, initial_window_location,
@ -697,8 +698,8 @@ fn surface_commit(
}); });
let refresh = token.with_surface_data(surface, |attributes| { let refresh = token.with_surface_data(surface, |attributes| {
attributes.user_data.insert_if_missing(SurfaceData::default); attributes.user_data.insert_if_missing(|| RefCell::new(SurfaceData::default()));
let data = attributes.user_data.get_mut::<SurfaceData>().unwrap(); let mut data = attributes.user_data.get::<RefCell<SurfaceData>>().unwrap().borrow_mut();
data.geometry = geometry; data.geometry = geometry;
data.input_region = attributes.input_region.clone(); data.input_region = attributes.input_region.clone();
@ -738,7 +739,7 @@ fn surface_commit(
let Rectangle { width, height, .. } = window_map.geometry(&toplevel).unwrap(); let Rectangle { width, height, .. } = window_map.geometry(&toplevel).unwrap();
let new_location = token.with_surface_data(surface, |attributes| { let new_location = token.with_surface_data(surface, |attributes| {
let data = attributes.user_data.get_mut::<SurfaceData>().unwrap(); let mut data = attributes.user_data.get::<RefCell<SurfaceData>>().unwrap().borrow_mut();
let mut new_location = None; let mut new_location = None;

View File

@ -35,6 +35,10 @@ use smithay::{
udev::{primary_gpu, udev_backend_bind, UdevBackend, UdevHandler}, udev::{primary_gpu, udev_backend_bind, UdevBackend, UdevHandler},
}, },
reexports::{ reexports::{
calloop::{
generic::{SourceFd, Generic},
EventLoop, LoopHandle, Source,
},
drm::control::{ drm::control::{
connector::{Info as ConnectorInfo, State as ConnectorState}, connector::{Info as ConnectorInfo, State as ConnectorState},
crtc, crtc,
@ -44,10 +48,6 @@ use smithay::{
input::Libinput, input::Libinput,
nix::{fcntl::OFlag, sys::stat::dev_t}, nix::{fcntl::OFlag, sys::stat::dev_t},
wayland_server::{ wayland_server::{
calloop::{
generic::{EventedFd, Generic},
EventLoop, LoopHandle, Source,
},
protocol::{wl_output, wl_surface}, protocol::{wl_output, wl_surface},
Display, Display,
}, },
@ -65,6 +65,7 @@ use crate::buffer_utils::BufferUtils;
use crate::glium_drawer::GliumDrawer; use crate::glium_drawer::GliumDrawer;
use crate::input_handler::AnvilInputHandler; use crate::input_handler::AnvilInputHandler;
use crate::shell::{init_shell, MyWindowMap, Roles}; use crate::shell::{init_shell, MyWindowMap, Roles};
use crate::AnvilState;
pub struct SessionFd(RawFd); pub struct SessionFd(RawFd);
impl AsRawFd for SessionFd { impl AsRawFd for SessionFd {
@ -78,7 +79,7 @@ type RenderDevice =
type RenderSurface = type RenderSurface =
EglSurface<EglGbmBackend<LegacyDrmDevice<SessionFd>>, GbmDevice<LegacyDrmDevice<SessionFd>>>; EglSurface<EglGbmBackend<LegacyDrmDevice<SessionFd>>, GbmDevice<LegacyDrmDevice<SessionFd>>>;
pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger) -> Result<(), ()> { pub fn run_udev(mut display: Display, mut event_loop: EventLoop<AnvilState>, log: Logger) -> Result<(), ()> {
let name = display.add_socket_auto().unwrap().into_string().unwrap(); let name = display.add_socket_auto().unwrap().into_string().unwrap();
info!(log, "Listening on wayland socket"; "name" => name.clone()); info!(log, "Listening on wayland socket"; "name" => name.clone());
::std::env::set_var("WAYLAND_DISPLAY", name); ::std::env::set_var("WAYLAND_DISPLAY", name);
@ -253,14 +254,19 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger
/* /*
* And run our loop * And run our loop
*/ */
let mut state = AnvilState::default();
while running.load(Ordering::SeqCst) { while running.load(Ordering::SeqCst) {
if event_loop if event_loop
.dispatch(Some(::std::time::Duration::from_millis(16)), &mut ()) .dispatch(Some(::std::time::Duration::from_millis(16)), &mut state)
.is_err() .is_err()
{ {
running.store(false, Ordering::SeqCst); running.store(false, Ordering::SeqCst);
} else { } else {
display.borrow_mut().flush_clients(); if state.need_wayland_dispatch {
display.borrow_mut().dispatch(std::time::Duration::from_millis(0), &mut state);
}
display.borrow_mut().flush_clients(&mut state);
window_map.borrow_mut().refresh(); window_map.borrow_mut().refresh();
} }
} }
@ -287,7 +293,7 @@ struct UdevHandlerImpl<S: SessionNotifier, Data: 'static> {
dev_t, dev_t,
( (
S::Id, S::Id,
Source<Generic<EventedFd<RenderDevice>>>, Source<Generic<SourceFd<RenderDevice>>>,
Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<RenderSurface>>>>, Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<RenderSurface>>>>,
), ),
>, >,

View File

@ -87,7 +87,7 @@ where
wl_surface, wl_surface,
self.location, self.location,
|wl_surface, attributes, role, &(mut x, mut y)| { |wl_surface, attributes, role, &(mut x, mut y)| {
let data = attributes.user_data.get::<SurfaceData>(); let data = attributes.user_data.get::<RefCell<SurfaceData>>();
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) { if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
x += subdata.location.0; x += subdata.location.0;
@ -96,7 +96,7 @@ where
let surface_local_point = (point.0 - x as f64, point.1 - y as f64); let surface_local_point = (point.0 - x as f64, point.1 - y as f64);
if data if data
.map(|data| data.contains_point(surface_local_point)) .map(|data| data.borrow().contains_point(surface_local_point))
.unwrap_or(false) .unwrap_or(false)
{ {
*found.borrow_mut() = Some((wl_surface.clone(), (x as f64, y as f64))); *found.borrow_mut() = Some((wl_surface.clone(), (x as f64, y as f64)));
@ -122,9 +122,9 @@ where
wl_surface, wl_surface,
(base_x, base_y), (base_x, base_y),
|_, attributes, role, &(mut x, mut y)| { |_, attributes, role, &(mut x, mut y)| {
let data = attributes.user_data.get::<SurfaceData>(); let data = attributes.user_data.get::<RefCell<SurfaceData>>();
if let Some((w, h)) = data.and_then(SurfaceData::size) { if let Some((w, h)) = data.and_then(|d| d.borrow().size()) {
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) { if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
x += subdata.location.0; x += subdata.location.0;
y += subdata.location.1; y += subdata.location.1;
@ -160,7 +160,7 @@ where
// It's the set geometry with the full bounding box as the fallback. // It's the set geometry with the full bounding box as the fallback.
ctoken ctoken
.with_surface_data(self.toplevel.get_surface().unwrap(), |attributes| { .with_surface_data(self.toplevel.get_surface().unwrap(), |attributes| {
attributes.user_data.get::<SurfaceData>().unwrap().geometry attributes.user_data.get::<RefCell<SurfaceData>>().unwrap().borrow().geometry
}) })
.unwrap_or(self.bbox) .unwrap_or(self.bbox)
} }

View File

@ -27,8 +27,9 @@ use crate::buffer_utils::BufferUtils;
use crate::glium_drawer::GliumDrawer; use crate::glium_drawer::GliumDrawer;
use crate::input_handler::AnvilInputHandler; use crate::input_handler::AnvilInputHandler;
use crate::shell::init_shell; use crate::shell::init_shell;
use crate::AnvilState;
pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop<()>, log: Logger) -> Result<(), ()> { pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop<AnvilState>, log: Logger) -> Result<(), ()> {
let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?; let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?;
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
@ -187,13 +188,18 @@ pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop<()>, log: Log
} }
} }
let mut state = AnvilState::default();
if event_loop if event_loop
.dispatch(Some(::std::time::Duration::from_millis(16)), &mut ()) .dispatch(Some(::std::time::Duration::from_millis(16)), &mut state)
.is_err() .is_err()
{ {
running.store(false, Ordering::SeqCst); running.store(false, Ordering::SeqCst);
} else { } else {
display.flush_clients(); if state.need_wayland_dispatch {
display.dispatch(std::time::Duration::from_millis(0), &mut state);
}
display.flush_clients(&mut state);
window_map.borrow_mut().refresh(); window_map.borrow_mut().refresh();
} }
} }

View File

@ -12,7 +12,7 @@ use drm::control::{crtc, ResourceHandles, ResourceInfo};
use nix::libc::dev_t; use nix::libc::dev_t;
use std::os::unix::io::{AsRawFd, RawFd}; use std::os::unix::io::{AsRawFd, RawFd};
use std::rc::Rc; use std::rc::Rc;
#[cfg(feature = "native_lib")] #[cfg(feature = "use_system_lib")]
use wayland_server::Display; use wayland_server::Display;
use super::{Device, DeviceHandler, Surface}; use super::{Device, DeviceHandler, Surface};
@ -20,7 +20,7 @@ use crate::backend::egl::context::GlAttributes;
use crate::backend::egl::error::Result as EGLResult; use crate::backend::egl::error::Result as EGLResult;
use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface}; use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface};
use crate::backend::egl::EGLContext; use crate::backend::egl::EGLContext;
#[cfg(feature = "native_lib")] #[cfg(feature = "use_system_lib")]
use crate::backend::egl::{EGLDisplay, EGLGraphicsBackend}; use crate::backend::egl::{EGLDisplay, EGLGraphicsBackend};
pub mod error; pub mod error;
@ -181,7 +181,7 @@ where
} }
} }
#[cfg(feature = "native_lib")] #[cfg(feature = "use_system_lib")]
impl<B, D> EGLGraphicsBackend for EglDevice<B, D> impl<B, D> EGLGraphicsBackend for EglDevice<B, D>
where where
B: Backend<Surface = <D as Device>::Surface> + 'static, B: Backend<Surface = <D as Device>::Surface> + 'static,

View File

@ -46,8 +46,8 @@ use std::iter::IntoIterator;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::path::PathBuf; use std::path::PathBuf;
use calloop::generic::{EventedFd, Generic}; use calloop::generic::{SourceFd, Generic};
use calloop::mio::Ready; use calloop::mio::Interest;
use calloop::InsertError; use calloop::InsertError;
use calloop::{LoopHandle, Source}; use calloop::{LoopHandle, Source};
@ -229,13 +229,13 @@ impl<A: AsRawFd> DevPath for A {
pub fn device_bind<D: Device + 'static, Data>( pub fn device_bind<D: Device + 'static, Data>(
handle: &LoopHandle<Data>, handle: &LoopHandle<Data>,
device: D, device: D,
) -> ::std::result::Result<Source<Generic<EventedFd<D>>>, InsertError<Generic<EventedFd<D>>>> ) -> ::std::result::Result<Source<Generic<SourceFd<D>>>, InsertError<Generic<SourceFd<D>>>>
where where
D: Device, D: Device,
Data: 'static, Data: 'static,
{ {
let mut source = Generic::from_fd_source(device); let mut source = Generic::from_fd_source(device);
source.set_interest(Ready::readable()); source.set_interest(Interest::READABLE);
handle.insert_source(source, |evt, _| { handle.insert_source(source, |evt, _| {
evt.source.borrow_mut().0.process_events(); evt.source.borrow_mut().0.process_events();

View File

@ -28,7 +28,7 @@ use std::{
}; };
#[cfg(feature = "wayland_frontend")] #[cfg(feature = "wayland_frontend")]
use wayland_server::{protocol::wl_buffer::WlBuffer, Display}; use wayland_server::{protocol::wl_buffer::WlBuffer, Display};
#[cfg(feature = "native_lib")] #[cfg(feature = "use_system_lib")]
use wayland_sys::server::wl_display; use wayland_sys::server::wl_display;
pub mod context; pub mod context;
@ -306,7 +306,7 @@ impl Drop for EGLImages {
/// Trait any backend type may implement that allows binding a [`Display`](wayland_server::Display) /// Trait any backend type may implement that allows binding a [`Display`](wayland_server::Display)
/// to create an [`EGLDisplay`] for EGL-based [`WlBuffer`]s. /// to create an [`EGLDisplay`] for EGL-based [`WlBuffer`]s.
#[cfg(feature = "native_lib")] #[cfg(feature = "use_system_lib")]
pub trait EGLGraphicsBackend { pub trait EGLGraphicsBackend {
/// Binds this EGL context to the given Wayland display. /// Binds this EGL context to the given Wayland display.
/// ///
@ -326,7 +326,7 @@ pub trait EGLGraphicsBackend {
/// Type to receive [`EGLImages`] for EGL-based [`WlBuffer`]s. /// Type to receive [`EGLImages`] for EGL-based [`WlBuffer`]s.
/// ///
/// Can be created by using [`EGLGraphicsBackend::bind_wl_display`]. /// Can be created by using [`EGLGraphicsBackend::bind_wl_display`].
#[cfg(feature = "native_lib")] #[cfg(feature = "use_system_lib")]
pub struct EGLDisplay { pub struct EGLDisplay {
egl: Weak<ffi::egl::types::EGLDisplay>, egl: Weak<ffi::egl::types::EGLDisplay>,
wayland: *mut wl_display, wayland: *mut wl_display,
@ -336,7 +336,7 @@ pub struct EGLDisplay {
egl_to_texture_support: bool, egl_to_texture_support: bool,
} }
#[cfg(feature = "native_lib")] #[cfg(feature = "use_system_lib")]
impl EGLDisplay { impl EGLDisplay {
fn new<B: native::Backend, N: native::NativeDisplay<B>>( fn new<B: native::Backend, N: native::NativeDisplay<B>>(
context: &EGLContext<B, N>, context: &EGLContext<B, N>,
@ -510,7 +510,7 @@ impl EGLDisplay {
} }
} }
#[cfg(feature = "native_lib")] #[cfg(feature = "use_system_lib")]
impl Drop for EGLDisplay { impl Drop for EGLDisplay {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(display) = self.egl.upgrade() { if let Some(display) = self.egl.upgrade() {
@ -523,14 +523,14 @@ impl Drop for EGLDisplay {
} }
} }
#[cfg(feature = "native_lib")] #[cfg(feature = "use_system_lib")]
impl<E: EGLGraphicsBackend> EGLGraphicsBackend for Rc<E> { impl<E: EGLGraphicsBackend> EGLGraphicsBackend for Rc<E> {
fn bind_wl_display(&self, display: &Display) -> Result<EGLDisplay> { fn bind_wl_display(&self, display: &Display) -> Result<EGLDisplay> {
(**self).bind_wl_display(display) (**self).bind_wl_display(display)
} }
} }
#[cfg(feature = "native_lib")] #[cfg(feature = "use_system_lib")]
impl<B: native::Backend, N: native::NativeDisplay<B>> EGLGraphicsBackend for EGLContext<B, N> { impl<B: native::Backend, N: native::NativeDisplay<B>> EGLGraphicsBackend for EGLContext<B, N> {
fn bind_wl_display(&self, display: &Display) -> Result<EGLDisplay> { fn bind_wl_display(&self, display: &Display) -> Result<EGLDisplay> {
if !self.wl_drm_support { if !self.wl_drm_support {

View File

@ -16,8 +16,8 @@ use std::{
}; };
use calloop::{ use calloop::{
generic::{EventedFd, Generic}, generic::{SourceFd, Generic},
mio::Ready, mio::Interest,
InsertError, LoopHandle, Source, InsertError, LoopHandle, Source,
}; };
@ -608,11 +608,11 @@ pub fn libinput_bind<Data: 'static>(
backend: LibinputInputBackend, backend: LibinputInputBackend,
handle: LoopHandle<Data>, handle: LoopHandle<Data>,
) -> ::std::result::Result< ) -> ::std::result::Result<
Source<Generic<EventedFd<LibinputInputBackend>>>, Source<Generic<SourceFd<LibinputInputBackend>>>,
InsertError<Generic<EventedFd<LibinputInputBackend>>>, InsertError<Generic<SourceFd<LibinputInputBackend>>>,
> { > {
let mut source = Generic::from_fd_source(backend); let mut source = Generic::from_fd_source(backend);
source.set_interest(Ready::readable()); source.set_interest(Interest::READABLE);
handle.insert_source(source, move |evt, _| { handle.insert_source(source, move |evt, _| {
let mut backend = evt.source.borrow_mut(); let mut backend = evt.source.borrow_mut();

View File

@ -53,8 +53,8 @@ use std::{
use systemd::login; use systemd::login;
use calloop::{ use calloop::{
generic::{Event, EventedRawFd, Generic}, generic::{Event, SourceRawFd, Generic},
mio::Ready, mio::Interest,
InsertError, LoopHandle, Source, InsertError, LoopHandle, Source,
}; };
@ -431,7 +431,7 @@ impl SessionNotifier for LogindSessionNotifier {
pub struct BoundLogindSession { pub struct BoundLogindSession {
notifier: LogindSessionNotifier, notifier: LogindSessionNotifier,
_watches: Vec<Watch>, _watches: Vec<Watch>,
sources: Vec<Source<Generic<EventedRawFd>>>, sources: Vec<Source<Generic<SourceRawFd>>>,
} }
/// Bind a [`LogindSessionNotifier`] to an [`EventLoop`](calloop::EventLoop). /// Bind a [`LogindSessionNotifier`] to an [`EventLoop`](calloop::EventLoop).
@ -449,17 +449,21 @@ pub fn logind_session_bind<Data: 'static>(
let sources = watches let sources = watches
.clone() .clone()
.into_iter() .into_iter()
.map(|watch| { .filter_map(|watch| {
let interest = match (watch.writable(), watch.readable()) {
(true, true) => Interest::WRITABLE | Interest::READABLE,
(true, false) => Interest::WRITABLE,
(false, true) => Interest::READABLE,
(false, false) => return None
};
let mut source = Generic::from_raw_fd(watch.fd()); let mut source = Generic::from_raw_fd(watch.fd());
source.set_interest( source.set_interest(interest);
if watch.readable() { Ready::readable() } else { Ready::empty() } let source = handle.insert_source(source, {
| if watch.writable() { Ready::writable() } else { Ready::empty() }
);
handle.insert_source(source, {
let mut notifier = notifier.clone(); let mut notifier = notifier.clone();
move |evt, _| notifier.event(evt) move |evt, _| notifier.event(evt)
}) });
}).collect::<::std::result::Result<Vec<Source<Generic<EventedRawFd>>>, InsertError<Generic<EventedRawFd>>>>() Some(source)
}).collect::<::std::result::Result<Vec<Source<Generic<SourceRawFd>>>, InsertError<Generic<SourceRawFd>>>>()
.map_err(|err| { .map_err(|err| {
( (
err.into(), err.into(),
@ -502,17 +506,17 @@ impl Drop for LogindSessionNotifier {
} }
impl LogindSessionNotifier { impl LogindSessionNotifier {
fn event(&mut self, event: Event<EventedRawFd>) { fn event(&mut self, event: Event<SourceRawFd>) {
let fd = event.source.borrow().0; let fd = event.source.borrow().0;
let readiness = event.readiness; let readiness = event.readiness;
let conn = self.internal.conn.borrow(); let conn = self.internal.conn.borrow();
let items = conn.watch_handle( let items = conn.watch_handle(
fd, fd,
if readiness.is_readable() && readiness.is_writable() { if readiness.readable && readiness.writable {
WatchEvent::Readable as u32 | WatchEvent::Writable as u32 WatchEvent::Readable as u32 | WatchEvent::Writable as u32
} else if readiness.is_readable() { } else if readiness.readable {
WatchEvent::Readable as u32 WatchEvent::Readable as u32
} else if readiness.is_writable() { } else if readiness.writable {
WatchEvent::Writable as u32 WatchEvent::Writable as u32
} else { } else {
return; return;

View File

@ -19,8 +19,8 @@ use std::{
use udev::{Context, Enumerator, EventType, MonitorBuilder, MonitorSocket, Result as UdevResult}; use udev::{Context, Enumerator, EventType, MonitorBuilder, MonitorSocket, Result as UdevResult};
use calloop::{ use calloop::{
generic::{EventedFd, Generic}, generic::{SourceFd, Generic},
mio::Ready, mio::Interest,
InsertError, LoopHandle, Source, InsertError, LoopHandle, Source,
}; };
@ -104,9 +104,9 @@ impl<T: UdevHandler + 'static> Drop for UdevBackend<T> {
pub fn udev_backend_bind<T: UdevHandler + 'static, Data: 'static>( pub fn udev_backend_bind<T: UdevHandler + 'static, Data: 'static>(
udev: UdevBackend<T>, udev: UdevBackend<T>,
handle: &LoopHandle<Data>, handle: &LoopHandle<Data>,
) -> Result<Source<Generic<EventedFd<UdevBackend<T>>>>, InsertError<Generic<EventedFd<UdevBackend<T>>>>> { ) -> Result<Source<Generic<SourceFd<UdevBackend<T>>>>, InsertError<Generic<SourceFd<UdevBackend<T>>>>> {
let mut source = Generic::from_fd_source(udev); let mut source = Generic::from_fd_source(udev);
source.set_interest(Ready::readable()); source.set_interest(Interest::READABLE);
handle.insert_source(source, |evt, _| { handle.insert_source(source, |evt, _| {
evt.source.borrow_mut().0.process_events(); evt.source.borrow_mut().0.process_events();

View File

@ -1,8 +1,8 @@
use std::{cell::RefCell, rc::Rc, sync::Mutex}; use std::{cell::RefCell, ops::Deref as _, rc::Rc, sync::Mutex};
use wayland_server::{ use wayland_server::{
protocol::{wl_compositor, wl_region, wl_subcompositor, wl_subsurface, wl_surface}, protocol::{wl_compositor, wl_region, wl_subcompositor, wl_subsurface, wl_surface},
NewResource, Filter, Main,
}; };
use super::{ use super::{
@ -16,16 +16,15 @@ use super::{
*/ */
pub(crate) fn implement_compositor<R, Impl>( pub(crate) fn implement_compositor<R, Impl>(
compositor: NewResource<wl_compositor::WlCompositor>, compositor: Main<wl_compositor::WlCompositor>,
log: ::slog::Logger, log: ::slog::Logger,
implem: Rc<RefCell<Impl>>, implem: Rc<RefCell<Impl>>,
) -> wl_compositor::WlCompositor ) -> wl_compositor::WlCompositor
where where
R: Default + 'static, R: Default + Send + 'static,
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static, Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static,
{ {
compositor.implement_closure( compositor.quick_assign(move |_compositor, request, _| match request {
move |request, _compositor| match request {
wl_compositor::Request::CreateSurface { id } => { wl_compositor::Request::CreateSurface { id } => {
trace!(log, "Creating a new wl_surface."); trace!(log, "Creating a new wl_surface.");
implement_surface(id, log.clone(), implem.clone()); implement_surface(id, log.clone(), implem.clone());
@ -35,10 +34,8 @@ where
implement_region(id); implement_region(id);
} }
_ => unreachable!(), _ => unreachable!(),
}, });
None::<fn(_)>, compositor.deref().clone()
(),
)
} }
/* /*
@ -81,14 +78,14 @@ where
} }
wl_surface::Request::SetOpaqueRegion { region } => { wl_surface::Request::SetOpaqueRegion { region } => {
let attributes = region.map(|r| { let attributes = region.map(|r| {
let attributes_mutex = r.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap(); let attributes_mutex = r.as_ref().user_data().get::<Mutex<RegionAttributes>>().unwrap();
attributes_mutex.lock().unwrap().clone() attributes_mutex.lock().unwrap().clone()
}); });
SurfaceData::<R>::with_data(&surface, |d| d.opaque_region = attributes); SurfaceData::<R>::with_data(&surface, |d| d.opaque_region = attributes);
} }
wl_surface::Request::SetInputRegion { region } => { wl_surface::Request::SetInputRegion { region } => {
let attributes = region.map(|r| { let attributes = region.map(|r| {
let attributes_mutex = r.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap(); let attributes_mutex = r.as_ref().user_data().get::<Mutex<RegionAttributes>>().unwrap();
attributes_mutex.lock().unwrap().clone() attributes_mutex.lock().unwrap().clone()
}); });
SurfaceData::<R>::with_data(&surface, |d| d.input_region = attributes); SurfaceData::<R>::with_data(&surface, |d| d.input_region = attributes);
@ -118,24 +115,25 @@ where
} }
fn implement_surface<R, Impl>( fn implement_surface<R, Impl>(
surface: NewResource<wl_surface::WlSurface>, surface: Main<wl_surface::WlSurface>,
log: ::slog::Logger, log: ::slog::Logger,
implem: Rc<RefCell<Impl>>, implem: Rc<RefCell<Impl>>,
) -> wl_surface::WlSurface ) -> wl_surface::WlSurface
where where
R: Default + 'static, R: Default + Send + 'static,
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static, Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static,
{ {
let surface = surface.implement_closure( surface.quick_assign({
{
let mut implem = SurfaceImplem::make(log, implem); let mut implem = SurfaceImplem::make(log, implem);
move |req, surface| implem.receive_surface_request(req, surface) move |surface, req, _| implem.receive_surface_request(req, surface.deref().clone())
}, });
Some(|surface| SurfaceData::<R>::cleanup(&surface)), surface.assign_destructor(Filter::new(|surface, _, _| SurfaceData::<R>::cleanup(&surface)));
SurfaceData::<R>::new(),
);
SurfaceData::<R>::init(&surface);
surface surface
.as_ref()
.user_data()
.set_threadsafe(|| SurfaceData::<R>::new());
SurfaceData::<R>::init(&surface);
surface.deref().clone()
} }
/* /*
@ -143,7 +141,11 @@ where
*/ */
fn region_implem(request: wl_region::Request, region: wl_region::WlRegion) { fn region_implem(request: wl_region::Request, region: wl_region::WlRegion) {
let attributes_mutex = region.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap(); let attributes_mutex = region
.as_ref()
.user_data()
.get::<Mutex<RegionAttributes>>()
.unwrap();
let mut guard = attributes_mutex.lock().unwrap(); let mut guard = attributes_mutex.lock().unwrap();
match request { match request {
wl_region::Request::Add { x, y, width, height } => guard wl_region::Request::Add { x, y, width, height } => guard
@ -159,12 +161,13 @@ fn region_implem(request: wl_region::Request, region: wl_region::WlRegion) {
} }
} }
fn implement_region(region: NewResource<wl_region::WlRegion>) -> wl_region::WlRegion { fn implement_region(region: Main<wl_region::WlRegion>) -> wl_region::WlRegion {
region.implement_closure( region.quick_assign(|region, req, _| region_implem(req, region.deref().clone()));
region_implem, region
None::<fn(_)>, .as_ref()
Mutex::new(RegionAttributes::default()), .user_data()
) .set_threadsafe(|| Mutex::new(RegionAttributes::default()));
region.deref().clone()
} }
/* /*
@ -172,13 +175,12 @@ fn implement_region(region: NewResource<wl_region::WlRegion>) -> wl_region::WlRe
*/ */
pub(crate) fn implement_subcompositor<R>( pub(crate) fn implement_subcompositor<R>(
subcompositor: NewResource<wl_subcompositor::WlSubcompositor>, subcompositor: Main<wl_subcompositor::WlSubcompositor>,
) -> wl_subcompositor::WlSubcompositor ) -> wl_subcompositor::WlSubcompositor
where where
R: RoleType + Role<SubsurfaceRole> + 'static, R: RoleType + Role<SubsurfaceRole> + 'static,
{ {
subcompositor.implement_closure( subcompositor.quick_assign(move |subcompositor, request, _| match request {
move |request, subcompositor| match request {
wl_subcompositor::Request::GetSubsurface { id, surface, parent } => { wl_subcompositor::Request::GetSubsurface { id, surface, parent } => {
if let Err(()) = SurfaceData::<R>::set_parent(&surface, &parent) { if let Err(()) = SurfaceData::<R>::set_parent(&surface, &parent) {
subcompositor.as_ref().post_error( subcompositor.as_ref().post_error(
@ -191,10 +193,8 @@ where
} }
wl_subcompositor::Request::Destroy => {} wl_subcompositor::Request::Destroy => {}
_ => unreachable!(), _ => unreachable!(),
}, });
None::<fn(_)>, subcompositor.deref().clone()
(),
)
} }
/* /*
@ -206,20 +206,23 @@ where
F: FnOnce(&mut SubsurfaceRole), F: FnOnce(&mut SubsurfaceRole),
R: RoleType + Role<SubsurfaceRole> + 'static, R: RoleType + Role<SubsurfaceRole> + 'static,
{ {
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap(); let surface = subsurface
.as_ref()
.user_data()
.get::<wl_surface::WlSurface>()
.unwrap();
SurfaceData::<R>::with_role_data::<SubsurfaceRole, _, _>(surface, |d| f(d)) SurfaceData::<R>::with_role_data::<SubsurfaceRole, _, _>(surface, |d| f(d))
.expect("The surface does not have a subsurface role while it has a wl_subsurface?!"); .expect("The surface does not have a subsurface role while it has a wl_subsurface?!");
} }
fn implement_subsurface<R>( fn implement_subsurface<R>(
subsurface: NewResource<wl_subsurface::WlSubsurface>, subsurface: Main<wl_subsurface::WlSubsurface>,
surface: wl_surface::WlSurface, surface: wl_surface::WlSurface,
) -> wl_subsurface::WlSubsurface ) -> wl_subsurface::WlSubsurface
where where
R: RoleType + Role<SubsurfaceRole> + 'static, R: RoleType + Role<SubsurfaceRole> + 'static,
{ {
subsurface.implement_closure( subsurface.quick_assign(|subsurface, request, _| {
|request, subsurface| {
match request { match request {
wl_subsurface::Request::SetPosition { x, y } => { wl_subsurface::Request::SetPosition { x, y } => {
with_subsurface_attributes::<R, _>(&subsurface, |attrs| { with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
@ -227,7 +230,11 @@ where
}) })
} }
wl_subsurface::Request::PlaceAbove { sibling } => { wl_subsurface::Request::PlaceAbove { sibling } => {
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap(); let surface = subsurface
.as_ref()
.user_data()
.get::<wl_surface::WlSurface>()
.unwrap();
if let Err(()) = SurfaceData::<R>::reorder(surface, Location::After, &sibling) { if let Err(()) = SurfaceData::<R>::reorder(surface, Location::After, &sibling) {
subsurface.as_ref().post_error( subsurface.as_ref().post_error(
wl_subsurface::Error::BadSurface as u32, wl_subsurface::Error::BadSurface as u32,
@ -236,7 +243,11 @@ where
} }
} }
wl_subsurface::Request::PlaceBelow { sibling } => { wl_subsurface::Request::PlaceBelow { sibling } => {
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap(); let surface = subsurface
.as_ref()
.user_data()
.get::<wl_surface::WlSurface>()
.unwrap();
if let Err(()) = SurfaceData::<R>::reorder(surface, Location::Before, &sibling) { if let Err(()) = SurfaceData::<R>::reorder(surface, Location::Before, &sibling) {
subsurface.as_ref().post_error( subsurface.as_ref().post_error(
wl_subsurface::Error::BadSurface as u32, wl_subsurface::Error::BadSurface as u32,
@ -247,27 +258,31 @@ where
wl_subsurface::Request::SetSync => with_subsurface_attributes::<R, _>(&subsurface, |attrs| { wl_subsurface::Request::SetSync => with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
attrs.sync = true; attrs.sync = true;
}), }),
wl_subsurface::Request::SetDesync => { wl_subsurface::Request::SetDesync => with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
attrs.sync = false; attrs.sync = false;
}) }),
}
wl_subsurface::Request::Destroy => { wl_subsurface::Request::Destroy => {
// Our destructor already handles it // Our destructor already handles it
} }
_ => unreachable!(), _ => unreachable!(),
} }
}, });
Some(|subsurface| destroy_subsurface::<R>(&subsurface)), subsurface.assign_destructor(Filter::new(|subsurface, _, _| {
surface, destroy_subsurface::<R>(&subsurface)
) }));
subsurface.as_ref().user_data().set_threadsafe(|| surface);
subsurface.deref().clone()
} }
fn destroy_subsurface<R>(subsurface: &wl_subsurface::WlSubsurface) fn destroy_subsurface<R>(subsurface: &wl_subsurface::WlSubsurface)
where where
R: RoleType + Role<SubsurfaceRole> + 'static, R: RoleType + Role<SubsurfaceRole> + 'static,
{ {
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap(); let surface = subsurface
.as_ref()
.user_data()
.get::<wl_surface::WlSurface>()
.unwrap();
if surface.as_ref().is_alive() { if surface.as_ref().is_alive() {
SurfaceData::<R>::unset_parent(&surface); SurfaceData::<R>::unset_parent(&surface);
} }

View File

@ -35,8 +35,7 @@
//! // Declare the roles enum //! // Declare the roles enum
//! define_roles!(MyRoles); //! define_roles!(MyRoles);
//! //!
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut display = wayland_server::Display::new();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! // Call the init function: //! // Call the init function:
//! let (token, _, _) = compositor_init::<MyRoles, _, _>( //! let (token, _, _) = compositor_init::<MyRoles, _, _>(
//! &mut display, //! &mut display,
@ -85,7 +84,7 @@ use wayland_server::{
protocol::{ protocol::{
wl_buffer, wl_callback, wl_compositor, wl_output, wl_region, wl_subcompositor, wl_surface::WlSurface, wl_buffer, wl_callback, wl_compositor, wl_output, wl_region, wl_subcompositor, wl_surface::WlSurface,
}, },
Display, Global, NewResource, Display, Filter, Global, Main, UserDataMap,
}; };
/// Description of which part of a surface /// Description of which part of a surface
@ -153,7 +152,7 @@ pub struct SurfaceAttributes {
/// User-controlled data /// User-controlled data
/// ///
/// This is your field to host whatever you need. /// This is your field to host whatever you need.
pub user_data: ::wayland_commons::utils::UserDataMap, pub user_data: UserDataMap,
} }
impl Default for SurfaceAttributes { impl Default for SurfaceAttributes {
@ -165,7 +164,7 @@ impl Default for SurfaceAttributes {
opaque_region: None, opaque_region: None,
input_region: None, input_region: None,
damage: Damage::Full, damage: Damage::Full,
user_data: ::wayland_commons::utils::UserDataMap::new(), user_data: UserDataMap::new(),
} }
} }
} }
@ -446,7 +445,7 @@ impl<R: RoleType + 'static> CompositorToken<R> {
/// If the region is not managed by the `CompositorGlobal` that provided this token, this /// If the region is not managed by the `CompositorGlobal` that provided this token, this
/// will panic (having more than one compositor is not supported). /// will panic (having more than one compositor is not supported).
pub fn get_region_attributes(self, region: &wl_region::WlRegion) -> RegionAttributes { pub fn get_region_attributes(self, region: &wl_region::WlRegion) -> RegionAttributes {
match region.as_ref().user_data::<Mutex<RegionAttributes>>() { match region.as_ref().user_data().get::<Mutex<RegionAttributes>>() {
Some(mutex) => mutex.lock().unwrap().clone(), Some(mutex) => mutex.lock().unwrap().clone(),
None => panic!("Accessing the data of foreign regions is not supported."), None => panic!("Accessing the data of foreign regions is not supported."),
} }
@ -473,19 +472,25 @@ pub fn compositor_init<R, Impl, L>(
) )
where where
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
R: Default + RoleType + Role<SubsurfaceRole> + 'static, R: Default + RoleType + Role<SubsurfaceRole> + Send + 'static,
Impl: FnMut(SurfaceEvent, WlSurface, CompositorToken<R>) + 'static, Impl: FnMut(SurfaceEvent, WlSurface, CompositorToken<R>) + 'static,
{ {
let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "compositor_handler")); let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "compositor_handler"));
let implem = Rc::new(RefCell::new(implem)); let implem = Rc::new(RefCell::new(implem));
let compositor = display.create_global(4, move |new_compositor, _version| { let compositor = display.create_global(
4,
Filter::new(move |(new_compositor, _version), _, _| {
self::handlers::implement_compositor::<R, Impl>(new_compositor, log.clone(), implem.clone()); self::handlers::implement_compositor::<R, Impl>(new_compositor, log.clone(), implem.clone());
}); }),
);
let subcompositor = display.create_global(1, move |new_subcompositor, _version| { let subcompositor = display.create_global(
1,
Filter::new(move |(new_subcompositor, _version), _, _| {
self::handlers::implement_subcompositor::<R>(new_subcompositor); self::handlers::implement_subcompositor::<R>(new_subcompositor);
}); }),
);
(CompositorToken::make(), compositor, subcompositor) (CompositorToken::make(), compositor, subcompositor)
} }
@ -513,7 +518,7 @@ pub enum SurfaceEvent {
/// for more details /// for more details
Frame { Frame {
/// The created `WlCallback` /// The created `WlCallback`
callback: NewResource<wl_callback::WlCallback>, callback: Main<wl_callback::WlCallback>,
}, },
} }

View File

@ -54,7 +54,11 @@ where
{ {
/// Initializes the surface, must be called at creation for state coherence /// Initializes the surface, must be called at creation for state coherence
pub fn init(surface: &WlSurface) { pub fn init(surface: &WlSurface) {
let my_data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let my_data_mutex = surface
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut my_data = my_data_mutex.lock().unwrap(); let mut my_data = my_data_mutex.lock().unwrap();
debug_assert!(my_data.children.is_empty()); debug_assert!(my_data.children.is_empty());
my_data.children.push(surface.clone()); my_data.children.push(surface.clone());
@ -62,11 +66,19 @@ where
/// Cleans the `as_ref().user_data` of that surface, must be called when it is destroyed /// Cleans the `as_ref().user_data` of that surface, must be called when it is destroyed
pub fn cleanup(surface: &WlSurface) { pub fn cleanup(surface: &WlSurface) {
let my_data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let my_data_mutex = surface
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut my_data = my_data_mutex.lock().unwrap(); let mut my_data = my_data_mutex.lock().unwrap();
if let Some(old_parent) = my_data.parent.take() { if let Some(old_parent) = my_data.parent.take() {
// We had a parent, lets unregister ourselves from it // We had a parent, lets unregister ourselves from it
let old_parent_mutex = old_parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let old_parent_mutex = old_parent
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut old_parent_guard = old_parent_mutex.lock().unwrap(); let mut old_parent_guard = old_parent_mutex.lock().unwrap();
old_parent_guard old_parent_guard
.children .children
@ -74,7 +86,7 @@ where
} }
// orphan all our children // orphan all our children
for child in &my_data.children { for child in &my_data.children {
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let child_mutex = child.as_ref().user_data().get::<Mutex<SurfaceData<R>>>().unwrap();
if std::ptr::eq(child_mutex, my_data_mutex) { if std::ptr::eq(child_mutex, my_data_mutex) {
// This child is ourselves, don't do anything. // This child is ourselves, don't do anything.
continue; continue;
@ -89,7 +101,11 @@ where
impl<R: RoleType + 'static> SurfaceData<R> { impl<R: RoleType + 'static> SurfaceData<R> {
pub fn has_a_role(surface: &WlSurface) -> bool { pub fn has_a_role(surface: &WlSurface) -> bool {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let data_mutex = surface
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let data_guard = data_mutex.lock().unwrap(); let data_guard = data_mutex.lock().unwrap();
<R as RoleType>::has_role(&data_guard.role) <R as RoleType>::has_role(&data_guard.role)
} }
@ -100,7 +116,11 @@ impl<R: RoleType + 'static> SurfaceData<R> {
R: Role<RoleData>, R: Role<RoleData>,
{ {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let data_mutex = surface
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let data_guard = data_mutex.lock().unwrap(); let data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::has(&data_guard.role) <R as Role<RoleData>>::has(&data_guard.role)
} }
@ -112,7 +132,11 @@ impl<R: RoleType + 'static> SurfaceData<R> {
RoleData: Default, RoleData: Default,
{ {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let data_mutex = surface
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::set(&mut data_guard.role) <R as Role<RoleData>>::set(&mut data_guard.role)
} }
@ -125,7 +149,11 @@ impl<R: RoleType + 'static> SurfaceData<R> {
R: Role<RoleData>, R: Role<RoleData>,
{ {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let data_mutex = surface
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::set_with(&mut data_guard.role, data) <R as Role<RoleData>>::set_with(&mut data_guard.role, data)
} }
@ -139,7 +167,11 @@ impl<R: RoleType + 'static> SurfaceData<R> {
R: Role<RoleData>, R: Role<RoleData>,
{ {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let data_mutex = surface
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::unset(&mut data_guard.role) <R as Role<RoleData>>::unset(&mut data_guard.role)
} }
@ -151,7 +183,11 @@ impl<R: RoleType + 'static> SurfaceData<R> {
F: FnOnce(&mut RoleData) -> T, F: FnOnce(&mut RoleData) -> T,
{ {
debug_assert!(surface.as_ref().is_alive()); debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let data_mutex = surface
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
let data = <R as Role<RoleData>>::data_mut(&mut data_guard.role)?; let data = <R as Role<RoleData>>::data_mut(&mut data_guard.role)?;
Ok(f(data)) Ok(f(data))
@ -161,7 +197,7 @@ impl<R: RoleType + 'static> SurfaceData<R> {
impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> { impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> {
/// Checks if the first surface is an ancestor of the second /// Checks if the first surface is an ancestor of the second
pub fn is_ancestor(a: &WlSurface, b: &WlSurface) -> bool { pub fn is_ancestor(a: &WlSurface, b: &WlSurface) -> bool {
let b_mutex = b.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let b_mutex = b.as_ref().user_data().get::<Mutex<SurfaceData<R>>>().unwrap();
let b_guard = b_mutex.lock().unwrap(); let b_guard = b_mutex.lock().unwrap();
if let Some(ref parent) = b_guard.parent { if let Some(ref parent) = b_guard.parent {
if parent.as_ref().equals(a.as_ref()) { if parent.as_ref().equals(a.as_ref()) {
@ -188,7 +224,7 @@ impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> {
// change child's parent // change child's parent
{ {
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let child_mutex = child.as_ref().user_data().get::<Mutex<SurfaceData<R>>>().unwrap();
let mut child_guard = child_mutex.lock().unwrap(); let mut child_guard = child_mutex.lock().unwrap();
// if surface already has a role, it cannot become a subsurface // if surface already has a role, it cannot become a subsurface
<R as Role<SubsurfaceRole>>::set(&mut child_guard.role)?; <R as Role<SubsurfaceRole>>::set(&mut child_guard.role)?;
@ -197,7 +233,11 @@ impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> {
} }
// register child to new parent // register child to new parent
{ {
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let parent_mutex = parent
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut parent_guard = parent_mutex.lock().unwrap(); let mut parent_guard = parent_mutex.lock().unwrap();
parent_guard.children.push(child.clone()) parent_guard.children.push(child.clone())
} }
@ -210,7 +250,7 @@ impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> {
pub fn unset_parent(child: &WlSurface) { pub fn unset_parent(child: &WlSurface) {
debug_assert!(child.as_ref().is_alive()); debug_assert!(child.as_ref().is_alive());
let old_parent = { let old_parent = {
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let child_mutex = child.as_ref().user_data().get::<Mutex<SurfaceData<R>>>().unwrap();
let mut child_guard = child_mutex.lock().unwrap(); let mut child_guard = child_mutex.lock().unwrap();
let old_parent = child_guard.parent.take(); let old_parent = child_guard.parent.take();
if old_parent.is_some() { if old_parent.is_some() {
@ -222,7 +262,11 @@ impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> {
}; };
// unregister from our parent // unregister from our parent
if let Some(old_parent) = old_parent { if let Some(old_parent) = old_parent {
let parent_mutex = old_parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let parent_mutex = old_parent
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut parent_guard = parent_mutex.lock().unwrap(); let mut parent_guard = parent_mutex.lock().unwrap();
parent_guard parent_guard
.children .children
@ -232,14 +276,18 @@ impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> {
/// Retrieve the parent surface (if any) of this surface /// Retrieve the parent surface (if any) of this surface
pub fn get_parent(child: &WlSurface) -> Option<WlSurface> { pub fn get_parent(child: &WlSurface) -> Option<WlSurface> {
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let child_mutex = child.as_ref().user_data().get::<Mutex<SurfaceData<R>>>().unwrap();
let child_guard = child_mutex.lock().unwrap(); let child_guard = child_mutex.lock().unwrap();
child_guard.parent.as_ref().cloned() child_guard.parent.as_ref().cloned()
} }
/// Retrieve the children surface (if any) of this surface /// Retrieve the children surface (if any) of this surface
pub fn get_children(parent: &WlSurface) -> Vec<WlSurface> { pub fn get_children(parent: &WlSurface) -> Vec<WlSurface> {
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let parent_mutex = parent
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let parent_guard = parent_mutex.lock().unwrap(); let parent_guard = parent_mutex.lock().unwrap();
parent_guard parent_guard
.children .children
@ -254,7 +302,11 @@ impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> {
/// Fails if `relative_to` is not a sibling or parent of `surface`. /// Fails if `relative_to` is not a sibling or parent of `surface`.
pub fn reorder(surface: &WlSurface, to: Location, relative_to: &WlSurface) -> Result<(), ()> { pub fn reorder(surface: &WlSurface, to: Location, relative_to: &WlSurface) -> Result<(), ()> {
let parent = { let parent = {
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let data_mutex = surface
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let data_guard = data_mutex.lock().unwrap(); let data_guard = data_mutex.lock().unwrap();
data_guard.parent.as_ref().cloned().unwrap() data_guard.parent.as_ref().cloned().unwrap()
}; };
@ -268,7 +320,11 @@ impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> {
None None
} }
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let parent_mutex = parent
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut parent_guard = parent_mutex.lock().unwrap(); let mut parent_guard = parent_mutex.lock().unwrap();
let my_index = index_of(surface, &parent_guard.children).unwrap(); let my_index = index_of(surface, &parent_guard.children).unwrap();
let mut other_index = match index_of(relative_to, &parent_guard.children) { let mut other_index = match index_of(relative_to, &parent_guard.children) {
@ -299,7 +355,8 @@ impl<R: 'static> SurfaceData<R> {
{ {
let data_mutex = surface let data_mutex = surface
.as_ref() .as_ref()
.user_data::<Mutex<SurfaceData<R>>>() .user_data()
.get::<Mutex<SurfaceData<R>>>()
.expect("Accessing the data of foreign surfaces is not supported."); .expect("Accessing the data of foreign surfaces is not supported.");
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
f(&mut data_guard.attributes) f(&mut data_guard.attributes)
@ -354,7 +411,11 @@ impl<R: 'static> SurfaceData<R> {
F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T), F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool, F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool,
{ {
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap(); let data_mutex = surface
.as_ref()
.user_data()
.get::<Mutex<SurfaceData<R>>>()
.unwrap();
let mut data_guard = data_mutex.lock().unwrap(); let mut data_guard = data_mutex.lock().unwrap();
let data_guard = &mut *data_guard; let data_guard = &mut *data_guard;
// call the filter on ourselves // call the filter on ourselves

View File

@ -1,11 +1,11 @@
use std::cell::RefCell; use std::{cell::RefCell, ops::Deref as _};
use wayland_server::{ use wayland_server::{
protocol::{ protocol::{
wl_data_device_manager::DndAction, wl_data_device_manager::DndAction,
wl_data_source::{Request, WlDataSource}, wl_data_source::{Request, WlDataSource},
}, },
NewResource, Main,
}; };
/// The metadata describing a data source /// The metadata describing a data source
@ -17,10 +17,9 @@ pub struct SourceMetadata {
pub dnd_action: DndAction, pub dnd_action: DndAction,
} }
pub(crate) fn implement_data_source(src: NewResource<WlDataSource>) -> WlDataSource { pub(crate) fn implement_data_source(src: Main<WlDataSource>) -> WlDataSource {
src.implement_closure( src.quick_assign(|me, req, _| {
|req, me| { let data: &RefCell<SourceMetadata> = me.as_ref().user_data().get().unwrap();
let data: &RefCell<SourceMetadata> = me.as_ref().user_data().unwrap();
let mut guard = data.borrow_mut(); let mut guard = data.borrow_mut();
match req { match req {
Request::Offer { mime_type } => guard.mime_types.push(mime_type), Request::Offer { mime_type } => guard.mime_types.push(mime_type),
@ -30,13 +29,15 @@ pub(crate) fn implement_data_source(src: NewResource<WlDataSource>) -> WlDataSou
Request::Destroy => {} Request::Destroy => {}
_ => unreachable!(), _ => unreachable!(),
} }
}, });
None::<fn(_)>, src.as_ref().user_data().set(|| {
RefCell::new(SourceMetadata { RefCell::new(SourceMetadata {
mime_types: Vec::new(), mime_types: Vec::new(),
dnd_action: DndAction::None, dnd_action: DndAction::None,
}), })
) });
src.deref().clone()
} }
/// Access the metadata of a data source /// Access the metadata of a data source
@ -44,7 +45,7 @@ pub fn with_source_metadata<T, F: FnOnce(&SourceMetadata) -> T>(
source: &WlDataSource, source: &WlDataSource,
f: F, f: F,
) -> Result<T, ()> { ) -> Result<T, ()> {
match source.as_ref().user_data::<RefCell<SourceMetadata>>() { match source.as_ref().user_data().get::<RefCell<SourceMetadata>>() {
Some(data) => Ok(f(&data.borrow())), Some(data) => Ok(f(&data.borrow())),
None => Err(()), None => Err(()),
} }

View File

@ -1,9 +1,8 @@
use std::cell::RefCell; use std::{cell::RefCell, ops::Deref as _, rc::Rc};
use std::rc::Rc;
use wayland_server::{ use wayland_server::{
protocol::{wl_data_device_manager::DndAction, wl_data_offer, wl_data_source, wl_pointer, wl_surface}, protocol::{wl_data_device_manager::DndAction, wl_data_offer, wl_data_source, wl_pointer, wl_surface},
NewResource, Main,
}; };
use crate::wayland::{ use crate::wayland::{
@ -107,7 +106,8 @@ impl<R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<R> {
{ {
let action_choice = device let action_choice = device
.as_ref() .as_ref()
.user_data::<DataDeviceData>() .user_data()
.get::<DataDeviceData>()
.unwrap() .unwrap()
.action_choice .action_choice
.clone(); .clone();
@ -239,14 +239,13 @@ struct OfferData {
} }
fn implement_dnd_data_offer( fn implement_dnd_data_offer(
offer: NewResource<wl_data_offer::WlDataOffer>, offer: Main<wl_data_offer::WlDataOffer>,
source: wl_data_source::WlDataSource, source: wl_data_source::WlDataSource,
offer_data: Rc<RefCell<OfferData>>, offer_data: Rc<RefCell<OfferData>>,
action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> DndAction + 'static>>, action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> DndAction + 'static>>,
) -> wl_data_offer::WlDataOffer { ) -> wl_data_offer::WlDataOffer {
use self::wl_data_offer::Request; use self::wl_data_offer::Request;
offer.implement_closure( offer.quick_assign(move |offer, req, _| {
move |req, offer| {
let mut data = offer_data.borrow_mut(); let mut data = offer_data.borrow_mut();
match req { match req {
Request::Accept { mime_type, .. } => { Request::Accept { mime_type, .. } => {
@ -314,8 +313,7 @@ fn implement_dnd_data_offer(
let source_actions = with_source_metadata(&source, |meta| meta.dnd_action) let source_actions = with_source_metadata(&source, |meta| meta.dnd_action)
.unwrap_or_else(|_| DndAction::empty()); .unwrap_or_else(|_| DndAction::empty());
let possible_actions = source_actions & DndAction::from_bits_truncate(dnd_actions); let possible_actions = source_actions & DndAction::from_bits_truncate(dnd_actions);
data.chosen_action = data.chosen_action = (&mut *action_choice.borrow_mut())(possible_actions, preferred_action);
(&mut *action_choice.borrow_mut())(possible_actions, preferred_action);
// check that the user provided callback respects that one precise action should be chosen // check that the user provided callback respects that one precise action should be chosen
debug_assert!( debug_assert!(
[DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action) [DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action)
@ -325,8 +323,7 @@ fn implement_dnd_data_offer(
} }
_ => unreachable!(), _ => unreachable!(),
} }
}, });
None::<fn(_)>,
(), offer.deref().clone()
)
} }

View File

@ -40,8 +40,7 @@
//! // to set a surface as a dnd icon //! // to set a surface as a dnd icon
//! define_roles!(Roles => [DnDIcon, DnDIconRole]); //! define_roles!(Roles => [DnDIcon, DnDIconRole]);
//! //!
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut display = wayland_server::Display::new();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None); //! # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None);
//! // init the data device: //! // init the data device:
//! init_data_device( //! init_data_device(
@ -54,9 +53,7 @@
//! ); //! );
//! ``` //! ```
use std::cell::RefCell; use std::{cell::RefCell, ops::Deref as _, os::unix::io::RawFd, rc::Rc};
use std::os::unix::io::RawFd;
use std::rc::Rc;
use wayland_server::{ use wayland_server::{
protocol::{ protocol::{
@ -64,7 +61,7 @@ use wayland_server::{
wl_data_device_manager::{self, DndAction}, wl_data_device_manager::{self, DndAction},
wl_data_offer, wl_data_source, wl_surface, wl_data_offer, wl_data_source, wl_surface,
}, },
Client, Display, Global, NewResource, Client, Display, Filter, Global, Main,
}; };
use crate::wayland::{ use crate::wayland::{
@ -175,15 +172,13 @@ impl SeatData {
// create a corresponding data offer // create a corresponding data offer
let offer = client let offer = client
.create_resource::<wl_data_offer::WlDataOffer>(dd.as_ref().version()) .create_resource::<wl_data_offer::WlDataOffer>(dd.as_ref().version())
.unwrap() .unwrap();
.implement_closure( offer.quick_assign(move |_offer, req, _| {
move |req, _offer| {
// selection data offers only care about the `receive` event // selection data offers only care about the `receive` event
if let wl_data_offer::Request::Receive { fd, mime_type } = req { if let wl_data_offer::Request::Receive { fd, mime_type } = req {
// check if the source and associated mime type is still valid // check if the source and associated mime type is still valid
let valid = with_source_metadata(&source, |meta| { let valid =
meta.mime_types.contains(&mime_type) with_source_metadata(&source, |meta| meta.mime_types.contains(&mime_type))
})
.unwrap_or(false) .unwrap_or(false)
&& source.as_ref().is_alive(); && source.as_ref().is_alive();
if !valid { if !valid {
@ -194,10 +189,7 @@ impl SeatData {
} }
let _ = ::nix::unistd::close(fd); let _ = ::nix::unistd::close(fd);
} }
}, });
None::<fn(_)>,
(),
);
// advertize the offer to the client // advertize the offer to the client
dd.data_offer(&offer); dd.data_offer(&offer);
with_source_metadata(data_source, |meta| { with_source_metadata(data_source, |meta| {
@ -219,16 +211,16 @@ impl SeatData {
let offer_meta = meta.clone(); let offer_meta = meta.clone();
let callback = dd let callback = dd
.as_ref() .as_ref()
.user_data::<DataDeviceData>() .user_data()
.get::<DataDeviceData>()
.unwrap() .unwrap()
.callback .callback
.clone(); .clone();
// create a corresponding data offer // create a corresponding data offer
let offer = client let offer = client
.create_resource::<wl_data_offer::WlDataOffer>(dd.as_ref().version()) .create_resource::<wl_data_offer::WlDataOffer>(dd.as_ref().version())
.unwrap() .unwrap();
.implement_closure( offer.quick_assign(move |_offer, req, _| {
move |req, _offer| {
// selection data offers only care about the `receive` event // selection data offers only care about the `receive` event
if let wl_data_offer::Request::Receive { fd, mime_type } = req { if let wl_data_offer::Request::Receive { fd, mime_type } = req {
// check if the associated mime type is valid // check if the associated mime type is valid
@ -243,10 +235,7 @@ impl SeatData {
}); });
} }
} }
}, });
None::<fn(_)>,
(),
);
// advertize the offer to the client // advertize the offer to the client
dd.data_offer(&offer); dd.data_offer(&offer);
for mime_type in meta.mime_types.iter().cloned() { for mime_type in meta.mime_types.iter().cloned() {
@ -300,15 +289,12 @@ where
let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "data_device_mgr")); let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "data_device_mgr"));
let action_choice = Rc::new(RefCell::new(action_choice)); let action_choice = Rc::new(RefCell::new(action_choice));
let callback = Rc::new(RefCell::new(callback)); let callback = Rc::new(RefCell::new(callback));
display.create_global(3, move |new_ddm, _version| { display.create_global(
implement_ddm( 3,
new_ddm, Filter::new(move |(ddm, _version), _, _| {
callback.clone(), implement_ddm(ddm, callback.clone(), action_choice.clone(), token, log.clone());
action_choice.clone(), }),
token, )
log.clone(),
);
})
} }
/// Set the data device focus to a certain client for a given seat /// Set the data device focus to a certain client for a given seat
@ -384,7 +370,7 @@ pub fn start_dnd<C>(
} }
fn implement_ddm<F, C, R>( fn implement_ddm<F, C, R>(
new_ddm: NewResource<wl_data_device_manager::WlDataDeviceManager>, ddm: Main<wl_data_device_manager::WlDataDeviceManager>,
callback: Rc<RefCell<C>>, callback: Rc<RefCell<C>>,
action_choice: Rc<RefCell<F>>, action_choice: Rc<RefCell<F>>,
token: CompositorToken<R>, token: CompositorToken<R>,
@ -396,8 +382,7 @@ where
R: Role<DnDIconRole> + 'static, R: Role<DnDIconRole> + 'static,
{ {
use self::wl_data_device_manager::Request; use self::wl_data_device_manager::Request;
new_ddm.implement_closure( ddm.quick_assign(move |_ddm, req, _data| match req {
move |req, _ddm| match req {
Request::CreateDataSource { id } => { Request::CreateDataSource { id } => {
self::data_source::implement_data_source(id); self::data_source::implement_data_source(id);
} }
@ -422,10 +407,9 @@ where
} }
}, },
_ => unreachable!(), _ => unreachable!(),
}, });
None::<fn(_)>,
(), ddm.deref().clone()
)
} }
struct DataDeviceData { struct DataDeviceData {
@ -434,7 +418,7 @@ struct DataDeviceData {
} }
fn implement_data_device<F, C, R>( fn implement_data_device<F, C, R>(
new_dd: NewResource<wl_data_device::WlDataDevice>, dd: Main<wl_data_device::WlDataDevice>,
seat: Seat, seat: Seat,
callback: Rc<RefCell<C>>, callback: Rc<RefCell<C>>,
action_choice: Rc<RefCell<F>>, action_choice: Rc<RefCell<F>>,
@ -451,8 +435,7 @@ where
callback: callback.clone(), callback: callback.clone(),
action_choice, action_choice,
}; };
new_dd.implement_closure( dd.quick_assign(move |dd, req, _| match req {
move |req, dd| match req {
Request::StartDrag { Request::StartDrag {
source, source,
origin, origin,
@ -524,10 +507,10 @@ where
.retain(|ndd| ndd.as_ref().is_alive() && (!ndd.as_ref().equals(&dd.as_ref()))) .retain(|ndd| ndd.as_ref().is_alive() && (!ndd.as_ref().equals(&dd.as_ref())))
} }
_ => unreachable!(), _ => unreachable!(),
}, });
None::<fn(_)>, dd.as_ref().user_data().set(|| dd_data);
dd_data,
) dd.deref().clone()
} }
/// A simple action chooser for DnD negociation /// A simple action chooser for DnD negociation

View File

@ -1,10 +1,8 @@
use std::cell::RefCell; use std::{cell::RefCell, ops::Deref as _, os::unix::io::RawFd, rc::Rc};
use std::os::unix::io::RawFd;
use std::rc::Rc;
use wayland_server::{ use wayland_server::{
protocol::{wl_data_device_manager::DndAction, wl_data_offer, wl_pointer, wl_surface}, protocol::{wl_data_device_manager::DndAction, wl_data_offer, wl_pointer, wl_surface},
NewResource, Main,
}; };
use crate::wayland::seat::{AxisFrame, GrabStartData, PointerGrab, PointerInnerHandle, Seat}; use crate::wayland::seat::{AxisFrame, GrabStartData, PointerGrab, PointerInnerHandle, Seat};
@ -120,7 +118,8 @@ where
{ {
let action_choice = device let action_choice = device
.as_ref() .as_ref()
.user_data::<DataDeviceData>() .user_data()
.get::<DataDeviceData>()
.unwrap() .unwrap()
.action_choice .action_choice
.clone(); .clone();
@ -229,7 +228,7 @@ struct OfferData {
} }
fn implement_dnd_data_offer<C>( fn implement_dnd_data_offer<C>(
offer: NewResource<wl_data_offer::WlDataOffer>, offer: Main<wl_data_offer::WlDataOffer>,
metadata: super::SourceMetadata, metadata: super::SourceMetadata,
offer_data: Rc<RefCell<OfferData>>, offer_data: Rc<RefCell<OfferData>>,
callback: Rc<RefCell<C>>, callback: Rc<RefCell<C>>,
@ -239,8 +238,7 @@ where
C: FnMut(ServerDndEvent) + 'static, C: FnMut(ServerDndEvent) + 'static,
{ {
use self::wl_data_offer::Request; use self::wl_data_offer::Request;
offer.implement_closure( offer.quick_assign(move |offer, req, _| {
move |req, offer| {
let mut data = offer_data.borrow_mut(); let mut data = offer_data.borrow_mut();
match req { match req {
Request::Accept { mime_type, .. } => { Request::Accept { mime_type, .. } => {
@ -297,8 +295,7 @@ where
); );
} }
let possible_actions = metadata.dnd_action & DndAction::from_bits_truncate(dnd_actions); let possible_actions = metadata.dnd_action & DndAction::from_bits_truncate(dnd_actions);
data.chosen_action = data.chosen_action = (&mut *action_choice.borrow_mut())(possible_actions, preferred_action);
(&mut *action_choice.borrow_mut())(possible_actions, preferred_action);
// check that the user provided callback respects that one precise action should be chosen // check that the user provided callback respects that one precise action should be chosen
debug_assert!( debug_assert!(
[DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action) [DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action)
@ -308,8 +305,7 @@ where
} }
_ => unreachable!(), _ => unreachable!(),
} }
}, });
None::<fn(_)>,
(), offer.deref().clone()
)
} }

View File

@ -51,8 +51,7 @@
//! //!
//! // Once this is defined, you can in your setup initialize the dmabuf global: //! // Once this is defined, you can in your setup initialize the dmabuf global:
//! //!
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut display = wayland_server::Display::new();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! // define your supported formats //! // define your supported formats
//! let formats = vec![ //! let formats = vec![
//! /* ... */ //! /* ... */
@ -70,11 +69,11 @@ use std::{cell::RefCell, os::unix::io::RawFd, rc::Rc};
pub use wayland_protocols::unstable::linux_dmabuf::v1::server::zwp_linux_buffer_params_v1::Flags; pub use wayland_protocols::unstable::linux_dmabuf::v1::server::zwp_linux_buffer_params_v1::Flags;
use wayland_protocols::unstable::linux_dmabuf::v1::server::{ use wayland_protocols::unstable::linux_dmabuf::v1::server::{
zwp_linux_buffer_params_v1::{ zwp_linux_buffer_params_v1::{
Error as ParamError, RequestHandler as ParamRequestHandler, ZwpLinuxBufferParamsV1 as BufferParams, Error as ParamError, Request as ParamsRequest, ZwpLinuxBufferParamsV1 as BufferParams,
}, },
zwp_linux_dmabuf_v1, zwp_linux_dmabuf_v1,
}; };
use wayland_server::{protocol::wl_buffer, Display, Global, NewResource}; use wayland_server::{protocol::wl_buffer, Display, Global, Main, Filter};
/// Representation of a Dmabuf format, as advertized to the client /// Representation of a Dmabuf format, as advertized to the client
pub struct Format { pub struct Format {
@ -161,9 +160,11 @@ pub trait DmabufHandler {
fn create_buffer( fn create_buffer(
&mut self, &mut self,
data: Self::BufferData, data: Self::BufferData,
buffer: NewResource<wl_buffer::WlBuffer>, buffer: Main<wl_buffer::WlBuffer>,
) -> wl_buffer::WlBuffer { ) -> wl_buffer::WlBuffer {
buffer.implement_closure(|_, _| {}, None::<fn(_)>, data) buffer.quick_assign(|_, _, _| {});
buffer.as_ref().user_data().set(|| data);
(*buffer).clone()
} }
} }
@ -193,29 +194,35 @@ where
formats.len() formats.len()
); );
display.create_global(3, move |new_dmabuf, version| { display.create_global(3, Filter::new(move |(dmabuf, version): (Main<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1>, u32), _, _| {
let dma_formats = formats.clone(); let dma_formats = formats.clone();
let dma_handler = handler.clone(); let dma_handler = handler.clone();
let dma_log = log.clone(); let dma_log = log.clone();
let dmabuf: zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1 = new_dmabuf.implement_closure( dmabuf.quick_assign(
move |req, _| { move |_, req, _| {
if let zwp_linux_dmabuf_v1::Request::CreateParams { params_id } = req { if let zwp_linux_dmabuf_v1::Request::CreateParams { params_id } = req {
params_id.implement( let mut handler = ParamsHandler {
ParamsHandler {
pending_planes: Vec::new(), pending_planes: Vec::new(),
max_planes, max_planes,
used: false, used: false,
formats: dma_formats.clone(), formats: dma_formats.clone(),
handler: dma_handler.clone(), handler: dma_handler.clone(),
log: dma_log.clone(), log: dma_log.clone(),
};
params_id.quick_assign(move |params, req, _| match req {
ParamsRequest::Add { fd, plane_idx, offset, stride, modifier_hi, modifier_lo } => {
handler.add(&*params, fd, plane_idx, offset, stride, modifier_hi, modifier_lo)
}, },
None::<fn(_)>, ParamsRequest::Create { width, height, format, flags } => {
(), handler.create(&*params, width, height, format, flags)
); },
ParamsRequest::CreateImmed { buffer_id, width, height, format, flags } => {
handler.create_immed(&*params, buffer_id, width, height, format, flags)
}
_ => {}
});
}
} }
},
None::<fn(_)>,
(),
); );
// send the supported formats // send the supported formats
@ -225,7 +232,7 @@ where
dmabuf.modifier(f.format.as_raw(), (f.modifier >> 32) as u32, f.modifier as u32); dmabuf.modifier(f.format.as_raw(), (f.modifier >> 32) as u32, f.modifier as u32);
} }
} }
}) }))
} }
struct ParamsHandler<H: DmabufHandler> { struct ParamsHandler<H: DmabufHandler> {
@ -237,10 +244,10 @@ struct ParamsHandler<H: DmabufHandler> {
log: ::slog::Logger, log: ::slog::Logger,
} }
impl<H: DmabufHandler> ParamRequestHandler for ParamsHandler<H> { impl<H: DmabufHandler> ParamsHandler<H> {
fn add( fn add(
&mut self, &mut self,
params: BufferParams, params: &BufferParams,
fd: RawFd, fd: RawFd,
plane_idx: u32, plane_idx: u32,
offset: u32, offset: u32,
@ -284,7 +291,7 @@ impl<H: DmabufHandler> ParamRequestHandler for ParamsHandler<H> {
}); });
} }
fn create(&mut self, params: BufferParams, width: i32, height: i32, format: u32, flags: u32) { fn create(&mut self, params: &BufferParams, width: i32, height: i32, format: u32, flags: u32) {
// Cannot reuse a params: // Cannot reuse a params:
if self.used { if self.used {
params.as_ref().post_error( params.as_ref().post_error(
@ -331,8 +338,8 @@ impl<H: DmabufHandler> ParamRequestHandler for ParamsHandler<H> {
fn create_immed( fn create_immed(
&mut self, &mut self,
params: BufferParams, params: &BufferParams,
buffer_id: NewResource<wl_buffer::WlBuffer>, buffer_id: Main<wl_buffer::WlBuffer>,
width: i32, width: i32,
height: i32, height: i32,
format: u32, format: u32,

View File

@ -28,8 +28,7 @@
//! use smithay::wayland::explicit_synchronization::*; //! use smithay::wayland::explicit_synchronization::*;
//! # define_roles!(MyRoles); //! # define_roles!(MyRoles);
//! # //! #
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut display = wayland_server::Display::new();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<MyRoles, _, _>( //! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<MyRoles, _, _>(
//! # &mut display, //! # &mut display,
//! # |_, _, _| {}, //! # |_, _, _| {},
@ -71,16 +70,24 @@
//! # } //! # }
//! ``` //! ```
use std::os::unix::io::RawFd; use std::{
cell::RefCell,
ops::{Deref as _, DerefMut as _},
os::unix::io::RawFd,
};
use wayland_protocols::unstable::linux_explicit_synchronization::v1::server::*; use wayland_protocols::unstable::linux_explicit_synchronization::v1::server::{
use wayland_server::{protocol::wl_surface::WlSurface, Display, Global, NewResource}; zwp_linux_buffer_release_v1::ZwpLinuxBufferReleaseV1,
zwp_linux_explicit_synchronization_v1::{self, ZwpLinuxExplicitSynchronizationV1},
zwp_linux_surface_synchronization_v1::{self, ZwpLinuxSurfaceSynchronizationV1},
};
use wayland_server::{protocol::wl_surface::WlSurface, Display, Filter, Global, Main};
use crate::wayland::compositor::{CompositorToken, SurfaceAttributes}; use crate::wayland::compositor::{CompositorToken, SurfaceAttributes};
/// An object to signal end of use of a buffer /// An object to signal end of use of a buffer
pub struct ExplicitBufferRelease { pub struct ExplicitBufferRelease {
release: zwp_linux_buffer_release_v1::ZwpLinuxBufferReleaseV1, release: ZwpLinuxBufferReleaseV1,
} }
impl ExplicitBufferRelease { impl ExplicitBufferRelease {
@ -115,16 +122,16 @@ pub struct ExplicitSyncState {
struct InternalState { struct InternalState {
sync_state: ExplicitSyncState, sync_state: ExplicitSyncState,
sync_resource: zwp_linux_surface_synchronization_v1::ZwpLinuxSurfaceSynchronizationV1, sync_resource: ZwpLinuxSurfaceSynchronizationV1,
} }
struct ESUserData { struct ESUserData {
state: Option<InternalState>, state: RefCell<Option<InternalState>>,
} }
impl ESUserData { impl ESUserData {
fn take_state(&mut self) -> Option<ExplicitSyncState> { fn take_state(&self) -> Option<ExplicitSyncState> {
if let Some(ref mut state) = self.state { if let Some(state) = self.state.borrow_mut().deref_mut() {
Some(ExplicitSyncState { Some(ExplicitSyncState {
acquire: state.sync_state.acquire.take(), acquire: state.sync_state.acquire.take(),
release: state.sync_state.release.take(), release: state.sync_state.release.take(),
@ -156,7 +163,7 @@ pub enum ExplicitSyncError {
pub fn get_explicit_synchronization_state(attrs: &mut SurfaceAttributes) -> Result<ExplicitSyncState, ()> { pub fn get_explicit_synchronization_state(attrs: &mut SurfaceAttributes) -> Result<ExplicitSyncState, ()> {
attrs attrs
.user_data .user_data
.get_mut::<ESUserData>() .get::<ESUserData>()
.and_then(|s| s.take_state()) .and_then(|s| s.take_state())
.ok_or(()) .ok_or(())
} }
@ -168,7 +175,7 @@ pub fn get_explicit_synchronization_state(attrs: &mut SurfaceAttributes) -> Resu
/// function. /// function.
pub fn send_explicit_synchronization_error(attrs: &SurfaceAttributes, error: ExplicitSyncError) { pub fn send_explicit_synchronization_error(attrs: &SurfaceAttributes, error: ExplicitSyncError) {
if let Some(ref data) = attrs.user_data.get::<ESUserData>() { if let Some(ref data) = attrs.user_data.get::<ESUserData>() {
if let Some(ref state) = data.state { if let Some(state) = data.state.borrow().deref() {
match error { match error {
ExplicitSyncError::InvalidFence => state.sync_resource.as_ref().post_error( ExplicitSyncError::InvalidFence => state.sync_resource.as_ref().post_error(
zwp_linux_surface_synchronization_v1::Error::InvalidFence as u32, zwp_linux_surface_synchronization_v1::Error::InvalidFence as u32,
@ -194,29 +201,31 @@ pub fn init_explicit_synchronization_global<R, L>(
display: &mut Display, display: &mut Display,
compositor: CompositorToken<R>, compositor: CompositorToken<R>,
logger: L, logger: L,
) -> Global<zwp_linux_explicit_synchronization_v1::ZwpLinuxExplicitSynchronizationV1> ) -> Global<ZwpLinuxExplicitSynchronizationV1>
where where
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
R: 'static, R: 'static,
{ {
let _log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "wayland_explicit_synchronization")); let _log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "wayland_explicit_synchronization"));
display.create_global::<zwp_linux_explicit_synchronization_v1::ZwpLinuxExplicitSynchronizationV1, _>( display.create_global::<ZwpLinuxExplicitSynchronizationV1, _>(
2, 2,
move |new_sync, _version| { Filter::new(
new_sync.implement_closure( move |(sync, _version): (Main<ZwpLinuxExplicitSynchronizationV1>, _), _, _| {
move |req, explicit_sync| { sync.quick_assign(move |explicit_sync, req, _| {
if let zwp_linux_explicit_synchronization_v1::Request::GetSynchronization { if let zwp_linux_explicit_synchronization_v1::Request::GetSynchronization {
id, id,
surface, surface,
} = req } = req
{ {
let exists = compositor.with_surface_data(&surface, |attrs| { let exists = compositor.with_surface_data(&surface, |attrs| {
attrs.user_data.insert_if_missing(|| ESUserData { state: None }); attrs.user_data.insert_if_missing(|| ESUserData {
state: RefCell::new(None),
});
attrs attrs
.user_data .user_data
.get::<ESUserData>() .get::<ESUserData>()
.map(|ud| ud.state.is_some()) .map(|ud| ud.state.borrow().is_some())
.unwrap() .unwrap()
}); });
if exists { if exists {
@ -228,8 +237,8 @@ where
} }
let surface_sync = implement_surface_sync(id, surface.clone(), compositor); let surface_sync = implement_surface_sync(id, surface.clone(), compositor);
compositor.with_surface_data(&surface, |attrs| { compositor.with_surface_data(&surface, |attrs| {
let data = attrs.user_data.get_mut::<ESUserData>().unwrap(); let data = attrs.user_data.get::<ESUserData>().unwrap();
data.state = Some(InternalState { *data.state.borrow_mut() = Some(InternalState {
sync_state: ExplicitSyncState { sync_state: ExplicitSyncState {
acquire: None, acquire: None,
release: None, release: None,
@ -238,24 +247,21 @@ where
}); });
}); });
} }
});
}, },
None::<fn(_)>, ),
(),
);
},
) )
} }
fn implement_surface_sync<R>( fn implement_surface_sync<R>(
id: NewResource<zwp_linux_surface_synchronization_v1::ZwpLinuxSurfaceSynchronizationV1>, id: Main<ZwpLinuxSurfaceSynchronizationV1>,
surface: WlSurface, surface: WlSurface,
compositor: CompositorToken<R>, compositor: CompositorToken<R>,
) -> zwp_linux_surface_synchronization_v1::ZwpLinuxSurfaceSynchronizationV1 ) -> ZwpLinuxSurfaceSynchronizationV1
where where
R: 'static, R: 'static,
{ {
id.implement_closure( id.quick_assign(move |surface_sync, req, _| match req {
move |req, surface_sync| match req {
zwp_linux_surface_synchronization_v1::Request::SetAcquireFence { fd } => { zwp_linux_surface_synchronization_v1::Request::SetAcquireFence { fd } => {
if !surface.as_ref().is_alive() { if !surface.as_ref().is_alive() {
surface_sync.as_ref().post_error( surface_sync.as_ref().post_error(
@ -264,8 +270,8 @@ where
) )
} }
compositor.with_surface_data(&surface, |attrs| { compositor.with_surface_data(&surface, |attrs| {
let data = attrs.user_data.get_mut::<ESUserData>().unwrap(); let data = attrs.user_data.get::<ESUserData>().unwrap();
if let Some(ref mut state) = data.state { if let Some(state) = data.state.borrow_mut().deref_mut() {
if state.sync_state.acquire.is_some() { if state.sync_state.acquire.is_some() {
surface_sync.as_ref().post_error( surface_sync.as_ref().post_error(
zwp_linux_surface_synchronization_v1::Error::DuplicateFence as u32, zwp_linux_surface_synchronization_v1::Error::DuplicateFence as u32,
@ -285,16 +291,17 @@ where
) )
} }
compositor.with_surface_data(&surface, |attrs| { compositor.with_surface_data(&surface, |attrs| {
let data = attrs.user_data.get_mut::<ESUserData>().unwrap(); let data = attrs.user_data.get::<ESUserData>().unwrap();
if let Some(ref mut state) = data.state { if let Some(state) = data.state.borrow_mut().deref_mut() {
if state.sync_state.acquire.is_some() { if state.sync_state.acquire.is_some() {
surface_sync.as_ref().post_error( surface_sync.as_ref().post_error(
zwp_linux_surface_synchronization_v1::Error::DuplicateRelease as u32, zwp_linux_surface_synchronization_v1::Error::DuplicateRelease as u32,
"Multiple releases added for a single surface commit.".into(), "Multiple releases added for a single surface commit.".into(),
) )
} else { } else {
release.quick_assign(|_, _, _| {});
state.sync_state.release = Some(ExplicitBufferRelease { state.sync_state.release = Some(ExplicitBufferRelease {
release: release.implement_dummy(), release: release.deref().clone(),
}); });
} }
} }
@ -303,14 +310,12 @@ where
zwp_linux_surface_synchronization_v1::Request::Destroy => { zwp_linux_surface_synchronization_v1::Request::Destroy => {
// disable the ESUserData // disable the ESUserData
compositor.with_surface_data(&surface, |attrs| { compositor.with_surface_data(&surface, |attrs| {
if let Some(ref mut data) = attrs.user_data.get_mut::<ESUserData>() { if let Some(ref mut data) = attrs.user_data.get::<ESUserData>() {
data.state = None; *data.state.borrow_mut() = None;
} }
}); });
} }
_ => (), _ => (),
}, });
None::<fn(_)>, id.deref().clone()
(),
)
} }

View File

@ -21,8 +21,7 @@
//! use smithay::wayland::output::{Output, PhysicalProperties, Mode}; //! use smithay::wayland::output::{Output, PhysicalProperties, Mode};
//! use wayland_server::protocol::wl_output; //! use wayland_server::protocol::wl_output;
//! //!
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut display = wayland_server::Display::new();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! // Create the Output with given name and physical properties //! // Create the Output with given name and physical properties
//! let (output, _output_global) = Output::new( //! let (output, _output_global) = Output::new(
//! &mut display, // the display //! &mut display, // the display
@ -49,12 +48,15 @@
//! output.add_mode(Mode { width: 1024, height: 768, refresh: 60000 }); //! output.add_mode(Mode { width: 1024, height: 768, refresh: 60000 });
//! ``` //! ```
use std::sync::{Arc, Mutex}; use std::{
ops::Deref as _,
sync::{Arc, Mutex},
};
use wayland_server::protocol::wl_output::{Subpixel, Transform}; use wayland_server::protocol::wl_output::{Subpixel, Transform};
use wayland_server::{ use wayland_server::{
protocol::wl_output::{Mode as WMode, WlOutput}, protocol::wl_output::{Mode as WMode, WlOutput},
Display, Global, NewResource, Display, Filter, Global, Main,
}; };
/// An output mode /// An output mode
@ -191,21 +193,24 @@ impl Output {
let output = Output { inner: inner.clone() }; let output = Output { inner: inner.clone() };
let global = display.create_global(3, move |new_output: NewResource<_>, _version| { let global = display.create_global(
let output = new_output.implement_closure( 3,
|_, _| {}, Filter::new(move |(output, _version): (Main<WlOutput>, _), _, _| {
Some(|output: WlOutput| { output.assign_destructor(Filter::new(|output: WlOutput, _, _| {
let inner = output.as_ref().user_data::<Arc<Mutex<Inner>>>().unwrap(); let inner = output.as_ref().user_data().get::<Arc<Mutex<Inner>>>().unwrap();
inner inner
.lock() .lock()
.unwrap() .unwrap()
.instances .instances
.retain(|o| !o.as_ref().equals(&output.as_ref())); .retain(|o| !o.as_ref().equals(&output.as_ref()));
}), }));
inner.clone(), output.as_ref().user_data().set_threadsafe({
); let inner = inner.clone();
inner.lock().unwrap().new_global(output); move || inner
}); });
inner.lock().unwrap().new_global(output.deref().clone());
}),
);
(output, global) (output, global)
} }

View File

@ -3,6 +3,7 @@ use std::{
cell::RefCell, cell::RefCell,
default::Default, default::Default,
io::{Error as IoError, Write}, io::{Error as IoError, Write},
ops::Deref as _,
os::unix::io::AsRawFd, os::unix::io::AsRawFd,
rc::Rc, rc::Rc,
}; };
@ -12,7 +13,7 @@ use wayland_server::{
wl_keyboard::{KeyState as WlKeyState, KeymapFormat, Request, WlKeyboard}, wl_keyboard::{KeyState as WlKeyState, KeymapFormat, Request, WlKeyboard},
wl_surface::WlSurface, wl_surface::WlSurface,
}, },
Client, NewResource, Client, Filter, Main,
}; };
use xkbcommon::xkb; use xkbcommon::xkb;
pub use xkbcommon::xkb::{keysyms, Keysym}; pub use xkbcommon::xkb::{keysyms, Keysym};
@ -448,32 +449,25 @@ impl KeyboardHandle {
} }
} }
pub(crate) fn implement_keyboard( pub(crate) fn implement_keyboard(keyboard: Main<WlKeyboard>, handle: Option<&KeyboardHandle>) -> WlKeyboard {
new_keyboard: NewResource<WlKeyboard>, keyboard.quick_assign(|_keyboard, request, _data| {
handle: Option<&KeyboardHandle>,
) -> WlKeyboard {
let destructor = match handle {
Some(h) => {
let arc = h.arc.clone();
Some(move |keyboard: WlKeyboard| {
arc.internal
.borrow_mut()
.known_kbds
.retain(|k| !k.as_ref().equals(&keyboard.as_ref()))
})
}
None => None,
};
new_keyboard.implement_closure(
|request, _keyboard| {
match request { match request {
Request::Release => { Request::Release => {
// Our destructors already handle it // Our destructors already handle it
} }
_ => unreachable!(), _ => unreachable!(),
} }
}, });
destructor,
(), if let Some(h) = handle {
) let arc = h.arc.clone();
keyboard.assign_destructor(Filter::new(move |keyboard: WlKeyboard, _, _| {
arc.internal
.borrow_mut()
.known_kbds
.retain(|k| !k.as_ref().equals(&keyboard.as_ref()))
}));
}
keyboard.deref().clone()
} }

View File

@ -17,8 +17,7 @@
//! // to set a surface as a cursor image //! // to set a surface as a cursor image
//! define_roles!(Roles => [CursorImage, CursorImageRole]); //! define_roles!(Roles => [CursorImage, CursorImageRole]);
//! //!
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut display = wayland_server::Display::new();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None); //! # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None);
//! // insert the seat: //! // insert the seat:
//! let (seat, seat_global) = Seat::new( //! let (seat, seat_global) = Seat::new(
@ -41,7 +40,7 @@
//! These methods return handles that can be cloned and sent across thread, so you can keep one around //! These methods return handles that can be cloned and sent across thread, so you can keep one around
//! in your event-handling code to forward inputs to your clients. //! in your event-handling code to forward inputs to your clients.
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, ops::Deref as _, rc::Rc};
mod keyboard; mod keyboard;
mod pointer; mod pointer;
@ -56,11 +55,9 @@ pub use self::{
use crate::wayland::compositor::{roles::Role, CompositorToken}; use crate::wayland::compositor::{roles::Role, CompositorToken};
use wayland_commons::utils::UserDataMap;
use wayland_server::{ use wayland_server::{
protocol::{wl_seat, wl_surface}, protocol::{wl_seat, wl_surface},
Display, Global, NewResource, Display, Filter, Global, Main, UserDataMap,
}; };
struct Inner { struct Inner {
@ -142,7 +139,9 @@ impl Seat {
user_data: UserDataMap::new(), user_data: UserDataMap::new(),
}); });
let seat = Seat { arc: arc.clone() }; let seat = Seat { arc: arc.clone() };
let global = display.create_global(5, move |new_seat, _version| { let global = display.create_global(
5,
Filter::new(move |(new_seat, _version), _, _| {
let seat = implement_seat(new_seat, arc.clone(), token); let seat = implement_seat(new_seat, arc.clone(), token);
let mut inner = arc.inner.borrow_mut(); let mut inner = arc.inner.borrow_mut();
if seat.as_ref().version() >= 2 { if seat.as_ref().version() >= 2 {
@ -150,14 +149,16 @@ impl Seat {
} }
seat.capabilities(inner.compute_caps()); seat.capabilities(inner.compute_caps());
inner.known_seats.push(seat); inner.known_seats.push(seat);
}); }),
);
(seat, global) (seat, global)
} }
/// Attempt to retrieve a [`Seat`] from an existing resource /// Attempt to retrieve a [`Seat`] from an existing resource
pub fn from_resource(seat: &wl_seat::WlSeat) -> Option<Seat> { pub fn from_resource(seat: &wl_seat::WlSeat) -> Option<Seat> {
seat.as_ref() seat.as_ref()
.user_data::<Rc<SeatRc>>() .user_data()
.get::<Rc<SeatRc>>()
.cloned() .cloned()
.map(|arc| Seat { arc }) .map(|arc| Seat { arc })
} }
@ -189,8 +190,7 @@ impl Seat {
/// # /// #
/// # define_roles!(Roles => [CursorImage, CursorImageRole]); /// # define_roles!(Roles => [CursorImage, CursorImageRole]);
/// # /// #
/// # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); /// # let mut display = wayland_server::Display::new();
/// # let mut display = wayland_server::Display::new(event_loop.handle());
/// # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None); /// # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None);
/// # let (mut seat, seat_global) = Seat::new( /// # let (mut seat, seat_global) = Seat::new(
/// # &mut display, /// # &mut display,
@ -332,7 +332,7 @@ impl ::std::cmp::PartialEq for Seat {
} }
fn implement_seat<R>( fn implement_seat<R>(
new_seat: NewResource<wl_seat::WlSeat>, seat: Main<wl_seat::WlSeat>,
arc: Rc<SeatRc>, arc: Rc<SeatRc>,
token: CompositorToken<R>, token: CompositorToken<R>,
) -> wl_seat::WlSeat ) -> wl_seat::WlSeat
@ -340,9 +340,8 @@ where
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + 'static,
{ {
let dest_arc = arc.clone(); let dest_arc = arc.clone();
new_seat.implement_closure( seat.quick_assign(move |seat, request, _| {
move |request, seat| { let arc = seat.as_ref().user_data().get::<Rc<SeatRc>>().unwrap();
let arc = seat.as_ref().user_data::<Rc<SeatRc>>().unwrap();
let inner = arc.inner.borrow_mut(); let inner = arc.inner.borrow_mut();
match request { match request {
wl_seat::Request::GetPointer { id } => { wl_seat::Request::GetPointer { id } => {
@ -370,14 +369,15 @@ where
} }
_ => unreachable!(), _ => unreachable!(),
} }
}, });
Some(move |seat: wl_seat::WlSeat| { seat.assign_destructor(Filter::new(move |seat: wl_seat::WlSeat, _, _| {
dest_arc dest_arc
.inner .inner
.borrow_mut() .borrow_mut()
.known_seats .known_seats
.retain(|s| !s.as_ref().equals(&seat.as_ref())); .retain(|s| !s.as_ref().equals(&seat.as_ref()));
}), }));
arc, seat.as_ref().user_data().set(move || arc);
)
seat.deref().clone()
} }

View File

@ -1,12 +1,11 @@
use std::cell::RefCell; use std::{cell::RefCell, ops::Deref as _, rc::Rc};
use std::rc::Rc;
use wayland_server::{ use wayland_server::{
protocol::{ protocol::{
wl_pointer::{self, Axis, AxisSource, ButtonState, Request, WlPointer}, wl_pointer::{self, Axis, AxisSource, ButtonState, Request, WlPointer},
wl_surface::WlSurface, wl_surface::WlSurface,
}, },
NewResource, Filter, Main,
}; };
use crate::wayland::compositor::{roles::Role, CompositorToken}; use crate::wayland::compositor::{roles::Role, CompositorToken};
@ -553,7 +552,7 @@ where
} }
pub(crate) fn implement_pointer<R>( pub(crate) fn implement_pointer<R>(
new_pointer: NewResource<WlPointer>, pointer: Main<WlPointer>,
handle: Option<&PointerHandle>, handle: Option<&PointerHandle>,
token: CompositorToken<R>, token: CompositorToken<R>,
) -> WlPointer ) -> WlPointer
@ -561,17 +560,7 @@ where
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + 'static,
{ {
let inner = handle.map(|h| h.inner.clone()); let inner = handle.map(|h| h.inner.clone());
let destructor = match inner.clone() { pointer.quick_assign(move |pointer, request, _data| {
Some(inner) => Some(move |pointer: WlPointer| {
inner
.borrow_mut()
.known_pointers
.retain(|p| !p.as_ref().equals(&pointer.as_ref()))
}),
None => None,
};
new_pointer.implement_closure(
move |request, pointer: WlPointer| {
match request { match request {
Request::SetCursor { Request::SetCursor {
surface, surface,
@ -622,10 +611,19 @@ where
} }
_ => unreachable!(), _ => unreachable!(),
} }
}, });
destructor,
(), if let Some(h) = handle {
) let inner = h.inner.clone();
pointer.assign_destructor(Filter::new(move |pointer: WlPointer, _, _| {
inner
.borrow_mut()
.known_pointers
.retain(|p| !p.as_ref().equals(&pointer.as_ref()))
}))
}
pointer.deref().clone()
} }
/* /*

View File

@ -42,8 +42,7 @@
//! [ShellSurface, ShellSurfaceRole] //! [ShellSurface, ShellSurfaceRole]
//! ); //! );
//! //!
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut display = wayland_server::Display::new();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<MyRoles, _, _>( //! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<MyRoles, _, _>(
//! # &mut display, //! # &mut display,
//! # |_, _, _| {}, //! # |_, _, _| {},
@ -71,7 +70,7 @@ use crate::wayland::compositor::{roles::Role, CompositorToken};
use wayland_server::{ use wayland_server::{
protocol::{wl_output, wl_seat, wl_shell, wl_shell_surface, wl_surface}, protocol::{wl_output, wl_seat, wl_shell, wl_shell_surface, wl_surface},
Display, Global, Display, Filter, Global,
}; };
mod wl_handlers; mod wl_handlers;
@ -315,9 +314,9 @@ where
})); }));
let state2 = state.clone(); let state2 = state.clone();
let global = display.create_global(1, move |shell, _version| { let global = display.create_global(1, Filter::new(move |(shell, _version), _, _data| {
self::wl_handlers::implement_shell(shell, ctoken, implementation.clone(), state2.clone()); self::wl_handlers::implement_shell(shell, ctoken, implementation.clone(), state2.clone());
}); }));
(state, global) (state, global)
} }

View File

@ -1,12 +1,13 @@
use std::{ use std::{
cell::RefCell, cell::RefCell,
ops::Deref as _,
rc::Rc, rc::Rc,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use wayland_server::{ use wayland_server::{
protocol::{wl_shell, wl_shell_surface, wl_surface}, protocol::{wl_shell, wl_shell_surface, wl_surface},
NewResource, Filter, Main,
}; };
use crate::wayland::compositor::{roles::Role, CompositorToken}; use crate::wayland::compositor::{roles::Role, CompositorToken};
@ -14,7 +15,7 @@ use crate::wayland::compositor::{roles::Role, CompositorToken};
use super::{ShellRequest, ShellState, ShellSurface, ShellSurfaceKind, ShellSurfaceRole}; use super::{ShellRequest, ShellState, ShellSurface, ShellSurfaceKind, ShellSurfaceRole};
pub(crate) fn implement_shell<R, Impl>( pub(crate) fn implement_shell<R, Impl>(
shell: NewResource<wl_shell::WlShell>, shell: Main<wl_shell::WlShell>,
ctoken: CompositorToken<R>, ctoken: CompositorToken<R>,
implementation: Rc<RefCell<Impl>>, implementation: Rc<RefCell<Impl>>,
state: Arc<Mutex<ShellState<R>>>, state: Arc<Mutex<ShellState<R>>>,
@ -22,8 +23,8 @@ pub(crate) fn implement_shell<R, Impl>(
R: Role<ShellSurfaceRole> + 'static, R: Role<ShellSurfaceRole> + 'static,
Impl: FnMut(ShellRequest<R>) + 'static, Impl: FnMut(ShellRequest<R>) + 'static,
{ {
shell.implement_closure( shell.quick_assign(
move |req, shell| { move |shell, req, _data| {
let (id, surface) = match req { let (id, surface) = match req {
wl_shell::Request::GetShellSurface { id, surface } => (id, surface), wl_shell::Request::GetShellSurface { id, surface } => (id, surface),
_ => unreachable!(), _ => unreachable!(),
@ -51,8 +52,6 @@ pub(crate) fn implement_shell<R, Impl>(
surface: make_handle(&shell_surface, ctoken), surface: make_handle(&shell_surface, ctoken),
}); });
}, },
None::<fn(_)>,
(),
); );
} }
@ -65,7 +64,8 @@ where
{ {
let data = shell_surface let data = shell_surface
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<R>>() .user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
ShellSurface { ShellSurface {
wl_surface: data.surface.clone(), wl_surface: data.surface.clone(),
@ -80,7 +80,7 @@ pub(crate) struct ShellSurfaceUserData<R> {
} }
fn implement_shell_surface<R, Impl>( fn implement_shell_surface<R, Impl>(
shell_surface: NewResource<wl_shell_surface::WlShellSurface>, shell_surface: Main<wl_shell_surface::WlShellSurface>,
surface: wl_surface::WlSurface, surface: wl_surface::WlSurface,
implementation: Rc<RefCell<Impl>>, implementation: Rc<RefCell<Impl>>,
ctoken: CompositorToken<R>, ctoken: CompositorToken<R>,
@ -91,11 +91,12 @@ where
Impl: FnMut(ShellRequest<R>) + 'static, Impl: FnMut(ShellRequest<R>) + 'static,
{ {
use self::wl_shell_surface::Request; use self::wl_shell_surface::Request;
shell_surface.implement_closure( shell_surface.quick_assign(
move |req, shell_surface| { move |shell_surface, req, _data| {
let data = shell_surface let data = shell_surface
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<R>>() .user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
let mut user_impl = implementation.borrow_mut(); let mut user_impl = implementation.borrow_mut();
match req { match req {
@ -185,13 +186,18 @@ where
_ => unreachable!(), _ => unreachable!(),
} }
}, },
Some(|shell_surface: wl_shell_surface::WlShellSurface| { );
shell_surface.assign_destructor(Filter::new(|shell_surface: wl_shell_surface::WlShellSurface, _, _data| {
let data = shell_surface let data = shell_surface
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<R>>() .user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
data.state.lock().unwrap().cleanup_surfaces(); data.state.lock().unwrap().cleanup_surfaces();
}), }));
ShellSurfaceUserData { surface, state },
) shell_surface.as_ref().user_data().set_threadsafe(|| ShellSurfaceUserData { surface, state });
shell_surface.deref().clone()
} }

View File

@ -47,8 +47,7 @@
//! /* ... */ //! /* ... */
//! } //! }
//! //!
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut display = wayland_server::Display::new();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<MyRoles, _, _>( //! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<MyRoles, _, _>(
//! # &mut display, //! # &mut display,
//! # |_, _, _| {}, //! # |_, _, _| {},
@ -94,14 +93,13 @@ use std::{
rc::Rc, rc::Rc,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use wayland_commons::utils::UserDataMap;
use wayland_protocols::{ use wayland_protocols::{
unstable::xdg_shell::v6::server::{zxdg_popup_v6, zxdg_shell_v6, zxdg_surface_v6, zxdg_toplevel_v6}, unstable::xdg_shell::v6::server::{zxdg_popup_v6, zxdg_shell_v6, zxdg_surface_v6, zxdg_toplevel_v6},
xdg_shell::server::{xdg_popup, xdg_positioner, xdg_surface, xdg_toplevel, xdg_wm_base}, xdg_shell::server::{xdg_popup, xdg_positioner, xdg_surface, xdg_toplevel, xdg_wm_base},
}; };
use wayland_server::{ use wayland_server::{
protocol::{wl_output, wl_seat, wl_surface}, protocol::{wl_output, wl_seat, wl_surface},
Display, Global, Display, Filter, Global, UserDataMap,
}; };
// handlers for the xdg_shell protocol // handlers for the xdg_shell protocol
@ -306,13 +304,13 @@ where
let shell_data_z = shell_data.clone(); let shell_data_z = shell_data.clone();
let xdg_shell_global = display.create_global(1, move |shell, _version| { let xdg_shell_global = display.create_global(1, Filter::new(move |(shell, _version), _, _data| {
self::xdg_handlers::implement_wm_base(shell, &shell_data); self::xdg_handlers::implement_wm_base(shell, &shell_data);
}); }));
let zxdgv6_shell_global = display.create_global(1, move |shell, _version| { let zxdgv6_shell_global = display.create_global(1, Filter::new(move |(shell, _version), _, _data| {
self::zxdgv6_handlers::implement_shell(shell, &shell_data_z); self::zxdgv6_handlers::implement_shell(shell, &shell_data_z);
}); }));
(shell_state, xdg_shell_global, zxdgv6_shell_global) (shell_state, xdg_shell_global, zxdgv6_shell_global)
} }
@ -418,7 +416,8 @@ where
ShellClientKind::Xdg(ref shell) => { ShellClientKind::Xdg(ref shell) => {
let user_data = shell let user_data = shell
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellUserData<R>>() .user_data()
.get::<self::xdg_handlers::ShellUserData<R>>()
.unwrap(); .unwrap();
let mut guard = user_data.client_data.lock().unwrap(); let mut guard = user_data.client_data.lock().unwrap();
if guard.pending_ping == 0 { if guard.pending_ping == 0 {
@ -430,7 +429,8 @@ where
ShellClientKind::ZxdgV6(ref shell) => { ShellClientKind::ZxdgV6(ref shell) => {
let user_data = shell let user_data = shell
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellUserData<R>>() .user_data()
.get::<self::zxdgv6_handlers::ShellUserData<R>>()
.unwrap(); .unwrap();
let mut guard = user_data.client_data.lock().unwrap(); let mut guard = user_data.client_data.lock().unwrap();
if guard.pending_ping == 0 { if guard.pending_ping == 0 {
@ -455,7 +455,8 @@ where
ShellClientKind::Xdg(ref shell) => { ShellClientKind::Xdg(ref shell) => {
let data = shell let data = shell
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellUserData<R>>() .user_data()
.get::<self::xdg_handlers::ShellUserData<R>>()
.unwrap(); .unwrap();
let mut guard = data.client_data.lock().unwrap(); let mut guard = data.client_data.lock().unwrap();
Ok(f(&mut guard.data)) Ok(f(&mut guard.data))
@ -463,7 +464,8 @@ where
ShellClientKind::ZxdgV6(ref shell) => { ShellClientKind::ZxdgV6(ref shell) => {
let data = shell let data = shell
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellUserData<R>>() .user_data()
.get::<self::zxdgv6_handlers::ShellUserData<R>>()
.unwrap(); .unwrap();
let mut guard = data.client_data.lock().unwrap(); let mut guard = data.client_data.lock().unwrap();
Ok(f(&mut guard.data)) Ok(f(&mut guard.data))
@ -526,14 +528,16 @@ where
ToplevelKind::Xdg(ref s) => { ToplevelKind::Xdg(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R>>() .user_data()
.get::<self::xdg_handlers::ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
ShellClientKind::Xdg(data.wm_base.clone()) ShellClientKind::Xdg(data.wm_base.clone())
} }
ToplevelKind::ZxdgV6(ref s) => { ToplevelKind::ZxdgV6(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>() .user_data()
.get::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
ShellClientKind::ZxdgV6(data.shell.clone()) ShellClientKind::ZxdgV6(data.shell.clone())
} }
@ -579,7 +583,8 @@ where
ToplevelKind::Xdg(ref s) => { ToplevelKind::Xdg(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R>>() .user_data()
.get::<self::xdg_handlers::ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
data.xdg_surface.as_ref().post_error( data.xdg_surface.as_ref().post_error(
xdg_surface::Error::NotConstructed as u32, xdg_surface::Error::NotConstructed as u32,
@ -589,7 +594,8 @@ where
ToplevelKind::ZxdgV6(ref s) => { ToplevelKind::ZxdgV6(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>() .user_data()
.get::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
data.xdg_surface.as_ref().post_error( data.xdg_surface.as_ref().post_error(
zxdg_surface_v6::Error::NotConstructed as u32, zxdg_surface_v6::Error::NotConstructed as u32,
@ -682,14 +688,16 @@ where
PopupKind::Xdg(ref p) => { PopupKind::Xdg(ref p) => {
let data = p let data = p
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R>>() .user_data()
.get::<self::xdg_handlers::ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
ShellClientKind::Xdg(data.wm_base.clone()) ShellClientKind::Xdg(data.wm_base.clone())
} }
PopupKind::ZxdgV6(ref p) => { PopupKind::ZxdgV6(ref p) => {
let data = p let data = p
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>() .user_data()
.get::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
ShellClientKind::ZxdgV6(data.shell.clone()) ShellClientKind::ZxdgV6(data.shell.clone())
} }
@ -739,7 +747,8 @@ where
PopupKind::Xdg(ref s) => { PopupKind::Xdg(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R>>() .user_data()
.get::<self::xdg_handlers::ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
data.xdg_surface.as_ref().post_error( data.xdg_surface.as_ref().post_error(
xdg_surface::Error::NotConstructed as u32, xdg_surface::Error::NotConstructed as u32,
@ -749,7 +758,8 @@ where
PopupKind::ZxdgV6(ref s) => { PopupKind::ZxdgV6(ref s) => {
let data = s let data = s
.as_ref() .as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>() .user_data()
.get::<self::zxdgv6_handlers::ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
data.xdg_surface.as_ref().post_error( data.xdg_surface.as_ref().post_error(
zxdg_surface_v6::Error::NotConstructed as u32, zxdg_surface_v6::Error::NotConstructed as u32,

View File

@ -1,10 +1,10 @@
use std::{cell::RefCell, sync::Mutex}; use std::{cell::RefCell, ops::Deref as _, sync::Mutex};
use crate::wayland::compositor::{roles::*, CompositorToken}; use crate::wayland::compositor::{roles::*, CompositorToken};
use wayland_protocols::xdg_shell::server::{ use wayland_protocols::xdg_shell::server::{
xdg_popup, xdg_positioner, xdg_surface, xdg_toplevel, xdg_wm_base, xdg_popup, xdg_positioner, xdg_surface, xdg_toplevel, xdg_wm_base,
}; };
use wayland_server::{protocol::wl_surface, NewResource}; use wayland_server::{protocol::wl_surface, Filter, Main};
use crate::utils::Rectangle; use crate::utils::Rectangle;
@ -15,15 +15,14 @@ use super::{
}; };
pub(crate) fn implement_wm_base<R>( pub(crate) fn implement_wm_base<R>(
shell: NewResource<xdg_wm_base::XdgWmBase>, shell: Main<xdg_wm_base::XdgWmBase>,
shell_data: &ShellData<R>, shell_data: &ShellData<R>,
) -> xdg_wm_base::XdgWmBase ) -> xdg_wm_base::XdgWmBase
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let shell = shell.implement_closure( shell.quick_assign(|shell, req, _data| wm_implementation::<R>(req, shell.deref().clone()));
wm_implementation::<R>, shell.as_ref().user_data().set(||
None::<fn(_)>,
ShellUserData { ShellUserData {
shell_data: shell_data.clone(), shell_data: shell_data.clone(),
client_data: Mutex::new(make_shell_client_data()), client_data: Mutex::new(make_shell_client_data()),
@ -33,7 +32,7 @@ where
(&mut *user_impl)(XdgRequest::NewClient { (&mut *user_impl)(XdgRequest::NewClient {
client: make_shell_client(&shell, shell_data.compositor_token), client: make_shell_client(&shell, shell_data.compositor_token),
}); });
shell shell.deref().clone()
} }
/* /*
@ -59,7 +58,7 @@ fn wm_implementation<R>(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWm
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = shell.as_ref().user_data::<ShellUserData<R>>().unwrap(); let data = shell.as_ref().user_data().get::<ShellUserData<R>>().unwrap();
match request { match request {
xdg_wm_base::Request::Destroy => { xdg_wm_base::Request::Destroy => {
// all is handled by destructor // all is handled by destructor
@ -86,9 +85,11 @@ where
); );
return; return;
} }
id.implement_closure( id.quick_assign(|surface, req, _data| {
xdg_surface_implementation::<R>, xdg_surface_implementation::<R>(req, surface.deref().clone())
Some(destroy_surface::<R>), });
id.assign_destructor(Filter::new(|surface, _, _data| destroy_surface::<R>(surface)));
id.as_ref().user_data().set(||
XdgSurfaceUserData { XdgSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: surface, wl_surface: surface,
@ -121,14 +122,13 @@ where
* xdg_positioner * xdg_positioner
*/ */
fn implement_positioner( fn implement_positioner(positioner: Main<xdg_positioner::XdgPositioner>) -> xdg_positioner::XdgPositioner {
positioner: NewResource<xdg_positioner::XdgPositioner>, positioner.quick_assign(
) -> xdg_positioner::XdgPositioner { |positioner, request, _data| {
positioner.implement_closure(
|request, positioner| {
let mutex = positioner let mutex = positioner
.as_ref() .as_ref()
.user_data::<RefCell<PositionerState>>() .user_data()
.get::<RefCell<PositionerState>>()
.unwrap(); .unwrap();
let mut state = mutex.borrow_mut(); let mut state = mutex.borrow_mut();
match request { match request {
@ -174,9 +174,12 @@ fn implement_positioner(
_ => unreachable!(), _ => unreachable!(),
} }
}, },
None::<fn(_)>, );
positioner.as_ref().user_data().set(||
RefCell::new(PositionerState::new()), RefCell::new(PositionerState::new()),
) );
positioner.deref().clone()
} }
/* /*
@ -193,7 +196,11 @@ fn destroy_surface<R>(surface: xdg_surface::XdgSurface)
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = surface.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap(); let data = surface
.as_ref()
.user_data()
.get::<XdgSurfaceUserData<R>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a // trying to change the role but it's a cleanup (possibly a
@ -219,7 +226,11 @@ fn xdg_surface_implementation<R>(request: xdg_surface::Request, xdg_surface: xdg
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = xdg_surface.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap(); let data = xdg_surface
.as_ref()
.user_data()
.get::<XdgSurfaceUserData<R>>()
.unwrap();
match request { match request {
xdg_surface::Request::Destroy => { xdg_surface::Request::Destroy => {
// all is handled by our destructor // all is handled by our destructor
@ -237,9 +248,11 @@ where
}); });
}) })
.expect("xdg_surface exists but surface has not shell_surface role?!"); .expect("xdg_surface exists but surface has not shell_surface role?!");
let toplevel = id.implement_closure( id.quick_assign(
toplevel_implementation::<R>, |toplevel, req, _data| toplevel_implementation::<R>(req, toplevel.deref().clone()),
Some(destroy_toplevel::<R>), );
id.assign_destructor(Filter::new(|toplevel, _, _data| destroy_toplevel::<R>(toplevel)));
id.as_ref().user_data().set(||
ShellSurfaceUserData { ShellSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -253,9 +266,9 @@ where
.lock() .lock()
.unwrap() .unwrap()
.known_toplevels .known_toplevels
.push(make_toplevel_handle(&toplevel)); .push(make_toplevel_handle(&id));
let handle = make_toplevel_handle(&toplevel); let handle = make_toplevel_handle(&id);
let mut user_impl = data.shell_data.user_impl.borrow_mut(); let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::NewToplevel { surface: handle }); (&mut *user_impl)(XdgRequest::NewToplevel { surface: handle });
} }
@ -266,11 +279,16 @@ where
} => { } => {
let positioner_data = positioner let positioner_data = positioner
.as_ref() .as_ref()
.user_data::<RefCell<PositionerState>>() .user_data()
.get::<RefCell<PositionerState>>()
.unwrap(); .unwrap();
let parent_surface = parent.map(|parent| { let parent_surface = parent.map(|parent| {
let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap(); let parent_data = parent
.as_ref()
.user_data()
.get::<XdgSurfaceUserData<R>>()
.unwrap();
parent_data.wl_surface.clone() parent_data.wl_surface.clone()
}); });
data.shell_data data.shell_data
@ -282,9 +300,9 @@ where
}); });
}) })
.expect("xdg_surface exists but surface has not shell_surface role?!"); .expect("xdg_surface exists but surface has not shell_surface role?!");
let popup = id.implement_closure( id.quick_assign(|popup, req, _data| xg_popup_implementation::<R>(req, popup.deref().clone()));
xg_popup_implementation::<R>, id.assign_destructor(Filter::new(|popup, _, _data| destroy_popup::<R>(popup)));
Some(destroy_popup::<R>), id.as_ref().user_data().set(||
ShellSurfaceUserData { ShellSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -298,9 +316,9 @@ where
.lock() .lock()
.unwrap() .unwrap()
.known_popups .known_popups
.push(make_popup_handle(&popup)); .push(make_popup_handle(&id));
let handle = make_popup_handle(&popup); let handle = make_popup_handle(&id);
let mut user_impl = data.shell_data.user_impl.borrow_mut(); let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::NewPopup { surface: handle }); (&mut *user_impl)(XdgRequest::NewPopup { surface: handle });
} }
@ -361,7 +379,11 @@ where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
F: FnOnce(&mut ToplevelState), F: FnOnce(&mut ToplevelState),
{ {
let toplevel_data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let toplevel_data = toplevel
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
shell_data shell_data
.compositor_token .compositor_token
.with_role_data::<XdgSurfaceRole, _, _>(&toplevel_data.wl_surface, |data| match data.pending_state { .with_role_data::<XdgSurfaceRole, _, _>(&toplevel_data.wl_surface, |data| match data.pending_state {
@ -375,7 +397,11 @@ pub fn send_toplevel_configure<R>(resource: &xdg_toplevel::XdgToplevel, configur
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = resource
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
let (width, height) = configure.size.unwrap_or((0, 0)); let (width, height) = configure.size.unwrap_or((0, 0));
// convert the Vec<State> (which is really a Vec<u32>) into Vec<u8> // convert the Vec<State> (which is really a Vec<u32>) into Vec<u8>
let states = { let states = {
@ -397,7 +423,11 @@ where
} }
fn make_toplevel_handle<R: 'static>(resource: &xdg_toplevel::XdgToplevel) -> super::ToplevelSurface<R> { fn make_toplevel_handle<R: 'static>(resource: &xdg_toplevel::XdgToplevel) -> super::ToplevelSurface<R> {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = resource
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
super::ToplevelSurface { super::ToplevelSurface {
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
shell_surface: ToplevelKind::Xdg(resource.clone()), shell_surface: ToplevelKind::Xdg(resource.clone()),
@ -409,7 +439,11 @@ fn toplevel_implementation<R>(request: xdg_toplevel::Request, toplevel: xdg_topl
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = toplevel
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
match request { match request {
xdg_toplevel::Request::Destroy => { xdg_toplevel::Request::Destroy => {
// all it done by the destructor // all it done by the destructor
@ -419,7 +453,8 @@ where
toplevel_data.parent = parent.map(|toplevel_surface_parent| { toplevel_data.parent = parent.map(|toplevel_surface_parent| {
toplevel_surface_parent toplevel_surface_parent
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<R>>() .user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap() .unwrap()
.wl_surface .wl_surface
.clone() .clone()
@ -456,7 +491,6 @@ where
}); });
} }
xdg_toplevel::Request::Resize { seat, serial, edges } => { xdg_toplevel::Request::Resize { seat, serial, edges } => {
let edges = xdg_toplevel::ResizeEdge::from_raw(edges).unwrap_or(xdg_toplevel::ResizeEdge::None);
let handle = make_toplevel_handle(&toplevel); let handle = make_toplevel_handle(&toplevel);
let mut user_impl = data.shell_data.user_impl.borrow_mut(); let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::Resize { (&mut *user_impl)(XdgRequest::Resize {
@ -512,7 +546,11 @@ fn destroy_toplevel<R>(toplevel: xdg_toplevel::XdgToplevel)
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = toplevel
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a // trying to change the role but it's a cleanup (possibly a
@ -543,7 +581,11 @@ pub(crate) fn send_popup_configure<R>(resource: &xdg_popup::XdgPopup, configure:
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = resource
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
let (x, y) = configure.position; let (x, y) = configure.position;
let (width, height) = configure.size; let (width, height) = configure.size;
let serial = configure.serial; let serial = configure.serial;
@ -557,7 +599,11 @@ where
} }
fn make_popup_handle<R: 'static>(resource: &xdg_popup::XdgPopup) -> super::PopupSurface<R> { fn make_popup_handle<R: 'static>(resource: &xdg_popup::XdgPopup) -> super::PopupSurface<R> {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = resource
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
super::PopupSurface { super::PopupSurface {
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
shell_surface: PopupKind::Xdg(resource.clone()), shell_surface: PopupKind::Xdg(resource.clone()),
@ -569,7 +615,11 @@ fn xg_popup_implementation<R>(request: xdg_popup::Request, popup: xdg_popup::Xdg
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = popup
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
match request { match request {
xdg_popup::Request::Destroy => { xdg_popup::Request::Destroy => {
// all is handled by our destructor // all is handled by our destructor
@ -591,7 +641,11 @@ fn destroy_popup<R>(popup: xdg_popup::XdgPopup)
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = popup
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a // trying to change the role but it's a cleanup (possibly a

View File

@ -1,4 +1,4 @@
use std::{cell::RefCell, sync::Mutex}; use std::{cell::RefCell, ops::Deref as _, sync::Mutex};
use crate::wayland::compositor::{roles::*, CompositorToken}; use crate::wayland::compositor::{roles::*, CompositorToken};
use wayland_protocols::{ use wayland_protocols::{
@ -7,7 +7,7 @@ use wayland_protocols::{
}, },
xdg_shell::server::{xdg_positioner, xdg_toplevel}, xdg_shell::server::{xdg_positioner, xdg_toplevel},
}; };
use wayland_server::{protocol::wl_surface, NewResource}; use wayland_server::{protocol::wl_surface, Filter, Main};
use crate::utils::Rectangle; use crate::utils::Rectangle;
@ -18,15 +18,14 @@ use super::{
}; };
pub(crate) fn implement_shell<R>( pub(crate) fn implement_shell<R>(
shell: NewResource<zxdg_shell_v6::ZxdgShellV6>, shell: Main<zxdg_shell_v6::ZxdgShellV6>,
shell_data: &ShellData<R>, shell_data: &ShellData<R>,
) -> zxdg_shell_v6::ZxdgShellV6 ) -> zxdg_shell_v6::ZxdgShellV6
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let shell = shell.implement_closure( shell.quick_assign(|shell, req, _data| shell_implementation::<R>(req, shell.deref().clone()));
shell_implementation::<R>, shell.as_ref().user_data().set(||
None::<fn(_)>,
ShellUserData { ShellUserData {
shell_data: shell_data.clone(), shell_data: shell_data.clone(),
client_data: Mutex::new(make_shell_client_data()), client_data: Mutex::new(make_shell_client_data()),
@ -36,7 +35,7 @@ where
(&mut *user_impl)(XdgRequest::NewClient { (&mut *user_impl)(XdgRequest::NewClient {
client: make_shell_client(&shell, shell_data.compositor_token), client: make_shell_client(&shell, shell_data.compositor_token),
}); });
shell shell.deref().clone()
} }
/* /*
@ -62,7 +61,7 @@ fn shell_implementation<R>(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = shell.as_ref().user_data::<ShellUserData<R>>().unwrap(); let data = shell.as_ref().user_data().get::<ShellUserData<R>>().unwrap();
match request { match request {
zxdg_shell_v6::Request::Destroy => { zxdg_shell_v6::Request::Destroy => {
// all is handled by destructor // all is handled by destructor
@ -89,9 +88,9 @@ where
); );
return; return;
} }
id.implement_closure( id.quick_assign(|surface, req, _data| xdg_surface_implementation::<R>(req, surface.deref().clone()));
xdg_surface_implementation::<R>, id.assign_destructor(Filter::new(|surface, _, _data| destroy_surface::<R>(surface)));
Some(destroy_surface::<R>), id.as_ref().user_data().set(||
XdgSurfaceUserData { XdgSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: surface, wl_surface: surface,
@ -125,13 +124,14 @@ where
*/ */
fn implement_positioner( fn implement_positioner(
positioner: NewResource<zxdg_positioner_v6::ZxdgPositionerV6>, positioner: Main<zxdg_positioner_v6::ZxdgPositionerV6>,
) -> zxdg_positioner_v6::ZxdgPositionerV6 { ) -> zxdg_positioner_v6::ZxdgPositionerV6 {
positioner.implement_closure( positioner.quick_assign(
|request, positioner| { |positioner, request, _data| {
let mutex = positioner let mutex = positioner
.as_ref() .as_ref()
.user_data::<RefCell<PositionerState>>() .user_data()
.get::<RefCell<PositionerState>>()
.unwrap(); .unwrap();
let mut state = mutex.borrow_mut(); let mut state = mutex.borrow_mut();
match request { match request {
@ -191,9 +191,12 @@ fn implement_positioner(
_ => unreachable!(), _ => unreachable!(),
} }
}, },
None::<fn(_)>, );
positioner.as_ref().user_data().set(||
RefCell::new(PositionerState::new()), RefCell::new(PositionerState::new()),
) );
positioner.deref().clone()
} }
/* /*
@ -210,7 +213,11 @@ fn destroy_surface<R>(surface: zxdg_surface_v6::ZxdgSurfaceV6)
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = surface.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap(); let data = surface
.as_ref()
.user_data()
.get::<XdgSurfaceUserData<R>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a // trying to change the role but it's a cleanup (possibly a
@ -238,7 +245,11 @@ fn xdg_surface_implementation<R>(
) where ) where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = xdg_surface.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap(); let data = xdg_surface
.as_ref()
.user_data()
.get::<XdgSurfaceUserData<R>>()
.unwrap();
match request { match request {
zxdg_surface_v6::Request::Destroy => { zxdg_surface_v6::Request::Destroy => {
// all is handled by our destructor // all is handled by our destructor
@ -256,9 +267,9 @@ fn xdg_surface_implementation<R>(
}); });
}) })
.expect("xdg_surface exists but surface has not shell_surface role?!"); .expect("xdg_surface exists but surface has not shell_surface role?!");
let toplevel = id.implement_closure( id.quick_assign(|toplevel, req, _data| toplevel_implementation::<R>(req, toplevel.deref().clone()));
toplevel_implementation::<R>, id.assign_destructor(Filter::new(|toplevel, _, _data| destroy_toplevel::<R>(toplevel)));
Some(destroy_toplevel::<R>), id.as_ref().user_data().set(||
ShellSurfaceUserData { ShellSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -272,9 +283,9 @@ fn xdg_surface_implementation<R>(
.lock() .lock()
.unwrap() .unwrap()
.known_toplevels .known_toplevels
.push(make_toplevel_handle(&toplevel)); .push(make_toplevel_handle(&id));
let handle = make_toplevel_handle(&toplevel); let handle = make_toplevel_handle(&id);
let mut user_impl = data.shell_data.user_impl.borrow_mut(); let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::NewToplevel { surface: handle }); (&mut *user_impl)(XdgRequest::NewToplevel { surface: handle });
} }
@ -285,10 +296,15 @@ fn xdg_surface_implementation<R>(
} => { } => {
let positioner_data = positioner let positioner_data = positioner
.as_ref() .as_ref()
.user_data::<RefCell<PositionerState>>() .user_data()
.get::<RefCell<PositionerState>>()
.unwrap(); .unwrap();
let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R>>().unwrap(); let parent_data = parent
.as_ref()
.user_data()
.get::<XdgSurfaceUserData<R>>()
.unwrap();
data.shell_data data.shell_data
.compositor_token .compositor_token
.with_role_data::<XdgSurfaceRole, _, _>(&data.wl_surface, |data| { .with_role_data::<XdgSurfaceRole, _, _>(&data.wl_surface, |data| {
@ -298,9 +314,9 @@ fn xdg_surface_implementation<R>(
}); });
}) })
.expect("xdg_surface exists but surface has not shell_surface role?!"); .expect("xdg_surface exists but surface has not shell_surface role?!");
let popup = id.implement_closure( id.quick_assign(|popup, req, _data| popup_implementation::<R>(req, popup.deref().clone()));
popup_implementation::<R>, id.assign_destructor(Filter::new(|popup, _, _data| destroy_popup::<R>(popup)));
Some(destroy_popup::<R>), id.as_ref().user_data().set(||
ShellSurfaceUserData { ShellSurfaceUserData {
shell_data: data.shell_data.clone(), shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
@ -314,9 +330,9 @@ fn xdg_surface_implementation<R>(
.lock() .lock()
.unwrap() .unwrap()
.known_popups .known_popups
.push(make_popup_handle(&popup)); .push(make_popup_handle(&id));
let handle = make_popup_handle(&popup); let handle = make_popup_handle(&id);
let mut user_impl = data.shell_data.user_impl.borrow_mut(); let mut user_impl = data.shell_data.user_impl.borrow_mut();
(&mut *user_impl)(XdgRequest::NewPopup { surface: handle }); (&mut *user_impl)(XdgRequest::NewPopup { surface: handle });
} }
@ -377,7 +393,11 @@ where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
F: FnOnce(&mut ToplevelState), F: FnOnce(&mut ToplevelState),
{ {
let data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = toplevel
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
data.shell_data data.shell_data
.compositor_token .compositor_token
.with_role_data::<XdgSurfaceRole, _, _>(&data.wl_surface, |data| match data.pending_state { .with_role_data::<XdgSurfaceRole, _, _>(&data.wl_surface, |data| match data.pending_state {
@ -391,7 +411,11 @@ pub fn send_toplevel_configure<R>(resource: &zxdg_toplevel_v6::ZxdgToplevelV6, c
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = resource
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
let (width, height) = configure.size.unwrap_or((0, 0)); let (width, height) = configure.size.unwrap_or((0, 0));
// convert the Vec<State> (which is really a Vec<u32>) into Vec<u8> // convert the Vec<State> (which is really a Vec<u32>) into Vec<u8>
let states = { let states = {
@ -415,7 +439,11 @@ where
fn make_toplevel_handle<R: 'static>( fn make_toplevel_handle<R: 'static>(
resource: &zxdg_toplevel_v6::ZxdgToplevelV6, resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
) -> super::ToplevelSurface<R> { ) -> super::ToplevelSurface<R> {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = resource
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
super::ToplevelSurface { super::ToplevelSurface {
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
shell_surface: ToplevelKind::ZxdgV6(resource.clone()), shell_surface: ToplevelKind::ZxdgV6(resource.clone()),
@ -427,7 +455,11 @@ fn toplevel_implementation<R>(request: zxdg_toplevel_v6::Request, toplevel: zxdg
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = toplevel
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
match request { match request {
zxdg_toplevel_v6::Request::Destroy => { zxdg_toplevel_v6::Request::Destroy => {
// all it done by the destructor // all it done by the destructor
@ -437,7 +469,8 @@ where
toplevel_data.parent = parent.map(|toplevel_surface_parent| { toplevel_data.parent = parent.map(|toplevel_surface_parent| {
let parent_data = toplevel_surface_parent let parent_data = toplevel_surface_parent
.as_ref() .as_ref()
.user_data::<ShellSurfaceUserData<R>>() .user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap(); .unwrap();
parent_data.wl_surface.clone() parent_data.wl_surface.clone()
}) })
@ -530,7 +563,11 @@ fn destroy_toplevel<R>(toplevel: zxdg_toplevel_v6::ZxdgToplevelV6)
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = toplevel.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = toplevel
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a // trying to change the role but it's a cleanup (possibly a
@ -561,7 +598,11 @@ pub(crate) fn send_popup_configure<R>(resource: &zxdg_popup_v6::ZxdgPopupV6, con
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = resource
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
let (x, y) = configure.position; let (x, y) = configure.position;
let (width, height) = configure.size; let (width, height) = configure.size;
let serial = configure.serial; let serial = configure.serial;
@ -575,7 +616,11 @@ where
} }
fn make_popup_handle<R: 'static>(resource: &zxdg_popup_v6::ZxdgPopupV6) -> super::PopupSurface<R> { fn make_popup_handle<R: 'static>(resource: &zxdg_popup_v6::ZxdgPopupV6) -> super::PopupSurface<R> {
let data = resource.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = resource
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
super::PopupSurface { super::PopupSurface {
wl_surface: data.wl_surface.clone(), wl_surface: data.wl_surface.clone(),
shell_surface: PopupKind::ZxdgV6(resource.clone()), shell_surface: PopupKind::ZxdgV6(resource.clone()),
@ -587,7 +632,11 @@ fn popup_implementation<R>(request: zxdg_popup_v6::Request, popup: zxdg_popup_v6
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = popup
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
match request { match request {
zxdg_popup_v6::Request::Destroy => { zxdg_popup_v6::Request::Destroy => {
// all is handled by our destructor // all is handled by our destructor
@ -609,7 +658,11 @@ fn destroy_popup<R>(popup: zxdg_popup_v6::ZxdgPopupV6)
where where
R: Role<XdgSurfaceRole> + 'static, R: Role<XdgSurfaceRole> + 'static,
{ {
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R>>().unwrap(); let data = popup
.as_ref()
.user_data()
.get::<ShellSurfaceUserData<R>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() { if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not // the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a // trying to change the role but it's a cleanup (possibly a

View File

@ -22,8 +22,7 @@
//! use smithay::wayland::shm::init_shm_global; //! use smithay::wayland::shm::init_shm_global;
//! use wayland_server::protocol::wl_shm::Format; //! use wayland_server::protocol::wl_shm::Format;
//! //!
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap(); //! # let mut display = wayland_server::Display::new();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! // Insert the ShmGlobal into your event loop //! // Insert the ShmGlobal into your event loop
//! // Here, we specify that Yuyv and C8 format are supported //! // Here, we specify that Yuyv and C8 format are supported
//! // additionally to the standard Argb8888 and Xrgb8888. //! // additionally to the standard Argb8888 and Xrgb8888.
@ -75,10 +74,10 @@
//! If you are already using an handler for this signal, you probably don't want to use this handler. //! If you are already using an handler for this signal, you probably don't want to use this handler.
use self::pool::{Pool, ResizeError}; use self::pool::{Pool, ResizeError};
use std::{rc::Rc, sync::Arc}; use std::{ops::Deref as _, rc::Rc, sync::Arc};
use wayland_server::{ use wayland_server::{
protocol::{wl_buffer, wl_shm, wl_shm_pool}, protocol::{wl_buffer, wl_shm, wl_shm_pool},
Display, Global, NewResource, Display, Filter, Global, Main,
}; };
mod pool; mod pool;
@ -120,20 +119,20 @@ where
log: log.new(o!("smithay_module" => "shm_handler")), log: log.new(o!("smithay_module" => "shm_handler")),
}; };
display.create_global::<wl_shm::WlShm, _>(1, move |shm_new: NewResource<_>, _version| { display.create_global::<wl_shm::WlShm, _>(
let shm = shm_new.implement_closure( 1,
{ Filter::new(move |(shm, _version): (Main<wl_shm::WlShm>, _), _, _| {
shm.quick_assign({
let mut data = data.clone(); let mut data = data.clone();
move |req, shm| data.receive_shm_message(req, shm) move |shm, req, _| data.receive_shm_message(req, shm.deref().clone())
}, });
None::<fn(_)>,
(),
);
// send the formats // send the formats
for &f in &data.formats[..] { for &f in &data.formats[..] {
shm.format(f); shm.format(f);
} }
}) }),
)
} }
/// Error that can occur when accessing an SHM buffer /// Error that can occur when accessing an SHM buffer
@ -164,7 +163,7 @@ pub fn with_buffer_contents<F, T>(buffer: &wl_buffer::WlBuffer, f: F) -> Result<
where where
F: FnOnce(&[u8], BufferData) -> T, F: FnOnce(&[u8], BufferData) -> T,
{ {
let data = match buffer.as_ref().user_data::<InternalBufferData>() { let data = match buffer.as_ref().user_data().get::<InternalBufferData>() {
Some(d) => d, Some(d) => d,
None => return Err(BufferAccessError::NotManaged), None => return Err(BufferAccessError::NotManaged),
}; };
@ -207,14 +206,11 @@ impl ShmGlobalData {
} }
}; };
let arc_pool = Arc::new(mmap_pool); let arc_pool = Arc::new(mmap_pool);
pool.implement_closure( pool.quick_assign({
{
let mut data = self.clone(); let mut data = self.clone();
move |req, pool| data.receive_pool_message(req, pool) move |pool, req, _| data.receive_pool_message(req, pool.deref().clone())
}, });
None::<fn(_)>, pool.as_ref().user_data().set(move || arc_pool);
arc_pool,
);
} }
} }
@ -242,7 +238,7 @@ impl ShmGlobalData {
fn receive_pool_message(&mut self, request: wl_shm_pool::Request, pool: wl_shm_pool::WlShmPool) { fn receive_pool_message(&mut self, request: wl_shm_pool::Request, pool: wl_shm_pool::WlShmPool) {
use self::wl_shm_pool::Request; use self::wl_shm_pool::Request;
let arc_pool = pool.as_ref().user_data::<Arc<Pool>>().unwrap(); let arc_pool = pool.as_ref().user_data().get::<Arc<Pool>>().unwrap();
match request { match request {
Request::CreateBuffer { Request::CreateBuffer {
@ -270,7 +266,8 @@ impl ShmGlobalData {
format, format,
}, },
}; };
buffer.implement_closure(|_, _| {}, None::<fn(_)>, data); buffer.quick_assign(|_,_,_| {});
buffer.as_ref().user_data().set(|| data);
} }
Request::Resize { size } => match arc_pool.resize(size) { Request::Resize { size } => match arc_pool.resize(size) {
Ok(()) => {} Ok(()) => {}

View File

@ -25,6 +25,7 @@
* *
*/ */
use std::{ use std::{
any::Any,
cell::RefCell, cell::RefCell,
env, env,
ffi::CString, ffi::CString,
@ -33,6 +34,12 @@ use std::{
net::UnixStream, net::UnixStream,
}, },
rc::Rc, rc::Rc,
sync::Arc,
};
use calloop::{
signals::{Signal, Signals},
LoopHandle, Source,
}; };
use nix::{ use nix::{
@ -42,13 +49,7 @@ use nix::{
Error as NixError, Result as NixResult, Error as NixError, Result as NixResult,
}; };
use wayland_server::{ use wayland_server::{Client, Display, Filter};
calloop::{
signals::{Signal, Signals},
LoopHandle, Source,
},
Client, Display,
};
use super::x11_sockets::{prepare_x11_sockets, X11Lock}; use super::x11_sockets::{prepare_x11_sockets, X11Lock};
@ -77,10 +78,11 @@ pub trait XWindowManager {
impl<WM: XWindowManager + 'static> XWayland<WM> { impl<WM: XWindowManager + 'static> XWayland<WM> {
/// Start the XWayland server /// Start the XWayland server
pub fn init<L, Data: 'static>( pub fn init<L, T: Any, Data: 'static>(
wm: WM, wm: WM,
handle: LoopHandle<Data>, handle: LoopHandle<Data>,
display: Rc<RefCell<Display>>, display: Rc<RefCell<Display>>,
data: &mut T,
logger: L, logger: L,
) -> Result<XWayland<WM>, ()> ) -> Result<XWayland<WM>, ()>
where where
@ -104,7 +106,7 @@ impl<WM: XWindowManager + 'static> XWayland<WM> {
instance: None, instance: None,
log: log.new(o!("smithay_module" => "XWayland")), log: log.new(o!("smithay_module" => "XWayland")),
})); }));
launch(&inner)?; launch(&inner, data)?;
Ok(XWayland { inner }) Ok(XWayland { inner })
} }
} }
@ -136,7 +138,10 @@ struct Inner<WM: XWindowManager> {
// Launch an XWayland server // Launch an XWayland server
// //
// Does nothing if there is already a launched instance // Does nothing if there is already a launched instance
fn launch<WM: XWindowManager + 'static>(inner: &Rc<RefCell<Inner<WM>>>) -> Result<(), ()> { fn launch<WM: XWindowManager + 'static, T: Any>(
inner: &Rc<RefCell<Inner<WM>>>,
data: &mut T,
) -> Result<(), ()> {
let mut guard = inner.borrow_mut(); let mut guard = inner.borrow_mut();
if guard.instance.is_some() { if guard.instance.is_some() {
return Ok(()); return Ok(());
@ -159,10 +164,12 @@ fn launch<WM: XWindowManager + 'static>(inner: &Rc<RefCell<Inner<WM>>>) -> Resul
guard guard
.wayland_display .wayland_display
.borrow_mut() .borrow_mut()
.create_client(wl_me.into_raw_fd()) .create_client(wl_me.into_raw_fd(), data)
}; };
client.data_map().insert_if_missing(|| inner.clone()); client.data_map().insert_if_missing(|| inner.clone());
client.add_destructor(client_destroy::<WM>); client.add_destructor(Filter::new(|e: Arc<_>, _, mut data| {
client_destroy::<WM, T>(&e, data.get().unwrap())
}));
// setup the SIGUSR1 handler // setup the SIGUSR1 handler
let sigusr1_handler = (&mut *guard.source_maker)(inner.clone())?; let sigusr1_handler = (&mut *guard.source_maker)(inner.clone())?;
@ -245,7 +252,7 @@ impl<WM: XWindowManager> Inner<WM> {
if let Some(s) = instance.sigusr1_handler.take() { if let Some(s) = instance.sigusr1_handler.take() {
s.remove(); s.remove();
} }
// All connexions and lockfiles are cleaned by their destructors // All connections and lockfiles are cleaned by their destructors
// Remove DISPLAY from the env // Remove DISPLAY from the env
::std::env::remove_var("DISPLAY"); ::std::env::remove_var("DISPLAY");
@ -257,7 +264,7 @@ impl<WM: XWindowManager> Inner<WM> {
} }
} }
fn client_destroy<WM: XWindowManager + 'static>(map: &::wayland_server::UserDataMap) { fn client_destroy<WM: XWindowManager + 'static, T: Any>(map: &::wayland_server::UserDataMap, data: &mut T) {
let inner = map.get::<Rc<RefCell<Inner<WM>>>>().unwrap(); let inner = map.get::<Rc<RefCell<Inner<WM>>>>().unwrap();
// shutdown the server // shutdown the server
@ -268,7 +275,7 @@ fn client_destroy<WM: XWindowManager + 'static>(map: &::wayland_server::UserData
// at startup there is no point // at startup there is no point
if started_at.map(|t| t.elapsed().as_secs()).unwrap_or(10) > 5 { if started_at.map(|t| t.elapsed().as_secs()).unwrap_or(10) > 5 {
warn!(inner.borrow().log, "XWayland crashed, restarting."); warn!(inner.borrow().log, "XWayland crashed, restarting.");
let _ = launch(&inner); let _ = launch(&inner, data);
} else { } else {
warn!( warn!(
inner.borrow().log, inner.borrow().log,