feat(wayland): implement all essential handlers

This commit is contained in:
Nova
2022-08-22 07:57:03 -04:00
parent bf4d5ba015
commit 060bd59d01
5 changed files with 183 additions and 36 deletions

View File

@@ -121,6 +121,11 @@ fn main() -> Result<()> {
},
);
drop(wayland_state);
drop(socket);
drop(display);
println!("Cleanly shut down the Wayland compositor");
let _ = event_stop_tx.send(());
event_thread
.join()

23
src/wayland/compositor.rs Normal file
View File

@@ -0,0 +1,23 @@
use super::WaylandState;
use smithay::{
backend::renderer::utils::{import_surface_tree, on_commit_buffer_handler},
delegate_compositor,
wayland::compositor::CompositorHandler,
};
impl CompositorHandler for WaylandState {
fn compositor_state(&mut self) -> &mut smithay::wayland::compositor::CompositorState {
&mut self.compositor_state
}
fn commit(
&mut self,
_dh: &smithay::reexports::wayland_server::DisplayHandle,
surface: &smithay::reexports::wayland_server::protocol::wl_surface::WlSurface,
) {
on_commit_buffer_handler(surface);
import_surface_tree(&mut self.renderer, surface, &self.log).unwrap();
}
}
delegate_compositor!(WaylandState);

View File

