Skip to content

Commit 5125712

Browse files
author
Chris Warren-Smith
committed
ANDROID: fix back-button handling
1 parent 4f9f2d1 commit 5125712

4 files changed

Lines changed: 33 additions & 25 deletions

File tree

src/platform/android/app/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ android {
77
// can override some attributes in main/AndroidManifest.xml
88
defaultConfig {
99
applicationId 'net.sourceforge.smallbasic'
10-
minSdkVersion 21
10+
minSdkVersion 23
1111
targetSdkVersion 36
12-
versionCode 89
12+
versionCode 90
1313
versionName '12.33'
1414
resourceConfigurations += ['en']
1515
}
@@ -53,6 +53,6 @@ android {
5353
}
5454

5555
dependencies {
56-
implementation 'androidx.core:core:1.17.0'
56+
implementation 'androidx.core:core:1.18.0'
5757
testImplementation 'junit:junit:4.13.2'
5858
}

src/platform/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ buildscript {
55
mavenCentral()
66
}
77
dependencies {
8-
classpath 'com.android.tools.build:gradle:9.0.0'
8+
classpath 'com.android.tools.build:gradle:9.1.0'
99
}
1010
}
1111

src/platform/android/jni/runtime.cpp

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ Runtime *runtime = nullptr;
3333
// Pipe file descriptors: g_backPipe[0] is read-end, g_backPipe[1] is write-end
3434
static 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
4037
static 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
//
129119
static 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

513505
MAEvent *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+
10061013
void Runtime::onResize(int width, int height, int imeState) {
10071014
logEntered();
10081015
if (_graphics != nullptr) {
@@ -1051,7 +1058,7 @@ void Runtime::onUnicodeChar(int ch) {
10511058

10521059
char *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 {
10961103
int 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;

src/platform/android/jni/runtime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct Runtime : public System {
7272
void share(const char *path) override { setString("share", path); }
7373
void showCursor(CursorType cursorType) override {}
7474
void showKeypad(bool show);
75+
void onBack();
7576
void onPaused(bool paused) { if (_graphics != nullptr) {_graphics->onPaused(paused);} }
7677
void onResize(int w, int h, int imeState);
7778
void onRunCompleted() override;

0 commit comments

Comments
 (0)