Files
lan-mouse/src/main.rs
Ferdinand Schober 64e3bf3ff4 release stuck keys (#53)
Keys are now released when
- A client disconnects and still has pressed keys
- A client disconnects through CTLR+ALT+SHIFT+WIN
- Lan Mouse terminates with keys still being pressed through a remote client

This is also fixes an issue caused by KDE's implementation of the remote desktop portal backend:
Keys are not correctly released when a remote desktop session is closed while keys are still pressed,
causing them to be permanently stuck until kwin is restarted.

This workaround remembers all pressed keys and releases them when lan-mouse exits or a device disconnects.

closes #15
2023-12-31 15:42:29 +01:00

77 lines
1.9 KiB
Rust

use anyhow::Result;
use std::process::{self, Child, Command};
use env_logger::Env;
use lan_mouse::{config::Config, frontend, server::Server};
use tokio::task::LocalSet;
pub fn main() {
// init logging
let env = Env::default().filter_or("LAN_MOUSE_LOG_LEVEL", "info");
env_logger::init_from_env(env);
if let Err(e) = run() {
log::error!("{e}");
process::exit(1);
}
}
pub fn start_service() -> Result<Child> {
let child = Command::new(std::env::current_exe()?)
.args(std::env::args().skip(1))
.arg("--daemon")
.spawn()?;
Ok(child)
}
pub fn run() -> Result<()> {
// parse config file + cli args
let config = Config::new()?;
log::debug!("{config:?}");
if config.daemon {
// if daemon is specified we run the service
run_service(&config)?;
} else {
// otherwise start the service as a child process and
// run a frontend
let mut service = start_service()?;
frontend::run_frontend(&config)?;
log::info!("terminating service");
#[cfg(unix)]
{
// on unix we give the service a chance to terminate gracefully
let pid = service.id() as libc::pid_t;
unsafe {
libc::kill(pid, libc::SIGINT);
}
service.wait()?;
}
service.kill()?;
}
anyhow::Ok(())
}
fn run_service(config: &Config) -> Result<()> {
// create single threaded tokio runtime
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_io()
.enable_time()
.build()?;
// run async event loop
runtime.block_on(LocalSet::new().run_until(async {
// run main loop
log::info!("Press Ctrl+Alt+Shift+Super to release the mouse");
let server = Server::new(config);
server.run().await?;
log::debug!("service exiting");
anyhow::Ok(())
}))?;
Ok(())
}