mirror of
https://github.com/2e3s/awatcher.git
synced 2025-06-07 12:05:49 +00:00
Aggregate into Watcher trait
This commit is contained in:
parent
91224d63e8
commit
32f0b5bccc
55
src/main.rs
55
src/main.rs
@ -15,8 +15,8 @@ use fern::colors::{Color, ColoredLevelConfig};
|
|||||||
use report_client::ReportClient;
|
use report_client::ReportClient;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::{error::Error, str::FromStr, sync::Arc, thread};
|
use std::{error::Error, str::FromStr, sync::Arc, thread};
|
||||||
use wl_kwin_idle::run as run_kwin_idle;
|
use wl_kwin_idle::KwinIdleWatcher;
|
||||||
use wl_kwin_window::run as run_kwin_active_window;
|
use wl_kwin_window::KwinWindowWatcher;
|
||||||
|
|
||||||
type BoxedError = Box<dyn Error>;
|
type BoxedError = Box<dyn Error>;
|
||||||
|
|
||||||
@ -47,6 +47,14 @@ fn setup_logger() -> Result<(), fern::InitError> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WatcherConstructor = fn() -> Result<Box<dyn Watcher>, BoxedError>;
|
||||||
|
trait Watcher: Send {
|
||||||
|
fn new() -> Result<Self, BoxedError>
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
fn watch(&mut self, client: &Arc<ReportClient>);
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
setup_logger().unwrap();
|
setup_logger().unwrap();
|
||||||
|
|
||||||
@ -60,14 +68,39 @@ fn main() {
|
|||||||
info!("Idle timeout: {} seconds", client.config.idle_timeout);
|
info!("Idle timeout: {} seconds", client.config.idle_timeout);
|
||||||
info!("Polling period: {} seconds", client.config.poll_time_idle);
|
info!("Polling period: {} seconds", client.config.poll_time_idle);
|
||||||
|
|
||||||
let client1 = Arc::clone(&client);
|
let mut thread_handlers = Vec::new();
|
||||||
let idle_handler = thread::spawn(move || run_kwin_idle(&client1));
|
let idle_watchers: Vec<WatcherConstructor> = vec![|| Ok(Box::new(KwinIdleWatcher::new()?))];
|
||||||
|
let window_watchers: Vec<WatcherConstructor> = vec![|| Ok(Box::new(KwinWindowWatcher::new()?))];
|
||||||
|
|
||||||
let client2 = Arc::clone(&client);
|
let filter_watcher = |watchers: Vec<WatcherConstructor>| {
|
||||||
let active_window_handler = thread::spawn(move || run_kwin_active_window(&client2));
|
watchers.iter().find_map(|watcher| match watcher() {
|
||||||
|
Ok(watcher) => Some(watcher),
|
||||||
idle_handler.join().expect("Idle thread failed");
|
Err(e) => {
|
||||||
active_window_handler
|
info!("Watcher cannot run: {e}");
|
||||||
.join()
|
None
|
||||||
.expect("Active window thread failed");
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let idle_watcher = filter_watcher(idle_watchers);
|
||||||
|
if let Some(mut watcher) = idle_watcher {
|
||||||
|
let thread_client = Arc::clone(&client);
|
||||||
|
let idle_handler = thread::spawn(move || watcher.watch(&thread_client));
|
||||||
|
thread_handlers.push(idle_handler);
|
||||||
|
} else {
|
||||||
|
warn!("No supported idle handler is found");
|
||||||
|
}
|
||||||
|
|
||||||
|
let window_watcher = filter_watcher(window_watchers);
|
||||||
|
if let Some(mut watcher) = window_watcher {
|
||||||
|
let thread_client = Arc::clone(&client);
|
||||||
|
let active_window_handler = thread::spawn(move || watcher.watch(&thread_client));
|
||||||
|
thread_handlers.push(active_window_handler);
|
||||||
|
} else {
|
||||||
|
warn!("No supported active window handler is found");
|
||||||
|
}
|
||||||
|
|
||||||
|
for handler in thread_handlers {
|
||||||
|
handler.join().unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,20 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_idle_timeout(&self, timeout: u32) -> Result<OrgKdeKwinIdleTimeout, BoxedError>
|
pub fn get_kwin_idle(&self) -> Result<OrgKdeKwinIdle, BoxedError>
|
||||||
|
where
|
||||||
|
T: Dispatch<OrgKdeKwinIdle, ()>,
|
||||||
|
{
|
||||||
|
self.globals
|
||||||
|
.bind::<OrgKdeKwinIdle, T, ()>(
|
||||||
|
&self.queue_handle,
|
||||||
|
1..=OrgKdeKwinIdle::interface().version,
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
.map_err(std::convert::Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_kwin_idle_timeout(&self, timeout: u32) -> Result<OrgKdeKwinIdleTimeout, BoxedError>
|
||||||
where
|
where
|
||||||
T: Dispatch<OrgKdeKwinIdle, ()>
|
T: Dispatch<OrgKdeKwinIdle, ()>
|
||||||
+ Dispatch<OrgKdeKwinIdleTimeout, ()>
|
+ Dispatch<OrgKdeKwinIdleTimeout, ()>
|
||||||
@ -47,11 +60,7 @@ where
|
|||||||
self.globals
|
self.globals
|
||||||
.bind(&self.queue_handle, 1..=WlSeat::interface().version, ())?;
|
.bind(&self.queue_handle, 1..=WlSeat::interface().version, ())?;
|
||||||
|
|
||||||
let idle: OrgKdeKwinIdle = self.globals.bind(
|
let idle = self.get_kwin_idle()?;
|
||||||
&self.queue_handle,
|
|
||||||
1..=OrgKdeKwinIdle::interface().version,
|
|
||||||
(),
|
|
||||||
)?;
|
|
||||||
Ok(idle.get_idle_timeout(&seat, timeout, &self.queue_handle, ()))
|
Ok(idle.get_idle_timeout(&seat, timeout, &self.queue_handle, ()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use crate::Watcher;
|
||||||
|
|
||||||
use super::report_client::ReportClient;
|
use super::report_client::ReportClient;
|
||||||
use super::wl_bindings;
|
use super::wl_bindings;
|
||||||
use super::wl_connection::WlEventConnection;
|
use super::wl_connection::WlEventConnection;
|
||||||
@ -60,7 +62,6 @@ impl IdleState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_loop(&mut self, connection: &mut WlEventConnection<Self>) -> Result<(), BoxedError> {
|
fn run_loop(&mut self, connection: &mut WlEventConnection<Self>) -> Result<(), BoxedError> {
|
||||||
// connection.event_queue.blocking_dispatch(self).unwrap();
|
|
||||||
connection.event_queue.roundtrip(self).unwrap();
|
connection.event_queue.roundtrip(self).unwrap();
|
||||||
let now = Utc::now();
|
let now = Utc::now();
|
||||||
if !self.is_idle {
|
if !self.is_idle {
|
||||||
@ -158,7 +159,19 @@ impl Dispatch<OrgKdeKwinIdleTimeout, ()> for IdleState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(client: &Arc<ReportClient>) {
|
pub struct KwinIdleWatcher {
|
||||||
|
connection: WlEventConnection<IdleState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Watcher for KwinIdleWatcher {
|
||||||
|
fn new() -> Result<Self, BoxedError> {
|
||||||
|
let connection: WlEventConnection<IdleState> = WlEventConnection::connect()?;
|
||||||
|
connection.get_kwin_idle()?;
|
||||||
|
|
||||||
|
Ok(Self { connection })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn watch(&mut self, client: &Arc<ReportClient>) {
|
||||||
let bucket_name = format!(
|
let bucket_name = format!(
|
||||||
"aw-watcher-afk_{}",
|
"aw-watcher-afk_{}",
|
||||||
gethostname::gethostname().into_string().unwrap()
|
gethostname::gethostname().into_string().unwrap()
|
||||||
@ -166,20 +179,21 @@ pub fn run(client: &Arc<ReportClient>) {
|
|||||||
|
|
||||||
client.create_bucket(&bucket_name, "afkstatus").unwrap();
|
client.create_bucket(&bucket_name, "afkstatus").unwrap();
|
||||||
|
|
||||||
let mut connection = WlEventConnection::connect().unwrap();
|
|
||||||
|
|
||||||
let mut idle_state = IdleState::new(
|
let mut idle_state = IdleState::new(
|
||||||
connection
|
self.connection
|
||||||
.get_idle_timeout(client.config.idle_timeout * 1000)
|
.get_kwin_idle_timeout(client.config.idle_timeout * 1000)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Arc::clone(client),
|
Arc::clone(client),
|
||||||
bucket_name,
|
bucket_name,
|
||||||
);
|
);
|
||||||
connection.event_queue.roundtrip(&mut idle_state).unwrap();
|
self.connection
|
||||||
|
.event_queue
|
||||||
|
.roundtrip(&mut idle_state)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
info!("Starting idle watcher");
|
info!("Starting idle watcher");
|
||||||
loop {
|
loop {
|
||||||
if let Err(e) = idle_state.run_loop(&mut connection) {
|
if let Err(e) = idle_state.run_loop(&mut self.connection) {
|
||||||
error!("Error on idle iteration {e}");
|
error!("Error on idle iteration {e}");
|
||||||
}
|
}
|
||||||
thread::sleep(time::Duration::from_secs(u64::from(
|
thread::sleep(time::Duration::from_secs(u64::from(
|
||||||
@ -187,3 +201,4 @@ pub fn run(client: &Arc<ReportClient>) {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use crate::Watcher;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This uses a hack with KWin scripts in order to receive the active window.
|
* This uses a hack with KWin scripts in order to receive the active window.
|
||||||
* For the moment of writing, KWin doesn't implement the appropriate protocols to get a top level window.
|
* For the moment of writing, KWin doesn't implement the appropriate protocols to get a top level window.
|
||||||
@ -29,11 +31,6 @@ impl KWinScript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn load(&self) -> Result<(), BoxedError> {
|
fn load(&self) -> Result<(), BoxedError> {
|
||||||
if self.is_loaded()? {
|
|
||||||
warn!("KWin script is already loaded, unloading");
|
|
||||||
self.unload().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = temp_dir().join("kwin_window.js");
|
let path = temp_dir().join("kwin_window.js");
|
||||||
std::fs::write(&path, KWIN_SCRIPT).unwrap();
|
std::fs::write(&path, KWIN_SCRIPT).unwrap();
|
||||||
|
|
||||||
@ -168,12 +165,26 @@ impl ActiveWindowInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(client: &Arc<ReportClient>) {
|
pub struct KwinWindowWatcher {
|
||||||
|
kwin_script: KWinScript,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Watcher for KwinWindowWatcher {
|
||||||
|
fn new() -> Result<Self, BoxedError> {
|
||||||
|
let kwin_script = KWinScript::new(Connection::session()?);
|
||||||
|
if kwin_script.is_loaded()? {
|
||||||
|
warn!("KWin script is already loaded, unloading");
|
||||||
|
kwin_script.unload()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { kwin_script })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn watch(&mut self, client: &Arc<ReportClient>) {
|
||||||
let hostname = gethostname::gethostname().into_string().unwrap();
|
let hostname = gethostname::gethostname().into_string().unwrap();
|
||||||
let bucket_name = format!("aw-watcher-window_{hostname}");
|
let bucket_name = format!("aw-watcher-window_{hostname}");
|
||||||
let kwin_script = KWinScript::new(Connection::session().unwrap());
|
|
||||||
|
|
||||||
kwin_script.load().unwrap();
|
self.kwin_script.load().unwrap();
|
||||||
|
|
||||||
let active_window = Arc::new(Mutex::new(ActiveWindow {
|
let active_window = Arc::new(Mutex::new(ActiveWindow {
|
||||||
caption: String::new(),
|
caption: String::new(),
|
||||||
@ -214,3 +225,4 @@ pub fn run(client: &Arc<ReportClient>) {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user