use crate::script_engine::instruction::{InstructionData, InstructionHandler, ScriptError};
use crate::script_engine::VMContext;
use crate::window::WindowActivationError;
pub struct ActiveHandler;
impl InstructionHandler for ActiveHandler {
fn name(&self) -> &str {
"active"
}
fn parse(&self, args: &[&str]) -> Result<InstructionData, ScriptError> {
if !args.is_empty() {
return Err(ScriptError::ParseError(format!(
"active instruction takes no arguments, got {}",
args.len()
)));
}
Ok(InstructionData::None)
}
fn execute(
&self,
context: &mut VMContext,
_data: &InstructionData,
_metadata: Option<&crate::script_engine::instruction::InstructionMetadata>,
) -> Result<(), ScriptError> {
use crate::window::ensure_window_active;
let hwnd = context.process.get_hwnd_or_err()?;
match ensure_window_active(hwnd, 300) {
Ok(()) => {
Ok(())
}
Err(WindowActivationError::Timeout) => {
Err(ScriptError::ExecutionError(format!(
"Window activation timed out. The window may be blocked by Windows foreground lock. \
Try running as administrator or ensure no other window has focus."
)))
}
Err(WindowActivationError::ActivationFailed) => {
Err(ScriptError::ExecutionError(
"Failed to activate window. Windows API rejected the request.".to_string()
))
}
Err(e) => {
Err(ScriptError::ExecutionError(format!("Window activation failed: {}", e)))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::hwnd::get_hwnd_list;
#[test]
fn test_active_handler_no_args() {
let handler = ActiveHandler;
let result = handler.parse(&["arg1"]);
assert!(result.is_err());
let result = handler.parse(&[]);
assert!(result.is_ok());
}
#[test]
fn test_active_instruction_requires_hwnd() {
let handler = ActiveHandler;
let mut context = VMContext::default();
let data = handler.parse(&[]).unwrap();
let result = handler.execute(&mut context, &data, None);
assert!(result.is_err());
let err = result.unwrap_err();
match err {
ScriptError::ExecutionError(msg) => {
assert!(msg.contains("window"), "Error message should mention window");
}
_ => panic!("Expected ExecutionError, got: {:?}", err),
}
}
#[test]
fn test_active_instruction_with_real_window() {
let hwnds = get_hwnd_list();
if let Some(&hwnd) = hwnds.first() {
let mut context = VMContext::default();
context.process.hwnd = Some(hwnd);
let handler = ActiveHandler;
let data = handler.parse(&[]).unwrap();
let result = handler.execute(&mut context, &data, None);
match result {
Ok(()) => println!("✓ Window activated successfully"),
Err(e) => {
println!("⚠ Activation failed (expected): {}", e);
}
}
}
}
}