Browse Source

Merge pull request #1770 from reven86/next-clean

Fix for app freeze when user tries to hide keyboard on android
Sean Taylor 10 years ago
parent
commit
c5a6706f40
1 changed files with 44 additions and 1 deletions
  1. 44 1
      gameplay/src/PlatformAndroid.cpp

+ 44 - 1
gameplay/src/PlatformAndroid.cpp

@@ -758,6 +758,16 @@ static float clampFuzz(float value, float fuzz)
 // Process the next input event.
 static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
 {
+    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY
+        && AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN
+        && AKeyEvent_getKeyCode(event) == AKEYCODE_BACK
+        && __displayKeyboard
+        )
+    {
+        Game::getInstance()->displayKeyboard(false);
+        return 1;
+    }
+
     int32_t deviceId = AInputEvent_getDeviceId(event);
     int32_t source = AInputEvent_getSource(event);
 
@@ -1242,6 +1252,36 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
     }
 }
 
+// Patch andoid_native_app_glue.c process_input function since it freezes app when user tries to hide keyboard
+// See: http://stackoverflow.com/questions/15913080/crash-when-closing-soft-keyboard-while-using-native-activity
+#include <android/log.h>
+#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__))
+#define LOGV(...)  ((void)0)
+static void process_input( struct android_app* app, struct android_poll_source* source)
+{
+    AInputEvent* event = NULL;
+
+    while(AInputQueue_getEvent(app->inputQueue, &event) >= 0)
+    {
+        int type = AInputEvent_getType(event);
+        LOGV("New input event: type=%d\n", AInputEvent_getType(event));
+
+        bool skip_predispatch
+            =  AInputEvent_getType(event)  == AINPUT_EVENT_TYPE_KEY
+            && AKeyEvent_getKeyCode(event) == AKEYCODE_BACK;
+
+        // skip predispatch (all it does is send to the IME)
+        if (!skip_predispatch && AInputQueue_preDispatchEvent(app->inputQueue, event))
+            return;
+
+        int32_t handled = 0;
+        if (app->onInputEvent != NULL)
+            handled = app->onInputEvent(app, event);
+        AInputQueue_finishEvent(app->inputQueue, event, handled);
+    }
+}
+
+
 Platform::Platform(Game* game)
     : _game(game)
 {
@@ -1313,6 +1353,9 @@ int Platform::enterMessagePump()
     __state->onAppCmd = engine_handle_cmd;
     __state->onInputEvent = engine_handle_input;
     
+    // Apply patch to native process_input function
+    __state->inputPollSource.process = process_input;
+
     // Prepare to monitor accelerometer.
     __sensorManager = ASensorManager_getInstance();
     __accelerometerSensor = ASensorManager_getDefaultSensor(__sensorManager, ASENSOR_TYPE_ACCELEROMETER);
@@ -1400,7 +1443,7 @@ int Platform::enterMessagePump()
                 }
             }
         }
-            
+
         // Display the keyboard.
         gameplay::displayKeyboard(__state, __displayKeyboard);
     }