Update example to use shell global
This commit is contained in:
parent
a86b3d6d67
commit
aab56047f0
|
@ -1,5 +1,3 @@
|
||||||
mod shell;
|
|
||||||
mod glium;
|
mod glium;
|
||||||
|
|
||||||
pub use self::glium::GliumDrawer;
|
pub use self::glium::GliumDrawer;
|
||||||
pub use self::shell::{ShellSurfaceRole, WlShellStubHandler};
|
|
||||||
|
|
|
@ -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<U, R, H> {
|
|
||||||
my_id: Option<usize>,
|
|
||||||
token: CompositorToken<U, R, H>,
|
|
||||||
surfaces: Vec<(wl_shell_surface::WlShellSurface, wl_surface::WlSurface)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct ShellSurfaceRole;
|
|
||||||
|
|
||||||
impl<U, R, H> WlShellStubHandler<U, R, H> {
|
|
||||||
pub fn new(compositor_token: CompositorToken<U, R, H>) -> WlShellStubHandler<U, R, H> {
|
|
||||||
WlShellStubHandler {
|
|
||||||
my_id: None,
|
|
||||||
token: compositor_token,
|
|
||||||
surfaces: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn surfaces(&self) -> &[(wl_shell_surface::WlShellSurface, wl_surface::WlSurface)] {
|
|
||||||
&self.surfaces
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<U, R, H> Init for WlShellStubHandler<U, R, H> {
|
|
||||||
fn init(&mut self, evqh: &mut EventLoopHandle, index: usize) {
|
|
||||||
self.my_id = Some(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl<U, R, H> GlobalHandler<wl_shell::WlShell> for WlShellStubHandler<U, R, H>
|
|
||||||
where
|
|
||||||
U: Send + 'static,
|
|
||||||
R: RoleType + Role<ShellSurfaceRole> + Send + 'static,
|
|
||||||
H: CompositorHandler<U, R> + 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<U, R, H> wl_shell::Handler for WlShellStubHandler<U, R, H>
|
|
||||||
where
|
|
||||||
U: Send + 'static,
|
|
||||||
R: RoleType + Role<ShellSurfaceRole> + Send + 'static,
|
|
||||||
H: CompositorHandler<U, R> + 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::<ShellSurfaceRole>(&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<U: [Send], R: [RoleType, Role<ShellSurfaceRole>, Send], H: [CompositorHandler<U, R>, Send]>, wl_shell::Handler, wl_shell::WlShell);
|
|
||||||
|
|
||||||
impl<U, R, H> wl_shell_surface::Handler for WlShellStubHandler<U, R, H>
|
|
||||||
where
|
|
||||||
U: Send + 'static,
|
|
||||||
H: CompositorHandler<U, R> + Send + 'static,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
server_declare_handler!(WlShellStubHandler<U: [Send], R: [Send], H: [CompositorHandler<U, R>, Send]>, wl_shell_surface::Handler, wl_shell_surface::WlShellSurface);
|
|
|
@ -2,6 +2,7 @@
|
||||||
extern crate glium;
|
extern crate glium;
|
||||||
#[macro_use(define_roles)]
|
#[macro_use(define_roles)]
|
||||||
extern crate smithay;
|
extern crate smithay;
|
||||||
|
extern crate wayland_protocols;
|
||||||
#[macro_use(server_declare_handler)]
|
#[macro_use(server_declare_handler)]
|
||||||
extern crate wayland_server;
|
extern crate wayland_server;
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ mod helpers;
|
||||||
|
|
||||||
use glium::Surface;
|
use glium::Surface;
|
||||||
|
|
||||||
use helpers::{GliumDrawer, ShellSurfaceRole, WlShellStubHandler};
|
use helpers::GliumDrawer;
|
||||||
use slog::{Drain, Logger};
|
use slog::{Drain, Logger};
|
||||||
|
|
||||||
use smithay::backend::graphics::glium::IntoGlium;
|
use smithay::backend::graphics::glium::IntoGlium;
|
||||||
|
@ -22,10 +23,15 @@ use smithay::backend::input::InputBackend;
|
||||||
use smithay::backend::winit;
|
use smithay::backend::winit;
|
||||||
use smithay::compositor::{self, CompositorHandler, CompositorToken, SubsurfaceRole, TraversalAction};
|
use smithay::compositor::{self, CompositorHandler, CompositorToken, SubsurfaceRole, TraversalAction};
|
||||||
use smithay::compositor::roles::Role;
|
use smithay::compositor::roles::Role;
|
||||||
|
use smithay::shell::{self, PopupConfigure, PopupSurface, ShellClient, ShellHandler, ShellSurfaceRole,
|
||||||
|
ToplevelConfigure, ToplevelSurface};
|
||||||
use smithay::shm::{BufferData, ShmGlobal, ShmToken};
|
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 ] );
|
define_roles!(Roles => [ ShellSurface, ShellSurfaceRole ] );
|
||||||
|
|
||||||
|
@ -36,6 +42,7 @@ struct SurfaceHandler {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct SurfaceData {
|
struct SurfaceData {
|
||||||
buffer: Option<(Vec<u8>, (u32, u32))>,
|
buffer: Option<(Vec<u8>, (u32, u32))>,
|
||||||
|
location: Option<(u32, u32)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl compositor::Handler<SurfaceData, Roles> for SurfaceHandler {
|
impl compositor::Handler<SurfaceData, Roles> for SurfaceHandler {
|
||||||
|
@ -70,7 +77,61 @@ impl compositor::Handler<SurfaceData, Roles> for SurfaceHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ShellSurfaceHandler;
|
||||||
|
|
||||||
|
impl shell::Handler<SurfaceData, Roles, SurfaceHandler, ()> 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<SurfaceData, Roles, SurfaceHandler, ()>)
|
||||||
|
-> ToplevelConfigure {
|
||||||
|
ToplevelConfigure {
|
||||||
|
size: None,
|
||||||
|
states: vec![],
|
||||||
|
serial: 42,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn new_popup(&mut self, evlh: &mut EventLoopHandle,
|
||||||
|
surface: PopupSurface<SurfaceData, Roles, SurfaceHandler, ()>)
|
||||||
|
-> PopupConfigure {
|
||||||
|
PopupConfigure {
|
||||||
|
size: (10, 10),
|
||||||
|
position: (10, 10),
|
||||||
|
serial: 42,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn move_(&mut self, evlh: &mut EventLoopHandle,
|
||||||
|
surface: ToplevelSurface<SurfaceData, Roles, SurfaceHandler, ()>, seat: &wl_seat::WlSeat,
|
||||||
|
serial: u32) {
|
||||||
|
}
|
||||||
|
fn resize(&mut self, evlh: &mut EventLoopHandle,
|
||||||
|
surface: ToplevelSurface<SurfaceData, Roles, SurfaceHandler, ()>, seat: &wl_seat::WlSeat,
|
||||||
|
serial: u32, edges: zxdg_toplevel_v6::ResizeEdge) {
|
||||||
|
}
|
||||||
|
fn grab(&mut self, evlh: &mut EventLoopHandle,
|
||||||
|
surface: PopupSurface<SurfaceData, Roles, SurfaceHandler, ()>, seat: &wl_seat::WlSeat,
|
||||||
|
serial: u32) {
|
||||||
|
}
|
||||||
|
fn change_display_state(&mut self, evlh: &mut EventLoopHandle,
|
||||||
|
surface: ToplevelSurface<SurfaceData, Roles, SurfaceHandler, ()>,
|
||||||
|
maximized: Option<bool>, minimized: Option<bool>, fullscreen: Option<bool>,
|
||||||
|
output: Option<&wl_output::WlOutput>)
|
||||||
|
-> ToplevelConfigure {
|
||||||
|
ToplevelConfigure {
|
||||||
|
size: None,
|
||||||
|
states: vec![],
|
||||||
|
serial: 42,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn show_window_menu(&mut self, evlh: &mut EventLoopHandle,
|
||||||
|
surface: ToplevelSurface<SurfaceData, Roles, SurfaceHandler, ()>,
|
||||||
|
seat: &wl_seat::WlSeat, serial: u32, x: i32, y: i32) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type MyCompositorHandler = CompositorHandler<SurfaceData, Roles, SurfaceHandler>;
|
type MyCompositorHandler = CompositorHandler<SurfaceData, Roles, SurfaceHandler>;
|
||||||
|
type MyShellHandler = ShellHandler<SurfaceData, Roles, SurfaceHandler, ShellSurfaceHandler, ()>;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// A logger facility, here we use the terminal for this example
|
// 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 =
|
let shell_handler_id = event_loop.add_handler_with_init(MyShellHandler::new(
|
||||||
event_loop.add_handler_with_init(WlShellStubHandler::new(compositor_token.clone()));
|
ShellSurfaceHandler,
|
||||||
event_loop.register_global::<wl_shell::WlShell, WlShellStubHandler<SurfaceData, Roles, SurfaceHandler>>(
|
compositor_token.clone(),
|
||||||
shell_handler_id,
|
log.clone(),
|
||||||
1,
|
));
|
||||||
);
|
event_loop.register_global::<wl_shell::WlShell, MyShellHandler>(shell_handler_id, 1);
|
||||||
|
event_loop.register_global::<zxdg_shell_v6::ZxdgShellV6, MyShellHandler>(shell_handler_id, 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize glium
|
* Initialize glium
|
||||||
|
@ -152,32 +214,31 @@ fn main() {
|
||||||
{
|
{
|
||||||
let screen_dimensions = context.get_framebuffer_dimensions();
|
let screen_dimensions = context.get_framebuffer_dimensions();
|
||||||
let state = event_loop.state();
|
let state = event_loop.state();
|
||||||
for &(_, ref surface) in state
|
for toplevel_surface in state
|
||||||
.get_handler::<WlShellStubHandler<SurfaceData, Roles, SurfaceHandler>>(shell_handler_id)
|
.get_handler::<MyShellHandler>(shell_handler_id)
|
||||||
.surfaces()
|
.toplevel_surfaces()
|
||||||
{
|
{
|
||||||
if surface.status() != Liveness::Alive {
|
if let Some(wl_surface) = toplevel_surface.get_surface() {
|
||||||
continue;
|
// this surface is a root of a subsurface tree that needs to be drawn
|
||||||
}
|
compositor_token.with_surface_tree(
|
||||||
// this surface is a root of a subsurface tree that needs to be drawn
|
wl_surface,
|
||||||
compositor_token.with_surface_tree(
|
(100, 100),
|
||||||
surface,
|
|surface, attributes, role, &(mut x, mut y)| {
|
||||||
(100, 100),
|
if let Some((ref contents, (w, h))) = attributes.user_data.buffer {
|
||||||
|surface, attributes, role, &(mut x, mut y)| {
|
// there is actually something to draw !
|
||||||
if let Some((ref contents, (w, h))) = attributes.user_data.buffer {
|
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
|
||||||
// there is actually something to draw !
|
x += subdata.x;
|
||||||
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
|
y += subdata.y;
|
||||||
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();
|
frame.finish().unwrap();
|
||||||
|
|
|
@ -115,7 +115,7 @@ where
|
||||||
H: CompositorHandler<U, R> + Send + 'static,
|
H: CompositorHandler<U, R> + Send + 'static,
|
||||||
{
|
{
|
||||||
/// Create a new CompositorHandler
|
/// Create a new CompositorHandler
|
||||||
pub fn new<F, L>(handler: SH, token: CompositorToken<U, R, H>, logger: L) -> ShellHandler<U, R, H, SH, SD>
|
pub fn new<L>(handler: SH, token: CompositorToken<U, R, H>, logger: L) -> ShellHandler<U, R, H, SH, SD>
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue