Pull the clock out into its own module
This commit is contained in:
parent
83b0b3482c
commit
89bcd620a6
2 changed files with 234 additions and 223 deletions
224
src/clock.rs
Normal file
224
src/clock.rs
Normal file
|
|
@ -0,0 +1,224 @@
|
||||||
|
use chrono::Local;
|
||||||
|
use smithay_client_toolkit::{
|
||||||
|
compositor::{CompositorHandler, CompositorState},
|
||||||
|
delegate_compositor, delegate_layer, delegate_output, delegate_registry, delegate_shm,
|
||||||
|
output::{OutputHandler, OutputState},
|
||||||
|
registry::{ProvidesRegistryState, RegistryState},
|
||||||
|
registry_handlers,
|
||||||
|
shell::{
|
||||||
|
wlr_layer::{LayerShell, LayerShellHandler, LayerSurface, LayerSurfaceConfigure},
|
||||||
|
WaylandSurface,
|
||||||
|
},
|
||||||
|
shm::{slot::SlotPool, Shm, ShmHandler},
|
||||||
|
};
|
||||||
|
use wayland_client::{
|
||||||
|
protocol::{wl_output, wl_shm, wl_surface},
|
||||||
|
Connection, QueueHandle,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct ClockApp {
|
||||||
|
pub registry_state: RegistryState,
|
||||||
|
pub output_state: OutputState,
|
||||||
|
pub compositor_state: CompositorState,
|
||||||
|
pub shm_state: Shm,
|
||||||
|
pub layer_shell: LayerShell,
|
||||||
|
|
||||||
|
pub pool: Option<SlotPool>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
pub layer_surface: Option<LayerSurface>,
|
||||||
|
pub configured: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClockApp {
|
||||||
|
pub fn draw(&mut self, _qh: &QueueHandle<Self>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
if let Some(layer_surface) = &self.layer_surface {
|
||||||
|
let width = self.width;
|
||||||
|
let height = self.height;
|
||||||
|
let stride = width as i32 * 4;
|
||||||
|
|
||||||
|
let pool = self.pool.get_or_insert_with(|| {
|
||||||
|
SlotPool::new((width * height * 4) as usize, &self.shm_state).unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
let (buffer, canvas) = pool
|
||||||
|
.create_buffer(width as i32, height as i32, stride, wl_shm::Format::Argb8888)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Get current time
|
||||||
|
let now = Local::now();
|
||||||
|
let time_str = now.format("%H:%M:%S").to_string();
|
||||||
|
let date_str = now.format("%A, %B %d, %Y").to_string();
|
||||||
|
|
||||||
|
// Draw using cairo
|
||||||
|
// Safety: We ensure the buffer lifetime is valid for the cairo surface
|
||||||
|
unsafe {
|
||||||
|
let surface = cairo::ImageSurface::create_for_data_unsafe(
|
||||||
|
canvas.as_mut_ptr(),
|
||||||
|
cairo::Format::ARgb32,
|
||||||
|
width as i32,
|
||||||
|
height as i32,
|
||||||
|
stride,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let ctx = cairo::Context::new(&surface)?;
|
||||||
|
|
||||||
|
// Background
|
||||||
|
ctx.set_source_rgb(0.1, 0.1, 0.15);
|
||||||
|
ctx.paint()?;
|
||||||
|
|
||||||
|
// Draw time
|
||||||
|
ctx.set_source_rgb(1.0, 1.0, 1.0);
|
||||||
|
ctx.select_font_face("Sans", cairo::FontSlant::Normal, cairo::FontWeight::Bold);
|
||||||
|
ctx.set_font_size(60.0);
|
||||||
|
|
||||||
|
let time_extents = ctx.text_extents(&time_str)?;
|
||||||
|
let time_x = (width as f64 - time_extents.width()) / 2.0 - time_extents.x_bearing();
|
||||||
|
let time_y = height as f64 / 2.0 - 10.0;
|
||||||
|
ctx.move_to(time_x, time_y);
|
||||||
|
ctx.show_text(&time_str)?;
|
||||||
|
|
||||||
|
// Draw date
|
||||||
|
ctx.set_font_size(20.0);
|
||||||
|
ctx.select_font_face("Sans", cairo::FontSlant::Normal, cairo::FontWeight::Normal);
|
||||||
|
let date_extents = ctx.text_extents(&date_str)?;
|
||||||
|
let date_x = (width as f64 - date_extents.width()) / 2.0 - date_extents.x_bearing();
|
||||||
|
let date_y = height as f64 / 2.0 + 35.0;
|
||||||
|
ctx.move_to(date_x, date_y);
|
||||||
|
ctx.show_text(&date_str)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
layer_surface
|
||||||
|
.wl_surface()
|
||||||
|
.attach(Some(buffer.wl_buffer()), 0, 0);
|
||||||
|
layer_surface.wl_surface().damage_buffer(0, 0, width as i32, height as i32);
|
||||||
|
layer_surface.wl_surface().commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CompositorHandler for ClockApp {
|
||||||
|
fn scale_factor_changed(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
_surface: &wl_surface::WlSurface,
|
||||||
|
_new_factor: i32,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform_changed(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
_surface: &wl_surface::WlSurface,
|
||||||
|
_new_transform: wl_output::Transform,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
qh: &QueueHandle<Self>,
|
||||||
|
_surface: &wl_surface::WlSurface,
|
||||||
|
_time: u32,
|
||||||
|
) {
|
||||||
|
let _ = self.draw(qh);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn surface_enter(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
_surface: &wl_surface::WlSurface,
|
||||||
|
_output: &wl_output::WlOutput,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn surface_leave(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
_surface: &wl_surface::WlSurface,
|
||||||
|
_output: &wl_output::WlOutput,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputHandler for ClockApp {
|
||||||
|
fn output_state(&mut self) -> &mut OutputState {
|
||||||
|
&mut self.output_state
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_output(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
_output: wl_output::WlOutput,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_output(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
_output: wl_output::WlOutput,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn output_destroyed(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
_output: wl_output::WlOutput,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayerShellHandler for ClockApp {
|
||||||
|
fn closed(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, _layer: &LayerSurface) {
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn configure(
|
||||||
|
&mut self,
|
||||||
|
_conn: &Connection,
|
||||||
|
qh: &QueueHandle<Self>,
|
||||||
|
_layer: &LayerSurface,
|
||||||
|
configure: LayerSurfaceConfigure,
|
||||||
|
_serial: u32,
|
||||||
|
) {
|
||||||
|
if configure.new_size.0 != 0 {
|
||||||
|
self.width = configure.new_size.0;
|
||||||
|
}
|
||||||
|
if configure.new_size.1 != 0 {
|
||||||
|
self.height = configure.new_size.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.configured = true;
|
||||||
|
let _ = self.draw(qh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShmHandler for ClockApp {
|
||||||
|
fn shm_state(&mut self) -> &mut Shm {
|
||||||
|
&mut self.shm_state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate_compositor!(ClockApp);
|
||||||
|
delegate_output!(ClockApp);
|
||||||
|
delegate_shm!(ClockApp);
|
||||||
|
delegate_layer!(ClockApp);
|
||||||
|
|
||||||
|
delegate_registry!(ClockApp);
|
||||||
|
|
||||||
|
impl ProvidesRegistryState for ClockApp {
|
||||||
|
fn registry(&mut self) -> &mut RegistryState {
|
||||||
|
&mut self.registry_state
|
||||||
|
}
|
||||||
|
|
||||||
|
registry_handlers![OutputState];
|
||||||
|
}
|
||||||
233
src/main.rs
233
src/main.rs
|
|
@ -1,24 +1,18 @@
|
||||||
use chrono::Local;
|
mod clock;
|
||||||
|
|
||||||
|
use clock::ClockApp;
|
||||||
use smithay_client_toolkit::{
|
use smithay_client_toolkit::{
|
||||||
compositor::{CompositorHandler, CompositorState},
|
compositor::CompositorState,
|
||||||
delegate_compositor, delegate_layer, delegate_output, delegate_registry, delegate_shm,
|
output::OutputState,
|
||||||
output::{OutputHandler, OutputState},
|
registry::RegistryState,
|
||||||
registry::{ProvidesRegistryState, RegistryState},
|
|
||||||
registry_handlers,
|
|
||||||
shell::{
|
shell::{
|
||||||
wlr_layer::{
|
wlr_layer::{Anchor, KeyboardInteractivity, Layer, LayerShell},
|
||||||
Anchor, KeyboardInteractivity, Layer, LayerShell, LayerShellHandler, LayerSurface,
|
|
||||||
LayerSurfaceConfigure,
|
|
||||||
},
|
|
||||||
WaylandSurface,
|
WaylandSurface,
|
||||||
},
|
},
|
||||||
shm::{slot::SlotPool, Shm, ShmHandler},
|
shm::Shm,
|
||||||
};
|
|
||||||
use wayland_client::{
|
|
||||||
globals::registry_queue_init,
|
|
||||||
protocol::{wl_output, wl_shm, wl_surface},
|
|
||||||
Connection, QueueHandle,
|
|
||||||
};
|
};
|
||||||
|
use wayland_client::globals::registry_queue_init;
|
||||||
|
use wayland_client::Connection;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let conn = Connection::connect_to_env()?;
|
let conn = Connection::connect_to_env()?;
|
||||||
|
|
@ -67,210 +61,3 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ClockApp {
|
|
||||||
registry_state: RegistryState,
|
|
||||||
output_state: OutputState,
|
|
||||||
compositor_state: CompositorState,
|
|
||||||
shm_state: Shm,
|
|
||||||
layer_shell: LayerShell,
|
|
||||||
|
|
||||||
pool: Option<SlotPool>,
|
|
||||||
width: u32,
|
|
||||||
height: u32,
|
|
||||||
layer_surface: Option<LayerSurface>,
|
|
||||||
configured: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClockApp {
|
|
||||||
fn draw(&mut self, _qh: &QueueHandle<Self>) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
if let Some(layer_surface) = &self.layer_surface {
|
|
||||||
let width = self.width;
|
|
||||||
let height = self.height;
|
|
||||||
let stride = width as i32 * 4;
|
|
||||||
|
|
||||||
let pool = self.pool.get_or_insert_with(|| {
|
|
||||||
SlotPool::new((width * height * 4) as usize, &self.shm_state).unwrap()
|
|
||||||
});
|
|
||||||
|
|
||||||
let (buffer, canvas) = pool
|
|
||||||
.create_buffer(width as i32, height as i32, stride, wl_shm::Format::Argb8888)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Get current time
|
|
||||||
let now = Local::now();
|
|
||||||
let time_str = now.format("%H:%M:%S").to_string();
|
|
||||||
let date_str = now.format("%A, %B %d, %Y").to_string();
|
|
||||||
|
|
||||||
// Draw using cairo
|
|
||||||
// Safety: We ensure the buffer lifetime is valid for the cairo surface
|
|
||||||
unsafe {
|
|
||||||
let surface = cairo::ImageSurface::create_for_data_unsafe(
|
|
||||||
canvas.as_mut_ptr(),
|
|
||||||
cairo::Format::ARgb32,
|
|
||||||
width as i32,
|
|
||||||
height as i32,
|
|
||||||
stride,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let ctx = cairo::Context::new(&surface)?;
|
|
||||||
|
|
||||||
// Background
|
|
||||||
ctx.set_source_rgb(0.1, 0.1, 0.15);
|
|
||||||
ctx.paint()?;
|
|
||||||
|
|
||||||
// Draw time
|
|
||||||
ctx.set_source_rgb(1.0, 1.0, 1.0);
|
|
||||||
ctx.select_font_face("Sans", cairo::FontSlant::Normal, cairo::FontWeight::Bold);
|
|
||||||
ctx.set_font_size(60.0);
|
|
||||||
|
|
||||||
let time_extents = ctx.text_extents(&time_str)?;
|
|
||||||
let time_x = (width as f64 - time_extents.width()) / 2.0 - time_extents.x_bearing();
|
|
||||||
let time_y = height as f64 / 2.0 - 10.0;
|
|
||||||
ctx.move_to(time_x, time_y);
|
|
||||||
ctx.show_text(&time_str)?;
|
|
||||||
|
|
||||||
// Draw date
|
|
||||||
ctx.set_font_size(20.0);
|
|
||||||
ctx.select_font_face("Sans", cairo::FontSlant::Normal, cairo::FontWeight::Normal);
|
|
||||||
let date_extents = ctx.text_extents(&date_str)?;
|
|
||||||
let date_x = (width as f64 - date_extents.width()) / 2.0 - date_extents.x_bearing();
|
|
||||||
let date_y = height as f64 / 2.0 + 35.0;
|
|
||||||
ctx.move_to(date_x, date_y);
|
|
||||||
ctx.show_text(&date_str)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
layer_surface
|
|
||||||
.wl_surface()
|
|
||||||
.attach(Some(buffer.wl_buffer()), 0, 0);
|
|
||||||
layer_surface.wl_surface().damage_buffer(0, 0, width as i32, height as i32);
|
|
||||||
layer_surface.wl_surface().commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CompositorHandler for ClockApp {
|
|
||||||
fn scale_factor_changed(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
_qh: &QueueHandle<Self>,
|
|
||||||
_surface: &wl_surface::WlSurface,
|
|
||||||
_new_factor: i32,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transform_changed(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
_qh: &QueueHandle<Self>,
|
|
||||||
_surface: &wl_surface::WlSurface,
|
|
||||||
_new_transform: wl_output::Transform,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fn frame(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
qh: &QueueHandle<Self>,
|
|
||||||
_surface: &wl_surface::WlSurface,
|
|
||||||
_time: u32,
|
|
||||||
) {
|
|
||||||
let _ = self.draw(qh);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn surface_enter(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
_qh: &QueueHandle<Self>,
|
|
||||||
_surface: &wl_surface::WlSurface,
|
|
||||||
_output: &wl_output::WlOutput,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fn surface_leave(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
_qh: &QueueHandle<Self>,
|
|
||||||
_surface: &wl_surface::WlSurface,
|
|
||||||
_output: &wl_output::WlOutput,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OutputHandler for ClockApp {
|
|
||||||
fn output_state(&mut self) -> &mut OutputState {
|
|
||||||
&mut self.output_state
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_output(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
_qh: &QueueHandle<Self>,
|
|
||||||
_output: wl_output::WlOutput,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_output(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
_qh: &QueueHandle<Self>,
|
|
||||||
_output: wl_output::WlOutput,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fn output_destroyed(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
_qh: &QueueHandle<Self>,
|
|
||||||
_output: wl_output::WlOutput,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LayerShellHandler for ClockApp {
|
|
||||||
fn closed(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, _layer: &LayerSurface) {
|
|
||||||
std::process::exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn configure(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
qh: &QueueHandle<Self>,
|
|
||||||
_layer: &LayerSurface,
|
|
||||||
configure: LayerSurfaceConfigure,
|
|
||||||
_serial: u32,
|
|
||||||
) {
|
|
||||||
if configure.new_size.0 != 0 {
|
|
||||||
self.width = configure.new_size.0;
|
|
||||||
}
|
|
||||||
if configure.new_size.1 != 0 {
|
|
||||||
self.height = configure.new_size.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.configured = true;
|
|
||||||
let _ = self.draw(qh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ShmHandler for ClockApp {
|
|
||||||
fn shm_state(&mut self) -> &mut Shm {
|
|
||||||
&mut self.shm_state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate_compositor!(ClockApp);
|
|
||||||
delegate_output!(ClockApp);
|
|
||||||
delegate_shm!(ClockApp);
|
|
||||||
delegate_layer!(ClockApp);
|
|
||||||
|
|
||||||
delegate_registry!(ClockApp);
|
|
||||||
|
|
||||||
impl ProvidesRegistryState for ClockApp {
|
|
||||||
fn registry(&mut self) -> &mut RegistryState {
|
|
||||||
&mut self.registry_state
|
|
||||||
}
|
|
||||||
|
|
||||||
registry_handlers![OutputState];
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue