Pass config from main to the relevant places
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
|
[idle]
|
||||||
idle_timeout = 20
|
idle_timeout = 20
|
||||||
dim_timeout = 60
|
dim_timeout = 60
|
||||||
lock_timeout = 300
|
lock_timeout = 300
|
||||||
sleep_timeout = 320
|
sleep_timeout = 320
|
||||||
|
lock_command = 'hyprlock'
|
||||||
|
sleep_command = 'systemctl sleep'
|
||||||
@@ -17,6 +17,7 @@ use crate::backend::json_socket::{JsonSocketBackend, State};
|
|||||||
use crate::backend::network::{NetworkBackendHandle, NetworkCommand, NetworkState};
|
use crate::backend::network::{NetworkBackendHandle, NetworkCommand, NetworkState};
|
||||||
use crate::backend::perf_stats::{Stats, StatsBackend};
|
use crate::backend::perf_stats::{Stats, StatsBackend};
|
||||||
use crate::backend::window_manager_hypr::{HyprlandComms, WindowManagerEvent};
|
use crate::backend::window_manager_hypr::{HyprlandComms, WindowManagerEvent};
|
||||||
|
use crate::config::Config;
|
||||||
use crate::ctl::ControlCommand;
|
use crate::ctl::ControlCommand;
|
||||||
use crossbeam_channel::{Receiver, Sender};
|
use crossbeam_channel::{Receiver, Sender};
|
||||||
use jmb_logger_rs::*;
|
use jmb_logger_rs::*;
|
||||||
@@ -28,7 +29,7 @@ pub(crate) type Registrator<M> = Sender<Sender<M>>;
|
|||||||
pub trait BackendThread<M: Debug + Clone, D> {
|
pub trait BackendThread<M: Debug + Clone, D> {
|
||||||
fn subscribe(registrator: Registrator<M>) -> (Receiver<M>, D);
|
fn subscribe(registrator: Registrator<M>) -> (Receiver<M>, D);
|
||||||
fn subscribers(&self) -> &Vec<Sender<M>>;
|
fn subscribers(&self) -> &Vec<Sender<M>>;
|
||||||
fn init(registration_rx: Receiver<Sender<M>>);
|
fn init(self, registration_rx: Receiver<Sender<M>>);
|
||||||
fn publish(&self, message: M) {
|
fn publish(&self, message: M) {
|
||||||
trace!(&LOGGER, "Sending: {message:?} to {:?}", self.subscribers());
|
trace!(&LOGGER, "Sending: {message:?} to {:?}", self.subscribers());
|
||||||
for tx in self.subscribers() {
|
for tx in self.subscribers() {
|
||||||
@@ -41,16 +42,19 @@ pub trait BackendThread<M: Debug + Clone, D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn start() -> Registrator<M> {
|
fn start(self) -> Registrator<M>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
let (registration_tx, registration_rx) = crossbeam_channel::unbounded::<Sender<M>>();
|
let (registration_tx, registration_rx) = crossbeam_channel::unbounded::<Sender<M>>();
|
||||||
Self::init(registration_rx);
|
Self::init(self, registration_rx);
|
||||||
registration_tx
|
registration_tx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SimpleBackendThread<M: Debug + Clone>: BackendThread<M, ()> {
|
pub trait SimpleBackendThread<M: Debug + Clone>: BackendThread<M, ()> {
|
||||||
fn subscribers(&self) -> &Vec<Sender<M>>;
|
fn subscribers(&self) -> &Vec<Sender<M>>;
|
||||||
fn init(registration_rx: Receiver<Sender<M>>);
|
fn init(self, registration_rx: Receiver<Sender<M>>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Debug + Clone, S: SimpleBackendThread<M>> BackendThread<M, ()> for S {
|
impl<M: Debug + Clone, S: SimpleBackendThread<M>> BackendThread<M, ()> for S {
|
||||||
@@ -64,8 +68,8 @@ impl<M: Debug + Clone, S: SimpleBackendThread<M>> BackendThread<M, ()> for S {
|
|||||||
SimpleBackendThread::subscribers(self)
|
SimpleBackendThread::subscribers(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(registration_rx: Receiver<Sender<M>>) {
|
fn init(self, registration_rx: Receiver<Sender<M>>) {
|
||||||
<S as SimpleBackendThread<M>>::init(registration_rx)
|
<S as SimpleBackendThread<M>>::init(self, registration_rx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,17 +99,17 @@ pub enum ChannelType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Backend {
|
impl Backend {
|
||||||
pub fn start() -> Self {
|
pub fn start(config: &Config) -> Self {
|
||||||
debug!(&LOGGER, "Starting Backend threads...");
|
debug!(&LOGGER, "Starting Backend threads...");
|
||||||
let hypr_registrator = HyprlandComms::start();
|
let hypr_registrator = HyprlandComms::new().start();
|
||||||
let net_registrator = NetworkBackendHandle::start();
|
let net_registrator = NetworkBackendHandle::new().start();
|
||||||
let br_registrator = BrightnessManager::start();
|
let br_registrator = BrightnessManager::new().start();
|
||||||
let stats_registrator = StatsBackend::start();
|
let stats_registrator = StatsBackend::new().start();
|
||||||
let audio_registrator = AudioBackend::start();
|
let audio_registrator = AudioBackend::new().start();
|
||||||
let media_registration = MediaBackend::start();
|
let media_registration = MediaBackend::new().start();
|
||||||
let netbird_registrator = JsonSocketBackend::start();
|
let netbird_registrator = JsonSocketBackend::new().start();
|
||||||
let idle_registrator = IdleDaemon::start();
|
let idle_registrator = IdleDaemon::new(config.idle.clone()).start();
|
||||||
let control_registrator = ControlSocket::start();
|
let control_registrator = ControlSocket::new().start();
|
||||||
debug!(&LOGGER, "Started Backend threads");
|
debug!(&LOGGER, "Started Backend threads");
|
||||||
Self {
|
Self {
|
||||||
hypr_registrator,
|
hypr_registrator,
|
||||||
|
|||||||
@@ -266,7 +266,16 @@ pub enum AudioMessage {
|
|||||||
|
|
||||||
pub struct AudioBackend {
|
pub struct AudioBackend {
|
||||||
subscribers: Vec<Sender<AudioMessage>>,
|
subscribers: Vec<Sender<AudioMessage>>,
|
||||||
command_tx: Sender<AudioMessage>,
|
command_tx: Option<Sender<AudioMessage>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AudioBackend {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
subscribers: vec![],
|
||||||
|
command_tx: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BackendThread<AudioMessage, Sender<AudioMessage>> for AudioBackend {
|
impl BackendThread<AudioMessage, Sender<AudioMessage>> for AudioBackend {
|
||||||
@@ -288,12 +297,10 @@ impl BackendThread<AudioMessage, Sender<AudioMessage>> for AudioBackend {
|
|||||||
&self.subscribers
|
&self.subscribers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(registration_rx: Receiver<Sender<AudioMessage>>) {
|
fn init(mut self, registration_rx: Receiver<Sender<AudioMessage>>) {
|
||||||
let (command_tx, command_rx) = crossbeam_channel::unbounded::<AudioMessage>();
|
let (command_tx, command_rx) = crossbeam_channel::unbounded::<AudioMessage>();
|
||||||
let instance = Arc::new(Mutex::new(Self {
|
self.command_tx = Some(command_tx);
|
||||||
subscribers: vec![],
|
let instance = Arc::new(Mutex::new(self));
|
||||||
command_tx,
|
|
||||||
}));
|
|
||||||
let (controller_tx, controller_rx) = crossbeam_channel::unbounded::<ControllerMsg>();
|
let (controller_tx, controller_rx) = crossbeam_channel::unbounded::<ControllerMsg>();
|
||||||
let notify = Arc::new(EventFD::new(0, EfdFlags::EFD_CLOEXEC).unwrap());
|
let notify = Arc::new(EventFD::new(0, EfdFlags::EFD_CLOEXEC).unwrap());
|
||||||
thread::spawn({
|
thread::spawn({
|
||||||
@@ -381,7 +388,8 @@ impl BackendThread<AudioMessage, Sender<AudioMessage>> for AudioBackend {
|
|||||||
.lock()
|
.lock()
|
||||||
.expect("Couldn't get lock")
|
.expect("Couldn't get lock")
|
||||||
.command_tx
|
.command_tx
|
||||||
.clone(),
|
.clone()
|
||||||
|
.unwrap(),
|
||||||
))
|
))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
@@ -460,13 +468,9 @@ impl BackendThread<MediaMessage, Sender<MediaMessage>> for MediaBackend {
|
|||||||
&self.subscribers
|
&self.subscribers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(registration_rx: Receiver<Sender<MediaMessage>>) {
|
fn init(self, registration_rx: Receiver<Sender<MediaMessage>>) {
|
||||||
let (tx, rx) = crossbeam_channel::unbounded::<MediaMessage>();
|
let (tx, rx) = crossbeam_channel::unbounded::<MediaMessage>();
|
||||||
let instance = Arc::new(Mutex::new(Self {
|
let instance = Arc::new(Mutex::new(self));
|
||||||
subscribers: vec![],
|
|
||||||
players: HashMap::new(),
|
|
||||||
active_player: None,
|
|
||||||
}));
|
|
||||||
thread::spawn({
|
thread::spawn({
|
||||||
let instance = instance.clone();
|
let instance = instance.clone();
|
||||||
move || {
|
move || {
|
||||||
@@ -545,6 +549,13 @@ impl BackendThread<MediaMessage, Sender<MediaMessage>> for MediaBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MediaBackend {
|
impl MediaBackend {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
subscribers: vec![],
|
||||||
|
players: HashMap::new(),
|
||||||
|
active_player: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
async fn find_existing_players(
|
async fn find_existing_players(
|
||||||
connection: &zbus::Connection,
|
connection: &zbus::Connection,
|
||||||
instance: Arc<Mutex<Self>>,
|
instance: Arc<Mutex<Self>>,
|
||||||
|
|||||||
@@ -143,12 +143,9 @@ impl BackendThread<BrightnessMessage, Sender<BrightnessMessage>> for BrightnessM
|
|||||||
&self.subscribers
|
&self.subscribers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(registration_rx: Receiver<Sender<BrightnessMessage>>) {
|
fn init(self, registration_rx: Receiver<Sender<BrightnessMessage>>) {
|
||||||
let (f2b_tx, f2b_rx) = crossbeam_channel::unbounded::<BrightnessMessage>();
|
let (f2b_tx, f2b_rx) = crossbeam_channel::unbounded::<BrightnessMessage>();
|
||||||
let instance = Arc::new(Mutex::new(Self {
|
let instance = Arc::new(Mutex::new(self));
|
||||||
display_cache: HashMap::new(),
|
|
||||||
subscribers: Vec::new(),
|
|
||||||
}));
|
|
||||||
let instance_clone = instance.clone();
|
let instance_clone = instance.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
while let Ok(tx) = registration_rx.recv() {
|
while let Ok(tx) = registration_rx.recv() {
|
||||||
@@ -246,6 +243,12 @@ enum Operation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BrightnessManager {
|
impl BrightnessManager {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
subscribers: vec![],
|
||||||
|
display_cache: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn set_brightness(&mut self, connector: String, percent: u8) {
|
pub fn set_brightness(&mut self, connector: String, percent: u8) {
|
||||||
if !self.display_cache.contains_key(&connector) {
|
if !self.display_cache.contains_key(&connector) {
|
||||||
self.register_display(connector.clone());
|
self.register_display(connector.clone());
|
||||||
|
|||||||
@@ -12,15 +12,21 @@ pub struct ControlSocket {
|
|||||||
subscribers: Vec<Sender<ControlCommand>>,
|
subscribers: Vec<Sender<ControlCommand>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ControlSocket {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
subscribers: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SimpleBackendThread<ControlCommand> for ControlSocket {
|
impl SimpleBackendThread<ControlCommand> for ControlSocket {
|
||||||
fn subscribers(&self) -> &Vec<Sender<ControlCommand>> {
|
fn subscribers(&self) -> &Vec<Sender<ControlCommand>> {
|
||||||
&self.subscribers
|
&self.subscribers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(registration_rx: Receiver<Sender<ControlCommand>>) {
|
fn init(self, registration_rx: Receiver<Sender<ControlCommand>>) {
|
||||||
let instance = Arc::new(Mutex::new(Self {
|
let instance = Arc::new(Mutex::new(self));
|
||||||
subscribers: Vec::new(),
|
|
||||||
}));
|
|
||||||
let instance_clone = instance.clone();
|
let instance_clone = instance.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
while let Ok(sender) = registration_rx.recv() {
|
while let Ok(sender) = registration_rx.recv() {
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ struct PerfEventAttr {
|
|||||||
sig_data: u64,
|
sig_data: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
const PERF_TYPE_RAW: u32 = 4;
|
|
||||||
const PERF_FORMAT_TOTAL_TIME_ENABLED: u64 = 1;
|
const PERF_FORMAT_TOTAL_TIME_ENABLED: u64 = 1;
|
||||||
const PERF_FORMAT_TOTAL_TIME_RUNNING: u64 = 2;
|
const PERF_FORMAT_TOTAL_TIME_RUNNING: u64 = 2;
|
||||||
|
|
||||||
@@ -95,8 +94,8 @@ impl I915Engine {
|
|||||||
fn open(name: &str) -> io::Result<Self> {
|
fn open(name: &str) -> io::Result<Self> {
|
||||||
let base = "/sys/bus/event_source/devices/i915";
|
let base = "/sys/bus/event_source/devices/i915";
|
||||||
|
|
||||||
let pmu_type = read_number(&format!("{base}/type")).unwrap() as u32;
|
let pmu_type = read_number(&format!("{base}/type"))? as u32;
|
||||||
let config = read_config(&format!("{base}/events/{name}")).unwrap();
|
let config = read_config(&format!("{base}/events/{name}"))?;
|
||||||
|
|
||||||
let mut attr = PerfEventAttr::default();
|
let mut attr = PerfEventAttr::default();
|
||||||
attr.type_ = pmu_type;
|
attr.type_ = pmu_type;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::backend::{BackendThread, Registrator};
|
use crate::backend::{BackendThread, Registrator};
|
||||||
use crate::config::Config;
|
use crate::config::IdleConfig;
|
||||||
use crate::{APP_NAME, LOGGER};
|
use crate::{APP_NAME, LOGGER};
|
||||||
use crossbeam_channel::{Receiver, Sender};
|
use crossbeam_channel::{Receiver, Sender};
|
||||||
use jmb_logger_rs::*;
|
use jmb_logger_rs::*;
|
||||||
@@ -100,6 +100,7 @@ pub enum IdleMessage {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct IdleDaemon {
|
pub struct IdleDaemon {
|
||||||
subscribers: Vec<Sender<IdleState>>,
|
subscribers: Vec<Sender<IdleState>>,
|
||||||
|
config: IdleConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BackendThread<IdleState, Sender<IdleMessage>> for IdleDaemon {
|
impl BackendThread<IdleState, Sender<IdleMessage>> for IdleDaemon {
|
||||||
@@ -121,12 +122,9 @@ impl BackendThread<IdleState, Sender<IdleMessage>> for IdleDaemon {
|
|||||||
&self.subscribers
|
&self.subscribers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(registration_rx: Receiver<Sender<IdleState>>) {
|
fn init(self, registration_rx: Receiver<Sender<IdleState>>) {
|
||||||
let config = Config::load();
|
|
||||||
let (tx, rx) = crossbeam_channel::unbounded::<IdleMessage>();
|
let (tx, rx) = crossbeam_channel::unbounded::<IdleMessage>();
|
||||||
let instance = Arc::new(Mutex::new(Self {
|
let instance = Arc::new(Mutex::new(self));
|
||||||
subscribers: Vec::new(),
|
|
||||||
}));
|
|
||||||
std::thread::spawn({
|
std::thread::spawn({
|
||||||
let instance = instance.clone();
|
let instance = instance.clone();
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
@@ -146,9 +144,9 @@ impl BackendThread<IdleState, Sender<IdleMessage>> for IdleDaemon {
|
|||||||
let (wl_tx, wl_rx) = watch::channel(false);
|
let (wl_tx, wl_rx) = watch::channel(false);
|
||||||
let (dbus_tx, dbus_rx) = watch::channel(false);
|
let (dbus_tx, dbus_rx) = watch::channel(false);
|
||||||
std::thread::spawn({
|
std::thread::spawn({
|
||||||
let config = config.clone();
|
let instance = instance.clone();
|
||||||
move || {
|
move || {
|
||||||
if let Err(err) = Self::start_idle_notifier(wl_tx, &config) {
|
if let Err(err) = Self::start_idle_notifier(wl_tx, instance) {
|
||||||
error!(&LOGGER, "Idle Daemon unexpectedly quit, reason: {err}");
|
error!(&LOGGER, "Idle Daemon unexpectedly quit, reason: {err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,7 +200,7 @@ impl BackendThread<IdleState, Sender<IdleMessage>> for IdleDaemon {
|
|||||||
let res = IdleDaemon::start_dbus(dbus_tx, instance_clone).await;
|
let res = IdleDaemon::start_dbus(dbus_tx, instance_clone).await;
|
||||||
match res {
|
match res {
|
||||||
Ok((_, _)) => {
|
Ok((_, _)) => {
|
||||||
Self::run_idle_timer(instance, wl_rx, dbus_rx, &config).await;
|
Self::run_idle_timer(instance, wl_rx, dbus_rx).await;
|
||||||
}
|
}
|
||||||
Err(err) => error!(&LOGGER, "Error running D-Bus Screensaver: {err}"),
|
Err(err) => error!(&LOGGER, "Error running D-Bus Screensaver: {err}"),
|
||||||
}
|
}
|
||||||
@@ -228,7 +226,7 @@ impl IdleStage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn timeout(self, cfg: &Config) -> Duration {
|
fn timeout(self, cfg: &IdleConfig) -> Duration {
|
||||||
match self {
|
match self {
|
||||||
Self::Dim => Duration::from_secs(cfg.dim_timeout_delta()),
|
Self::Dim => Duration::from_secs(cfg.dim_timeout_delta()),
|
||||||
Self::TurnOff => Duration::from_secs(cfg.lock_timeout_delta()),
|
Self::TurnOff => Duration::from_secs(cfg.lock_timeout_delta()),
|
||||||
@@ -238,11 +236,16 @@ impl IdleStage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IdleDaemon {
|
impl IdleDaemon {
|
||||||
|
pub fn new(config: IdleConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
subscribers: vec![],
|
||||||
|
config,
|
||||||
|
}
|
||||||
|
}
|
||||||
async fn run_idle_timer(
|
async fn run_idle_timer(
|
||||||
instance: Arc<Mutex<Self>>,
|
instance: Arc<Mutex<Self>>,
|
||||||
mut wl_rx: watch::Receiver<bool>,
|
mut wl_rx: watch::Receiver<bool>,
|
||||||
mut dbus_rx: watch::Receiver<bool>,
|
mut dbus_rx: watch::Receiver<bool>,
|
||||||
config: &Config,
|
|
||||||
) {
|
) {
|
||||||
loop {
|
loop {
|
||||||
if let Err(e) = wl_rx.changed().await {
|
if let Err(e) = wl_rx.changed().await {
|
||||||
@@ -254,12 +257,13 @@ impl IdleDaemon {
|
|||||||
if wl_idle && !dbus_state {
|
if wl_idle && !dbus_state {
|
||||||
let mut stage = IdleStage::Dim;
|
let mut stage = IdleStage::Dim;
|
||||||
loop {
|
loop {
|
||||||
|
let timeout = stage.timeout(&instance.lock().unwrap().config);
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = sleep(stage.timeout(config)) => {
|
_ = sleep(timeout) => {
|
||||||
match stage {
|
match stage {
|
||||||
IdleStage::Dim => instance.lock().unwrap().publish(IdleState::Dimmed),
|
IdleStage::Dim => instance.lock().unwrap().publish(IdleState::Dimmed),
|
||||||
IdleStage::TurnOff => _ = Command::new("hyprlock").spawn(),
|
IdleStage::TurnOff => _ = Command::new("bash").arg("-c").arg(format!("'{}'", instance.lock().unwrap().config.lock_command())).spawn(),
|
||||||
IdleStage::Sleep => _ = Command::new("systemctl").arg("sleep").spawn(),
|
IdleStage::Sleep => _ = Command::new("bash").arg("-c").arg(format!("'{}'", instance.lock().unwrap().config.sleep_command())).spawn(),
|
||||||
}
|
}
|
||||||
stage = stage.next();
|
stage = stage.next();
|
||||||
}
|
}
|
||||||
@@ -286,7 +290,10 @@ impl IdleDaemon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_idle_notifier(tx: watch::Sender<bool>, config: &Config) -> Result<(), Box<dyn Error>> {
|
fn start_idle_notifier(
|
||||||
|
tx: watch::Sender<bool>,
|
||||||
|
instance: Arc<Mutex<IdleDaemon>>,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let conn = Connection::connect_to_env()?;
|
let conn = Connection::connect_to_env()?;
|
||||||
let (globals, mut event_queue) = registry_queue_init::<WlState>(&conn)?;
|
let (globals, mut event_queue) = registry_queue_init::<WlState>(&conn)?;
|
||||||
let queue_handle = event_queue.handle();
|
let queue_handle = event_queue.handle();
|
||||||
@@ -298,7 +305,7 @@ impl IdleDaemon {
|
|||||||
let mut state = WlState { idle: None, tx };
|
let mut state = WlState { idle: None, tx };
|
||||||
|
|
||||||
let _notification = notifier.get_idle_notification(
|
let _notification = notifier.get_idle_notification(
|
||||||
(config.idle_timeout() * 1000) as u32,
|
(instance.lock().unwrap().config.idle_timeout() * 1000) as u32,
|
||||||
&seat,
|
&seat,
|
||||||
&queue_handle,
|
&queue_handle,
|
||||||
(),
|
(),
|
||||||
|
|||||||
@@ -37,6 +37,13 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl JsonSocketBackend {
|
impl JsonSocketBackend {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
subscribers: vec![],
|
||||||
|
state: initial_state_tailscale(),
|
||||||
|
socket_address: String::from("/var/run/netbird-http.sock"),
|
||||||
|
}
|
||||||
|
}
|
||||||
async fn _watch(instance: Arc<Mutex<Self>>) -> Result<(), Box<dyn Error + Send + Sync>> {
|
async fn _watch(instance: Arc<Mutex<Self>>) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||||
let socket_address = instance
|
let socket_address = instance
|
||||||
.lock()
|
.lock()
|
||||||
@@ -197,14 +204,8 @@ impl BackendThread<State, ()> for JsonSocketBackend {
|
|||||||
&self.subscribers
|
&self.subscribers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(registration_rx: Receiver<Sender<State>>) {
|
fn init(self, registration_rx: Receiver<Sender<State>>) {
|
||||||
let state = initial_state_tailscale();
|
let instance = Arc::new(Mutex::new(self));
|
||||||
|
|
||||||
let instance = Arc::new(Mutex::new(Self {
|
|
||||||
subscribers: vec![],
|
|
||||||
state,
|
|
||||||
socket_address: String::from("/var/run/netbird-http.sock"),
|
|
||||||
}));
|
|
||||||
|
|
||||||
let instance_clone = instance.clone();
|
let instance_clone = instance.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ pub enum NetworkState {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct NetworkBackendHandle {
|
pub struct NetworkBackendHandle {
|
||||||
subscribers: Vec<Sender<NetworkState>>,
|
subscribers: Vec<Sender<NetworkState>>,
|
||||||
command_tx: UnboundedSender<NetworkCommand>,
|
command_tx: Option<UnboundedSender<NetworkCommand>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EventDebouncer {
|
struct EventDebouncer {
|
||||||
@@ -140,12 +140,9 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
|||||||
&self.subscribers
|
&self.subscribers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(registration_rx: Receiver<Sender<NetworkState>>) {
|
fn init(mut self, registration_rx: Receiver<Sender<NetworkState>>) {
|
||||||
let (command_tx, mut command_rx) = tokio::sync::mpsc::unbounded_channel::<NetworkCommand>();
|
let (command_tx, mut command_rx) = tokio::sync::mpsc::unbounded_channel::<NetworkCommand>();
|
||||||
let instance = Self {
|
self.command_tx = Some(command_tx);
|
||||||
subscribers: vec![],
|
|
||||||
command_tx,
|
|
||||||
};
|
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let runtime = tokio::runtime::Builder::new_current_thread()
|
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
@@ -163,7 +160,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
|||||||
|
|
||||||
std::thread::spawn({
|
std::thread::spawn({
|
||||||
let nm = nm.clone();
|
let nm = nm.clone();
|
||||||
let mut instance = instance.clone();
|
let mut instance = self.clone();
|
||||||
move || {
|
move || {
|
||||||
let runtime = tokio::runtime::Builder::new_current_thread()
|
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
@@ -172,7 +169,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
|||||||
|
|
||||||
runtime.block_on(async move {
|
runtime.block_on(async move {
|
||||||
while let Ok(tx) = registration_rx.recv() {
|
while let Ok(tx) = registration_rx.recv() {
|
||||||
if tx.send(NetworkState::Init(instance.command_tx.clone())).is_ok() {
|
if tx.send(NetworkState::Init(instance.command_tx.clone().unwrap())).is_ok() {
|
||||||
instance.subscribers.push(tx);
|
instance.subscribers.push(tx);
|
||||||
let _ = instance.send_all_networks(&nm).await;
|
let _ = instance.send_all_networks(&nm).await;
|
||||||
let _ = instance.send_active_connection(&nm).await;
|
let _ = instance.send_active_connection(&nm).await;
|
||||||
@@ -205,7 +202,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
|||||||
// Run the command without stopping event processing
|
// Run the command without stopping event processing
|
||||||
// while a potentially slow connection operation runs.
|
// while a potentially slow connection operation runs.
|
||||||
let nm = nm.clone();
|
let nm = nm.clone();
|
||||||
let instance_clone = instance.clone();
|
let instance_clone = self.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
match command {
|
match command {
|
||||||
@@ -241,7 +238,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
|||||||
match event {
|
match event {
|
||||||
Some(event_res) => {
|
Some(event_res) => {
|
||||||
match event_res {
|
match event_res {
|
||||||
Ok(event) => instance.handle_event(&nm, event, &mut debouncer).await,
|
Ok(event) => self.handle_event(&nm, event, &mut debouncer).await,
|
||||||
Err(err) => error!(&LOGGER, "Error: {err:?}"),
|
Err(err) => error!(&LOGGER, "Error: {err:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -250,7 +247,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
|||||||
}
|
}
|
||||||
_ = &mut debouncer.sleep, if debouncer.deadline.is_some() => {
|
_ = &mut debouncer.sleep, if debouncer.deadline.is_some() => {
|
||||||
debouncer.deadline = None;
|
debouncer.deadline = None;
|
||||||
let _ = instance.send_all_networks(&nm).await;
|
let _ = self.send_all_networks(&nm).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -260,6 +257,12 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkBackendHandle {
|
impl NetworkBackendHandle {
|
||||||
|
pub fn new() -> NetworkBackendHandle {
|
||||||
|
Self {
|
||||||
|
subscribers: vec![],
|
||||||
|
command_tx: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
async fn connect(&self, nm: &NetworkManager, ssid: String, creds: WifiSecurity) {
|
async fn connect(&self, nm: &NetworkManager, ssid: String, creds: WifiSecurity) {
|
||||||
let previous_ssid = nm.current_ssid().await;
|
let previous_ssid = nm.current_ssid().await;
|
||||||
let res = nm.connect(&ssid, None, creds).await;
|
let res = nm.connect(&ssid, None, creds).await;
|
||||||
|
|||||||
@@ -31,6 +31,14 @@ pub struct StatsBackend {
|
|||||||
subscribers: Vec<Sender<Stats>>,
|
subscribers: Vec<Sender<Stats>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StatsBackend {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
subscribers: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl BackendThread<Stats, ()> for StatsBackend {
|
impl BackendThread<Stats, ()> for StatsBackend {
|
||||||
fn subscribe(registrator: Registrator<Stats>) -> (Receiver<Stats>, ()) {
|
fn subscribe(registrator: Registrator<Stats>) -> (Receiver<Stats>, ()) {
|
||||||
let (tx, rx) = crossbeam_channel::unbounded::<Stats>();
|
let (tx, rx) = crossbeam_channel::unbounded::<Stats>();
|
||||||
@@ -42,10 +50,8 @@ impl BackendThread<Stats, ()> for StatsBackend {
|
|||||||
&self.subscribers
|
&self.subscribers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(registration_rx: Receiver<Sender<Stats>>) {
|
fn init(self, registration_rx: Receiver<Sender<Stats>>) {
|
||||||
let instance = Arc::new(Mutex::new(Self {
|
let instance = Arc::new(Mutex::new(self));
|
||||||
subscribers: Vec::new(),
|
|
||||||
}));
|
|
||||||
thread::spawn({
|
thread::spawn({
|
||||||
let instance = instance.clone();
|
let instance = instance.clone();
|
||||||
move || {
|
move || {
|
||||||
|
|||||||
@@ -28,11 +28,9 @@ impl SimpleBackendThread<WindowManagerEvent> for HyprlandComms {
|
|||||||
&self.subscribers
|
&self.subscribers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(registration_rx: Receiver<Sender<WindowManagerEvent>>) {
|
fn init(self, registration_rx: Receiver<Sender<WindowManagerEvent>>) {
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let instance = Arc::new(Mutex::new(Self {
|
let instance = Arc::new(Mutex::new(self));
|
||||||
subscribers: vec![],
|
|
||||||
}));
|
|
||||||
let mut listener = EventListener::new();
|
let mut listener = EventListener::new();
|
||||||
|
|
||||||
let inst_clone = instance.clone();
|
let inst_clone = instance.clone();
|
||||||
@@ -153,6 +151,12 @@ impl SimpleBackendThread<WindowManagerEvent> for HyprlandComms {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HyprlandComms {
|
impl HyprlandComms {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
subscribers: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn monitor_id_from_workspace_id(id: WorkspaceId) -> Option<MonitorId> {
|
fn monitor_id_from_workspace_id(id: WorkspaceId) -> Option<MonitorId> {
|
||||||
if let Ok(wss) = Workspaces::get()
|
if let Ok(wss) = Workspaces::get()
|
||||||
&& let Some(ws) = wss.to_vec().iter().find(|ws| ws.id().unwrap() == id)
|
&& let Some(ws) = wss.to_vec().iter().find(|ws| ws.id().unwrap() == id)
|
||||||
|
|||||||
@@ -1,23 +1,9 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone, Default)]
|
||||||
pub(crate) struct Config {
|
pub(crate) struct Config {
|
||||||
idle_timeout: u64,
|
pub idle: IdleConfig,
|
||||||
dim_timeout: u64,
|
|
||||||
lock_timeout: u64,
|
|
||||||
sleep_timeout: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Config {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
idle_timeout: 20,
|
|
||||||
dim_timeout: 60,
|
|
||||||
lock_timeout: 300,
|
|
||||||
sleep_timeout: 320,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@@ -28,7 +14,31 @@ impl Config {
|
|||||||
.flatten()
|
.flatten()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
pub(crate) struct IdleConfig {
|
||||||
|
idle_timeout: u64,
|
||||||
|
dim_timeout: u64,
|
||||||
|
lock_timeout: u64,
|
||||||
|
sleep_timeout: u64,
|
||||||
|
lock_command: String,
|
||||||
|
sleep_command: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for IdleConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
idle_timeout: 20,
|
||||||
|
dim_timeout: 60,
|
||||||
|
lock_timeout: 300,
|
||||||
|
sleep_timeout: 320,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IdleConfig {
|
||||||
pub fn idle_timeout(&self) -> u64 {
|
pub fn idle_timeout(&self) -> u64 {
|
||||||
self.idle_timeout
|
self.idle_timeout
|
||||||
}
|
}
|
||||||
@@ -56,4 +66,12 @@ impl Config {
|
|||||||
pub fn sleep_timeout_delta(&self) -> u64 {
|
pub fn sleep_timeout_delta(&self) -> u64 {
|
||||||
self.sleep_timeout - self.lock_timeout_delta()
|
self.sleep_timeout - self.lock_timeout_delta()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lock_command(&self) -> &str {
|
||||||
|
&self.lock_command
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sleep_command(&self) -> &str {
|
||||||
|
&self.sleep_command
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@@ -5,13 +5,13 @@ mod css;
|
|||||||
mod ctl;
|
mod ctl;
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
use glib::clone;
|
use glib::clone;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{Application, CssProvider, gdk, gio};
|
use gtk::{Application, CssProvider, gdk, gio};
|
||||||
use jmb_logger_rs::*;
|
use jmb_logger_rs::*;
|
||||||
use notify::RecommendedWatcher;
|
use notify::RecommendedWatcher;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::process::Command;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub const LOGGER: Logger = Logger::create(Level::DEBUG);
|
pub const LOGGER: Logger = Logger::create(Level::DEBUG);
|
||||||
@@ -20,16 +20,14 @@ pub const APP_NAME: &str = "net.jmb19905.jmb-bar";
|
|||||||
fn main() {
|
fn main() {
|
||||||
info!(&LOGGER, "Starting jmb-bar");
|
info!(&LOGGER, "Starting jmb-bar");
|
||||||
|
|
||||||
gio::resources_register_include!("templates.gresource").expect("Failed to register resources");
|
let config = Config::load();
|
||||||
|
let backend = Backend::start(&config);
|
||||||
|
|
||||||
|
gio::resources_register_include!("templates.gresource").expect("Failed to register resources");
|
||||||
let app = Application::builder().application_id(APP_NAME).build();
|
let app = Application::builder().application_id(APP_NAME).build();
|
||||||
|
|
||||||
let watcher_slot: Rc<RefCell<Option<RecommendedWatcher>>> = Rc::new(RefCell::new(None));
|
let watcher_slot: Rc<RefCell<Option<RecommendedWatcher>>> = Rc::new(RefCell::new(None));
|
||||||
|
|
||||||
let _ = Command::new("pkill hypridle").output(); // Kill existing hypridle processes
|
|
||||||
|
|
||||||
let backend = Backend::start();
|
|
||||||
|
|
||||||
app.connect_startup(move |_| {
|
app.connect_startup(move |_| {
|
||||||
debug!(&LOGGER, "Connect startup");
|
debug!(&LOGGER, "Connect startup");
|
||||||
let provider = CssProvider::new();
|
let provider = CssProvider::new();
|
||||||
|
|||||||
Reference in New Issue
Block a user