Refactored command flow to separate daemon invocation, added status handling, and improved error handling. - New Features: Added `execute_local` helper and `BatteryCommands::Status` handling. - Enhancements: Simplified daemon checks, removed redundant condition, improved readability and error messages. - Bug Fixes: Fixed missed daemon return path for status command and ensured proper touchpad inhibition logic.
120 lines
3.7 KiB
Rust
120 lines
3.7 KiB
Rust
use crate::cli::TouchpadCommands;
|
|
use log::{debug, error, info};
|
|
use std::fs;
|
|
use std::path::Path;
|
|
use zbus::Connection;
|
|
use zbus::proxy;
|
|
|
|
#[proxy(
|
|
interface = "org.lapctl1",
|
|
default_service = "org.lapctl",
|
|
default_path = "/org/lapctl"
|
|
)]
|
|
trait Lapctl {
|
|
async fn set_touchpad_inhibition(&self, inhibited: bool) -> zbus::Result<()>;
|
|
}
|
|
|
|
fn try_call_daemon(command: &TouchpadCommands) -> bool {
|
|
let rt = match tokio::runtime::Runtime::new() {
|
|
Ok(rt) => rt,
|
|
Err(_) => return false,
|
|
};
|
|
|
|
rt.block_on(async {
|
|
let connection =
|
|
match tokio::time::timeout(std::time::Duration::from_secs(2), Connection::system())
|
|
.await
|
|
{
|
|
Ok(Ok(conn)) => conn,
|
|
_ => return false,
|
|
};
|
|
|
|
let proxy = match LapctlProxy::new(&connection).await {
|
|
Ok(p) => p,
|
|
Err(_) => return false,
|
|
};
|
|
|
|
let res = match command {
|
|
TouchpadCommands::Enable => {
|
|
tokio::time::timeout(
|
|
std::time::Duration::from_secs(2),
|
|
proxy.set_touchpad_inhibition(false),
|
|
)
|
|
.await
|
|
}
|
|
TouchpadCommands::Disable => {
|
|
tokio::time::timeout(
|
|
std::time::Duration::from_secs(2),
|
|
proxy.set_touchpad_inhibition(true),
|
|
)
|
|
.await
|
|
}
|
|
};
|
|
|
|
matches!(res, Ok(Ok(_)))
|
|
})
|
|
}
|
|
|
|
pub fn execute(command: &TouchpadCommands) {
|
|
match command {
|
|
TouchpadCommands::Enable => println!("Enabling touchpad..."),
|
|
TouchpadCommands::Disable => println!("Disabling touchpad..."),
|
|
}
|
|
|
|
if try_call_daemon(command) {
|
|
return;
|
|
}
|
|
|
|
execute_local(command);
|
|
}
|
|
|
|
pub fn execute_local(command: &TouchpadCommands) {
|
|
match command {
|
|
TouchpadCommands::Enable => set_touchpad_inhibition(false),
|
|
TouchpadCommands::Disable => set_touchpad_inhibition(true),
|
|
}
|
|
}
|
|
|
|
fn set_touchpad_inhibition(inhibited: bool) {
|
|
let dev_input = Path::new("/sys/class/input");
|
|
if !dev_input.exists() {
|
|
error!("Could not find /sys/class/input. Is this a Linux system?");
|
|
return;
|
|
}
|
|
|
|
if let Ok(entries) = fs::read_dir(dev_input) {
|
|
let mut found = false;
|
|
for entry in entries.flatten() {
|
|
let name = entry.file_name();
|
|
let name_str = name.to_string_lossy();
|
|
|
|
if name_str.starts_with("input") {
|
|
let name_file = entry.path().join("name");
|
|
if let Ok(content) = fs::read_to_string(name_file) {
|
|
let content_lower = content.to_lowercase();
|
|
if content_lower.contains("touchpad") || content_lower.contains("trackpad") {
|
|
found = true;
|
|
let inhibited_file = entry.path().join("inhibited");
|
|
if inhibited_file.exists() {
|
|
let val = if inhibited { "1" } else { "0" };
|
|
match fs::write(&inhibited_file, val) {
|
|
Ok(_) => info!("Set inhibit={} for {}", inhibited, name_str),
|
|
Err(e) => {
|
|
debug!("Failed to write to {}: {}", inhibited_file.display(), e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if found {
|
|
println!("Operation completed successfully.");
|
|
} else {
|
|
error!("No touchpad device found in /sys/class/input.");
|
|
}
|
|
} else {
|
|
error!("Failed to read directory /sys/class/input.");
|
|
}
|
|
}
|