View: replace custom isAttachedToWindow tracking with GTK signals

This commit is contained in:
Julian Winkler
2025-10-10 12:00:47 +02:00
parent 2288f2bce9
commit d4aca99823
8 changed files with 37 additions and 53 deletions

View File

@@ -415,6 +415,14 @@ JNIEXPORT jboolean JNICALL Java_android_view_View_nativeIsFocused
JNIEXPORT jboolean JNICALL Java_android_view_View_native_1getMatrix JNIEXPORT jboolean JNICALL Java_android_view_View_native_1getMatrix
(JNIEnv *, jobject, jlong, jlong); (JNIEnv *, jobject, jlong, jlong);
/*
* Class: android_view_View
* Method: nativeIsAttachedToWindow
* Signature: (J)Z
*/
JNIEXPORT jboolean JNICALL Java_android_view_View_nativeIsAttachedToWindow
(JNIEnv *, jobject, jlong);
/* /*
* Class: android_view_View * Class: android_view_View
* Method: native_keep_screen_on * Method: native_keep_screen_on

View File

@@ -85,6 +85,8 @@ void set_up_handle_cache(JNIEnv *env)
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.view.dispatchKeyEvent = _METHOD(handle_cache.view.class, "dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z");
handle_cache.view.onKeyDown = _METHOD(handle_cache.view.class, "onKeyDown", "(ILandroid/view/KeyEvent;)Z"); handle_cache.view.onKeyDown = _METHOD(handle_cache.view.class, "onKeyDown", "(ILandroid/view/KeyEvent;)Z");
handle_cache.view.onAttachedToWindow = _METHOD(handle_cache.view.class, "onAttachedToWindow", "()V");
handle_cache.view.onDetachedFromWindow = _METHOD(handle_cache.view.class, "onDetachedFromWindow", "()V");
handle_cache.view_group.class = _REF((*env)->FindClass(env, "android/view/ViewGroup")); handle_cache.view_group.class = _REF((*env)->FindClass(env, "android/view/ViewGroup"));
handle_cache.view_group.dispatchTouchEvent = _METHOD(handle_cache.view_group.class, "dispatchTouchEvent", "(Landroid/view/MotionEvent;)Z"); handle_cache.view_group.dispatchTouchEvent = _METHOD(handle_cache.view_group.class, "dispatchTouchEvent", "(Landroid/view/MotionEvent;)Z");

View File

@@ -84,6 +84,8 @@ struct handle_cache {
jmethodID getAllSuperClasses; jmethodID getAllSuperClasses;
jmethodID dispatchKeyEvent; jmethodID dispatchKeyEvent;
jmethodID onKeyDown; jmethodID onKeyDown;
jmethodID onAttachedToWindow;
jmethodID onDetachedFromWindow;
} view; } view;
struct { struct {
jclass class; jclass class;

View File

@@ -505,6 +505,13 @@ static void java_widget_class_init(JavaWidgetClass *class) {
} }
G_DEFINE_TYPE(JavaWidget, java_widget, GTK_TYPE_WIDGET) G_DEFINE_TYPE(JavaWidget, java_widget, GTK_TYPE_WIDGET)
static void java_method_cb(WrapperWidget *wrapper, jmethodID method) {
JNIEnv *env = get_jni_env();
(*env)->CallVoidMethod(env, wrapper->jobj, method);
if ((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
}
JNIEXPORT jlong JNICALL Java_android_view_View_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs) JNIEXPORT jlong JNICALL Java_android_view_View_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs)
{ {
WrapperWidget *wrapper = g_object_ref(WRAPPER_WIDGET(wrapper_widget_new())); WrapperWidget *wrapper = g_object_ref(WRAPPER_WIDGET(wrapper_widget_new()));
@@ -527,6 +534,11 @@ JNIEXPORT jlong JNICALL Java_android_view_View_native_1constructor(JNIEnv *env,
gtk_widget_add_controller(widget, controller); gtk_widget_add_controller(widget, controller);
} }
if (_METHOD(class, "onAttachedToWindow", "()V") != handle_cache.view.onAttachedToWindow)
g_signal_connect(wrapper, "map", G_CALLBACK(java_method_cb), handle_cache.view.onAttachedToWindow);
if (_METHOD(class, "onDetachedFromWindow", "()V") != handle_cache.view.onDetachedFromWindow)
g_signal_connect(wrapper, "unmap", G_CALLBACK(java_method_cb), handle_cache.view.onDetachedFromWindow);
return _INTPTR(widget); return _INTPTR(widget);
} }
@@ -841,3 +853,9 @@ JNIEXPORT void JNICALL Java_android_view_View_native_1keep_1screen_1on(JNIEnv *e
g_object_set_data(G_OBJECT(widget), "keep-screen-on-cookie", GINT_TO_POINTER(cookie)); g_object_set_data(G_OBJECT(widget), "keep-screen-on-cookie", GINT_TO_POINTER(cookie));
} }
} }
JNIEXPORT jboolean JNICALL Java_android_view_View_nativeIsAttachedToWindow(JNIEnv *env, jobject this, jlong widget_ptr)
{
GtkWidget *widget = GTK_WIDGET(_PTR(widget_ptr));
return gtk_widget_get_mapped(widget);
}

View File

@@ -841,8 +841,6 @@ public class View implements Drawable.Callback {
private int scrollX = 0; private int scrollX = 0;
private int scrollY = 0; private int scrollY = 0;
private boolean attachedToWindow = false;
public long widget; // pointer public long widget; // pointer
private int oldWidthMeasureSpec = -1; private int oldWidthMeasureSpec = -1;
@@ -1836,7 +1834,10 @@ public class View implements Drawable.Callback {
public void setPaddingRelative(int start, int top, int end, int bottom) {} public void setPaddingRelative(int start, int top, int end, int bottom) {}
public boolean isAttachedToWindow() {return attachedToWindow;} private native boolean nativeIsAttachedToWindow(long widget);
public boolean isAttachedToWindow() {
return nativeIsAttachedToWindow(widget);
}
public void requestApplyInsets() {} public void requestApplyInsets() {}
@@ -1910,34 +1911,13 @@ public class View implements Drawable.Callback {
private boolean keepScreenOn = false; private boolean keepScreenOn = false;
private static native void native_keep_screen_on(long widget, boolean keepScreenOn); private static native void native_keep_screen_on(long widget, boolean keepScreenOn);
public void setKeepScreenOn(boolean screenOn) { public void setKeepScreenOn(boolean screenOn) {
if (attachedToWindow && keepScreenOn != screenOn) if (isAttachedToWindow() && keepScreenOn != screenOn)
native_keep_screen_on(widget, screenOn); native_keep_screen_on(widget, screenOn);
keepScreenOn = screenOn; keepScreenOn = screenOn;
} }
protected void onAttachedToWindow () { protected void onAttachedToWindow() {}
attachedToWindow = true; protected void onDetachedFromWindow() {}
if (onAttachStateChangeListener != null) {
onAttachStateChangeListener.onViewAttachedToWindow(this);
}
if (keepScreenOn)
native_keep_screen_on(widget, true);
}
protected void onDetachedFromWindow() {
if (onAttachStateChangeListener != null) {
onAttachStateChangeListener.onViewDetachedFromWindow(this);
}
if (keepScreenOn)
native_keep_screen_on(widget, false);
}
void detachFromWindowInternal() {
onDetachedFromWindow();
attachedToWindow = false;
}
public void attachToWindowInternal() {
onAttachedToWindow();
}
public void setLayerType(int layerType, Paint paint) {} public void setLayerType(int layerType, Paint paint) {}

View File

@@ -77,8 +77,6 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
index = children.size(); index = children.size();
children.add(index, child); children.add(index, child);
native_addView(widget, child.widget, index, params); native_addView(widget, child.widget, index, params);
if (isAttachedToWindow())
child.onAttachedToWindow();
if (onHierarchyChangeListener != null) if (onHierarchyChangeListener != null)
onHierarchyChangeListener.onChildViewAdded(this, child); onHierarchyChangeListener.onChildViewAdded(this, child);
@@ -111,8 +109,6 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
child.parent = null; child.parent = null;
children.remove(child); children.remove(child);
native_removeView(widget, child.widget); native_removeView(widget, child.widget);
if (isAttachedToWindow())
child.detachFromWindowInternal();
if (onHierarchyChangeListener != null) { if (onHierarchyChangeListener != null) {
onHierarchyChangeListener.onChildViewRemoved(this, child); onHierarchyChangeListener.onChildViewRemoved(this, child);
} }
@@ -136,8 +132,6 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
child.parent = null; child.parent = null;
it.remove(); it.remove();
native_removeView(widget, child.widget); native_removeView(widget, child.widget);
if (isAttachedToWindow())
child.detachFromWindowInternal();
if (onHierarchyChangeListener != null) { if (onHierarchyChangeListener != null) {
onHierarchyChangeListener.onChildViewRemoved(this, child); onHierarchyChangeListener.onChildViewRemoved(this, child);
} }
@@ -169,8 +163,6 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
return; return;
child.parent = null; child.parent = null;
native_removeView(widget, child.widget); native_removeView(widget, child.widget);
if (isAttachedToWindow())
child.detachFromWindowInternal();
if (onHierarchyChangeListener != null) { if (onHierarchyChangeListener != null) {
onHierarchyChangeListener.onChildViewRemoved(this, child); onHierarchyChangeListener.onChildViewRemoved(this, child);
} }
@@ -363,22 +355,6 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {} public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
for (View child: children) {
child.onAttachedToWindow();
}
}
@Override
protected void detachFromWindowInternal() {
super.detachFromWindowInternal();
for (View child: children) {
child.detachFromWindowInternal();
}
}
protected boolean isChildrenDrawingOrderEnabled() { return false; } protected boolean isChildrenDrawingOrderEnabled() { return false; }
@Override @Override

View File

@@ -39,7 +39,6 @@ public class Window {
this.context = context; this.context = context;
decorView = new FrameLayout(context); decorView = new FrameLayout(context);
decorView.setId(android.R.id.content); decorView.setId(android.R.id.content);
decorView.onAttachedToWindow();
} }
public void addFlags(int flags) {} public void addFlags(int flags) {}

View File

@@ -74,7 +74,6 @@ public class PopupWindow {
contentView = view; contentView = view;
if (contentView != null) { if (contentView != null) {
contentView.setBackground(getBackground()); contentView.setBackground(getBackground());
contentView.attachToWindowInternal();
} }
native_setContentView(popover, view == null ? 0 : view.widget); native_setContentView(popover, view == null ? 0 : view.widget);
} }