Fix formatting

This commit is contained in:
2026-03-17 19:26:42 +01:00
parent f4f8e94e6e
commit 446426ea47
9 changed files with 177 additions and 104 deletions
+1
View File
@@ -19,5 +19,6 @@ pkgs.rustPlatform.buildRustPackage {
nativeBuildInputs = [ nativeBuildInputs = [
pkgs.pkg-config pkgs.pkg-config
pkgs.rustPlatform.bindgenHook pkgs.rustPlatform.bindgenHook
pkgs.rustfmt
]; ];
} }
+14 -12
View File
@@ -35,7 +35,8 @@ impl pam_client::ConversationHandler for LockConversation {
} }
} }
pub fn create_and_run_auth_loop() -> Option<(channel::Sender<Zeroizing<String>>, channel::Channel<bool>)> { pub fn create_and_run_auth_loop(
) -> Option<(channel::Sender<Zeroizing<String>>, channel::Channel<bool>)> {
let username = get_current_username() let username = get_current_username()
.expect("Failed to get username") .expect("Failed to get username")
.to_str() .to_str()
@@ -49,7 +50,10 @@ pub fn create_and_run_auth_loop() -> Option<(channel::Sender<Zeroizing<String>>,
} }
Err(err) => { Err(err) => {
error!("Failed to initialize PAM context: {:?}", err); error!("Failed to initialize PAM context: {:?}", err);
error!("Ensure that the PAM service '{}' is correctly configured.", SERVICE_NAME); error!(
"Ensure that the PAM service '{}' is correctly configured.",
SERVICE_NAME
);
return None; return None;
} }
} }
@@ -67,17 +71,15 @@ pub fn create_and_run_auth_loop() -> Option<(channel::Sender<Zeroizing<String>>,
password: Some(password), password: Some(password),
}; };
match Context::new(SERVICE_NAME, Some(username.as_str()), conversation) { match Context::new(SERVICE_NAME, Some(username.as_str()), conversation) {
Ok(mut context) => { Ok(mut context) => match context.authenticate(Flag::NONE) {
match context.authenticate(Flag::NONE) { Ok(()) => {
Ok(()) => { auth_res_send.send(true).unwrap();
auth_res_send.send(true).unwrap();
}
Err(err) => {
error!("Pam authenticate failed with {:?}", err);
auth_res_send.send(false).unwrap();
}
} }
} Err(err) => {
error!("Pam authenticate failed with {:?}", err);
auth_res_send.send(false).unwrap();
}
},
Err(err) => { Err(err) => {
error!("Failed to re-initialize PAM context: {:?}", err); error!("Failed to re-initialize PAM context: {:?}", err);
auth_res_send.send(false).unwrap(); auth_res_send.send(false).unwrap();
+48 -29
View File
@@ -135,15 +135,14 @@ pub struct Config {
impl Config { impl Config {
pub fn load() -> Self { pub fn load() -> Self {
use clap::CommandFactory; use clap::CommandFactory;
let mut config = Config::parse(); let mut config = Config::parse();
let cmd = Config::command(); let cmd = Config::command();
let matches = cmd.get_matches(); let matches = cmd.get_matches();
// Helper to check if a value was explicitly set on command line // Helper to check if a value was explicitly set on command line
let is_cli = |key: &str| { let is_cli =
matches.value_source(key) == Some(clap::parser::ValueSource::CommandLine) |key: &str| matches.value_source(key) == Some(clap::parser::ValueSource::CommandLine);
};
// 1. Config file layer (overrides defaults and themes) // 1. Config file layer (overrides defaults and themes)
let config_path = config.config.clone().unwrap_or_else(|| { let config_path = config.config.clone().unwrap_or_else(|| {
@@ -156,7 +155,7 @@ impl Config {
if let Ok(file_content) = std::fs::read_to_string(&config_path) { if let Ok(file_content) = std::fs::read_to_string(&config_path) {
if let Ok(table) = toml::from_str::<toml::Table>(&file_content) { if let Ok(table) = toml::from_str::<toml::Table>(&file_content) {
log::debug!("Loaded configuration from {:?}", config_path); log::debug!("Loaded configuration from {:?}", config_path);
let merge_bool = |val: &mut bool, key: &str| { let merge_bool = |val: &mut bool, key: &str| {
if !is_cli(key) { if !is_cli(key) {
if let Some(toml::Value::Boolean(b)) = table.get(key) { if let Some(toml::Value::Boolean(b)) = table.get(key) {
@@ -199,55 +198,55 @@ impl Config {
merge_f32(&mut config.grace, "grace"); merge_f32(&mut config.grace, "grace");
merge_f32(&mut config.fade_in, "fade_in"); merge_f32(&mut config.fade_in, "fade_in");
merge_string(&mut config.pam_service, "pam_service"); merge_string(&mut config.pam_service, "pam_service");
merge_bool(&mut config.show_media, "show_media"); merge_bool(&mut config.show_media, "show_media");
merge_bool(&mut config.show_battery, "show_battery"); merge_bool(&mut config.show_battery, "show_battery");
merge_bool(&mut config.show_network, "show_network"); merge_bool(&mut config.show_network, "show_network");
merge_bool(&mut config.show_bluetooth, "show_bluetooth"); merge_bool(&mut config.show_bluetooth, "show_bluetooth");
merge_bool(&mut config.show_album_art, "show_album_art"); merge_bool(&mut config.show_album_art, "show_album_art");
merge_bool(&mut config.show_keyboard_layout, "show_keyboard_layout"); merge_bool(&mut config.show_keyboard_layout, "show_keyboard_layout");
if !is_cli("image") { if !is_cli("image") {
if let Some(toml::Value::String(s)) = table.get("image") { if let Some(toml::Value::String(s)) = table.get("image") {
config.image = Some(std::path::PathBuf::from(s)); config.image = Some(std::path::PathBuf::from(s));
} }
} }
if !is_cli("wifi_icon") { if !is_cli("wifi_icon") {
if let Some(toml::Value::String(s)) = table.get("wifi_icon") { if let Some(toml::Value::String(s)) = table.get("wifi_icon") {
config.wifi_icon = Some(s.clone()); config.wifi_icon = Some(s.clone());
} }
} }
if !is_cli("bluetooth_icon") { if !is_cli("bluetooth_icon") {
if let Some(toml::Value::String(s)) = table.get("bluetooth_icon") { if let Some(toml::Value::String(s)) = table.get("bluetooth_icon") {
config.bluetooth_icon = Some(s.clone()); config.bluetooth_icon = Some(s.clone());
} }
} }
if !is_cli("battery_icon") { if !is_cli("battery_icon") {
if let Some(toml::Value::String(s)) = table.get("battery_icon") { if let Some(toml::Value::String(s)) = table.get("battery_icon") {
config.battery_icon = Some(s.clone()); config.battery_icon = Some(s.clone());
} }
} }
if !is_cli("media_prev_icon") { if !is_cli("media_prev_icon") {
if let Some(toml::Value::String(s)) = table.get("media_prev_icon") { if let Some(toml::Value::String(s)) = table.get("media_prev_icon") {
config.media_prev_icon = Some(s.clone()); config.media_prev_icon = Some(s.clone());
} }
} }
if !is_cli("media_stop_icon") { if !is_cli("media_stop_icon") {
if let Some(toml::Value::String(s)) = table.get("media_stop_icon") { if let Some(toml::Value::String(s)) = table.get("media_stop_icon") {
config.media_stop_icon = Some(s.clone()); config.media_stop_icon = Some(s.clone());
} }
} }
if !is_cli("media_play_icon") { if !is_cli("media_play_icon") {
if let Some(toml::Value::String(s)) = table.get("media_play_icon") { if let Some(toml::Value::String(s)) = table.get("media_play_icon") {
config.media_play_icon = Some(s.clone()); config.media_play_icon = Some(s.clone());
} }
} }
if !is_cli("media_next_icon") { if !is_cli("media_next_icon") {
if let Some(toml::Value::String(s)) = table.get("media_next_icon") { if let Some(toml::Value::String(s)) = table.get("media_next_icon") {
config.media_next_icon = Some(s.clone()); config.media_next_icon = Some(s.clone());
@@ -261,20 +260,40 @@ impl Config {
if let Some(theme) = &config.theme { if let Some(theme) = &config.theme {
match theme.as_str() { match theme.as_str() {
"modern" => { "modern" => {
if config.effect_blur.is_none() && !is_cli("effect_blur") { config.effect_blur = Some((10, 3)); } if config.effect_blur.is_none() && !is_cli("effect_blur") {
if config.effect_vignette.is_none() && !is_cli("effect_vignette") { config.effect_vignette = Some((0.5, 0.5)); } config.effect_blur = Some((10, 3));
if !is_cli("indicator_radius") { config.indicator_radius = 120; } }
if !is_cli("ring_color") { config.ring_color = (0.2, 0.6, 0.8, 1.0); } if config.effect_vignette.is_none() && !is_cli("effect_vignette") {
config.effect_vignette = Some((0.5, 0.5));
}
if !is_cli("indicator_radius") {
config.indicator_radius = 120;
}
if !is_cli("ring_color") {
config.ring_color = (0.2, 0.6, 0.8, 1.0);
}
} }
"pixel" => { "pixel" => {
if config.effect_pixelate.is_none() && !is_cli("effect_pixelate") { config.effect_pixelate = Some(10); } if config.effect_pixelate.is_none() && !is_cli("effect_pixelate") {
if !is_cli("indicator_radius") { config.indicator_radius = 80; } config.effect_pixelate = Some(10);
if !is_cli("ring_color") { config.ring_color = (0.8, 0.2, 0.2, 1.0); } }
if !is_cli("indicator_radius") {
config.indicator_radius = 80;
}
if !is_cli("ring_color") {
config.ring_color = (0.8, 0.2, 0.2, 1.0);
}
} }
"glass" => { "glass" => {
if config.effect_blur.is_none() && !is_cli("effect_blur") { config.effect_blur = Some((20, 5)); } if config.effect_blur.is_none() && !is_cli("effect_blur") {
if !is_cli("inside_color") { config.inside_color = (1.0, 1.0, 1.0, 0.1); } config.effect_blur = Some((20, 5));
if !is_cli("ring_color") { config.ring_color = (1.0, 1.0, 1.0, 0.5); } }
if !is_cli("inside_color") {
config.inside_color = (1.0, 1.0, 1.0, 0.1);
}
if !is_cli("ring_color") {
config.ring_color = (1.0, 1.0, 1.0, 0.5);
}
} }
_ => { _ => {
log::warn!("Unknown theme: {}", theme); log::warn!("Unknown theme: {}", theme);
+1 -2
View File
@@ -100,8 +100,7 @@ impl InputHandler {
} }
/// Update timers (should be called periodically) /// Update timers (should be called periodically)
pub fn update(&mut self) { pub fn update(&mut self) {}
}
/// Get the current Caps Lock state /// Get the current Caps Lock state
pub fn caps_lock(&self) -> bool { pub fn caps_lock(&self) -> bool {
+3 -5
View File
@@ -165,11 +165,9 @@ impl LockedSurface {
event: smithay_client_toolkit::seat::keyboard::KeyEvent, event: smithay_client_toolkit::seat::keyboard::KeyEvent,
modifiers: smithay_client_toolkit::seat::keyboard::Modifiers, modifiers: smithay_client_toolkit::seat::keyboard::Modifiers,
) -> Option<InputAction> { ) -> Option<InputAction> {
let action = self.input_handler.handle_key_event( let action = self
event.keysym, .input_handler
event.utf8, .handle_key_event(event.keysym, event.utf8, modifiers);
modifiers,
);
match action { match action {
InputAction::PasswordChanged => { InputAction::PasswordChanged => {
+19 -12
View File
@@ -10,12 +10,12 @@ mod util;
use config::Config; use config::Config;
use lock::LockManager; use lock::LockManager;
use screenshot::{CaptureData, Screenshot, ScreenshotManager}; use screenshot::{CaptureData, Screenshot, ScreenshotManager};
use system::SystemManager;
use std::error::Error; use std::error::Error;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io::Write; use std::io::Write;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use system::SystemManager;
use wayland_client::protocol::wl_output::WlOutput; use wayland_client::protocol::wl_output::WlOutput;
use wayland_client::protocol::wl_surface::WlSurface; use wayland_client::protocol::wl_surface::WlSurface;
use wayland_client::{Connection, Dispatch, Proxy, QueueHandle}; use wayland_client::{Connection, Dispatch, Proxy, QueueHandle};
@@ -489,7 +489,7 @@ impl Dispatch<ZwlrScreencopyFrameV1, CaptureData> for WaylandLock {
stride, stride,
} => { } => {
let format = format.into_result().unwrap(); let format = format.into_result().unwrap();
let mut info = data.info.lock().unwrap(); let mut info = data.info.lock().unwrap();
*info = Some(screenshot::BufferInfo { *info = Some(screenshot::BufferInfo {
width, width,
@@ -503,7 +503,8 @@ impl Dispatch<ZwlrScreencopyFrameV1, CaptureData> for WaylandLock {
let size = (stride as usize) * (height as usize); let size = (stride as usize) * (height as usize);
match SlotPool::new(size, &state.shm_state) { match SlotPool::new(size, &state.shm_state) {
Ok(mut pool) => { Ok(mut pool) => {
match pool.create_buffer(width as i32, height as i32, stride as i32, format) { match pool.create_buffer(width as i32, height as i32, stride as i32, format)
{
Ok((buffer, _canvas)) => { Ok((buffer, _canvas)) => {
frame.copy(buffer.wl_buffer()); frame.copy(buffer.wl_buffer());
*data.buffer.lock().unwrap() = Some(buffer); *data.buffer.lock().unwrap() = Some(buffer);
@@ -525,8 +526,10 @@ impl Dispatch<ZwlrScreencopyFrameV1, CaptureData> for WaylandLock {
let info = data.info.lock().unwrap().take(); let info = data.info.lock().unwrap().take();
let flags = data.flags.lock().unwrap().take(); let flags = data.flags.lock().unwrap().take();
let pool = data.pool.lock().unwrap().take(); let pool = data.pool.lock().unwrap().take();
if let (Some(buffer), Some(info), Some(flags), Some(mut pool)) = (buffer, info, flags, pool) { if let (Some(buffer), Some(info), Some(flags), Some(mut pool)) =
(buffer, info, flags, pool)
{
let handle = screenshot::ScreencopyBufferHandle { let handle = screenshot::ScreencopyBufferHandle {
buffer, buffer,
info, info,
@@ -608,7 +611,7 @@ fn main() -> Result<(), Box<dyn Error>> {
// Initialize state without pool first // Initialize state without pool first
// We'll create the pool after we know the output dimensions // We'll create the pool after we know the output dimensions
// Initialize pool with a minimal size, it will be resized once outputs are detected // Initialize pool with a minimal size, it will be resized once outputs are detected
let pool = SlotPool::new(1, &shm_state)?; let pool = SlotPool::new(1, &shm_state)?;
@@ -648,7 +651,8 @@ fn main() -> Result<(), Box<dyn Error>> {
if let Ok(img) = image::open(image_path) { if let Ok(img) = image::open(image_path) {
let img = img.to_rgba8(); let img = img.to_rgba8();
let (w, h) = img.dimensions(); let (w, h) = img.dimensions();
let mut surface = cairo::ImageSurface::create(cairo::Format::ARgb32, w as i32, h as i32).unwrap(); let mut surface =
cairo::ImageSurface::create(cairo::Format::ARgb32, w as i32, h as i32).unwrap();
{ {
let mut surface_data = surface.data().unwrap(); let mut surface_data = surface.data().unwrap();
for y in 0..h { for y in 0..h {
@@ -662,18 +666,21 @@ fn main() -> Result<(), Box<dyn Error>> {
} }
} }
} }
let mut ss = Screenshot::new(surface); let mut ss = Screenshot::new(surface);
let _ = ss.apply_effects(&state.config); let _ = ss.apply_effects(&state.config);
let surface = ss.into_inner(); let surface = ss.into_inner();
let num_outputs = state.output_state.outputs().count(); let num_outputs = state.output_state.outputs().count();
state.captured_backgrounds = vec![Some(surface); num_outputs]; state.captured_backgrounds = vec![Some(surface); num_outputs];
// Disable screenshots if image was successfully loaded // Disable screenshots if image was successfully loaded
state.config.screenshots = false; state.config.screenshots = false;
} else { } else {
log::error!("Failed to load custom background image from {:?}", image_path); log::error!(
"Failed to load custom background image from {:?}",
image_path
);
} }
} }
@@ -724,7 +731,7 @@ fn main() -> Result<(), Box<dyn Error>> {
} }
let mut status = state.system_manager.get_status(); let mut status = state.system_manager.get_status();
status.keyboard_layout = Some(state.current_layout.to_string()); status.keyboard_layout = Some(state.current_layout.to_string());
if let Ok(mut lm) = state.lock_manager.lock() { if let Ok(mut lm) = state.lock_manager.lock() {
lm.set_system_status(status); lm.set_system_status(status);
+84 -37
View File
@@ -351,18 +351,18 @@ impl Renderer {
self.context.stroke().unwrap(); self.context.stroke().unwrap();
} }
// Use caps lock color when caps lock is on and indicator is enabled, otherwise ring color // Use caps lock color when caps lock is on and indicator is enabled, otherwise ring color
let (r, g, b, a) = if self.caps_lock { let (r, g, b, a) = if self.caps_lock {
self.config.caps_lock_color self.config.caps_lock_color
} else { } else {
self.config.ring_color self.config.ring_color
}; };
self.context.new_path(); self.context.new_path();
self.context.set_source_rgba(r, g, b, a * self.fade_alpha); self.context.set_source_rgba(r, g, b, a * self.fade_alpha);
self.context.set_line_width(thickness); self.context.set_line_width(thickness);
self.context self.context
.arc(center_x, center_y, radius, 0.0, 2.0 * std::f64::consts::PI); .arc(center_x, center_y, radius, 0.0, 2.0 * std::f64::consts::PI);
self.context.stroke().unwrap(); self.context.stroke().unwrap();
let (r, g, b, a) = self.config.separator_color; let (r, g, b, a) = self.config.separator_color;
if a > 0.0 { if a > 0.0 {
@@ -507,7 +507,8 @@ impl Renderer {
if let Ok(img) = image::load_from_memory(data) { if let Ok(img) = image::load_from_memory(data) {
let img = img.to_rgba8(); let img = img.to_rgba8();
let (w, h) = img.dimensions(); let (w, h) = img.dimensions();
let mut surface = ImageSurface::create(Format::ARgb32, w as i32, h as i32).unwrap(); let mut surface =
ImageSurface::create(Format::ARgb32, w as i32, h as i32).unwrap();
{ {
let mut surface_data = surface.data().unwrap(); let mut surface_data = surface.data().unwrap();
for y in 0..h { for y in 0..h {
@@ -528,7 +529,11 @@ impl Renderer {
} }
let has_art = self.config.show_album_art && self.media_art_surface.is_some(); let has_art = self.config.show_album_art && self.media_art_surface.is_some();
let text_x = if has_art { center_x - spacing / 2.0 } else { center_x }; let text_x = if has_art {
center_x - spacing / 2.0
} else {
center_x
};
let art_x = center_x - spacing - art_size / 2.0; let art_x = center_x - spacing - art_size / 2.0;
if has_art { if has_art {
@@ -544,7 +549,8 @@ impl Renderer {
} }
self.context.new_path(); self.context.new_path();
self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.9); self.context
.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.9);
self.context.set_font_size(16.0); self.context.set_font_size(16.0);
let display_text = if let Some(ref artist) = self.system_status.media_artist { let display_text = if let Some(ref artist) = self.system_status.media_artist {
@@ -554,14 +560,19 @@ impl Renderer {
}; };
let te = self.context.text_extents(&display_text).unwrap(); let te = self.context.text_extents(&display_text).unwrap();
self.context.move_to(text_x - te.width() / 2.0, start_y + 20.0); self.context
.move_to(text_x - te.width() / 2.0, start_y + 20.0);
self.context.show_text(&display_text).unwrap(); self.context.show_text(&display_text).unwrap();
let status_text = if self.system_status.media_playing { let status_text = if self.system_status.media_playing {
if let Some(ref icon) = self.media_play_icon_surface { if let Some(ref icon) = self.media_play_icon_surface {
// Draw play icon instead of text // Draw play icon instead of text
let play_y = start_y + 40.0; let play_y = start_y + 40.0;
self.draw_icon_at(center_x - icon.width() as f64 / 2.0, play_y - icon.height() as f64 / 2.0, icon); self.draw_icon_at(
center_x - icon.width() as f64 / 2.0,
play_y - icon.height() as f64 / 2.0,
icon,
);
"" ""
} else { } else {
"▶ Playing" "▶ Playing"
@@ -569,51 +580,57 @@ impl Renderer {
} else { } else {
"⏸ Paused" "⏸ Paused"
}; };
if !status_text.is_empty() { if !status_text.is_empty() {
self.context.set_font_size(12.0); self.context.set_font_size(12.0);
let se = self.context.text_extents(status_text).unwrap(); let se = self.context.text_extents(status_text).unwrap();
self.context.move_to(text_x - se.width() / 2.0, start_y + 40.0); self.context
.move_to(text_x - se.width() / 2.0, start_y + 40.0);
self.context.show_text(status_text).unwrap(); self.context.show_text(status_text).unwrap();
} }
let controls_y = start_y + 65.0; let controls_y = start_y + 65.0;
// Draw media control icons // Draw media control icons
let icon_size = 20.0; let icon_size = 20.0;
let icon_spacing = 40.0; let icon_spacing = 40.0;
let controls_center_x = center_x; let controls_center_x = center_x;
// Previous icon // Previous icon
if let Some(ref icon) = self.media_prev_icon_surface { if let Some(ref icon) = self.media_prev_icon_surface {
let ix = controls_center_x - icon_spacing; let ix = controls_center_x - icon_spacing;
self.draw_icon_at(ix - icon_size / 2.0, controls_y - icon_size / 2.0, icon); self.draw_icon_at(ix - icon_size / 2.0, controls_y - icon_size / 2.0, icon);
} else { } else {
self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.7); self.context
.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.7);
self.context.set_font_size(16.0); self.context.set_font_size(16.0);
self.context.move_to(controls_center_x - icon_spacing - 8.0, controls_y); self.context
.move_to(controls_center_x - icon_spacing - 8.0, controls_y);
self.context.show_text("").unwrap(); self.context.show_text("").unwrap();
} }
// Stop icon // Stop icon
if let Some(ref icon) = self.media_stop_icon_surface { if let Some(ref icon) = self.media_stop_icon_surface {
let ix = controls_center_x; let ix = controls_center_x;
self.draw_icon_at(ix - icon_size / 2.0, controls_y - icon_size / 2.0, icon); self.draw_icon_at(ix - icon_size / 2.0, controls_y - icon_size / 2.0, icon);
} else { } else {
self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.7); self.context
.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.7);
self.context.set_font_size(16.0); self.context.set_font_size(16.0);
self.context.move_to(controls_center_x - 8.0, controls_y); self.context.move_to(controls_center_x - 8.0, controls_y);
self.context.show_text("").unwrap(); self.context.show_text("").unwrap();
} }
// Next icon // Next icon
if let Some(ref icon) = self.media_next_icon_surface { if let Some(ref icon) = self.media_next_icon_surface {
let ix = controls_center_x + icon_spacing; let ix = controls_center_x + icon_spacing;
self.draw_icon_at(ix - icon_size / 2.0, controls_y - icon_size / 2.0, icon); self.draw_icon_at(ix - icon_size / 2.0, controls_y - icon_size / 2.0, icon);
} else { } else {
self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.7); self.context
.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.7);
self.context.set_font_size(16.0); self.context.set_font_size(16.0);
self.context.move_to(controls_center_x + icon_spacing - 8.0, controls_y); self.context
.move_to(controls_center_x + icon_spacing - 8.0, controls_y);
self.context.show_text("").unwrap(); self.context.show_text("").unwrap();
} }
} }
@@ -638,7 +655,15 @@ impl Renderer {
self.context.show_text(ssid).unwrap(); self.context.show_text(ssid).unwrap();
} else { } else {
let strength = self.system_status.wifi_strength.unwrap_or(0); let strength = self.system_status.wifi_strength.unwrap_or(0);
let icon = if strength > 75 { "📶" } else if strength > 50 { "📶" } else if strength > 25 { "📶" } else { "📶" }; let icon = if strength > 75 {
"📶"
} else if strength > 50 {
"📶"
} else if strength > 25 {
"📶"
} else {
"📶"
};
let text = format!("{} {}", icon, ssid); let text = format!("{} {}", icon, ssid);
self.context.new_path(); self.context.new_path();
self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha); self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha);
@@ -649,7 +674,8 @@ impl Renderer {
} else { } else {
let text = "📵 No WiFi"; let text = "📵 No WiFi";
self.context.new_path(); self.context.new_path();
self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.5); self.context
.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.5);
self.context.set_font_size(16.0); self.context.set_font_size(16.0);
self.context.move_to(x, y); self.context.move_to(x, y);
self.context.show_text(text).unwrap(); self.context.show_text(text).unwrap();
@@ -673,7 +699,14 @@ impl Renderer {
self.context.move_to(text_x, y); self.context.move_to(text_x, y);
self.context.show_text(&battery_text).unwrap(); self.context.show_text(&battery_text).unwrap();
} else { } else {
self.draw_battery_icon_at(x, y - 12.0, icon_width, 15.0, percent, self.system_status.is_charging); self.draw_battery_icon_at(
x,
y - 12.0,
icon_width,
15.0,
percent,
self.system_status.is_charging,
);
let battery_text = format!("{:.0}%", percent); let battery_text = format!("{:.0}%", percent);
self.context.new_path(); self.context.new_path();
self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha); self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha);
@@ -703,7 +736,10 @@ impl Renderer {
self.context.move_to(text_x, y); self.context.move_to(text_x, y);
self.context.show_text(&devices).unwrap(); self.context.show_text(&devices).unwrap();
} else { } else {
let text = format!("🔵 {} device(s)", self.system_status.bluetooth_devices.len()); let text = format!(
"🔵 {} device(s)",
self.system_status.bluetooth_devices.len()
);
self.context.new_path(); self.context.new_path();
self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha); self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha);
self.context.set_font_size(14.0); self.context.set_font_size(14.0);
@@ -713,7 +749,8 @@ impl Renderer {
} else { } else {
let text = "🔴 Bluetooth off"; let text = "🔴 Bluetooth off";
self.context.new_path(); self.context.new_path();
self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.5); self.context
.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha * 0.5);
self.context.set_font_size(14.0); self.context.set_font_size(14.0);
self.context.move_to(x, y); self.context.move_to(x, y);
self.context.show_text(text).unwrap(); self.context.show_text(text).unwrap();
@@ -750,7 +787,15 @@ impl Renderer {
self.context.restore().unwrap(); self.context.restore().unwrap();
} }
fn draw_battery_icon_at(&self, x: f64, y: f64, width: f64, height: f64, percent: f64, charging: bool) { fn draw_battery_icon_at(
&self,
x: f64,
y: f64,
width: f64,
height: f64,
percent: f64,
charging: bool,
) {
let alpha = self.fade_alpha; let alpha = self.fade_alpha;
self.context.new_path(); self.context.new_path();
self.context.set_source_rgba(1.0, 1.0, 1.0, alpha * 0.5); self.context.set_source_rgba(1.0, 1.0, 1.0, alpha * 0.5);
@@ -758,7 +803,8 @@ impl Renderer {
self.context.rectangle(x, y, width, height); self.context.rectangle(x, y, width, height);
self.context.stroke().unwrap(); self.context.stroke().unwrap();
self.context.new_path(); self.context.new_path();
self.context.rectangle(x + width, y + height / 4.0, 3.0, height / 2.0); self.context
.rectangle(x + width, y + height / 4.0, 3.0, height / 2.0);
self.context.fill().unwrap(); self.context.fill().unwrap();
let fill_width = (width - 4.0) * (percent / 100.0); let fill_width = (width - 4.0) * (percent / 100.0);
self.context.new_path(); self.context.new_path();
@@ -767,7 +813,8 @@ impl Renderer {
} else { } else {
self.context.set_source_rgba(0.2, 1.0, 0.2, alpha * 0.8); self.context.set_source_rgba(0.2, 1.0, 0.2, alpha * 0.8);
} }
self.context.rectangle(x + 2.0, y + 2.0, fill_width, height - 4.0); self.context
.rectangle(x + 2.0, y + 2.0, fill_width, height - 4.0);
self.context.fill().unwrap(); self.context.fill().unwrap();
if charging { if charging {
self.context.new_path(); self.context.new_path();
+2 -2
View File
@@ -115,10 +115,10 @@ impl Screenshot {
for y in 0..height { for y in 0..height {
melt_amount += rng.gen_range(0.0..factor); melt_amount += rng.gen_range(0.0..factor);
let src_y = (y as f32 - melt_amount).max(0.0) as i32; let src_y = (y as f32 - melt_amount).max(0.0) as i32;
let src_idx = (src_y as usize * stride) + (x as usize * 4); let src_idx = (src_y as usize * stride) + (x as usize * 4);
let dst_idx = (y as usize * stride) + (x as usize * 4); let dst_idx = (y as usize * stride) + (x as usize * 4);
// Copy the pixel from above to create a smear // Copy the pixel from above to create a smear
let pixel = [ let pixel = [
data[src_idx], data[src_idx],
+5 -5
View File
@@ -1,8 +1,8 @@
use std::sync::{Arc, Mutex}; use log::{debug, error};
use mpris::PlayerFinder; use mpris::PlayerFinder;
use zbus::Connection; use std::sync::{Arc, Mutex};
use log::{error, debug};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use zbus::Connection;
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct SystemStatus { pub struct SystemStatus {
@@ -89,7 +89,7 @@ impl SystemManager {
new_status.media_title = metadata.title().map(|s| s.to_string()); new_status.media_title = metadata.title().map(|s| s.to_string());
new_status.media_artist = metadata.artists().map(|a| a.join(", ")); new_status.media_artist = metadata.artists().map(|a| a.join(", "));
new_status.media_art_url = metadata.art_url().map(|u| u.to_string()); new_status.media_art_url = metadata.art_url().map(|u| u.to_string());
if new_status.media_art_url != last_art_url { if new_status.media_art_url != last_art_url {
last_art_url = new_status.media_art_url.clone(); last_art_url = new_status.media_art_url.clone();
last_art_data = None; last_art_data = None;
@@ -216,7 +216,7 @@ impl SystemManager {
SystemCommand::Reboot => "Reboot", SystemCommand::Reboot => "Reboot",
SystemCommand::Suspend => "Suspend", SystemCommand::Suspend => "Suspend",
}; };
debug!("Executing system command: {}", method); debug!("Executing system command: {}", method);
// Set a timeout for the DBus call to prevent hanging the background thread // Set a timeout for the DBus call to prevent hanging the background thread
let result = tokio::time::timeout( let result = tokio::time::timeout(