fix reference counting for GtkWidgets created from java

GtkWidgets extend GInitiallyUnowned and are automatically freed when
removing from parent widget. We need to add an extra reference, to make
sure the object keeps alive as long as the java widget has a reference
to it
This commit is contained in:
Julian Winkler
2023-08-22 13:49:09 +02:00
parent faf4a3281e
commit 36b6132324
12 changed files with 36 additions and 11 deletions

View File

@@ -255,6 +255,14 @@ JNIEXPORT jlong JNICALL Java_android_view_View_native_1constructor
JNIEXPORT void JNICALL Java_android_view_View_native_1set_1size_1request
(JNIEnv *, jobject, jint, jint);
/*
* Class: android_view_View
* Method: native_destructor
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_android_view_View_native_1destructor
(JNIEnv *, jobject, jlong);
/*
* Class: android_view_View
* Method: nativeInvalidate

View File

@@ -176,7 +176,7 @@ gboolean tick_callback(GtkWidget* widget, GdkFrameClock* frame_clock, gpointer u
JNIEXPORT jlong JNICALL Java_android_view_View_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs)
{
GtkWidget *wrapper = wrapper_widget_new();
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *area = gtk_drawing_area_new();
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), area);
wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this);
@@ -191,3 +191,8 @@ JNIEXPORT void JNICALL Java_android_view_View_nativeInvalidate(JNIEnv *env, jcla
gtk_widget_queue_draw(gtk_widget_get_parent(widget));
}
JNIEXPORT void JNICALL Java_android_view_View_native_1destructor(JNIEnv *env, jobject this, jlong widget_ptr)
{
g_object_unref(gtk_widget_get_parent(_PTR(widget_ptr)));
}

View File

@@ -14,7 +14,7 @@
*/
JNIEXPORT jlong JNICALL Java_android_view_ViewGroup_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs)
{
GtkWidget *wrapper = wrapper_widget_new();
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1); // spacing of 1
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), box);
gtk_widget_set_name(GTK_WIDGET(box), "ViewGroup");

View File

@@ -56,7 +56,7 @@ extern int FIXME__HEIGHT;
JNIEXPORT jlong JNICALL Java_android_opengl_GLSurfaceView_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs)
{
GtkWidget *wrapper = wrapper_widget_new();
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
gtk_widget_set_vexpand(wrapper, TRUE);
GtkWidget *gl_area = gtk_gl_area_new();
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), gl_area);

View File

@@ -85,7 +85,7 @@ static void on_resize(GtkWidget* self, gint width, gint height, struct jni_callb
JNIEXPORT jlong JNICALL Java_android_view_SurfaceView_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs)
{
GtkWidget *wrapper = wrapper_widget_new();
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *dummy = surface_view_widget_new();
gtk_widget_set_name(dummy, "dummy widget for SurfaceView");
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), dummy);

View File

@@ -77,7 +77,7 @@ void frame_layout_widget_insert_child_at_index(FrameLayoutWidget *parent, GtkWid
JNIEXPORT jlong JNICALL Java_android_widget_FrameLayout_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs)
{
GtkWidget *wrapper = wrapper_widget_new();
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *frame_layout = frame_layout_widget_new();
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), frame_layout);
gtk_widget_set_name(GTK_WIDGET(frame_layout), "FrameLayout");

View File

@@ -9,7 +9,7 @@
JNIEXPORT jlong JNICALL Java_android_widget_ImageView_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs)
{
GtkWidget *wrapper = wrapper_widget_new();
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *image = gtk_picture_new_for_resource("/org/gtk/libgtk/icons/16x16/status/image-missing.png"); // show "broken image" icon
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), image);
wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this);

View File

@@ -14,7 +14,7 @@ JNIEXPORT jlong JNICALL Java_android_widget_LinearLayout_native_1constructor(JNI
{
int orientation = attribute_set_get_int(env, attrs, "orientation", NULL, 1);
GtkWidget *wrapper = wrapper_widget_new();
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *box = gtk_box_new(orientation ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, 1); // spacing of 1
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), box);
gtk_widget_set_name(GTK_WIDGET(box), "LinearLayout");

View File

@@ -14,7 +14,7 @@ JNIEXPORT jlong JNICALL Java_android_widget_RelativeLayout_native_1constructor(J
{
int orientation = attribute_set_get_int(env, attrs, "orientation", NULL, 1);
GtkWidget *wrapper = wrapper_widget_new();
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *box = gtk_box_new(orientation ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, 1); // spacing of 1
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), box);
gtk_widget_set_name(GTK_WIDGET(box), "RelativeLayout");

View File

@@ -14,7 +14,7 @@ JNIEXPORT jlong JNICALL Java_android_widget_ScrollView_native_1constructor(JNIEn
{
int orientation = attribute_set_get_int(env, attrs, "orientation", NULL, 0);
GtkWidget *wrapper = wrapper_widget_new();
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *box = gtk_box_new(orientation ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, 1); // spacing of 1
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), box);
gtk_widget_set_name(GTK_WIDGET(box), "ScrollView");

View File

@@ -13,7 +13,7 @@ JNIEXPORT jlong JNICALL Java_android_widget_TextView_native_1constructor(JNIEnv
// _SET_OBJ_FIELD(this, "text", "Ljava/lang/String;", _JSTRING(text)); //TODO: sadly this might be needed, but it's not atm
GtkWidget *wrapper = wrapper_widget_new();
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *label = gtk_label_new(text);
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), label);
return _INTPTR(label);

View File

@@ -775,7 +775,9 @@ public class View extends Object {
public static HashMap<Integer, View> view_by_id = new HashMap<Integer, View>();
public View() {} // FIXME
public View() {
this(Context.this_application);
} // FIXME
public View(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -843,6 +845,7 @@ public class View extends Object {
protected native long native_constructor(Context context, AttributeSet attrs); // will create a custom GtkWidget with a custom drawing function
private native void native_set_size_request(int width, int height);
protected native void native_destructor(long widget);
// --- stubs
@@ -1052,4 +1055,13 @@ public class View extends Object {
public int getVisibility() {return View.VISIBLE;}
public boolean isInEditMode() {return false;}
@Override
protected void finalize() throws Throwable {
try {
native_destructor(widget);
} finally {
super.finalize();
}
}
}