ITADN

Example of not accepting mouse input

#192Openyyy33 创建于 2025-03-22
Y
yyy33commented
Even though I have the relevant axis inputs turned on, when I connect the mouse to my phone via otg and input it, I can't receive any mouse events in rust ```rust use android_activity::{ input::{Axis, Button, InputEvent, KeyAction, KeyEvent, KeyMapChar, MotionAction}, AndroidApp, InputStatus, MainEvent, PollEvent, }; use log::info; #[no_mangle] fn android_main(app: AndroidApp) { android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Info)); app.enable_motion_axis(Axis::X); app.enable_motion_axis(Axis::Y); app.enable_motion_axis(Axis::Vscroll); app.enable_motion_axis(Axis::Hscroll); app.enable_motion_axis(Axis::RelativeX); app.enable_motion_axis(Axis::RelativeY); app.enable_motion_axis(Axis::X); app.enable_motion_axis(Axis::Y); app.enable_motion_axis(Axis::Pressure); app.enable_motion_axis(Axis::Size); app.enable_motion_axis(Axis::TouchMajor); app.enable_motion_axis(Axis::TouchMinor); app.enable_motion_axis(Axis::Orientation); let mut quit = false; let mut redraw_pending = true; let mut native_window: Option<ndk::native_window::NativeWindow> = None; let mut combining_accent = None; while !quit { app.poll_events( Some(std::time::Duration::from_secs(1)), /* timeout */ |event| { match event { PollEvent::Wake => {} PollEvent::Timeout => { // Real app would probably rely on vblank sync via graphics API... redraw_pending = true; } PollEvent::Main(main_event) => { match main_event { MainEvent::SaveState { saver, .. } => { saver.store("foo://bar".as_bytes()); } MainEvent::Pause => {} MainEvent::Resume { loader, .. } => { if let Some(state) = loader.load() { if let Ok(uri) = String::from_utf8(state) {} } } MainEvent::InitWindow { .. } => { native_window = app.native_window(); redraw_pending = true; } MainEvent::TerminateWindow { .. } => { native_window = None; } MainEvent::WindowResized { .. } => { redraw_pending = true; } MainEvent::RedrawNeeded { .. } => { redraw_pending = true; } MainEvent::InputAvailable { .. } => { redraw_pending = true; } MainEvent::ConfigChanged { .. } => {} MainEvent::LowMemory => {} MainEvent::Destroy => quit = true, _ => { /* ... */ } } } _ => {} } if redraw_pending { if let Some(native_window) = &native_window { redraw_pending = false; // Handle input, via a lending iterator match app.input_events_iter() { Ok(mut iter) => loop { if !iter.next(|event| { match event { InputEvent::KeyEvent(key_event) => { let combined_key_char = character_map_and_combine_key( &app, key_event, &mut combining_accent, ); } InputEvent::MotionEvent(motion_event) => { let action = match motion_event.action() { MotionAction::Down => "Down", MotionAction::Up => "Up", MotionAction::Move => "Move", MotionAction::Cancel => "Cancel", MotionAction::Outside => "Outside", MotionAction::PointerDown => "PointerDown", MotionAction::PointerUp => "PointerUp", MotionAction::HoverMove => "HoverMove", MotionAction::Scroll => "Scroll", MotionAction::HoverEnter => "HoverEnter", MotionAction::HoverExit => "HoverExit", MotionAction::ButtonPress => "ButtonPress", MotionAction::ButtonRelease => "ButtonRelease", _ => "Unknow Action", }; let button = match motion_event.action_button() { Button::Back => "Back", Button::Forward => "Forward", Button::Primary => "Primary", Button::Secondary => "Secondary", Button::StylusPrimary => "StylusPrimary", Button::StylusSecondary => "StylusSecondary", Button::Tertiary => "Tertiary", _ => "Unknow Action", }; println!( "MotionEvent, Button: {:?}, Action: {:?}", button, action ); } InputEvent::TextEvent(state) => {} _ => {} } InputStatus::Unhandled }) { break; } }, Err(err) => { log::error!("Failed to get input events iterator: {err:?}"); } } dummy_render(native_window); } } }, ); } } /// Tries to map the `key_event` to a `KeyMapChar` containing a unicode character or dead key accent /// /// This shows how to take a `KeyEvent` and look up its corresponding `KeyCharacterMap` and /// use that to try and map the `key_code` + `meta_state` to a unicode character or a /// dead key that be combined with the next key press. fn character_map_and_combine_key( app: &AndroidApp, key_event: &KeyEvent, combining_accent: &mut Option<char>, ) -> Option<KeyMapChar> { let device_id = key_event.device_id(); let key_map = match app.device_key_character_map(device_id) { Ok(key_map) => key_map, Err(err) => { log::error!("Failed to look up `KeyCharacterMap` for device {device_id}: {err:?}"); return None; } }; match key_map.get(key_event.key_code(), key_event.meta_state()) { Ok(KeyMapChar::Unicode(unicode)) => { // Only do dead key combining on key down if key_event.action() == KeyAction::Down { let combined_unicode = if let Some(accent) = combining_accent { match key_map.get_dead_char(*accent, unicode) { Ok(Some(key)) => { info!("KeyEvent: Combined '{unicode}' with accent '{accent}' to give '{key}'"); Some(key) } Ok(None) => None, Err(err) => { log::error!("KeyEvent: Failed to combine 'dead key' accent '{accent}' with '{unicode}': {err:?}"); None } } } else { info!("KeyEvent: Pressed '{unicode}'"); Some(unicode) }; *combining_accent = None; combined_unicode.map(|unicode| KeyMapChar::Unicode(unicode)) } else { Some(KeyMapChar::Unicode(unicode)) } } Ok(KeyMapChar::CombiningAccent(accent)) => { if key_event.action() == KeyAction::Down { info!("KeyEvent: Pressed 'dead key' combining accent '{accent}'"); *combining_accent = Some(accent); } Some(KeyMapChar::CombiningAccent(accent)) } Ok(KeyMapChar::None) => { // Leave any combining_accent state in tact (seems to match how other // Android apps work) info!("KeyEvent: Pressed non-unicode key"); None } Err(err) => { log::error!("KeyEvent: Failed to get key map character: {err:?}"); *combining_accent = None; None } } } /// Post a NOP frame to the window /// /// Since this is a bare minimum test app we don't depend /// on any GPU graphics APIs but we do need to at least /// convince Android that we're drawing something and are /// responsive, otherwise it will stop delivering input /// events to us. fn dummy_render(native_window: &ndk::native_window::NativeWindow) { unsafe { let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed(); let mut rect: ndk_sys::ARect = std::mem::zeroed(); ndk_sys::ANativeWindow_lock( native_window.ptr().as_ptr() as _, &mut buf as _, &mut rect as _, ); // Note: we don't try and touch the buffer since that // also requires us to handle various buffer formats ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _); } } ```
0 条评论