diff --git a/examples/android_send_event_block.rs b/examples/android_send_event_block.rs new file mode 100644 index 0000000000..105c5d1c5c --- /dev/null +++ b/examples/android_send_event_block.rs @@ -0,0 +1,60 @@ +#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))] +fn main() { + use simple_logger::SimpleLogger; + use winit::{ + event::{ElementState, Event, Touch, TouchPhase, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, + }; + + enum UserEvent { + MyEvent, + } + + let event_loop = EventLoop::with_user_event(); + + let window = WindowBuilder::new() + .with_title("A fantastic window!") + .build(&event_loop) + .unwrap(); + + let proxy = event_loop.create_proxy(); + let mut request_redraw = false; + + event_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Poll; + + match event { + Event::WindowEvent { event, .. } => match event { + WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, + WindowEvent::Touch(Touch { + phase: TouchPhase::Started, + .. + }) + | WindowEvent::MouseInput { + state: ElementState::Pressed, + .. + } => { + request_redraw = !request_redraw; + println!("request_redraw = {}", request_redraw); + } + _ => (), + }, + Event::MainEventsCleared => { + println!("MainEventsCleared!"); + std::thread::sleep(std::time::Duration::from_millis(200)); + let _ = proxy.send_event(UserEvent::MyEvent); + if request_redraw { + window.request_redraw(); + } + } + Event::RedrawRequested(_) => { + println!("Redrawing!"); + } + Event::UserEvent(UserEvent::MyEvent) => { + println!("I received MyEvent"); + } + _ => (), + } + }); +} diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 9457894e81..e1550a34da 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -34,14 +34,15 @@ lazy_static! { static ref INTERNAL_EVENT: RwLock> = RwLock::new(None); } +#[derive(Clone, Copy)] enum InternalEvent { RedrawRequested, + UserEvent, } enum EventSource { Callback, InputQueue, - User, Internal(InternalEvent), } @@ -217,13 +218,13 @@ fn poll(poll: Poll) -> Option { _ => unreachable!(), }, Poll::Timeout => None, - Poll::Wake => Some( + Poll::Wake => Some(EventSource::Internal( INTERNAL_EVENT .write() .unwrap() .take() - .map_or(EventSource::User, EventSource::Internal), - ), + .unwrap_or(InternalEvent::UserEvent), + )), Poll::Callback => unreachable!(), } } @@ -465,19 +466,19 @@ impl EventLoop { } } } - Some(EventSource::User) => { - let mut user_queue = self.user_queue.lock().unwrap(); - while let Some(event) = user_queue.pop_front() { - call_event_handler!( - event_handler, - self.window_target(), - control_flow, - event::Event::UserEvent(event) - ); - } - } Some(EventSource::Internal(internal)) => match internal { InternalEvent::RedrawRequested => redraw = true, + InternalEvent::UserEvent => { + let mut user_queue = self.user_queue.lock().unwrap(); + while let Some(event) = user_queue.pop_front() { + call_event_handler!( + event_handler, + self.window_target(), + control_flow, + event::Event::UserEvent(event) + ); + } + } }, None => {} } @@ -581,6 +582,7 @@ pub struct EventLoopProxy { impl EventLoopProxy { pub fn send_event(&self, event: T) -> Result<(), event_loop::EventLoopClosed> { + *INTERNAL_EVENT.write().unwrap() = Some(InternalEvent::UserEvent); self.queue.lock().unwrap().push_back(event); self.looper.wake(); Ok(()) @@ -674,7 +676,11 @@ impl Window { } pub fn request_redraw(&self) { - *INTERNAL_EVENT.write().unwrap() = Some(InternalEvent::RedrawRequested); + // insert RedrawRequest if None + let _ = *INTERNAL_EVENT + .write() + .unwrap() + .get_or_insert(InternalEvent::RedrawRequested); ForeignLooper::for_thread().unwrap().wake(); }