Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Back handle whether yes or not #3

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions internal/driver/mobile/app/GoNativeActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public class GoNativeActivity extends NativeActivity {
private native void insetsChanged(int top, int bottom, int left, int right);
private native void keyboardTyped(String str);
private native void keyboardDelete();
private native void backPressed();
private native void setDarkMode(boolean dark);

private EditText mTextEdit;
Expand Down Expand Up @@ -314,21 +313,6 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
filePickerReturned(uri.toString());
}

@Override
public void onBackPressed() {
// skip the default behaviour - we can call finishActivity if we want to go back
backPressed();
}

public void finishActivity() {
runOnUiThread(new Runnable() {
@Override
public void run() {
GoNativeActivity.super.onBackPressed();
}
});
}

@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
Expand Down
35 changes: 18 additions & 17 deletions internal/driver/mobile/app/android.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {

static int main_running = 0;

void set_global(ANativeActivity *activity){
JNIEnv* env = activity->env;
if (current_class != NULL){
(*env)->DeleteGlobalRef(activity->env, current_class);
}
// Note that activity->clazz is mis-named.
current_class = (*env)->GetObjectClass(env, activity->clazz);
current_class = (*env)->NewGlobalRef(env, current_class);
key_rune_method = find_static_method(env, current_class, "getRune", "(III)I");
show_keyboard_method = find_static_method(env, current_class, "showKeyboard", "(I)V");
hide_keyboard_method = find_static_method(env, current_class, "hideKeyboard", "()V");
show_file_open_method = find_static_method(env, current_class, "showFileOpen", "(Ljava/lang/String;)V");
show_file_save_method = find_static_method(env, current_class, "showFileSave", "(Ljava/lang/String;Ljava/lang/String;)V");
finish_method = find_method(env, current_class, "finish", "()V");
setCurrentContext(activity->vm, (*env)->NewGlobalRef(env, activity->clazz));
}

// Entry point from our subclassed NativeActivity.
//
// By here, the Go runtime has been initialized (as we are running in
Expand All @@ -77,19 +94,7 @@ static int main_running = 0;
void ANativeActivity_onCreate(ANativeActivity *activity, void* savedState, size_t savedStateSize) {
if (!main_running) {
JNIEnv* env = activity->env;

// Note that activity->clazz is mis-named.
current_class = (*env)->GetObjectClass(env, activity->clazz);
current_class = (*env)->NewGlobalRef(env, current_class);
key_rune_method = find_static_method(env, current_class, "getRune", "(III)I");
show_keyboard_method = find_static_method(env, current_class, "showKeyboard", "(I)V");
hide_keyboard_method = find_static_method(env, current_class, "hideKeyboard", "()V");
show_file_open_method = find_static_method(env, current_class, "showFileOpen", "(Ljava/lang/String;)V");
show_file_save_method = find_static_method(env, current_class, "showFileSave", "(Ljava/lang/String;Ljava/lang/String;)V");
finish_method = find_method(env, current_class, "finishActivity", "()V");

setCurrentContext(activity->vm, (*env)->NewGlobalRef(env, activity->clazz));

set_global(activity); // useless? OnStart?
// Set FILESDIR
if (setenv("FILESDIR", activity->internalDataPath, 1) != 0) {
LOG_INFO("setenv(\"FILESDIR\", \"%s\", 1) failed: %d", activity->internalDataPath, errno);
Expand Down Expand Up @@ -281,10 +286,6 @@ void Java_org_golang_app_GoNativeActivity_keyboardDelete(JNIEnv *env, jclass cla
keyboardDelete();
}

void Java_org_golang_app_GoNativeActivity_backPressed(JNIEnv *env, jclass clazz) {
onBackPressed();
}

void Java_org_golang_app_GoNativeActivity_setDarkMode(JNIEnv *env, jclass clazz, jboolean dark) {
setDarkMode((bool)dark);
}
72 changes: 42 additions & 30 deletions internal/driver/mobile/app/android.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void hideKeyboard(JNIEnv* env);
void showFileOpen(JNIEnv* env, char* mimes);
void showFileSave(JNIEnv* env, char* mimes, char* filename);
void finish(JNIEnv* env, jobject ctx);
void set_global(ANativeActivity *activity);

void Java_org_golang_app_GoNativeActivity_filePickerReturned(JNIEnv *env, jclass clazz, jstring str);
*/
Expand Down Expand Up @@ -78,18 +79,6 @@ var mimeMap = map[string]string{
".txt": "text/plain",
}

// GoBack asks the OS to go to the previous app / activity
func GoBack() {
err := RunOnJVM(func(_, jniEnv, ctx uintptr) error {
env := (*C.JNIEnv)(unsafe.Pointer(jniEnv))
C.finish(env, C.jobject(ctx))
return nil
})
if err != nil {
log.Fatalf("app: %v", err)
}
}

// RunOnJVM runs fn on a new goroutine locked to an OS thread with a JNIEnv.
//
// RunOnJVM blocks until the call to fn is complete. Any Java
Expand Down Expand Up @@ -133,10 +122,12 @@ func callMain(mainPC uintptr) {

//export onStart
func onStart(activity *C.ANativeActivity) {
C.set_global(activity)
}

//export onResume
func onResume(activity *C.ANativeActivity) {
C.set_global(activity)
}

//export onSaveInstanceState
Expand All @@ -152,17 +143,21 @@ func onPause(activity *C.ANativeActivity) {
func onStop(activity *C.ANativeActivity) {
}

//export onBackPressed
var is_back_handled bool

func onBackPressed() {
k := key.Event{
Code: key.CodeBackButton,
Direction: key.DirPress,
if is_back_handled {
k := key.Event{
Code: key.CodeBackButton,
Direction: key.DirPress,
}
log.Println("Logging key event back")
theApp.events.In() <- k
k.Direction = key.DirRelease
theApp.events.In() <- k
return 1
}
log.Println("Logging key event back")
theApp.events.In() <- k

k.Direction = key.DirRelease
theApp.events.In() <- k
return 0
}

//export onCreate
Expand Down Expand Up @@ -230,6 +225,15 @@ type windowConfig struct {
pixelsPerPt float32
}

func Finish() {
RunOnJVM(func(vm, jniEnv, ctx uintptr) error {
println("finish")
env := (*C.JNIEnv)(unsafe.Pointer(jniEnv)) // not a Go heap pointer
C.finish(env, C.jobject(ctx))
return nil
})
}

func windowConfigRead(activity *C.ANativeActivity) windowConfig {
aconfig := C.AConfiguration_new()
C.AConfiguration_fromAssetManager(aconfig, activity.assetManager)
Expand Down Expand Up @@ -555,21 +559,22 @@ func runInputQueue(vm, jniEnv, ctx uintptr) error {
}
}


func processEvents(env *C.JNIEnv, q *C.AInputQueue) {
var e *C.AInputEvent
for C.AInputQueue_getEvent(q, &e) >= 0 {
if C.AInputQueue_preDispatchEvent(q, e) != 0 {
continue
}
processEvent(env, e)
C.AInputQueue_finishEvent(q, e, 0)
handle := processEvent(env, e)
C.AInputQueue_finishEvent(q, e, C.int(handle))
}
}

func processEvent(env *C.JNIEnv, e *C.AInputEvent) {
func processEvent(env *C.JNIEnv, e *C.AInputEvent) int {
switch C.AInputEvent_getType(e) {
case C.AINPUT_EVENT_TYPE_KEY:
processKey(env, e)
return processKey(env, e)
case C.AINPUT_EVENT_TYPE_MOTION:
// At most one of the events in this batch is an up or down event; get its index and change.
upDownIndex := C.size_t(C.AMotionEvent_getAction(e)&C.AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> C.AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT
Expand All @@ -596,21 +601,27 @@ func processEvent(env *C.JNIEnv, e *C.AInputEvent) {
default:
log.Printf("unknown input event, type=%d", C.AInputEvent_getType(e))
}
return 0
}

func processKey(env *C.JNIEnv, e *C.AInputEvent) {
func processKey(env *C.JNIEnv, e *C.AInputEvent) int {
deviceID := C.AInputEvent_getDeviceId(e)
if deviceID == 0 {
// Software keyboard input, leaving for scribe/IME.
return
return 0
}
keyCode := C.AKeyEvent_getKeyCode(e)
if (keyCode == C.AKEYCODE_BACK) {
return onBackPressed() // Handle back button press and return handle
} else if (keyCode == C.AKEYCODE_MENU) {
return 1 // Handle menu button press
}

k := key.Event{
Rune: rune(C.getKeyRune(env, e)),
Code: convAndroidKeyCode(int32(C.AKeyEvent_getKeyCode(e))),
Code: convAndroidKeyCode(int32(keyCode)),
}
if k.Rune >= '0' && k.Rune <= '9' { // GBoard generates key events for numbers, but we see them in textChanged
return
return 0
}
switch C.AKeyEvent_getAction(e) {
case C.AKEY_STATE_DOWN:
Expand All @@ -622,6 +633,7 @@ func processKey(env *C.JNIEnv, e *C.AInputEvent) {
}
// TODO(crawshaw): set Modifiers.
theApp.events.In() <- k
return 0
}

func eglGetError() string {
Expand Down
6 changes: 2 additions & 4 deletions internal/driver/mobile/app/darwin_desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ func main(f func(App)) {
C.runApp()
}

func GoBack() {
// When simulating mobile there are no other activities open (and we can't just force background)
}

// loop is the primary drawing loop.
//
// After Cocoa has captured the initial OS thread for processing Cocoa
Expand Down Expand Up @@ -108,6 +104,8 @@ func (a *app) loop(ctx C.GLintptr) {
}
}

func Finish() {}

var drawDone = make(chan struct{})

// drawgl is used by Cocoa to occasionally request screen updates.
Expand Down
6 changes: 2 additions & 4 deletions internal/driver/mobile/app/darwin_ios.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,6 @@ var DisplayMetrics struct {
HeightPx int
}

func GoBack() {
// Apple do not permit apps to exit in any way other than user pressing home button / gesture
}

//export setDisplayMetrics
func setDisplayMetrics(width, height int, scale int) {
DisplayMetrics.WidthPx = width
Expand Down Expand Up @@ -151,6 +147,8 @@ func updateConfig(width, height, orientation int32) {
theApp.events.In() <- paint.Event{External: true}
}

func Finish() {}

// touchIDs is the current active touches. The position in the array
// is the ID, the value is the UITouch* pointer value.
//
Expand Down
3 changes: 1 addition & 2 deletions internal/driver/mobile/app/shiny.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ func main(f func(a App)) {
fmt.Errorf("Running mobile simulation mode does not currently work on Windows.")
}

func GoBack() {
// When simulating mobile there are no other activities open (and we can't just force background)
func Finish() { // When simulating mobile there are no other activities open (and we can't just force background)
}

// driverShowVirtualKeyboard does nothing on desktop
Expand Down
4 changes: 1 addition & 3 deletions internal/driver/mobile/app/x11.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@ func main(f func(App)) {
}
}

func GoBack() {
// When simulating mobile there are no other activities open (and we can't just force background)
}
func Finish() {}

//export onResize
func onResize(w, h int) {
Expand Down
5 changes: 1 addition & 4 deletions internal/driver/mobile/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,8 @@ func (d *mobileDriver) AbsolutePositionForObject(co fyne.CanvasObject) fyne.Posi
return pos.Subtract(inset)
}

func (d *mobileDriver) GoBack() {
app.GoBack()
}

func (d *mobileDriver) Quit() {
app.Finish()
// Android and iOS guidelines say this should not be allowed!
}

Expand Down
14 changes: 14 additions & 0 deletions internal/driver/mobile/mobileinit/ctx_android.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ static char* checkException(uintptr_t jnienv) {
static void unlockJNI(JavaVM *vm) {
(*vm)->DetachCurrentThread(vm);
}
static void deletePrevCtx(JNIEnv* env,jobject ctx){
(*env)->DeleteGlobalRef(env, ctx);
}
static int is_null(jobject ctx){
if (ctx == NULL) return 1;
return 0;
}
*/
import "C"

Expand All @@ -80,6 +87,13 @@ var currentCtx C.jobject
// The android.context.Context object must be a global reference.
func SetCurrentContext(vm unsafe.Pointer, ctx uintptr) {
currentVM = (*C.JavaVM)(vm)
if int(C.is_null(currentCtx)) == 1 {
RunOnJVM(func(vm, jniEnv, ctx uintptr) error {
env := (*C.JNIEnv)(unsafe.Pointer(jniEnv)) // not a Go heap pointer
C.deletePrevCtx(env, C.jobject(ctx))
return nil
})
}
currentCtx = (C.jobject)(ctx)
}

Expand Down