Przeglądaj źródła

app/android: bugfix for android where app is active with IME, switch to another app, close screen for 15 mns, open screen, switch back to app. The screen will redraw as if IME is still shown so we explicitly re-request insets when priming screen.

darkfi 4 dni temu
rodzic
commit
b7c6f295ce

+ 13 - 2
bin/app/java/MainActivity.java

@@ -86,7 +86,8 @@ if (true) return main.inpcon;
 
 native static void onApplyInsets(
     int sys_left, int sys_top, int sys_right, int sys_bottom,
-    int ime_left, int ime_top, int ime_right, int ime_bottom
+    int ime_left, int ime_top, int ime_right, int ime_bottom,
+    boolean ime_visible
 );
 
 //% END
@@ -103,7 +104,8 @@ native static void onApplyInsets(
 
     onApplyInsets(
         sysInsets.left, sysInsets.top, sysInsets.right, sysInsets.bottom,
-        imeInsets.left, imeInsets.top, imeInsets.right, imeInsets.bottom
+        imeInsets.left, imeInsets.top, imeInsets.right, imeInsets.bottom,
+        insets.isVisible(WindowInsets.Type.ime())
     );
 }
 // Workaround for Java error due to remaining body.
@@ -152,6 +154,15 @@ public boolean isImeVisible() {
     return insets.isVisible(Type.ime());
 }
 
+public void requestApplyInsets() {
+    runOnUiThread(new Runnable() {
+        @Override
+        public void run() {
+            view.requestApplyInsets();
+        }
+    });
+}
+
 public VideoDecoder createVideoDecoder() {
     VideoDecoder decoder = new VideoDecoder();
     decoder.setContext(this);

+ 5 - 2
bin/app/src/android/insets.rs

@@ -51,17 +51,20 @@ pub unsafe extern "C" fn Java_darkfi_darkfi_1app_ResizingLayout_onApplyInsets(
     ime_top: ndk_sys::jint,
     ime_right: ndk_sys::jint,
     ime_bottom: ndk_sys::jint,
+    ime_visible: ndk_sys::jboolean,
 ) {
     debug!(
         target: "android::insets",
         "onApplyInsets() \
             sys=({sys_left}, {sys_top}, {sys_right}, {sys_bottom}) \
             ime=({ime_left}, {ime_top}, {ime_right}, {ime_bottom}) \
-        )"
+            ime_visible={} \
+        )",
+        ime_visible != 0
     );
     let mut globals = GLOBALS.lock();
     globals.insets = [sys_left as f32, sys_top as f32, sys_right as f32, sys_bottom as f32];
-    if ime_bottom > 0 {
+    if ime_visible != 0 && ime_bottom > 0 {
         globals.insets[3] = ime_bottom as f32;
     }
     if let Some(sender) = &globals.sender {

+ 9 - 0
bin/app/src/android/mod.rs

@@ -85,6 +85,15 @@ pub fn is_ime_visible() -> bool {
     call_mainactivity_bool_method!("isImeVisible")
 }
 
+/// Ask Android to redispatch the current window insets to ResizingLayout,
+/// which triggers the onApplyInsets callback with fresh values.
+pub fn request_apply_insets() {
+    unsafe {
+        let env = get_jni_env();
+        ndk_utils::call_void_method!(env, android::ACTIVITY, "requestApplyInsets", "()V");
+    }
+}
+
 /// Open `url` in the platform's default handler (e.g. the browser) by calling the
 /// `openUrl` method on MainActivity, which fires an `ACTION_VIEW` intent. Android
 /// only. The URL string is converted to a Java `String` via `NewStringUTF` and the

+ 5 - 0
bin/app/src/gfx/mod.rs

@@ -900,6 +900,11 @@ impl Stage {
         // Trigger a full screen redraw by sending a resize event
         let (width, height) = miniquad::window::screen_size();
         self.event_pub.notify_resize(Dimension::from([width, height]));
+
+        #[cfg(target_os = "android")]
+        {
+            crate::android::request_apply_insets();
+        }
     }
 }