Skip to content
This repository has been archived by the owner on Aug 3, 2024. It is now read-only.

Commit

Permalink
Added layer shell
Browse files Browse the repository at this point in the history
  • Loading branch information
Timidger committed Jun 8, 2018
1 parent 7df1de8 commit 7ffd1a5
Show file tree
Hide file tree
Showing 6 changed files with 567 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ pub use self::events::{key_events, seat_events, tablet_pad_events, tablet_tool_e
xdg_shell_v6_events, xdg_shell_events};
pub use self::manager::{InputManagerHandler, KeyboardHandler, OutputBuilder, OutputBuilderResult,
OutputHandler, OutputManagerHandler, PointerHandler, TabletPadHandler,
TabletToolHandler, TouchHandler, XdgV6ShellHandler, XdgV6ShellManagerHandler,
XdgShellHandler, XdgShellManagerHandler};
TabletToolHandler, TouchHandler,
XdgV6ShellHandler, XdgV6ShellManagerHandler,
XdgShellHandler, XdgShellManagerHandler,
LayerShellManagerHandler, LayerShellHandler};
pub use self::types::area::*;
pub use self::types::cursor::*;
pub use self::types::data_device::*;
Expand Down
82 changes: 82 additions & 0 deletions src/manager/layer_shell_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! Handler for layer shell client.
use libc;

use wlroots_sys::{wlr_layer_surface, wlr_xdg_popup};

use {Surface, SurfaceHandle, LayerSurface, LayerSurfaceHandle, XdgShellSurface, XdgShellSurfaceHandle,
XdgPopup, XdgShellState};
use compositor::{compositor_handle, CompositorHandle};


/// Handles events from the client layer shells.
pub trait LayerShellHandler {
/// Called when the surface is ready to be mapped. It should be added to the list of views
/// at this time.
fn on_map(&mut self, CompositorHandle, SurfaceHandle, LayerSurfaceHandle) {}

/// Called when the surface should be unmapped.
///
/// It should be removed from the list of views at this time,
/// but may be remapped at a later time.
fn on_unmap(&mut self, CompositorHandle, SurfaceHandle, LayerSurfaceHandle) {}

/// Called when there is a new popup.
fn new_popup(&mut self, CompositorHandle, SurfaceHandle, LayerSurfaceHandle, XdgShellSurfaceHandle) {}
}

wayland_listener!(LayerShell, (LayerSurface, Surface, Box<LayerShellHandler>), [
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() {
Some(handle) => handle,
None => return
};
manager.on_map(compositor,
surface.weak_reference(),
shell_surface.weak_reference());
};
on_unmap_listener => on_unmap_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() {
Some(handle) => handle,
None => return
};

manager.on_unmap(compositor,
surface.weak_reference(),
shell_surface.weak_reference());
};
new_popup_listener => new_popup_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() {
Some(handle) => handle,
None => return
};
let popup_ptr = data as *mut wlr_xdg_popup;
// TODO This seems really incorrect.
// Is base right?
// Shouldn't we store this somewhere now?
// ugh
let xdg_surface = (*popup_ptr).base;
let popup = XdgPopup::from_shell(xdg_surface, popup_ptr);
let xdg_surface = XdgShellSurface::new(xdg_surface, XdgShellState::Popup(popup));

manager.new_popup(compositor,
surface.weak_reference(),
shell_surface.weak_reference(),
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()
}
}
76 changes: 76 additions & 0 deletions src/manager/layer_shell_manager.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//! 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;

use {LayerSurface, LayerSurfaceHandle, LayerShellHandler, Surface};
use super::layer_shell_handler::LayerShell;
use compositor::{compositor_handle, CompositorHandle};

pub trait LayerShellManagerHandler {
/// Callback that is triggered when a new layer shell surface appears.
fn new_surface(&mut self,
CompositorHandle,
LayerSurfaceHandle)
-> Option<Box<LayerShellHandler>>;

/// Callback that is triggered when a layer shell surface is destroyed.
fn surface_destroyed(&mut self, CompositorHandle, LayerSurfaceHandle);
}

wayland_listener!(LayerShellManager, (Vec<Box<LayerShell>>, Box<LayerShellManagerHandler>), [
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 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);
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 _,
layer_surface.on_map_listener() as _);
wl_signal_add(&mut (*data).events.unmap as *mut _ as _,
layer_surface.on_unmap_listener() as _);
wl_signal_add(&mut (*data).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 _);
}
};
]);
4 changes: 4 additions & 0 deletions src/manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ mod xdg_shell_v6_manager;
mod xdg_shell_v6_handler;
mod xdg_shell_manager;
mod xdg_shell_handler;
mod layer_shell_manager;
mod layer_shell_handler;
mod tablet_pad_handler;
mod tablet_tool_handler;

Expand All @@ -24,3 +26,5 @@ pub use self::xdg_shell_v6_handler::*;
pub use self::xdg_shell_v6_manager::*;
pub use self::xdg_shell_handler::*;
pub use self::xdg_shell_manager::*;
pub use self::layer_shell_handler::*;
pub use self::layer_shell_manager::*;
Loading

0 comments on commit 7ffd1a5

Please sign in to comment.