@@ -33,9 +33,6 @@ Runtime *runtime = nullptr;
3333// Pipe file descriptors: g_backPipe[0] is read-end, g_backPipe[1] is write-end
3434static int g_backPipe[2 ] = {-1 , -1 };
3535
36- // whether native back key handling is active
37- static bool g_predictiveBack = false ;
38-
3936// the logical top of the screen
4037static int g_top = 0 ;
4138
@@ -115,23 +112,18 @@ void handleCommand(android_app *app, int32_t cmd) {
115112 }
116113}
117114
118- static void pushBackEvent () {
119- auto *maEvent = new MAEvent ();
120- maEvent->nativeKey = AKEYCODE_BACK;
121- maEvent->type = EVENT_TYPE_KEY_PRESSED;
122- runtime->pushEvent (maEvent);
123- }
124-
125115//
126116// Callback registered with ALooper that is triggered when the pipe receives data.
127117// This is what wakes the blocked ALooper_pollOnce() and lets us run pushBackEvent().
128118//
129119static int pipeCallback (int fd, int events, void *data) {
130120 // clear the byte that woke the pipe, then return 1 to stay registered
131- logEntered ();
132- char buf[1 ];
133- read (fd, buf, 1 );
134- pushBackEvent ();
121+ if (runtime != nullptr && runtime->isActive ()) {
122+ logEntered ();
123+ char buf[1 ];
124+ read (fd, buf, 1 );
125+ runtime->onBack ();
126+ }
135127 return 1 ;
136128}
137129
@@ -165,8 +157,9 @@ static void process_input(android_app *app, android_poll_source *source) {
165157 AKeyEvent_getKeyCode (event) == AKEYCODE_BACK) {
166158 // prevent AInputQueue_preDispatchEvent from attempting to close
167159 // the keypad here to avoid a crash in android 4.2 + 4.3.
168- if (AKeyEvent_getAction (event) == AKEY_EVENT_ACTION_DOWN && runtime->isActive () && !g_predictiveBack) {
169- pushBackEvent ();
160+ if (AKeyEvent_getAction (event) == AKEY_EVENT_ACTION_DOWN && runtime != nullptr && runtime->isActive ()) {
161+ trace (" AKEYCODE_BACK event" );
162+ runtime->onBack ();
170163 }
171164 AInputQueue_finishEvent (app->inputQueue , event, true );
172165 } else if (!AInputQueue_preDispatchEvent (app->inputQueue , event)) {
@@ -297,8 +290,7 @@ Runtime::Runtime(android_app *app) :
297290 _looper = ALooper_forThread ();
298291 _sensorManager = ASensorManager_getInstance ();
299292 memset (&_sensors, 0 , sizeof (_sensors));
300- g_predictiveBack = getBoolean (" isPredictiveBack" );
301- if (g_predictiveBack) {
293+ if (getBoolean (" isPredictiveBack" )) {
302294 setupBackWakePipe (_looper);
303295 }
304296}
@@ -512,7 +504,7 @@ char *Runtime::loadResource(const char *fileName) {
512504
513505MAEvent *Runtime::popEvent () {
514506 pthread_mutex_lock (&_mutex);
515- MAEvent *result = _eventQueue->pop ();
507+ auto *result = _eventQueue->pop ();
516508 pthread_mutex_unlock (&_mutex);
517509 return result;
518510}
@@ -1003,6 +995,21 @@ void Runtime::showKeypad(bool show) {
1003995 _app->activity ->vm ->DetachCurrentThread ();
1004996}
1005997
998+ void Runtime::onBack () {
999+ pthread_mutex_lock (&_mutex);
1000+ auto *current = _eventQueue->peek ();
1001+ if (current == nullptr || current->nativeKey != AKEYCODE_BACK) {
1002+ trace (" pushing back event to the queue" );
1003+ auto *event = new MAEvent ();
1004+ event->nativeKey = AKEYCODE_BACK;
1005+ event->type = EVENT_TYPE_KEY_PRESSED;
1006+ _eventQueue->push (event);
1007+ } else {
1008+ trace (" skipping duplicate back event" );
1009+ }
1010+ pthread_mutex_unlock (&_mutex);
1011+ }
1012+
10061013void Runtime::onResize (int width, int height, int imeState) {
10071014 logEntered ();
10081015 if (_graphics != nullptr ) {
@@ -1051,7 +1058,7 @@ void Runtime::onUnicodeChar(int ch) {
10511058
10521059char *Runtime::getClipboardText () {
10531060 char *result;
1054- String text = getStringBytes (" getClipboardText" );
1061+ auto text = getStringBytes (" getClipboardText" );
10551062 if (!text.empty ()) {
10561063 result = strdup (text.c_str ());
10571064 } else {
@@ -1096,7 +1103,7 @@ void System::completeKeyword(int index) const {
10961103int maGetEvent (MAEvent *event) {
10971104 int result;
10981105 if (runtime->hasEvent ()) {
1099- MAEvent *nextEvent = runtime->popEvent ();
1106+ auto *nextEvent = runtime->popEvent ();
11001107 event->point = nextEvent->point ;
11011108 event->type = nextEvent->type ;
11021109 delete nextEvent;
0 commit comments