@@ -1,21 +1,38 @@
pub mod compositor;
pub mod xdg_decoration;
mod xdg_shell;
use anyhow::Result;
use slog::Logger;
use smithay::{
backend::renderer::gles2::Gles2Renderer,
delegate_output, delegate_shm,
reexports::wayland_server::{
backend::{ClientData, ClientId, DisconnectReason},
protocol::wl_output::Subpixel,
Display, DisplayHandle,
},
utils::Size,
wayland::{
buffer::BufferHandler,
compositor::CompositorState,
output::{Output, OutputManagerState, Scale::Integer},
seat::SeatState,
shell::xdg::{decoration::XdgDecorationState, XdgShellState},
shm::{ShmHandler, ShmState},
},
};
pub struct ClientState;
impl ClientData for ClientState {
fn initialized(&self, _client_id: ClientId) {
println!("initialized");
fn initialized(&self, client_id: ClientId) {
println!("Wayland client {:?} connected", client_id);
}
fn disconnected(&self, _client_id: ClientId, _reason: DisconnectReason) {
println!("disconnected");
fn disconnected(&self, client_id: ClientId, reason: DisconnectReason) {
println!(
"Wayland client {:?} disconnected because {:#?}",
client_id, reason
);
}
}
@@ -24,13 +41,13 @@ pub struct WaylandState {
pub display_handle: DisplayHandle,
pub renderer: Gles2Renderer,
// pub compositor_state: CompositorState,
// pub xdg_shell_state: XdgShellState,
// pub xdg_decoration_state: XdgDecorationState,
// pub shm_state: ShmState,
// pub output_manager_state: OutputManagerState,
// pub output: Output,
// pub seat_state: SeatState<WaylandState>,
pub compositor_state: CompositorState,
pub xdg_shell_state: XdgShellState,
pub xdg_decoration_state: XdgDecorationState,
pub shm_state: ShmState,
pub output_manager_state: OutputManagerState,
pub output: Output,
pub seat_state: SeatState<WaylandState>,
// pub data_device_state: DataDeviceState,
}
@@ -42,38 +59,52 @@ impl WaylandState {
) -> Result<Self> {
let display_handle = display.handle();
// let compositor_state = CompositorState::new::<Self, _>(&display_handle, log.clone());
// let xdg_shell_state = XdgShellState::new::<Self, _>(&display_handle, log.clone());
// let xdg_decoration_state = XdgDecorationState::new::<Self, _>(&display_handle, log.clone());
// let shm_state = ShmState::new::<Self, _>(&display_handle, vec![], log.clone());
// let output_manager_state = OutputManagerState::new_with_xdg_output::<Self>(&display_handle);
// let output = Output::new(
// "1x".to_owned(),
// smithay::wayland::output::PhysicalProperties {
// size: Size::default(),
// subpixel: Subpixel::None,
// make: "Virtual XR Display".to_owned(),
// model: "Your Headset Name Here".to_owned(),
// },
// log.clone(),
// );
// let _global = output.create_global::<Self>(&display_handle);
// output.change_current_state(None, None, Some(Integer(2)), None);
// let seat_state = SeatState::new();
let compositor_state = CompositorState::new::<Self, _>(&display_handle, log.clone());
let xdg_shell_state = XdgShellState::new::<Self, _>(&display_handle, log.clone());
let xdg_decoration_state = XdgDecorationState::new::<Self, _>(&display_handle, log.clone());
let shm_state = ShmState::new::<Self, _>(&display_handle, vec![], log.clone());
let output_manager_state = OutputManagerState::new_with_xdg_output::<Self>(&display_handle);
let output = Output::new(
"1x".to_owned(),
smithay::wayland::output::PhysicalProperties {
size: Size::default(),
subpixel: Subpixel::None,
make: "Virtual XR Display".to_owned(),
model: "Your Headset Name Here".to_owned(),
},
log.clone(),
);
let _global = output.create_global::<Self>(&display_handle);
output.change_current_state(None, None, Some(Integer(2)), None);
let seat_state = SeatState::new();
// let data_device_state = DataDeviceState::new(&dh, log.clone());
Ok(WaylandState {
log,
display_handle,
renderer,
// compositor_state,
// xdg_shell_state,
// xdg_decoration_state,
// shm_state,
// output_manager_state,
// output,
// seat_state,
compositor_state,
xdg_shell_state,
xdg_decoration_state,
shm_state,
output_manager_state,
output,
seat_state,
// data_device_state,
})
}
}
impl BufferHandler for WaylandState {
fn buffer_destroyed(
&mut self,
_buffer: &smithay::reexports::wayland_server::protocol::wl_buffer::WlBuffer,
) {
}
}
impl ShmHandler for WaylandState {
fn shm_state(&self) -> &smithay::wayland::shm::ShmState {
&self.shm_state
}
}
delegate_shm!(WaylandState);
delegate_output!(WaylandState);

View File

@@ -0,0 +1,36 @@
use smithay::{
delegate_xdg_decoration,
reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode,
wayland::shell::xdg::decoration::XdgDecorationHandler,
};
use super::WaylandState;
impl XdgDecorationHandler for WaylandState {
fn new_decoration(
&mut self,
_dh: &smithay::reexports::wayland_server::DisplayHandle,
toplevel: smithay::wayland::shell::xdg::ToplevelSurface,
) {
toplevel.with_pending_state(|state| {
state.decoration_mode = Some(Mode::ServerSide);
});
toplevel.send_configure();
}
fn request_mode(
&mut self,
_dh: &smithay::reexports::wayland_server::DisplayHandle,
_toplevel: smithay::wayland::shell::xdg::ToplevelSurface,
_mode: smithay::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode,
) {
}
fn unset_mode(
&mut self,
_dh: &smithay::reexports::wayland_server::DisplayHandle,
_toplevel: smithay::wayland::shell::xdg::ToplevelSurface,
) {
}
}
delegate_xdg_decoration!(WaylandState);

52
src/wayland/xdg_shell.rs Normal file
View File

@@ -0,0 +1,52 @@
use smithay::{
delegate_xdg_shell,
reexports::wayland_protocols::xdg::{
decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode,
shell::server::xdg_toplevel::State,
},
wayland::shell::xdg::XdgShellHandler,
};
use super::WaylandState;
impl XdgShellHandler for WaylandState {
fn xdg_shell_state(&mut self) -> &mut smithay::wayland::shell::xdg::XdgShellState {
&mut self.xdg_shell_state
}
fn new_toplevel(
&mut self,
_dh: &smithay::reexports::wayland_server::DisplayHandle,
surface: smithay::wayland::shell::xdg::ToplevelSurface,
) {
self.output
.enter(&self.display_handle, surface.wl_surface());
surface.with_pending_state(|state| {
state.states.set(State::Fullscreen);
state.decoration_mode = Some(Mode::ServerSide);
});
surface.send_configure();
}
fn new_popup(
&mut self,
_dh: &smithay::reexports::wayland_server::DisplayHandle,
surface: smithay::wayland::shell::xdg::PopupSurface,
_positioner: smithay::wayland::shell::xdg::PositionerState,
) {
self.output
.enter(&self.display_handle, surface.wl_surface());
let _ = surface.send_configure();
}
fn grab(
&mut self,
_dh: &smithay::reexports::wayland_server::DisplayHandle,
_surface: smithay::wayland::shell::xdg::PopupSurface,
_seat: smithay::reexports::wayland_server::protocol::wl_seat::WlSeat,
_serial: smithay::wayland::Serial,
) {
todo!()
}
}
delegate_xdg_shell!(WaylandState);