mirror of
https://github.com/2e3s/awatcher.git
synced 2025-07-21 09:30:05 +00:00
Separate watchers to a module
This commit is contained in:
parent
56f492438f
commit
a758913d52
62
src/main.rs
62
src/main.rs
@ -4,15 +4,8 @@
|
||||
extern crate log;
|
||||
|
||||
mod config;
|
||||
mod kwin_window;
|
||||
mod report_client;
|
||||
mod wl_bindings;
|
||||
mod wl_connection;
|
||||
mod wl_foreign_toplevel;
|
||||
mod wl_kwin_idle;
|
||||
mod x11_connection;
|
||||
mod x11_screensaver_idle;
|
||||
mod x11_window;
|
||||
mod watchers;
|
||||
|
||||
use config::Config;
|
||||
use fern::colors::{Color, ColoredLevelConfig};
|
||||
@ -20,55 +13,10 @@ use report_client::ReportClient;
|
||||
use std::env;
|
||||
use std::{error::Error, str::FromStr, sync::Arc, thread};
|
||||
|
||||
use crate::watchers::ConstructorFilter;
|
||||
|
||||
type BoxedError = Box<dyn Error>;
|
||||
|
||||
trait Watcher: Send {
|
||||
fn new() -> Result<Self, BoxedError>
|
||||
where
|
||||
Self: Sized;
|
||||
fn watch(&mut self, client: &Arc<ReportClient>);
|
||||
}
|
||||
|
||||
type BoxedWatcher = Box<dyn Watcher>;
|
||||
|
||||
type WatcherConstructor = (&'static str, fn() -> Result<BoxedWatcher, BoxedError>);
|
||||
type WatcherConstructors = [WatcherConstructor];
|
||||
|
||||
trait WatchersFilter {
|
||||
fn filter_first_supported(&self) -> Option<BoxedWatcher>;
|
||||
}
|
||||
|
||||
impl WatchersFilter for WatcherConstructors {
|
||||
fn filter_first_supported(&self) -> Option<BoxedWatcher> {
|
||||
self.iter().find_map(|(name, watcher)| match watcher() {
|
||||
Ok(watcher) => Some(watcher),
|
||||
Err(e) => {
|
||||
info!("{name} cannot run: {e}");
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! watcher {
|
||||
($watcher_struct:ty) => {
|
||||
(stringify!($watcher_struct), || {
|
||||
Ok(Box::new(<$watcher_struct>::new()?))
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
const IDLE_WATCHERS: &[WatcherConstructor] = &[
|
||||
watcher!(wl_kwin_idle::IdleWatcher),
|
||||
watcher!(x11_screensaver_idle::IdleWatcher),
|
||||
];
|
||||
|
||||
const ACTIVE_WINDOW_WATCHERS: &[WatcherConstructor] = &[
|
||||
watcher!(wl_foreign_toplevel::WindowWatcher),
|
||||
watcher!(kwin_window::WindowWatcher),
|
||||
watcher!(x11_window::WindowWatcher),
|
||||
];
|
||||
|
||||
fn setup_logger() -> Result<(), fern::InitError> {
|
||||
let log_setting = env::var("AWATCHER_LOG").unwrap_or("info".to_string());
|
||||
|
||||
@ -128,7 +76,7 @@ fn main() -> Result<(), BoxedError> {
|
||||
|
||||
let mut thread_handlers = Vec::new();
|
||||
|
||||
let idle_watcher = IDLE_WATCHERS.filter_first_supported();
|
||||
let idle_watcher = watchers::IDLE.filter_first_supported();
|
||||
if let Some(mut watcher) = idle_watcher {
|
||||
let thread_client = Arc::clone(&client);
|
||||
let idle_handler = thread::spawn(move || watcher.watch(&thread_client));
|
||||
@ -137,7 +85,7 @@ fn main() -> Result<(), BoxedError> {
|
||||
warn!("No supported idle handler is found");
|
||||
}
|
||||
|
||||
let window_watcher = ACTIVE_WINDOW_WATCHERS.filter_first_supported();
|
||||
let window_watcher = watchers::ACTIVE_WINDOW.filter_first_supported();
|
||||
if let Some(mut watcher) = window_watcher {
|
||||
let thread_client = Arc::clone(&client);
|
||||
let active_window_handler = thread::spawn(move || watcher.watch(&thread_client));
|
||||
|
58
src/watchers.rs
Normal file
58
src/watchers.rs
Normal file
@ -0,0 +1,58 @@
|
||||
mod kwin_window;
|
||||
mod wl_bindings;
|
||||
mod wl_connection;
|
||||
mod wl_foreign_toplevel;
|
||||
mod wl_kwin_idle;
|
||||
mod x11_connection;
|
||||
mod x11_screensaver_idle;
|
||||
mod x11_window;
|
||||
|
||||
use crate::{report_client::ReportClient, BoxedError};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait Watcher: Send {
|
||||
fn new() -> Result<Self, BoxedError>
|
||||
where
|
||||
Self: Sized;
|
||||
fn watch(&mut self, client: &Arc<ReportClient>);
|
||||
}
|
||||
|
||||
type BoxedWatcher = Box<dyn Watcher>;
|
||||
|
||||
type WatcherConstructor = (&'static str, fn() -> Result<BoxedWatcher, BoxedError>);
|
||||
type WatcherConstructors = [WatcherConstructor];
|
||||
|
||||
pub trait ConstructorFilter {
|
||||
fn filter_first_supported(&self) -> Option<BoxedWatcher>;
|
||||
}
|
||||
|
||||
impl ConstructorFilter for WatcherConstructors {
|
||||
fn filter_first_supported(&self) -> Option<BoxedWatcher> {
|
||||
self.iter().find_map(|(name, watcher)| match watcher() {
|
||||
Ok(watcher) => Some(watcher),
|
||||
Err(e) => {
|
||||
info!("{name} cannot run: {e}");
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! watcher {
|
||||
($watcher_struct:ty) => {
|
||||
(stringify!($watcher_struct), || {
|
||||
Ok(Box::new(<$watcher_struct>::new()?))
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
pub const IDLE: &WatcherConstructors = &[
|
||||
watcher!(wl_kwin_idle::IdleWatcher),
|
||||
watcher!(x11_screensaver_idle::IdleWatcher),
|
||||
];
|
||||
|
||||
pub const ACTIVE_WINDOW: &WatcherConstructors = &[
|
||||
watcher!(wl_foreign_toplevel::WindowWatcher),
|
||||
watcher!(kwin_window::WindowWatcher),
|
||||
watcher!(x11_window::WindowWatcher),
|
||||
];
|
@ -1,12 +1,10 @@
|
||||
use crate::Watcher;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* Inspired by https://github.com/k0kubun/xremap/
|
||||
*/
|
||||
use super::report_client::ReportClient;
|
||||
use super::BoxedError;
|
||||
use super::{BoxedError, Watcher};
|
||||
use crate::report_client::ReportClient;
|
||||
use std::env::temp_dir;
|
||||
use std::path::Path;
|
||||
use std::sync::{mpsc::channel, Arc, Mutex};
|
@ -14,11 +14,11 @@ pub mod idle {
|
||||
|
||||
pub mod __interfaces {
|
||||
use wayland_client::protocol::__interfaces::*;
|
||||
wayland_scanner::generate_interfaces!("src/wl-protocols/idle.xml");
|
||||
wayland_scanner::generate_interfaces!("src/watchers/wl-protocols/idle.xml");
|
||||
}
|
||||
use self::__interfaces::*;
|
||||
|
||||
wayland_scanner::generate_client_code!("src/wl-protocols/idle.xml");
|
||||
wayland_scanner::generate_client_code!("src/watchers/wl-protocols/idle.xml");
|
||||
}
|
||||
|
||||
pub mod wlr_foreign_toplevel {
|
||||
@ -33,9 +33,9 @@ pub mod wlr_foreign_toplevel {
|
||||
|
||||
pub mod __interfaces {
|
||||
use wayland_client::protocol::__interfaces::*;
|
||||
wayland_scanner::generate_interfaces!("src/wl-protocols/wlr-foreign-toplevel-management-unstable-v1.xml");
|
||||
wayland_scanner::generate_interfaces!("src/watchers/wl-protocols/wlr-foreign-toplevel-management-unstable-v1.xml");
|
||||
}
|
||||
use self::__interfaces::*;
|
||||
|
||||
wayland_scanner::generate_client_code!("src/wl-protocols/wlr-foreign-toplevel-management-unstable-v1.xml");
|
||||
wayland_scanner::generate_client_code!("src/watchers/wl-protocols/wlr-foreign-toplevel-management-unstable-v1.xml");
|
||||
}
|
@ -1,22 +1,19 @@
|
||||
use std::collections::HashMap;
|
||||
use std::{sync::Arc, thread};
|
||||
|
||||
use crate::{wl_connection::subscribe_state, Watcher};
|
||||
|
||||
use super::report_client::ReportClient;
|
||||
use super::wl_bindings;
|
||||
use super::wl_bindings::wlr_foreign_toplevel::zwlr_foreign_toplevel_handle_v1::{
|
||||
Event as HandleEvent, State as HandleState, ZwlrForeignToplevelHandleV1,
|
||||
};
|
||||
use super::wl_bindings::wlr_foreign_toplevel::zwlr_foreign_toplevel_manager_v1::{
|
||||
Event as ManagerEvent, ZwlrForeignToplevelManagerV1, EVT_TOPLEVEL_OPCODE,
|
||||
};
|
||||
use super::wl_connection::WlEventConnection;
|
||||
use super::BoxedError;
|
||||
use super::{wl_connection::subscribe_state, Watcher};
|
||||
use crate::report_client::ReportClient;
|
||||
use std::collections::HashMap;
|
||||
use std::{sync::Arc, thread};
|
||||
use wayland_client::{
|
||||
event_created_child, globals::GlobalListContents, protocol::wl_registry, Connection, Dispatch,
|
||||
Proxy, QueueHandle,
|
||||
};
|
||||
use wl_bindings::wlr_foreign_toplevel::zwlr_foreign_toplevel_handle_v1::{
|
||||
Event as HandleEvent, State as HandleState, ZwlrForeignToplevelHandleV1,
|
||||
};
|
||||
use wl_bindings::wlr_foreign_toplevel::zwlr_foreign_toplevel_manager_v1::{
|
||||
Event as ManagerEvent, ZwlrForeignToplevelManagerV1, EVT_TOPLEVEL_OPCODE,
|
||||
};
|
||||
|
||||
struct WindowData {
|
||||
app_id: String,
|
@ -1,9 +1,8 @@
|
||||
use crate::Watcher;
|
||||
|
||||
use super::report_client::ReportClient;
|
||||
use super::wl_bindings;
|
||||
use super::wl_connection::{subscribe_state, WlEventConnection};
|
||||
use super::BoxedError;
|
||||
use super::Watcher;
|
||||
use crate::report_client::ReportClient;
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use std::{sync::Arc, thread};
|
||||
use wayland_client::{
|
@ -1,9 +1,9 @@
|
||||
use std::{sync::Arc, thread};
|
||||
|
||||
use super::{x11_connection::X11Connection, BoxedError, Watcher};
|
||||
use crate::report_client::ReportClient;
|
||||
use chrono::{Duration, Utc};
|
||||
|
||||
use crate::{report_client::ReportClient, x11_connection::X11Connection, BoxedError, Watcher};
|
||||
|
||||
pub struct IdleWatcher {
|
||||
connection: X11Connection,
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use super::{x11_connection::X11Connection, BoxedError, Watcher};
|
||||
use crate::report_client::ReportClient;
|
||||
use std::thread;
|
||||
|
||||
use crate::{report_client::ReportClient, x11_connection::X11Connection, BoxedError, Watcher};
|
||||
|
||||
pub struct WindowWatcher {
|
||||
connection: X11Connection,
|
||||
last_title: String,
|
Loading…
x
Reference in New Issue
Block a user