diff --git a/library/modules/platform/android.sx b/library/modules/platform/android.sx index 180dd4d..98885ba 100644 --- a/library/modules/platform/android.sx +++ b/library/modules/platform/android.sx @@ -134,31 +134,56 @@ sx_android_activity_clazz :: (activity: *void) -> *void { sx_load_ptr_at(activity, ANATIVEACTIVITY_CLAZZ_OFFSET); } -// sx-side reimplementation of the JNI dispatch chain inside -// `sx_android_query_safe_insets`. Caller provides an already-attached -// `JNIEnv*` and the activity's `clazz` jobject. Outputs physical-pixel -// insets just like the C foreign helper above. Eventually replaces -// the foreign call once the JavaVM env-attach plumbing has a sx -// equivalent or a thinner C shim. -sx_query_safe_insets_jni :: (env: *void, activity: *void, top: *s32, left: *s32, bottom: *s32, right: *s32) -> void { +// Declarative JNI class bindings for the safe-insets dispatch chain +// (Phase 2D migration). Each `#jni_class` declares the sx-side alias, +// the JNI class path, and the methods we use — `inst.method(args)` +// inside a `#jni_env(env) { ... }` scope lowers to the same JNI vtable +// indirection as the hand-rolled `#jni_call` form, with the descriptor +// auto-derived from the sx signature (see [src/ir/jni_descriptor.zig]). +WindowInsets :: #jni_class("android/view/WindowInsets") { + getSystemWindowInsetTop :: (self: *Self) -> s32; + getSystemWindowInsetLeft :: (self: *Self) -> s32; + getSystemWindowInsetBottom :: (self: *Self) -> s32; + getSystemWindowInsetRight :: (self: *Self) -> s32; +} + +View :: #jni_class("android/view/View") { + getRootWindowInsets :: (self: *Self) -> *WindowInsets; +} + +Window :: #jni_class("android/view/Window") { + getDecorView :: (self: *Self) -> *View; +} + +Activity :: #jni_class("android/app/Activity") { + getWindow :: (self: *Self) -> *Window; +} + +// sx-side reimplementation of the JNI dispatch chain. Caller provides +// an already-attached `JNIEnv*` and the activity's `clazz` jobject +// (cast to `*Activity` so the method-call DSL can find it in the +// foreign-class registry). Outputs physical-pixel insets. +sx_query_safe_insets_jni :: (env: *void, activity: *Activity, top: *s32, left: *s32, bottom: *s32, right: *s32) -> void { inline if OS != .android { return; } top.* = 0; left.* = 0; bottom.* = 0; right.* = 0; if activity == null { return; } - window := #jni_call(*void)(env, activity, "getWindow", "()Landroid/view/Window;"); - if window == null { return; } + #jni_env(env) { + window := activity.getWindow(); + if window == null { return; } - decor := #jni_call(*void)(env, window, "getDecorView", "()Landroid/view/View;"); - if decor == null { return; } + decor := window.getDecorView(); + if decor == null { return; } - insets := #jni_call(*void)(env, decor, "getRootWindowInsets", "()Landroid/view/WindowInsets;"); - if insets == null { return; } + insets := decor.getRootWindowInsets(); + if insets == null { return; } - top.* = #jni_call(s32)(env, insets, "getSystemWindowInsetTop", "()I"); - left.* = #jni_call(s32)(env, insets, "getSystemWindowInsetLeft", "()I"); - bottom.* = #jni_call(s32)(env, insets, "getSystemWindowInsetBottom", "()I"); - right.* = #jni_call(s32)(env, insets, "getSystemWindowInsetRight", "()I"); + top.* = insets.getSystemWindowInsetTop(); + left.* = insets.getSystemWindowInsetLeft(); + bottom.* = insets.getSystemWindowInsetBottom(); + right.* = insets.getSystemWindowInsetRight(); + } } // EGL — display/surface/context/config are opaque to us. @@ -396,7 +421,7 @@ impl Platform for AndroidPlatform { attached : bool = false; env := sx_android_get_env(g_android_activity, @attached); if env != null { - clazz := sx_android_activity_clazz(g_android_activity); + clazz : *Activity = xx sx_android_activity_clazz(g_android_activity); sx_query_safe_insets_jni(env, clazz, @t, @l, @b, @r); if attached { sx_android_detach_env(g_android_activity); } }