diff --git a/Cargo.toml b/Cargo.toml index 309c505..b68028b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,10 +13,17 @@ path = "src/lib.rs" name = "test" path = "src/examples/main.rs" +[features] +default = [] +crossbeam = ["crossbeam-channel"] + [dependencies] -crossbeam = "0.8.2" log = "0.4.19" +[dependencies.crossbeam-channel] +version = "0.5" +optional = true + [target.'cfg(windows)'.dependencies] windows = {version = "0.48.0", features = ["Win32_UI_Accessibility", "Win32_Foundation", "Win32_UI_WindowsAndMessaging", "Win32_Graphics_Gdi", "Win32_System_Com", "Win32_System_Ole"]} diff --git a/src/lib.rs b/src/lib.rs index 9a6e54d..97b48a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,12 @@ -use std::sync::mpsc::Receiver; +#[cfg(feature = "crossbeam")] +use crossbeam_channel::{unbounded, Receiver}; -#[cfg_attr(unix, path = "linux/mod.rs")] -#[cfg_attr(windows, path = "windows/mod.rs")] -#[cfg_attr(mac, path = "windows/mod.rs")] +#[cfg(not(feature = "crossbeam"))] +use std::sync::mpsc::{channel as unbounded, Receiver}; + +#[cfg_attr(target_os = "linux", path = "linux/mod.rs")] +#[cfg_attr(target_os = "windows", path = "windows/mod.rs")] +#[cfg_attr(target_os = "macos", path = "macos/mod.rs")] pub mod platform_impl; #[derive(Debug, Clone, Copy, Default)] @@ -34,7 +38,7 @@ pub fn focus_target() { } pub fn register>(window_title: T) -> Receiver { - let (tx, rx) = std::sync::mpsc::channel(); + let (tx, rx) = unbounded(); platform_impl::init(window_title.into(), tx).expect("Catastrophe"); diff --git a/src/linux/mod.rs b/src/linux/mod.rs index 20a0e8d..e4c3489 100644 --- a/src/linux/mod.rs +++ b/src/linux/mod.rs @@ -1,7 +1,10 @@ -use std::{ - cell::OnceCell, - sync::{atomic::AtomicPtr, Arc, Mutex, OnceLock}, -}; +use std::sync::{Arc, Mutex, OnceLock}; + +#[cfg(feature = "crossbeam")] +use crossbeam_channel::Sender; + +#[cfg(not(feature = "crossbeam"))] +use std::sync::mpsc::Sender; use x11rb::{ connect, @@ -65,35 +68,33 @@ fn get_atom>(conn: &RustConnection, name: T) -> Option { //Not very pretty and a bit wasteful making a new connection and getting the atom every time.. pub fn focus_target() { - unsafe { - if let Some(target) = TARGET.get() { - if let Ok(target) = target.lock() { - if *target != x11rb::NONE { - if let Ok((conn, _screen_num)) = connect(None) { - let net_active_window = get_atom(&conn, "_NET_ACTIVE_WINDOW").unwrap(); - - let event = ClientMessageEvent { - response_type: xproto::CLIENT_MESSAGE_EVENT, - format: 32, - sequence: 0, - window: *target, - type_: net_active_window, - data: ClientMessageData::from([1, x11rb::CURRENT_TIME, 0, 0, 0]), - }; - - if let Ok(cookie) = conn.send_event( - false, - conn.setup().roots[_screen_num].root, - EventMask::SUBSTRUCTURE_NOTIFY | EventMask::SUBSTRUCTURE_REDIRECT, - event, - ) { - if let Err(e) = cookie.check() { - log::error!("Error focusing target: {e:?}"); - } + if let Some(target) = TARGET.get() { + if let Ok(target) = target.lock() { + if *target != x11rb::NONE { + if let Ok((conn, _screen_num)) = connect(None) { + let net_active_window = get_atom(&conn, "_NET_ACTIVE_WINDOW").unwrap(); + + let event = ClientMessageEvent { + response_type: xproto::CLIENT_MESSAGE_EVENT, + format: 32, + sequence: 0, + window: *target, + type_: net_active_window, + data: ClientMessageData::from([1, x11rb::CURRENT_TIME, 0, 0, 0]), + }; + + if let Ok(cookie) = conn.send_event( + false, + conn.setup().roots[_screen_num].root, + EventMask::SUBSTRUCTURE_NOTIFY | EventMask::SUBSTRUCTURE_REDIRECT, + event, + ) { + if let Err(e) = cookie.check() { + log::error!("Error focusing target: {e:?}"); } - - conn.flush().ok(); } + + conn.flush().ok(); } } } @@ -105,7 +106,7 @@ struct Runtime { root: Window, target: Target, atoms: AtomCollection, - underlay_tx: std::sync::mpsc::Sender, + underlay_tx: Sender, active: Window, } @@ -133,11 +134,9 @@ impl Runtime { ///Using this instead to allow setting the globally accessible target too for focus_target. fn set_target(&mut self, wid: Window) { self.target.wid = wid; - unsafe { - if let Some(target) = TARGET.get() { - if let Ok(mut target) = target.lock() { - *target = wid; - } + if let Some(target) = TARGET.get() { + if let Ok(mut target) = target.lock() { + *target = wid; } } } @@ -360,10 +359,7 @@ impl Runtime { } } -pub fn init( - window_title: String, - tx: std::sync::mpsc::Sender, -) -> Result<(), String> { +pub fn init(window_title: String, tx: Sender) -> Result<(), String> { TARGET .set(Arc::new(Mutex::new(Window::default()))) .map_err(|e| log::error!("Could not init global TARGET storage {e:?}")) diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 1c0f824..c3b19c4 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -22,6 +22,13 @@ use windows::Win32::{ UI::Accessibility::{SetWinEventHook, UnhookWinEvent, HWINEVENTHOOK}, }; +#[cfg(feature = "crossbeam")] +use crossbeam_channel::{Sender}; + +#[cfg(not(feature = "crossbeam"))] +use std::sync::mpsc::{Sender}; + + use crate::{Bounds, UnderlayEvent}; static GLOBAL_RUNTIME: AtomicPtr>> = AtomicPtr::new(std::ptr::null_mut()); @@ -213,7 +220,7 @@ struct Runtime { target: TargetWindow, - underlay_tx: std::sync::mpsc::Sender, + underlay_tx: Sender, uipi_msg_id: u32, } @@ -474,7 +481,7 @@ const OW_FOREGROUND_TIMER_MS: u32 = 83; pub fn init( window_title: String, - tx: std::sync::mpsc::Sender, + tx: Sender, ) -> Result<(), String> { std::thread::spawn(move || { let uipi_msg_id = register_message("UNDERLAY_UIPI_TEST");