From 0b2b75057de0b1bd4903d48690270fad94123970 Mon Sep 17 00:00:00 2001 From: Yusuf007R Date: Fri, 14 Oct 2022 09:40:00 -0500 Subject: [PATCH] feat(wm): add tcp event notifications This commits allow tcp clients to receive event notifications. That way if you want to make a custom input handler you do not have to connect to tcp socket and create a named pipe at the same time. --- komorebi/src/main.rs | 27 ++++++++++++++++++++++++++- komorebi/src/process_command.rs | 10 +++++++--- komorebi/src/process_event.rs | 4 ++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/komorebi/src/main.rs b/komorebi/src/main.rs index 81070231..f90cc810 100644 --- a/komorebi/src/main.rs +++ b/komorebi/src/main.rs @@ -328,7 +328,12 @@ pub struct Notification { pub state: State, } -pub fn notify_subscribers(notification: &str) -> Result<()> { +pub fn send_notification(notification: &str) -> Result<()> { + notify_subscribers(notification)?; + notify_tcp_clients(notification) +} + +fn notify_subscribers(notification: &str) -> Result<()> { let mut stale_subscriptions = vec![]; let mut subscriptions = SUBSCRIPTION_PIPES.lock(); for (subscriber, pipe) in subscriptions.iter_mut() { @@ -362,6 +367,26 @@ pub fn notify_subscribers(notification: &str) -> Result<()> { Ok(()) } +fn notify_tcp_clients(notification: &str) -> Result<()> { + let mut tcp_clients = TCP_CONNECTIONS.lock(); + for (addrs, stream) in tcp_clients.iter_mut() { + match stream.write(notification.as_bytes()) { + Ok(_) => { + tracing::debug!("pushed notification to the tcp_client: {}", addrs); + } + Err(error) => { + tracing::error!( + "failed to push notification to the tcp_client: {}, got error: {}", + addrs, + error + ); + } + } + } + + Ok(()) +} + #[cfg(feature = "deadlock_detection")] #[tracing::instrument] fn detect_deadlocks() { diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index b8f64e68..a13a3eac 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -4,6 +4,7 @@ use std::io::BufRead; use std::io::BufReader; use std::io::Read; use std::io::Write; +use std::mem::drop; use std::net::TcpListener; use std::net::TcpStream; use std::num::NonZeroUsize; @@ -35,7 +36,7 @@ use komorebi_core::WindowKind; use crate::border::Border; use crate::current_virtual_desktop; -use crate::notify_subscribers; +use crate::send_notification; use crate::window::Window; use crate::window_manager; use crate::window_manager::WindowManager; @@ -112,6 +113,9 @@ pub fn listen_for_commands_tcp(wm: Arc>, port: usize) { stream.try_clone().expect("stream should be cloneable"), ); + // This has to be done to be able to send notifications to the tcp_connections + drop(connections); + tracing::info!("listening for incoming tcp messages from {}", &addr); match read_commands_tcp(&wm, &mut stream, &addr) { @@ -932,7 +936,7 @@ pub fn read_commands_uds(wm: &Arc>, stream: UnixStream) -> } wm.process_command(message.clone())?; - notify_subscribers(&serde_json::to_string(&Notification { + send_notification(&serde_json::to_string(&Notification { event: NotificationEvent::Socket(message.clone()), state: wm.as_ref().into(), })?)?; @@ -984,7 +988,7 @@ pub fn read_commands_tcp( } wm.process_command(message.clone())?; - notify_subscribers(&serde_json::to_string(&Notification { + send_notification(&serde_json::to_string(&Notification { event: NotificationEvent::Socket(message.clone()), state: wm.as_ref().into(), })?)?; diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index 56263573..65f023e4 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -14,7 +14,7 @@ use komorebi_core::WindowContainerBehaviour; use crate::border::Border; use crate::current_virtual_desktop; -use crate::notify_subscribers; +use crate::send_notification; use crate::window_manager::WindowManager; use crate::window_manager_event::WindowManagerEvent; use crate::windows_api::WindowsApi; @@ -596,7 +596,7 @@ impl WindowManager { .open(hwnd_json)?; serde_json::to_writer_pretty(&file, &known_hwnds)?; - notify_subscribers(&serde_json::to_string(&Notification { + send_notification(&serde_json::to_string(&Notification { event: NotificationEvent::WindowManager(*event), state: self.as_ref().into(), })?)?;