Skip to content

Commit 7592490

Browse files
committed
feat: background managed keys
1 parent 8756d0a commit 7592490

2 files changed

Lines changed: 115 additions & 0 deletions

File tree

maa-framework/src/controller.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,25 @@ impl Controller {
702702
common::check_bool(ret)
703703
}
704704

705+
/// Configure background managed key domain for Win32 controllers.
706+
///
707+
/// Must be set before connection. After setting, matching ClickKey / LongPressKey / KeyDown / KeyUp
708+
/// operations automatically route through the background guardian path.
709+
/// Only supported by Win32 controllers; other controllers will fail.
710+
///
711+
/// Pass an empty slice to clear managed keys.
712+
pub fn set_background_managed_keys(&self, keys: &[i32]) -> MaaResult<()> {
713+
let ret = unsafe {
714+
sys::MaaControllerSetOption(
715+
self.inner.handle.as_ptr(),
716+
sys::MaaCtrlOptionEnum_MaaCtrlOption_BackgroundManagedKeys as i32,
717+
keys.as_ptr() as *mut c_void,
718+
std::mem::size_of_val(keys) as u64,
719+
)
720+
};
721+
common::check_bool(ret)
722+
}
723+
705724
// === New controller types ===
706725

707726
pub fn new_dbg(read_path: &str) -> MaaResult<Self> {

maa-framework/tests/binding_test.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,102 @@ fn test_controller_sink_operations() {
835835
println!(" PASS: controller sink operations");
836836
}
837837

838+
#[test]
839+
fn test_controller_background_managed_keys() {
840+
println!("\n=== test_controller_background_managed_keys ===");
841+
842+
let _ = init_test_env();
843+
844+
let test_res_dir = get_test_resources_dir();
845+
let screenshot_dir = test_res_dir.join("Screenshot");
846+
847+
if !screenshot_dir.exists() {
848+
panic!(
849+
"Screenshot directory not found at {:?}. Run: git submodule update --init",
850+
screenshot_dir
851+
);
852+
}
853+
854+
// Test with DbgController (non-Win32, should fail)
855+
let controller = Controller::new_dbg(screenshot_dir.to_str().unwrap())
856+
.expect("Failed to create dbg controller");
857+
let result = controller.set_background_managed_keys(&[0x57, 0x41]);
858+
println!(" dbg_controller set_background_managed_keys: {:?}", result);
859+
assert!(
860+
result.is_err(),
861+
"DbgController should not support BackgroundManagedKeys"
862+
);
863+
864+
// Test with Win32 controller if available
865+
if cfg!(all(target_os = "windows", feature = "win32")) {
866+
match Toolkit::find_desktop_windows() {
867+
Ok(desktop_windows) if !desktop_windows.is_empty() => {
868+
let mut win32_ctrl = None;
869+
for window in desktop_windows {
870+
if let Ok(ctrl) = Controller::new_win32(
871+
window.hwnd as *mut std::os::raw::c_void,
872+
maa_framework::sys::MaaWin32ScreencapMethod_GDI
873+
as maa_framework::sys::MaaWin32ScreencapMethod,
874+
maa_framework::sys::MaaWin32InputMethod_Seize
875+
as maa_framework::sys::MaaWin32InputMethod,
876+
maa_framework::sys::MaaWin32InputMethod_Seize
877+
as maa_framework::sys::MaaWin32InputMethod,
878+
) {
879+
win32_ctrl = Some(ctrl);
880+
break;
881+
}
882+
}
883+
884+
if let Some(ctrl) = win32_ctrl {
885+
// Set option before connection (should succeed)
886+
let ret = ctrl.set_background_managed_keys(&[0x57, 0x41]);
887+
println!(
888+
" win32_controller set_background_managed_keys (before connection): {:?}",
889+
ret
890+
);
891+
assert!(
892+
ret.is_ok(),
893+
"Win32Controller should support BackgroundManagedKeys before connection"
894+
);
895+
896+
// After connection, setting non-empty array should succeed
897+
let conn_id = ctrl.post_connection().expect("Failed to post connection");
898+
ctrl.wait(conn_id);
899+
let ret_post = ctrl.set_background_managed_keys(&[0x57, 0x41]);
900+
println!(
901+
" win32_controller set_background_managed_keys (after connection): {:?}",
902+
ret_post
903+
);
904+
assert!(
905+
ret_post.is_ok(),
906+
"Win32Controller should support BackgroundManagedKeys after connection"
907+
);
908+
909+
// Empty array should clear managed keys
910+
let ret_clear = ctrl.set_background_managed_keys(&[]);
911+
println!(
912+
" win32_controller set_background_managed_keys (clear with empty): {:?}",
913+
ret_clear
914+
);
915+
assert!(
916+
ret_clear.is_ok(),
917+
"Win32Controller should support clearing BackgroundManagedKeys with empty array"
918+
);
919+
} else {
920+
println!(" SKIP: failed to create Win32 controller");
921+
}
922+
}
923+
_ => {
924+
println!(" SKIP: no desktop windows found for Win32 test");
925+
}
926+
}
927+
} else {
928+
println!(" SKIP: Win32 test requires Windows target with win32 feature");
929+
}
930+
931+
println!(" PASS: background managed keys API");
932+
}
933+
838934
// ============================================================================
839935
// Tasker API Tests
840936
// ============================================================================

0 commit comments

Comments
 (0)