use crate::wayland::session_lock::lock_context::LockSurfaceParams; use log::info; use std::rc::Rc; use wayland_client::{Proxy, backend::ObjectId, protocol::wl_surface::WlSurface}; use wayland_protocols::ext::session_lock::v1::client::ext_session_lock_surface_v1::ExtSessionLockSurfaceV1; use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1; use wayland_protocols::wp::viewporter::client::wp_viewport::WpViewport; pub struct LockSurface { surface: Rc, session_surface: Rc, fractional_scale: Option>, viewport: Option>, width: u32, height: u32, configured: bool, } impl LockSurface { pub fn create(params: &LockSurfaceParams<'_>) -> Self { let surface = Rc::new(params.compositor.create_surface(params.queue_handle, ())); let session_surface = Rc::new(params.session_lock.get_lock_surface( &surface, params.output, params.queue_handle, (), )); let fractional_scale = params.fractional_scale_manager.map(|manager| { info!("Creating fractional scale object for lock surface"); Rc::new(manager.get_fractional_scale(&surface, params.queue_handle, ())) }); let viewport = params.viewporter.map(|vp| { info!("Creating viewport for lock surface"); Rc::new(vp.get_viewport(&surface, params.queue_handle, ())) }); surface.set_buffer_scale(1); Self { surface, session_surface, fractional_scale, viewport, width: 0, height: 0, configured: false, } } pub fn handle_configure(&mut self, serial: u32, width: u32, height: u32) { info!("Lock surface configured with compositor size: {width}x{height}"); self.session_surface.ack_configure(serial); self.width = width; self.height = height; self.configured = true; } #[must_use] pub const fn width(&self) -> u32 { self.width } #[must_use] pub const fn height(&self) -> u32 { self.height } #[must_use] pub fn surface_id(&self) -> ObjectId { self.surface.id() } #[must_use] pub fn lock_surface_id(&self) -> ObjectId { self.session_surface.id() } pub fn fractional_scale(&self) -> Option<&Rc> { self.fractional_scale.as_ref() } pub const fn has_fractional_scale(&self) -> bool { self.fractional_scale.is_some() } pub const fn has_viewport(&self) -> bool { self.viewport.is_some() } pub fn configure_fractional_viewport(&self, logical_width: u32, logical_height: u32) { self.surface.set_buffer_scale(1); if let Some(vp) = &self.viewport { let width_i32 = i32::try_from(logical_width).unwrap_or(i32::MAX); let height_i32 = i32::try_from(logical_height).unwrap_or(i32::MAX); vp.set_destination(width_i32, height_i32); } } pub fn configure_buffer_scale(&self, buffer_scale: i32) { self.surface.set_buffer_scale(buffer_scale); } pub fn destroy(&self) { self.session_surface.destroy(); self.surface.destroy(); } } impl Drop for LockSurface { fn drop(&mut self) { self.destroy(); } }