diff --git a/src/kanata.rs b/src/kanata.rs index 22355c303..d744dd9b7 100644 --- a/src/kanata.rs +++ b/src/kanata.rs @@ -257,6 +257,15 @@ impl Kanata { Ok(()) } + pub fn change_layer(&mut self, layer_name: String) { + for (i, l) in self.layer_info.iter().enumerate() { + if l.name == layer_name { + self.layout.set_default_layer(i); + return; + } + } + } + fn check_handle_layer_change(&mut self, tx: &Option>) { let cur_layer = self.layout.current_layer(); if cur_layer != self.prev_layer { diff --git a/src/main.rs b/src/main.rs index 352b15f6f..659c9ca6b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,7 @@ mod tcp_server; use clap::Parser; use kanata::Kanata; -use tcp_server::NotificationServer; +use tcp_server::TcpServer; type CfgPath = PathBuf; @@ -81,8 +81,8 @@ fn main_impl(args: ValidatedArgs) -> Result<()> { // while also maintaining `tick()` calls to keyberon. let (server, ntx, nrx) = if let Some(port) = args.port { - let mut server = NotificationServer::new(port); - server.start(); + let mut server = TcpServer::new(port); + server.start(kanata_arc.clone()); let (ntx, nrx) = crossbeam_channel::bounded(10); (Some(server), Some(ntx), Some(nrx)) } else { diff --git a/src/tcp_server.rs b/src/tcp_server.rs index 7cc6ca3bb..0b2b639fc 100644 --- a/src/tcp_server.rs +++ b/src/tcp_server.rs @@ -1,11 +1,14 @@ +use crate::Kanata; use anyhow::Result; use parking_lot::Mutex; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use std::io::{BufReader, Read}; use std::net::{TcpListener, TcpStream}; +use std::str::FromStr; use std::sync::Arc; -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Deserialize)] pub enum EventNotification { LayerChange { new: String }, } @@ -16,12 +19,20 @@ impl EventNotification { } } -pub struct NotificationServer { +impl FromStr for EventNotification { + type Err = serde_json::Error; + + fn from_str(s: &str) -> std::result::Result { + serde_json::from_str(s) + } +} + +pub struct TcpServer { pub port: i32, pub connections: Arc>>, } -impl NotificationServer { +impl TcpServer { pub fn new(port: i32) -> Self { Self { port, @@ -29,7 +40,7 @@ impl NotificationServer { } } - pub fn start(&mut self) { + pub fn start(&mut self, kanata: Arc>) { let listener = TcpListener::bind(format!("0.0.0.0:{}", self.port)) .expect("could not start the tcp server"); @@ -43,7 +54,35 @@ impl NotificationServer { .expect("could not find peer address") .to_string(); - cl.lock().insert(addr, stream); + { + cl.lock().insert(addr.clone(), stream); + } + + if let Some(stream) = cl.lock().get(&addr) { + let stream = stream + .try_clone() + .expect("could not clone tcpstream to read incoming messages"); + + let k_cl = kanata.clone(); + std::thread::spawn(move || { + log::info!("listening for incoming messages {}", &addr); + loop { + let mut buffer: [u8; 1024] = [0; 1024]; + let mut reader = BufReader::new(&stream); + if let Ok(size) = reader.read(&mut buffer) { + if let Ok(event) = EventNotification::from_str( + &String::from_utf8_lossy(&buffer[..size]), + ) { + match event { + EventNotification::LayerChange { new } => { + k_cl.lock().change_layer(new); + } + } + } + } + } + }); + }; } Err(_) => log::error!("not able to accept client connection"), }