diff --git a/CHANGELOG.md b/CHANGELOG.md index 48b46118..355a415c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- On Android, implement `Window::request_redraw` - **Breaking:** On Web, remove the `stdweb` backend. - Added `Window::focus_window`to bring the window to the front and set input focus. diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index de69bc92..b7853cf0 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -20,12 +20,24 @@ use std::{ lazy_static! { static ref CONFIG: RwLock = RwLock::new(Configuration::new()); + // If this is `Some()` a `Poll::Wake` is considered an `EventSource::Internal` with the event + // contained in the `Option`. The event is moved outside of the `Option` replacing it with a + // `None`. + // + // This allows us to inject event into the event loop without going through `ndk-glue` and + // calling unsafe function that should only be called by Android. + static ref INTERNAL_EVENT: RwLock> = RwLock::new(None); +} + +enum InternalEvent { + RedrawRequested, } enum EventSource { Callback, InputQueue, User, + Internal(InternalEvent), } fn poll(poll: Poll) -> Option { @@ -36,7 +48,13 @@ fn poll(poll: Poll) -> Option { _ => unreachable!(), }, Poll::Timeout => None, - Poll::Wake => Some(EventSource::User), + Poll::Wake => Some( + INTERNAL_EVENT + .write() + .unwrap() + .take() + .map_or(EventSource::User, EventSource::Internal), + ), Poll::Callback => unreachable!(), } } @@ -283,6 +301,9 @@ impl EventLoop { ); } } + Some(EventSource::Internal(internal)) => match internal { + InternalEvent::RedrawRequested => redraw = true, + }, None => {} } @@ -478,7 +499,8 @@ impl Window { } pub fn request_redraw(&self) { - // TODO + *INTERNAL_EVENT.write().unwrap() = Some(InternalEvent::RedrawRequested); + ForeignLooper::for_thread().unwrap().wake(); } pub fn inner_position(&self) -> Result, error::NotSupportedError> { diff --git a/src/window.rs b/src/window.rs index 4c649c42..9d326ce1 100644 --- a/src/window.rs +++ b/src/window.rs @@ -438,7 +438,7 @@ impl Window { /// ## Platform-specific /// /// - **iOS:** Can only be called on the main thread. - /// - **Android:** Unsupported. + /// - **Android:** Subsequent calls after `MainEventsCleared` are not handled. #[inline] pub fn request_redraw(&self) { self.window.request_redraw()