use crate::error::{AumateError, Result};
use active_win_pos_rs::{ActiveWindow, get_active_window};
#[derive(Debug, Clone)]
pub struct WindowInfo {
pub title: String,
pub process_id: u32,
pub process_path: String,
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
pub window_id: String,
}
impl WindowInfo {
fn from_active_window(window: ActiveWindow) -> Self {
Self {
title: window.title,
process_id: window.process_id as u32,
process_path: window.process_path.to_string_lossy().to_string(),
x: window.position.x,
y: window.position.y,
width: window.position.width,
height: window.position.height,
window_id: window.window_id.to_string(),
}
}
pub fn process_name(&self) -> &str {
self.process_path.rsplit(std::path::MAIN_SEPARATOR).next().unwrap_or(&self.process_path)
}
}
pub fn get_active_window_info() -> Result<WindowInfo> {
let active_window = get_active_window()
.map_err(|_| AumateError::Window("Failed to get active window".to_string()))?;
Ok(WindowInfo::from_active_window(active_window))
}
pub fn get_all_windows() -> Result<Vec<WindowInfo>> {
let active_window = get_active_window()
.map_err(|_| AumateError::Window("Failed to get active window".to_string()))?;
Ok(vec![WindowInfo::from_active_window(active_window)])
}
pub fn find_windows_by_title(search_title: &str) -> Result<Vec<WindowInfo>> {
let active_window = get_active_window()
.map_err(|_| AumateError::Window("Failed to get active window".to_string()))?;
let search_lower = search_title.to_lowercase();
if active_window.title.to_lowercase().contains(&search_lower) {
Ok(vec![WindowInfo::from_active_window(active_window)])
} else {
Ok(vec![])
}
}
pub fn find_windows_by_process(process_name: &str) -> Result<Vec<WindowInfo>> {
let active_window = get_active_window()
.map_err(|_| AumateError::Window("Failed to get active window".to_string()))?;
let process_lower = process_name.to_lowercase();
let process_path_str = active_window.process_path.to_string_lossy().to_lowercase();
if process_path_str.contains(&process_lower) {
Ok(vec![WindowInfo::from_active_window(active_window)])
} else {
Ok(vec![])
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_active_window() {
let result = get_active_window_info();
match result {
Ok(window) => {
println!("Active window: {}", window.title);
}
Err(e) => {
println!("No active window found: {}", e);
}
}
}
#[test]
fn test_get_all_windows() {
let result = get_all_windows();
match result {
Ok(windows) => {
println!("Found {} windows", windows.len());
for window in windows.iter().take(5) {
println!(" - {}: {}", window.process_name(), window.title);
}
}
Err(e) => {
println!("Failed to get windows: {}", e);
}
}
}
}