Made sure we can actually render UI elements
This commit is contained in:
+27
-1
@@ -1,11 +1,13 @@
|
|||||||
use cairo::ImageSurface;
|
use cairo::ImageSurface;
|
||||||
|
use std::error::Error;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use wayland_client::protocol::wl_surface;
|
use wayland_client::protocol::{wl_shm, wl_surface};
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::input::{InputAction, InputHandler};
|
use crate::input::{InputAction, InputHandler};
|
||||||
use crate::render::Renderer;
|
use crate::render::Renderer;
|
||||||
use crate::screenshot::Screenshot;
|
use crate::screenshot::Screenshot;
|
||||||
|
use smithay_client_toolkit::shm::slot::SlotPool;
|
||||||
|
|
||||||
/// Manages a locked surface for a single output
|
/// Manages a locked surface for a single output
|
||||||
pub struct LockedSurface {
|
pub struct LockedSurface {
|
||||||
@@ -144,6 +146,30 @@ impl LockedSurface {
|
|||||||
self.last_update = Instant::now();
|
self.last_update = Instant::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Commit the rendered frame to the Wayland surface
|
||||||
|
pub fn commit(&self, pool: &mut SlotPool) -> Result<(), Box<dyn Error>> {
|
||||||
|
// Get pixel data from renderer
|
||||||
|
let pixel_data = self.renderer.get_pixel_data()?;
|
||||||
|
let (width, height, stride) = self.renderer.surface_info();
|
||||||
|
|
||||||
|
// Create buffer from pool
|
||||||
|
let (buffer, mut canvas) =
|
||||||
|
pool.create_buffer(width, height, stride, wl_shm::Format::Argb8888)?;
|
||||||
|
|
||||||
|
// Copy pixel data to buffer
|
||||||
|
let copy_len = pixel_data.len().min(canvas.len());
|
||||||
|
canvas[..copy_len].copy_from_slice(&pixel_data[..copy_len]);
|
||||||
|
|
||||||
|
// Attach buffer to Wayland surface and commit
|
||||||
|
if let Some(wl_surface) = &self.wayland_surface {
|
||||||
|
buffer.attach_to(wl_surface)?;
|
||||||
|
wl_surface.damage_buffer(0, 0, width, height);
|
||||||
|
wl_surface.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Handle resize event from Wayland
|
/// Handle resize event from Wayland
|
||||||
pub fn resize(&mut self, width: i32, height: i32) {
|
pub fn resize(&mut self, width: i32, height: i32) {
|
||||||
if width <= 0 || height <= 0 {
|
if width <= 0 || height <= 0 {
|
||||||
|
|||||||
+26
-3
@@ -84,11 +84,13 @@ fn lock_wayland_session(
|
|||||||
lock_manager: Arc<Mutex<LockManager>>,
|
lock_manager: Arc<Mutex<LockManager>>,
|
||||||
ctrlc_exit: Arc<std::sync::atomic::AtomicBool>,
|
ctrlc_exit: Arc<std::sync::atomic::AtomicBool>,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
use smithay_client_toolkit::reexports::calloop;
|
||||||
|
use smithay_client_toolkit::reexports::calloop::timer::TimeoutAction;
|
||||||
use smithay_client_toolkit::{
|
use smithay_client_toolkit::{
|
||||||
compositor::{CompositorHandler, CompositorState},
|
compositor::{CompositorHandler, CompositorState},
|
||||||
output::{OutputHandler, OutputState},
|
output::{OutputHandler, OutputState},
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::{channel, EventLoop, LoopHandle},
|
calloop::{channel, timer, EventLoop, LoopHandle},
|
||||||
calloop_wayland_source::WaylandSource,
|
calloop_wayland_source::WaylandSource,
|
||||||
},
|
},
|
||||||
registry::{ProvidesRegistryState, RegistryState},
|
registry::{ProvidesRegistryState, RegistryState},
|
||||||
@@ -651,7 +653,7 @@ fn lock_wayland_session(
|
|||||||
|
|
||||||
shm_state: Shm::bind(&globals, &qh).map_err(|_| "wl_shm protocol not supported")?,
|
shm_state: Shm::bind(&globals, &qh).map_err(|_| "wl_shm protocol not supported")?,
|
||||||
pool: SlotPool::new(
|
pool: SlotPool::new(
|
||||||
1920 * 1080 * 4,
|
1920 * 1080 * 4 * 3, // triple buffering for smooth rendering
|
||||||
&Shm::bind(&globals, &qh).map_err(|_| "wl_shm protocol not supported")?,
|
&Shm::bind(&globals, &qh).map_err(|_| "wl_shm protocol not supported")?,
|
||||||
)
|
)
|
||||||
.map_err(|e| format!("Failed to create slot pool: {:?}", e))?,
|
.map_err(|e| format!("Failed to create slot pool: {:?}", e))?,
|
||||||
@@ -688,6 +690,28 @@ fn lock_wayland_session(
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Insert a timer to update and commit surfaces at 60fps
|
||||||
|
let render_timer = timer::Timer::from_duration(Duration::from_millis(16));
|
||||||
|
event_loop.handle().insert_source(
|
||||||
|
render_timer,
|
||||||
|
|event, _metadata, state: &mut WaylandLock| {
|
||||||
|
// Update lock manager (renders to Cairo surfaces)
|
||||||
|
if let Ok(mut lock_manager) = state.lock_manager.lock() {
|
||||||
|
lock_manager.update();
|
||||||
|
// Commit each surface that has a Wayland surface
|
||||||
|
for surface in lock_manager.surfaces.iter_mut() {
|
||||||
|
if let Some(wl_surface) = surface.wayland_surface() {
|
||||||
|
if let Err(e) = surface.commit(&mut state.pool) {
|
||||||
|
log::error!("Failed to commit surface: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Reschedule timer to fire again in 16ms (60fps)
|
||||||
|
calloop::timer::TimeoutAction::ToDuration(Duration::from_millis(16))
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
log_to_file("Starting event loop");
|
log_to_file("Starting event loop");
|
||||||
eprintln!("Starting event loop - press Enter to unlock");
|
eprintln!("Starting event loop - press Enter to unlock");
|
||||||
|
|
||||||
@@ -706,7 +730,6 @@ fn run_demonstration_mode(
|
|||||||
_config: Config,
|
_config: Config,
|
||||||
lock_manager: Arc<Mutex<LockManager>>,
|
lock_manager: Arc<Mutex<LockManager>>,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
println!("wayrustlock - Wayland Screen Locker (Demonstration Mode)");
|
println!("wayrustlock - Wayland Screen Locker (Demonstration Mode)");
|
||||||
|
|||||||
Reference in New Issue
Block a user