Bug 573020 - [GTK4] ExpandItem not showing when expanded

- Added GTK4 way to reparent Control widgets, this is a replacement to
GTK.gtk_widget_reparent
- Added gtk_picture_set_can_shrink, to mimic the behavior of expand item
images in GTK3
- Connected resize signal from GTK4 version of SWTFixed as a replacement
to size-allocate signal

Change-Id: Ib8c1add0dca651cdc46abb04adf0777d31bd7be5
Signed-off-by: Paul D'Pong <sdamrong@redhat.com>
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/179570
Tested-by: Platform Bot <platform-bot@eclipse.org>
Reviewed-by: Alexander Kurtakov <akurtako@redhat.com>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
index c4f61fe..aaebd21 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
@@ -423,6 +423,16 @@
 }
 #endif
 
+#ifndef NO_gtk_1picture_1set_1can_1shrink
+JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1picture_1set_1can_1shrink)
+	(JNIEnv *env, jclass that, jlong arg0, jboolean arg1)
+{
+	GTK4_NATIVE_ENTER(env, that, gtk_1picture_1set_1can_1shrink_FUNC);
+	gtk_picture_set_can_shrink((GtkPicture *)arg0, arg1);
+	GTK4_NATIVE_EXIT(env, that, gtk_1picture_1set_1can_1shrink_FUNC);
+}
+#endif
+
 #ifndef NO_gtk_1picture_1set_1paintable
 JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1picture_1set_1paintable)
 	(JNIEnv *env, jclass that, jlong arg0, jlong arg1)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c
index a07082a..f41d7b7 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c
@@ -56,6 +56,7 @@
 	"gtk_1im_1context_1filter_1keypress",
 	"gtk_1init_1check",
 	"gtk_1picture_1new",
+	"gtk_1picture_1set_1can_1shrink",
 	"gtk_1picture_1set_1paintable",
 	"gtk_1rgb_1to_1hsv",
 };
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
index a26f0e2..54ce9be 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
@@ -66,6 +66,7 @@
 	gtk_1im_1context_1filter_1keypress_FUNC,
 	gtk_1init_1check_FUNC,
 	gtk_1picture_1new_FUNC,
+	gtk_1picture_1set_1can_1shrink_FUNC,
 	gtk_1picture_1set_1paintable_FUNC,
 	gtk_1rgb_1to_1hsv_FUNC,
 } GTK4_FUNCS;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
index 19b0685..77cab8c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
@@ -110,6 +110,8 @@
 	 * @param paintable cast=(GdkPaintable *)
 	 */
 	public static final native void gtk_picture_set_paintable(long picture, long paintable);
+	/** @param picture cast=(GtkPicture *) */
+	public static final native void gtk_picture_set_can_shrink(long picture, boolean can_shrink);
 
 	/* GTK Initialization */
 	public static final native boolean gtk_init_check();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
index cc0b337..d57975b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
@@ -2869,25 +2869,32 @@
 	assert parentContainer != 0 : "Improper use of Control.gtk_widget_reparent. Widget currently has no parent.";
 	if (parentContainer != 0) {
 
-		// gtk_widget_reparent (..) is deprecated as of Gtk 3.14 and removed in Gtk4.
-		// However, the current alternative of removing/adding widget from/to a container causes errors. (see note below).
-		// TODO - research a better way to reparent. See 534089.
-		GTK.gtk_widget_reparent(widget, newParentHandle);
+		if (GTK.GTK4) {
+			OS.g_object_ref(widget);
+			OS.swt_fixed_remove(parentContainer, widget);
+			OS.swt_fixed_add(newParentHandle, widget);
+			OS.g_object_unref(widget);
+		} else {
+			// gtk_widget_reparent (..) is deprecated as of Gtk 3.14 and removed in Gtk4.
+			// However, the current alternative of removing/adding widget from/to a container causes errors. (see note below).
+			// TODO - research a better way to reparent. See 534089.
+			GTK.gtk_widget_reparent(widget, newParentHandle);
 
-		// Removing/Adding containers doesn't seem to reparent sub-gdkWindows properly and throws errors.
-		// Steps to reproduce:
-		//  - From bug 534089, download the first attachment plugin: "Plug-in to reproduce the problem with"
-		//  - Import it into your eclipse. Launch a child eclipse with this plugin. Ensure child workspace is cleaned upon launch so that you see welcome screen.
-		//  - Upon closing the welcome screen, you will see an eclipse error message: "org.eclipse.swt.SWTError: No more handles"
-		//  - The following is printed into the console: 'gdk_window_new(): parent is destroyed'
-		// After some research, I found that gtk_widget_repartent(..) also reparents sub-windows, but moving widget between containers doesn't do this,
-		// This seems to leave some gdkWindows with incorrect parents.
-//			OS.g_object_ref (widget);
-//			GTK.gtk_container_remove (parentContainer, widget);
-//			GTK.gtk_container_add (newParentHandle, widget);
-//			OS.g_object_unref (widget);
+			// Removing/Adding containers doesn't seem to reparent sub-gdkWindows properly and throws errors.
+			// Steps to reproduce:
+			//  - From bug 534089, download the first attachment plugin: "Plug-in to reproduce the problem with"
+			//  - Import it into your eclipse. Launch a child eclipse with this plugin. Ensure child workspace is cleaned upon launch so that you see welcome screen.
+			//  - Upon closing the welcome screen, you will see an eclipse error message: "org.eclipse.swt.SWTError: No more handles"
+			//  - The following is printed into the console: 'gdk_window_new(): parent is destroyed'
+			// After some research, I found that gtk_widget_repartent(..) also reparents sub-windows, but moving widget between containers doesn't do this,
+			// This seems to leave some gdkWindows with incorrect parents.
+//				OS.g_object_ref (widget);
+//				GTK.gtk_container_remove (parentContainer, widget);
+//				GTK.gtk_container_add (newParentHandle, widget);
+//				OS.g_object_unref (widget);
 
-		control.fixParentGdkResource();
+			control.fixParentGdkResource();
+		}
 	}
 }
 
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ExpandItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ExpandItem.java
index caa3914..2330fa6 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ExpandItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ExpandItem.java
@@ -139,6 +139,7 @@
 	if (GTK.GTK4) {
 		imageHandle = GTK4.gtk_picture_new();
 		if (imageHandle == 0) error(SWT.ERROR_NO_HANDLES);
+		GTK4.gtk_picture_set_can_shrink(imageHandle, false);
 
 		GTK4.gtk_box_append(boxHandle, imageHandle);
 		GTK4.gtk_box_append(boxHandle, labelHandle);
@@ -327,6 +328,8 @@
 
 		long enterAddress = display.enterMotionScrollCallback.getAddress();
 		OS.g_signal_connect (motionController, OS.enter, enterAddress, ENTER);
+
+		OS.g_signal_connect(clientHandle, OS.resize, display.resizeProc, 0);
 	} else {
 		OS.g_signal_connect_closure(clientHandle, OS.size_allocate, display.getClosure(SIZE_ALLOCATE), true);