mirror of
https://github.com/2e3s/awatcher.git
synced 2025-07-22 10:00: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;
|
extern crate log;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
mod kwin_window;
|
|
||||||
mod report_client;
|
mod report_client;
|
||||||
mod wl_bindings;
|
mod watchers;
|
||||||
mod wl_connection;
|
|
||||||
mod wl_foreign_toplevel;
|
|
||||||
mod wl_kwin_idle;
|
|
||||||
mod x11_connection;
|
|
||||||
mod x11_screensaver_idle;
|
|
||||||
mod x11_window;
|
|
||||||
|
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use fern::colors::{Color, ColoredLevelConfig};
|
use fern::colors::{Color, ColoredLevelConfig};
|
||||||
@ -20,55 +13,10 @@ 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 crate::watchers::ConstructorFilter;
|
||||||
|
|
||||||
type BoxedError = Box<dyn Error>;
|
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> {
|
fn setup_logger() -> Result<(), fern::InitError> {
|
||||||
let log_setting = env::var("AWATCHER_LOG").unwrap_or("info".to_string());
|
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 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 {
|
if let Some(mut watcher) = idle_watcher {
|
||||||
let thread_client = Arc::clone(&client);
|
let thread_client = Arc::clone(&client);
|
||||||
let idle_handler = thread::spawn(move || watcher.watch(&thread_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");
|
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 {
|
if let Some(mut watcher) = window_watcher {
|
||||||
let thread_client = Arc::clone(&client);
|
let thread_client = Arc::clone(&client);
|
||||||
let active_window_handler = thread::spawn(move || watcher.watch(&thread_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.
|
* 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.
|
||||||
* Inspired by https://github.com/k0kubun/xremap/
|
* Inspired by https://github.com/k0kubun/xremap/
|
||||||
*/
|
*/
|
||||||
use super::report_client::ReportClient;
|
use super::{BoxedError, Watcher};
|
||||||
use super::BoxedError;
|
use crate::report_client::ReportClient;
|
||||||
use std::env::temp_dir;
|
use std::env::temp_dir;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{mpsc::channel, Arc, Mutex};
|
use std::sync::{mpsc::channel, Arc, Mutex};
|
@ -14,11 +14,11 @@ pub mod idle {
|
|||||||
|
|
||||||
pub mod __interfaces {
|
pub mod __interfaces {
|
||||||
use wayland_client::protocol::__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::*;
|
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 {
|
pub mod wlr_foreign_toplevel {
|
||||||
@ -33,9 +33,9 @@ pub mod wlr_foreign_toplevel {
|
|||||||
|
|
||||||
pub mod __interfaces {
|
pub mod __interfaces {
|
||||||
use wayland_client::protocol::__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::*;
|
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 super::wl_bindings::wlr_foreign_toplevel::zwlr_foreign_toplevel_handle_v1::{
|
||||||
use std::{sync::Arc, thread};
|
Event as HandleEvent, State as HandleState, ZwlrForeignToplevelHandleV1,
|
||||||
|
};
|
||||||
use crate::{wl_connection::subscribe_state, Watcher};
|
use super::wl_bindings::wlr_foreign_toplevel::zwlr_foreign_toplevel_manager_v1::{
|
||||||
|
Event as ManagerEvent, ZwlrForeignToplevelManagerV1, EVT_TOPLEVEL_OPCODE,
|
||||||
use super::report_client::ReportClient;
|
};
|
||||||
use super::wl_bindings;
|
|
||||||
use super::wl_connection::WlEventConnection;
|
use super::wl_connection::WlEventConnection;
|
||||||
use super::BoxedError;
|
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::{
|
use wayland_client::{
|
||||||
event_created_child, globals::GlobalListContents, protocol::wl_registry, Connection, Dispatch,
|
event_created_child, globals::GlobalListContents, protocol::wl_registry, Connection, Dispatch,
|
||||||
Proxy, QueueHandle,
|
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 {
|
struct WindowData {
|
||||||
app_id: String,
|
app_id: String,
|
@ -1,9 +1,8 @@
|
|||||||
use crate::Watcher;
|
|
||||||
|
|
||||||
use super::report_client::ReportClient;
|
|
||||||
use super::wl_bindings;
|
use super::wl_bindings;
|
||||||
use super::wl_connection::{subscribe_state, WlEventConnection};
|
use super::wl_connection::{subscribe_state, WlEventConnection};
|
||||||
use super::BoxedError;
|
use super::BoxedError;
|
||||||
|
use super::Watcher;
|
||||||
|
use crate::report_client::ReportClient;
|
||||||
use chrono::{DateTime, Duration, Utc};
|
use chrono::{DateTime, Duration, Utc};
|
||||||
use std::{sync::Arc, thread};
|
use std::{sync::Arc, thread};
|
||||||
use wayland_client::{
|
use wayland_client::{
|
@ -1,9 +1,9 @@
|
|||||||
use std::{sync::Arc, thread};
|
use std::{sync::Arc, thread};
|
||||||
|
|
||||||
|
use super::{x11_connection::X11Connection, BoxedError, Watcher};
|
||||||
|
use crate::report_client::ReportClient;
|
||||||
use chrono::{Duration, Utc};
|
use chrono::{Duration, Utc};
|
||||||
|
|
||||||
use crate::{report_client::ReportClient, x11_connection::X11Connection, BoxedError, Watcher};
|
|
||||||
|
|
||||||
pub struct IdleWatcher {
|
pub struct IdleWatcher {
|
||||||
connection: X11Connection,
|
connection: X11Connection,
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
|
use super::{x11_connection::X11Connection, BoxedError, Watcher};
|
||||||
|
use crate::report_client::ReportClient;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use crate::{report_client::ReportClient, x11_connection::X11Connection, BoxedError, Watcher};
|
|
||||||
|
|
||||||
pub struct WindowWatcher {
|
pub struct WindowWatcher {
|
||||||
connection: X11Connection,
|
connection: X11Connection,
|
||||||
last_title: String,
|
last_title: String,
|
Loading…
x
Reference in New Issue
Block a user