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.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.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.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 getIdName;
jmethodID getAllSuperClasses;
jmethodID dispatchKeyEvent;
} view;
struct {
jclass class;

View File

@@ -272,6 +272,62 @@ static bool on_click(GtkGestureClick *gesture, int n_press, double x, double y,
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)
{
JavaVM *jvm;
@@ -308,6 +364,15 @@ void wrapper_widget_set_jobject(WrapperWidget *wrapper, JNIEnv *env, jobject job
gtk_widget_add_controller(wrapper->child, controller);
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)

View File

@@ -1737,6 +1737,8 @@ public class KeyEvent extends InputEvent {
private long mEventTime;
private String mCharacters;
int unicodeValue; // set from native code using gdk_keyval_to_unicode
public interface Callback {
/**
* 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.
*/
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) {return false;}
public boolean dispatchKeyEvent(KeyEvent event) {return false;}
}

View File

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