use helios_common::protocol::WindowInfo; // ── Windows implementation ────────────────────────────────────────────────── #[cfg(windows)] mod win_impl { use super::*; use std::sync::Mutex; use windows::Win32::Foundation::{BOOL, HWND, LPARAM}; use windows::Win32::UI::WindowsAndMessaging::{ BringWindowToTop, EnumWindows, GetWindowTextW, IsWindowVisible, SetForegroundWindow, ShowWindow, SW_MAXIMIZE, SW_MINIMIZE, SW_RESTORE, SHOW_WINDOW_CMD, }; use windows::Win32::UI::Input::KeyboardAndMouse::{ keybd_event, KEYEVENTF_KEYUP, VK_MENU, }; // Collect HWNDs via EnumWindows callback unsafe extern "system" fn enum_callback(hwnd: HWND, lparam: LPARAM) -> BOOL { let list = &mut *(lparam.0 as *mut Vec); list.push(hwnd); BOOL(1) } fn get_all_hwnds() -> Vec { let mut list: Vec = Vec::new(); unsafe { let _ = EnumWindows( Some(enum_callback), LPARAM(&mut list as *mut Vec as isize), ); } list } fn hwnd_title(hwnd: HWND) -> String { let mut buf = [0u16; 512]; let len = unsafe { GetWindowTextW(hwnd, &mut buf) }; String::from_utf16_lossy(&buf[..len as usize]) } pub fn list_windows() -> Result, String> { let hwnds = get_all_hwnds(); let mut windows = Vec::new(); for hwnd in hwnds { let visible = unsafe { IsWindowVisible(hwnd).as_bool() }; let title = hwnd_title(hwnd); // Only return visible windows with a non-empty title if !visible || title.is_empty() { continue; } windows.push(WindowInfo { id: hwnd.0 as u64, title, visible: true, }); } Ok(windows) } pub fn minimize_all() -> Result<(), String> { let hwnds = get_all_hwnds(); for hwnd in hwnds { let visible = unsafe { IsWindowVisible(hwnd).as_bool() }; let title = hwnd_title(hwnd); if visible && !title.is_empty() { unsafe { let _ = ShowWindow(hwnd, SW_MINIMIZE); } } } Ok(()) } /// Bypass Windows Focus Stealing Prevention by sending a fake Alt keypress /// before calling SetForegroundWindow. Without this, SetForegroundWindow /// silently fails when the calling thread is not in the foreground. unsafe fn force_foreground(hwnd: HWND) { keybd_event(VK_MENU.0 as u8, 0, Default::default(), 0); keybd_event(VK_MENU.0 as u8, 0, KEYEVENTF_KEYUP, 0); ShowWindow(hwnd, SW_RESTORE); BringWindowToTop(hwnd).ok(); SetForegroundWindow(hwnd); } pub fn focus_window(window_id: u64) -> Result<(), String> { let hwnd = HWND(window_id as isize); unsafe { force_foreground(hwnd); } Ok(()) } pub fn maximize_and_focus(window_id: u64) -> Result<(), String> { let hwnd = HWND(window_id as isize); unsafe { ShowWindow(hwnd, SW_MAXIMIZE); force_foreground(hwnd); } Ok(()) } } // ── Non-Windows stubs ─────────────────────────────────────────────────────── #[cfg(not(windows))] mod win_impl { use super::*; pub fn list_windows() -> Result, String> { Err("Window management is only supported on Windows".to_string()) } pub fn minimize_all() -> Result<(), String> { Err("Window management is only supported on Windows".to_string()) } pub fn focus_window(_window_id: u64) -> Result<(), String> { Err("Window management is only supported on Windows".to_string()) } pub fn maximize_and_focus(_window_id: u64) -> Result<(), String> { Err("Window management is only supported on Windows".to_string()) } } // ── Public API ────────────────────────────────────────────────────────────── pub fn list_windows() -> Result, String> { win_impl::list_windows() } pub fn minimize_all() -> Result<(), String> { win_impl::minimize_all() } pub fn focus_window(window_id: u64) -> Result<(), String> { win_impl::focus_window(window_id) } pub fn maximize_and_focus(window_id: u64) -> Result<(), String> { win_impl::maximize_and_focus(window_id) }