diff --git a/examples/helpers/mod.rs b/examples/helpers/mod.rs index 6964d2b..407fec4 100644 --- a/examples/helpers/mod.rs +++ b/examples/helpers/mod.rs @@ -1,5 +1,3 @@ -mod shell; mod glium; pub use self::glium::GliumDrawer; -pub use self::shell::{ShellSurfaceRole, WlShellStubHandler}; diff --git a/examples/helpers/shell.rs b/examples/helpers/shell.rs deleted file mode 100644 index e3d9b14..0000000 --- a/examples/helpers/shell.rs +++ /dev/null @@ -1,93 +0,0 @@ - - -use smithay::compositor::{CompositorToken, Handler as CompositorHandler}; -use smithay::compositor::roles::{Role, RoleType}; -use wayland_server::{Client, EventLoopHandle, GlobalHandler, Init, Resource}; -use wayland_server::protocol::{wl_shell, wl_shell_surface, wl_surface}; - -/// A very basic handler for wl_shell -/// -/// All it does is track which wl_shell_surface exist and which do not, -/// as well as the roles associated to them. -/// -/// That's it. -pub struct WlShellStubHandler { - my_id: Option, - token: CompositorToken, - surfaces: Vec<(wl_shell_surface::WlShellSurface, wl_surface::WlSurface)>, -} - -#[derive(Default)] -pub struct ShellSurfaceRole; - -impl WlShellStubHandler { - pub fn new(compositor_token: CompositorToken) -> WlShellStubHandler { - WlShellStubHandler { - my_id: None, - token: compositor_token, - surfaces: Vec::new(), - } - } - - pub fn surfaces(&self) -> &[(wl_shell_surface::WlShellSurface, wl_surface::WlSurface)] { - &self.surfaces - } -} - -impl Init for WlShellStubHandler { - fn init(&mut self, evqh: &mut EventLoopHandle, index: usize) { - self.my_id = Some(index) - } -} - - -impl GlobalHandler for WlShellStubHandler -where - U: Send + 'static, - R: RoleType + Role + Send + 'static, - H: CompositorHandler + Send + 'static, -{ - fn bind(&mut self, evqh: &mut EventLoopHandle, client: &Client, global: wl_shell::WlShell) { - evqh.register::<_, Self>( - &global, - self.my_id - .expect("WlShellStubHandler was not properly initialized."), - ); - } -} - -impl wl_shell::Handler for WlShellStubHandler -where - U: Send + 'static, - R: RoleType + Role + Send + 'static, - H: CompositorHandler + Send + 'static, -{ - fn get_shell_surface(&mut self, evqh: &mut EventLoopHandle, client: &Client, - resource: &wl_shell::WlShell, id: wl_shell_surface::WlShellSurface, - surface: &wl_surface::WlSurface) { - let surface = surface.clone().expect( - "WlShellStubHandler can only manage surfaces managed by Smithay's CompositorHandler.", - ); - if self.token.give_role::(&surface).is_err() { - // This surface already has a role, and thus cannot be given one! - resource.post_error( - wl_shell::Error::Role as u32, - "Surface already has a role.".into(), - ); - return; - } - evqh.register::<_, Self>(&id, self.my_id.unwrap()); - self.surfaces.push((id, surface)) - } -} - -server_declare_handler!(WlShellStubHandler, Send], H: [CompositorHandler, Send]>, wl_shell::Handler, wl_shell::WlShell); - -impl wl_shell_surface::Handler for WlShellStubHandler -where - U: Send + 'static, - H: CompositorHandler + Send + 'static, -{ -} - -server_declare_handler!(WlShellStubHandler, Send]>, wl_shell_surface::Handler, wl_shell_surface::WlShellSurface); diff --git a/examples/simple.rs b/examples/simple.rs index 8635357..2abf90a 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -2,6 +2,7 @@ extern crate glium; #[macro_use(define_roles)] extern crate smithay; +extern crate wayland_protocols; #[macro_use(server_declare_handler)] extern crate wayland_server; @@ -14,7 +15,7 @@ mod helpers; use glium::Surface; -use helpers::{GliumDrawer, ShellSurfaceRole, WlShellStubHandler}; +use helpers::GliumDrawer; use slog::{Drain, Logger}; use smithay::backend::graphics::glium::IntoGlium; @@ -22,10 +23,15 @@ use smithay::backend::input::InputBackend; use smithay::backend::winit; use smithay::compositor::{self, CompositorHandler, CompositorToken, SubsurfaceRole, TraversalAction}; use smithay::compositor::roles::Role; +use smithay::shell::{self, PopupConfigure, PopupSurface, ShellClient, ShellHandler, ShellSurfaceRole, + ToplevelConfigure, ToplevelSurface}; use smithay::shm::{BufferData, ShmGlobal, ShmToken}; -use wayland_server::{Client, EventLoopHandle, Liveness, Resource}; -use wayland_server::protocol::{wl_compositor, wl_shell, wl_shm, wl_subcompositor, wl_surface}; +use wayland_protocols::unstable::xdg_shell::server::{zxdg_shell_v6, zxdg_toplevel_v6}; + +use wayland_server::{Client, EventLoopHandle, Liveness, Resource}; +use wayland_server::protocol::{wl_compositor, wl_output, wl_seat, wl_shell, wl_shm, wl_subcompositor, + wl_surface}; define_roles!(Roles => [ ShellSurface, ShellSurfaceRole ] ); @@ -36,6 +42,7 @@ struct SurfaceHandler { #[derive(Default)] struct SurfaceData { buffer: Option<(Vec, (u32, u32))>, + location: Option<(u32, u32)>, } impl compositor::Handler for SurfaceHandler { @@ -70,7 +77,61 @@ impl compositor::Handler for SurfaceHandler { } } +struct ShellSurfaceHandler; + +impl shell::Handler for ShellSurfaceHandler { + fn new_client(&mut self, evlh: &mut EventLoopHandle, client: ShellClient<()>) {} + fn client_pong(&mut self, evlh: &mut EventLoopHandle, client: ShellClient<()>) {} + fn new_toplevel(&mut self, evlh: &mut EventLoopHandle, + surface: ToplevelSurface) + -> ToplevelConfigure { + ToplevelConfigure { + size: None, + states: vec![], + serial: 42, + } + } + fn new_popup(&mut self, evlh: &mut EventLoopHandle, + surface: PopupSurface) + -> PopupConfigure { + PopupConfigure { + size: (10, 10), + position: (10, 10), + serial: 42, + } + } + fn move_(&mut self, evlh: &mut EventLoopHandle, + surface: ToplevelSurface, seat: &wl_seat::WlSeat, + serial: u32) { + } + fn resize(&mut self, evlh: &mut EventLoopHandle, + surface: ToplevelSurface, seat: &wl_seat::WlSeat, + serial: u32, edges: zxdg_toplevel_v6::ResizeEdge) { + } + fn grab(&mut self, evlh: &mut EventLoopHandle, + surface: PopupSurface, seat: &wl_seat::WlSeat, + serial: u32) { + } + fn change_display_state(&mut self, evlh: &mut EventLoopHandle, + surface: ToplevelSurface, + maximized: Option, minimized: Option, fullscreen: Option, + output: Option<&wl_output::WlOutput>) + -> ToplevelConfigure { + ToplevelConfigure { + size: None, + states: vec![], + serial: 42, + } + } + fn show_window_menu(&mut self, evlh: &mut EventLoopHandle, + surface: ToplevelSurface, + seat: &wl_seat::WlSeat, serial: u32, x: i32, y: i32) { + } +} + + type MyCompositorHandler = CompositorHandler; +type MyShellHandler = ShellHandler; fn main() { // A logger facility, here we use the terminal for this example @@ -121,14 +182,15 @@ fn main() { }; /* - * Initialize the shell stub global + * Initialize the shell global */ - let shell_handler_id = - event_loop.add_handler_with_init(WlShellStubHandler::new(compositor_token.clone())); - event_loop.register_global::>( - shell_handler_id, - 1, - ); + let shell_handler_id = event_loop.add_handler_with_init(MyShellHandler::new( + ShellSurfaceHandler, + compositor_token.clone(), + log.clone(), + )); + event_loop.register_global::(shell_handler_id, 1); + event_loop.register_global::(shell_handler_id, 1); /* * Initialize glium @@ -152,32 +214,31 @@ fn main() { { let screen_dimensions = context.get_framebuffer_dimensions(); let state = event_loop.state(); - for &(_, ref surface) in state - .get_handler::>(shell_handler_id) - .surfaces() + for toplevel_surface in state + .get_handler::(shell_handler_id) + .toplevel_surfaces() { - if surface.status() != Liveness::Alive { - continue; - } - // this surface is a root of a subsurface tree that needs to be drawn - compositor_token.with_surface_tree( - surface, - (100, 100), - |surface, attributes, role, &(mut x, mut y)| { - if let Some((ref contents, (w, h))) = attributes.user_data.buffer { - // there is actually something to draw ! - if let Ok(subdata) = Role::::data(role) { - x += subdata.x; - y += subdata.y; + if let Some(wl_surface) = toplevel_surface.get_surface() { + // this surface is a root of a subsurface tree that needs to be drawn + compositor_token.with_surface_tree( + wl_surface, + (100, 100), + |surface, attributes, role, &(mut x, mut y)| { + if let Some((ref contents, (w, h))) = attributes.user_data.buffer { + // there is actually something to draw ! + if let Ok(subdata) = Role::::data(role) { + x += subdata.x; + y += subdata.y; + } + drawer.draw(&mut frame, contents, (w, h), (x, y), screen_dimensions); + TraversalAction::DoChildren((x, y)) + } else { + // we are not display, so our children are neither + TraversalAction::SkipChildren } - drawer.draw(&mut frame, contents, (w, h), (x, y), screen_dimensions); - TraversalAction::DoChildren((x, y)) - } else { - // we are not display, so our children are neither - TraversalAction::SkipChildren - } - }, - ); + }, + ); + } } } frame.finish().unwrap(); diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 00cbc5c..1777b7d 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -115,7 +115,7 @@ where H: CompositorHandler + Send + 'static, { /// Create a new CompositorHandler - pub fn new(handler: SH, token: CompositorToken, logger: L) -> ShellHandler + pub fn new(handler: SH, token: CompositorToken, logger: L) -> ShellHandler where L: Into>, {