implement dispatchKeyEvent callback

This commit is contained in:
Julian Winkler
2024-11-30 17:46:43 +01:00
committed by Mis012
parent fe7790c4ff
commit 036b5510d3
6 changed files with 77 additions and 1 deletions

View File

@@ -142,6 +142,7 @@ void set_up_handle_cache(JNIEnv *env)
handle_cache.view.getId = _METHOD(handle_cache.view.class, "getId", "()I"); handle_cache.view.getId = _METHOD(handle_cache.view.class, "getId", "()I");
handle_cache.view.getIdName = _METHOD(handle_cache.view.class, "getIdName", "()Ljava/lang/String;"); handle_cache.view.getIdName = _METHOD(handle_cache.view.class, "getIdName", "()Ljava/lang/String;");
handle_cache.view.getAllSuperClasses = _METHOD(handle_cache.view.class, "getAllSuperClasses", "()Ljava/lang/String;"); handle_cache.view.getAllSuperClasses = _METHOD(handle_cache.view.class, "getAllSuperClasses", "()Ljava/lang/String;");
handle_cache.view.dispatchKeyEvent = _METHOD(handle_cache.view.class, "dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z");
handle_cache.asset_manager.class = _REF((*env)->FindClass(env, "android/content/res/AssetManager")); handle_cache.asset_manager.class = _REF((*env)->FindClass(env, "android/content/res/AssetManager"));
handle_cache.asset_manager.extractFromAPK = _STATIC_METHOD(handle_cache.asset_manager.class, "extractFromAPK", "(Ljava/lang/String;Ljava/lang/String;)V"); handle_cache.asset_manager.extractFromAPK = _STATIC_METHOD(handle_cache.asset_manager.class, "extractFromAPK", "(Ljava/lang/String;Ljava/lang/String;)V");

View File

@@ -88,6 +88,7 @@ struct handle_cache {
jmethodID getId; jmethodID getId;
jmethodID getIdName; jmethodID getIdName;
jmethodID getAllSuperClasses; jmethodID getAllSuperClasses;
jmethodID dispatchKeyEvent;
} view; } view;
struct { struct {
jclass class; jclass class;

View File

@@ -272,6 +272,62 @@ static bool on_click(GtkGestureClick *gesture, int n_press, double x, double y,
return ret; return ret;
} }
#define KEYCODE_DPAD_UP 19
#define KEYCODE_DPAD_DOWN 20
#define KEYCODE_DPAD_LEFT 21
#define KEYCODE_DPAD_RIGHT 22
#define KEYCODE_ENTER 66
#define KEYCODE_DEL 67
#define KEYCODE_FORWARD_DEL 112
static int map_key_code(int key_code) {
switch (key_code) {
case GDK_KEY_Up:
return KEYCODE_DPAD_UP;
case GDK_KEY_Down:
return KEYCODE_DPAD_DOWN;
case GDK_KEY_Left:
return KEYCODE_DPAD_LEFT;
case GDK_KEY_Right:
return KEYCODE_DPAD_RIGHT;
case GDK_KEY_Return:
return KEYCODE_ENTER;
case GDK_KEY_BackSpace:
return KEYCODE_DEL;
case GDK_KEY_Delete:
return KEYCODE_FORWARD_DEL;
default:
return key_code;
}
}
#define ACTION_DOWN 0
#define ACTION_UP 1
static gboolean on_key_pressed(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, WrapperWidget *wrapper)
{
JNIEnv *env = get_jni_env();
jobject key_event = (*env)->NewObject(env, handle_cache.key_event.class, handle_cache.key_event.constructor, ACTION_DOWN, map_key_code(keyval));
_SET_INT_FIELD(key_event, "unicodeValue", gdk_keyval_to_unicode(keyval));
gboolean ret = (*env)->CallBooleanMethod(env, wrapper->jobj, handle_cache.view.dispatchKeyEvent, key_event);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
return ret;
}
static gboolean on_key_released(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, WrapperWidget *wrapper)
{
JNIEnv *env = get_jni_env();
jobject key_event = (*env)->NewObject(env, handle_cache.key_event.class, handle_cache.key_event.constructor, ACTION_UP, map_key_code(keyval));
_SET_INT_FIELD(key_event, "unicodeValue", gdk_keyval_to_unicode(keyval));
gboolean ret = (*env)->CallBooleanMethod(env, wrapper->jobj, handle_cache.view.dispatchKeyEvent, key_event);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
return ret;
}
void wrapper_widget_set_jobject(WrapperWidget *wrapper, JNIEnv *env, jobject jobj) void wrapper_widget_set_jobject(WrapperWidget *wrapper, JNIEnv *env, jobject jobj)
{ {
JavaVM *jvm; JavaVM *jvm;
@@ -308,6 +364,15 @@ void wrapper_widget_set_jobject(WrapperWidget *wrapper, JNIEnv *env, jobject job
gtk_widget_add_controller(wrapper->child, controller); gtk_widget_add_controller(wrapper->child, controller);
widget_set_needs_allocation(wrapper->child); widget_set_needs_allocation(wrapper->child);
} }
jmethodID dispatch_key_event_method = _METHOD(_CLASS(jobj), "dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z");
if (dispatch_key_event_method != handle_cache.view.dispatchKeyEvent) {
GtkEventController *controller = GTK_EVENT_CONTROLLER(gtk_event_controller_key_new());
g_signal_connect(controller, "key-pressed", G_CALLBACK(on_key_pressed), wrapper);
g_signal_connect(controller, "key-released", G_CALLBACK(on_key_released), wrapper);
gtk_widget_add_controller(GTK_WIDGET(wrapper), controller);
gtk_widget_set_focusable(GTK_WIDGET(wrapper), TRUE);
}
} }
void wrapper_widget_set_layout_params(WrapperWidget *wrapper, int width, int height) void wrapper_widget_set_layout_params(WrapperWidget *wrapper, int width, int height)

View File

@@ -1737,6 +1737,8 @@ public class KeyEvent extends InputEvent {
private long mEventTime; private long mEventTime;
private String mCharacters; private String mCharacters;
int unicodeValue; // set from native code using gdk_keyval_to_unicode
public interface Callback { public interface Callback {
/** /**
* Called when a key down event has occurred. If you return true, * Called when a key down event has occurred. If you return true,
@@ -2984,7 +2986,8 @@ public class KeyEvent extends InputEvent {
* @return The associated character or combining accent, or 0 if none. * @return The associated character or combining accent, or 0 if none.
*/ */
public int getUnicodeChar(int metaState) { public int getUnicodeChar(int metaState) {
return getKeyCharacterMap().get(mKeyCode, metaState); // return getKeyCharacterMap().get(mKeyCode, metaState);
return unicodeValue;
} }
/** /**

View File

@@ -2086,4 +2086,6 @@ public class View implements Drawable.Callback {
public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {return false;} public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {return false;}
public boolean requestRectangleOnScreen(Rect rectangle) {return false;} public boolean requestRectangleOnScreen(Rect rectangle) {return false;}
public boolean dispatchKeyEvent(KeyEvent event) {return false;}
} }

View File

@@ -20,4 +20,8 @@ public class InputMethodManager {
return Collections.emptyList(); return Collections.emptyList();
} }
public void restartInput(View view) {}
public void updateSelection(View view, int selStart, int selEnd, int candidatesStart, int candidatesEnd) {}
} }