rs_blocks/blocks/
brightness.rs

1// Copyright ⓒ 2019-2021 Lewis Belcher
2// Licensed under the MIT license (see LICENSE or <http://opensource.org/licenses/MIT>).
3// All files in the project carrying such notice may not be copied, modified, or
4// distributed except according to those terms
5
6//! # Brightness block
7//!
8//! Use this block to get brightness monitoring in the status bar.
9//!
10//! Typical configuration:
11//!
12//! ```toml
13//! [brightness]
14//! ```
15//!
16//! ## Configuration options
17//!
18//! - `name`: Name of the block (must be unique)
19//! - `period`: Default update period in seconds (extra updates may occur on
20//!    event changes etc)
21//! - `update_signal`: Used to define what signal to listen on for immediate
22//!    retriggering of updates
23//! - `path_to_current_brightness`: Path to kernel file for current brightness
24//!    (usually something like `/sys/class/backlight/intel_backlight/brightness`
25//!    for intel based machines)
26//! - `path_to_max_brightness`: Path to kernel file for max brightness (usually
27//!    something like `/sys/class/backlight/intel_backlight/max_brightness` for
28//!    intel based machines)
29
30use crate::blocks::{Block, Configure, Message, Sender, ValidatedPath};
31use crate::utils;
32use serde::Deserialize;
33use std::thread;
34
35#[derive(Configure, Deserialize)]
36pub struct Brightness {
37	#[serde(default = "default_name")]
38	name: String,
39	#[serde(default = "default_period")]
40	period: f32,
41	#[serde(default = "default_update_signal")]
42	update_signal: i32,
43	#[serde(default = "default_path_to_current_brightness")]
44	path_to_current_brightness: ValidatedPath,
45	#[serde(default = "default_path_to_max_brightness")]
46	path_to_max_brightness: ValidatedPath,
47}
48
49fn default_name() -> String {
50	"brightness".to_string()
51}
52
53fn default_period() -> f32 {
54	1.0
55}
56
57fn default_update_signal() -> i32 {
58	signal_hook::SIGUSR1
59}
60
61fn default_path_to_current_brightness() -> ValidatedPath {
62	ValidatedPath("/sys/class/backlight/intel_backlight/brightness".to_string())
63}
64
65fn default_path_to_max_brightness() -> ValidatedPath {
66	ValidatedPath("/sys/class/backlight/intel_backlight/max_brightness".to_string())
67}
68
69impl Sender for Brightness {
70	fn add_sender(&self, channel: crossbeam_channel::Sender<Message>) -> anyhow::Result<()> {
71		let name = self.get_name();
72		let mut block = Block::new(name.clone(), true);
73		let mut monitor =
74			utils::monitor_file(self.path_to_current_brightness.0.clone(), self.period);
75		let recv = utils::wait_for_signal(self.update_signal, self.period);
76		let max = utils::file_to_f32(&self.path_to_max_brightness.0)? / 100.0;
77
78		thread::spawn(move || loop {
79			let output = monitor.read();
80			block.full_text = Some(if let Ok(num) = utils::str_to_f32(&output) {
81				format!(" {:.0}%", num / max)
82			} else {
83				output
84			});
85			channel.send((name.clone(), block.to_string())).unwrap();
86			recv.recv().unwrap();
87		});
88
89		Ok(())
90	}
91}