diff --git a/src/compositor.rs b/src/compositor.rs index eb9aa20f..0280c2fd 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -15,7 +15,7 @@ use render::GenericRenderer; use wayland_sys::server::{wl_display, wl_event_loop, signal::wl_signal_add, WAYLAND_SERVER_HANDLE}; use wlroots_sys::{wlr_backend, wlr_backend_autocreate, wlr_backend_destroy, wlr_backend_start, - wlr_compositor, wlr_compositor_create, wlr_compositor_destroy, wlr_wl_shell, + wlr_compositor, wlr_compositor_create, wlr_compositor_destroy, wlr_xdg_shell_v6, wlr_xdg_shell_v6_create, wlr_xdg_shell, wlr_xdg_shell_create, wlr_layer_shell_create, wlr_layer_shell}; use wlroots_sys::wayland_server::sys::wl_display_init_shm; @@ -331,7 +331,7 @@ impl CompositorBuilder { let mut layer_shell_global = ptr::null_mut(); let layer_shell_manager = self.layer_shell_manager_handler.map(|handler| { layer_shell_global = wlr_layer_shell_create(display as *mut _); - let mut layer_shell_manager = LayerShellManager::new((vec![], handler)); + let mut layer_shell_manager = LayerShellManager::new(handler); wl_signal_add(&mut (*layer_shell_global).events.new_surface as *mut _ as _, layer_shell_manager.add_listener() as *mut _ as _); layer_shell_manager diff --git a/src/manager/layer_shell_handler.rs b/src/manager/layer_shell_handler.rs index d3cafd27..5902dd13 100644 --- a/src/manager/layer_shell_handler.rs +++ b/src/manager/layer_shell_handler.rs @@ -2,6 +2,7 @@ use libc; +use wayland_sys::server::WAYLAND_SERVER_HANDLE; use wlroots_sys::{wlr_layer_surface, wlr_xdg_popup}; use {Surface, SurfaceHandle, LayerSurface, LayerSurfaceHandle, XdgShellSurface, XdgShellSurfaceHandle, @@ -23,9 +24,38 @@ pub trait LayerShellHandler { /// Called when there is a new popup. fn new_popup(&mut self, CompositorHandle, SurfaceHandle, LayerSurfaceHandle, XdgShellSurfaceHandle) {} + + /// Called when the Layer Shell is destroyed. + fn destroyed(&mut self, CompositorHandle, SurfaceHandle, LayerSurfaceHandle) {} } wayland_listener!(LayerShell, (LayerSurface, Surface, Box), [ + destroy_listener => destroy_notify: |this: &mut LayerShell, data: *mut libc::c_void,| unsafe { + let layer_surface_ptr = data as *mut wlr_layer_surface; + { + let (ref shell_surface, ref surface, ref mut manager) = this.data; + let compositor = match compositor_handle() { + Some(handle) => handle, + None => return + }; + manager.destroyed(compositor, + surface.weak_reference(), + shell_surface.weak_reference()); + } + ffi_dispatch!(WAYLAND_SERVER_HANDLE, + wl_list_remove, + &mut (*this.destroy_listener()).link as *mut _ as _); + ffi_dispatch!(WAYLAND_SERVER_HANDLE, + wl_list_remove, + &mut (*this.on_map_listener()).link as *mut _ as _); + ffi_dispatch!(WAYLAND_SERVER_HANDLE, + wl_list_remove, + &mut (*this.on_unmap_listener()).link as *mut _ as _); + ffi_dispatch!(WAYLAND_SERVER_HANDLE, + wl_list_remove, + &mut (*this.new_popup_listener()).link as *mut _ as _); + Box::from_raw((*layer_surface_ptr).data as *mut LayerShell); + }; on_map_listener => on_map_notify: |this: &mut LayerShell, _data: *mut libc::c_void,| unsafe { let (ref shell_surface, ref surface, ref mut manager) = this.data; let compositor = match compositor_handle() { @@ -70,13 +100,3 @@ wayland_listener!(LayerShell, (LayerSurface, Surface, Box), [ xdg_surface.weak_reference()); }; ]); - -impl LayerShell { - pub(crate) unsafe fn surface_ptr(&self) -> *mut wlr_layer_surface { - self.data.0.as_ptr() - } - - pub(crate) fn surface_mut(&mut self) -> LayerSurfaceHandle { - self.data.0.weak_reference() - } -} diff --git a/src/manager/layer_shell_manager.rs b/src/manager/layer_shell_manager.rs index 2ce31bcc..54f14104 100644 --- a/src/manager/layer_shell_manager.rs +++ b/src/manager/layer_shell_manager.rs @@ -1,7 +1,6 @@ //! Manager for layer shell clients. use libc; -use wayland_sys::server::WAYLAND_SERVER_HANDLE; use wayland_sys::server::signal::wl_signal_add; use wlroots_sys::wlr_layer_surface; @@ -15,62 +14,33 @@ pub trait LayerShellManagerHandler { CompositorHandle, LayerSurfaceHandle) -> Option>; - - /// Callback that is triggered when a layer shell surface is destroyed. - fn surface_destroyed(&mut self, CompositorHandle, LayerSurfaceHandle); } -wayland_listener!(LayerShellManager, (Vec>, Box), [ +wayland_listener!(LayerShellManager, Box, [ add_listener => add_notify: |this: &mut LayerShellManager, data: *mut libc::c_void,| unsafe { - let remove_listener = this.remove_listener() as *mut _ as _; - let (ref mut shells, ref mut manager) = this.data; - let data = data as *mut wlr_layer_surface; + let ref mut manager = this.data; + let layer_surface_ptr = data as *mut wlr_layer_surface; let compositor = match compositor_handle() { Some(handle) => handle, None => return }; - wlr_log!(L_DEBUG, "New layer shell surface request {:p}", data); - let surface = Surface::new((*data).surface); - let layer_surface = LayerSurface::new(data); + wlr_log!(L_DEBUG, "New layer shell surface request {:p}", layer_surface_ptr); + let surface = Surface::new((*layer_surface_ptr).surface); + let layer_surface = LayerSurface::new(layer_surface_ptr); let new_surface_res = manager.new_surface(compositor, layer_surface.weak_reference()); if let Some(layer_surface_handler) = new_surface_res { let mut layer_surface = LayerShell::new((layer_surface, surface, layer_surface_handler)); - // Hook the destroy event into this manager. - wl_signal_add(&mut (*data).events.destroy as *mut _ as _, - remove_listener); - - // Hook the other events into the shell surface. - wl_signal_add(&mut (*data).events.map as *mut _ as _, + wl_signal_add(&mut (*layer_surface_ptr).events.destroy as *mut _ as _, + layer_surface.destroy_listener() as _); + wl_signal_add(&mut (*layer_surface_ptr).events.map as *mut _ as _, layer_surface.on_map_listener() as _); - wl_signal_add(&mut (*data).events.unmap as *mut _ as _, + wl_signal_add(&mut (*layer_surface_ptr).events.unmap as *mut _ as _, layer_surface.on_unmap_listener() as _); - wl_signal_add(&mut (*data).events.new_popup as *mut _ as _, + wl_signal_add(&mut (*layer_surface_ptr).events.new_popup as *mut _ as _, layer_surface.new_popup_listener() as _); - shells.push(layer_surface); - } - }; - remove_listener => remove_notify: |this: &mut LayerShellManager, data: *mut libc::c_void,| - unsafe { - let (ref mut shells, ref mut manager) = this.data; - let data = data as *mut wlr_layer_surface; - let compositor = match compositor_handle() { - Some(handle) => handle, - None => return - }; - if let Some(index) = shells.iter().position(|shell| shell.surface_ptr() == data) { - let mut removed_shell = shells.remove(index); - manager.surface_destroyed(compositor, removed_shell.surface_mut()); - ffi_dispatch!(WAYLAND_SERVER_HANDLE, - wl_list_remove, - &mut (*removed_shell.on_map_listener()).link as *mut _ as _); - ffi_dispatch!(WAYLAND_SERVER_HANDLE, - wl_list_remove, - &mut (*removed_shell.on_unmap_listener()).link as *mut _ as _); - ffi_dispatch!(WAYLAND_SERVER_HANDLE, - wl_list_remove, - &mut (*removed_shell.new_popup_listener()).link as *mut _ as _); + (*layer_surface_ptr).data = Box::into_raw(layer_surface) as *mut _; } }; ]); diff --git a/src/types/shell/layer_shell.rs b/src/types/shell/layer_shell.rs index a6119282..ee71c8c1 100644 --- a/src/types/shell/layer_shell.rs +++ b/src/types/shell/layer_shell.rs @@ -116,10 +116,6 @@ impl LayerSurface { layer_surface } } - pub(crate) unsafe fn as_ptr(&self) -> *mut wlr_layer_surface { - self.layer_surface - } - unsafe fn from_handle(handle: &LayerSurfaceHandle) -> HandleResult { let liveliness = handle.handle .upgrade()