use std::time::Duration;
use super::common::unique_pipe_name;
use super::test_desktop::{
DaemonGuard, TestDesktop, TestWindow, query_windows, start_test_daemon, unique_title,
};
fn wait(ms: u64) {
std::thread::sleep(Duration::from_millis(ms));
}
fn hwnd_of(json: &serde_json::Value, title: &str) -> Option<i64> {
json["windows"]
.as_array()?
.iter()
.find(|w| w["title"].as_str() == Some(title))
.and_then(|w| w["hwnd"].as_i64())
}
fn debug_windows(json: &serde_json::Value) -> String {
json["windows"]
.as_array()
.map(|arr| {
arr.iter()
.map(|w| {
let title = w["title"].as_str().unwrap_or("?");
let hwnd = w["hwnd"].as_i64().unwrap_or(-1);
let focused = if json["focused"].as_i64() == Some(hwnd) {
" *FOCUSED"
} else {
""
};
format!("{title}@{hwnd:#x}{focused}")
})
.collect::<Vec<_>>()
.join(", ")
})
.unwrap_or_else(|| "<no windows array>".into())
}
#[test]
fn window_creation_focus_lands_on_newly_created_window() {
let td = TestDesktop::create().expect("test desktop");
let pipe = unique_pipe_name();
let mut _child = start_test_daemon(&pipe, &td.name).expect("start daemon");
let _guard = DaemonGuard::new(&pipe);
wait(500);
let t1 = unique_title("Focus-A");
let t2 = unique_title("Focus-B");
let w1 = TestWindow::create(&t1).expect("create W1");
wait(400);
let w2 = TestWindow::create(&t2).expect("create W2");
wait(1500);
let json = query_windows(&pipe).expect("query after W1+W2");
let w1_hwnd = hwnd_of(&json, &t1)
.unwrap_or_else(|| panic!("W1 '{t1}' missing. Windows: {}", debug_windows(&json)));
let w2_hwnd = hwnd_of(&json, &t2)
.unwrap_or_else(|| panic!("W2 '{t2}' missing. Windows: {}", debug_windows(&json)));
assert_eq!(
json["focused"].as_i64(),
Some(w2_hwnd),
"focus should be on W2 (last created). Windows: {}",
debug_windows(&json)
);
assert_ne!(
json["focused"].as_i64(),
Some(w1_hwnd),
"focus should have moved off W1 onto W2. Windows: {}",
debug_windows(&json)
);
println!("✓ window_creation_focus_lands_on_newly_created_window: focused=W2 ({w2_hwnd:#x})");
drop(w1);
drop(w2);
drop(td);
}
#[test]
fn window_creation_focus_follows_each_new_window() {
let td = TestDesktop::create().expect("test desktop");
let pipe = unique_pipe_name();
let mut _child = start_test_daemon(&pipe, &td.name).expect("start daemon");
let _guard = DaemonGuard::new(&pipe);
wait(500);
let t1 = unique_title("Trail-1");
let t2 = unique_title("Trail-2");
let t3 = unique_title("Trail-3");
let w1 = TestWindow::create(&t1).expect("create W1");
wait(400);
let w2 = TestWindow::create(&t2).expect("create W2");
wait(400);
let w3 = TestWindow::create(&t3).expect("create W3");
wait(1500);
let json = query_windows(&pipe).expect("query after W1+W2+W3");
let w1_hwnd = hwnd_of(&json, &t1)
.unwrap_or_else(|| panic!("W1 '{t1}' missing. Windows: {}", debug_windows(&json)));
let w3_hwnd = hwnd_of(&json, &t3)
.unwrap_or_else(|| panic!("W3 '{t3}' missing. Windows: {}", debug_windows(&json)));
assert_eq!(
json["focused"].as_i64(),
Some(w3_hwnd),
"focus should be on W3 (last created). Windows: {}",
debug_windows(&json)
);
assert_ne!(
json["focused"].as_i64(),
Some(w1_hwnd),
"focus should not be stuck on W1. Windows: {}",
debug_windows(&json)
);
println!(
"✓ window_creation_focus_follows_each_new_window: focused=W3 ({w3_hwnd:#x}), not W1 ({w1_hwnd:#x})"
);
drop(w1);
drop(w2);
drop(w3);
drop(td);
}