From d3ad875ba5f055f6210a910750f833eaba31d14e Mon Sep 17 00:00:00 2001 From: Theo Dann-Muirhead Date: Fri, 26 Sep 2025 10:50:13 +0100 Subject: [PATCH] MenuItem.ImageSet() GTK4 fix. --- .../Eclipse SWT PI/gtk/library/gtk4.c | 32 ++++++++++ .../org/eclipse/swt/internal/gtk4/GTK4.java | 14 ++++- .../gtk/org/eclipse/swt/widgets/MenuItem.java | 62 ++++++++++++++----- 3 files changed, 93 insertions(+), 15 deletions(-) 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 3ebcddc354a..3d7ab2f81d4 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 @@ -319,6 +319,26 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1box_1prepend) } #endif +#ifndef NO_gtk_1box_1remove +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1box_1remove) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1box_1remove_FUNC); + gtk_box_remove((GtkBox *)arg0, (GtkWidget *)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1box_1remove_FUNC); +} +#endif + +#ifndef NO_gtk_1box_1reorder_1child_1after +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1box_1reorder_1child_1after) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1box_1reorder_1child_1after_FUNC); + gtk_box_reorder_child_after((GtkBox *)arg0, (GtkWidget *)arg1, (GtkWidget *)arg2); + GTK4_NATIVE_EXIT(env, that, gtk_1box_1reorder_1child_1after_FUNC); +} +#endif + #ifndef NO_gtk_1button_1new_1from_1icon_1name JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1button_1new_1from_1icon_1name) (JNIEnv *env, jclass that, jbyteArray arg0) @@ -1561,6 +1581,18 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1image_1new_1from_1icon_1name) } #endif +#ifndef NO_gtk_1image_1new_1from_1paintable +JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1image_1new_1from_1paintable) + (JNIEnv *env, jclass that, jlong arg0) +{ + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1image_1new_1from_1paintable_FUNC); + rc = (jlong)gtk_image_new_from_paintable((GdkPaintable *)arg0); + GTK4_NATIVE_EXIT(env, that, gtk_1image_1new_1from_1paintable_FUNC); + return rc; +} +#endif + #ifndef NO_gtk_1image_1set_1from_1icon_1name JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1image_1set_1from_1icon_1name) (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1) 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 48ceb120d5c..1f656d74975 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 @@ -70,6 +70,17 @@ public class GTK4 { * @param child cast=(GtkWidget *) */ public static final native void gtk_box_prepend(long box, long child); + /** + * @param box cast=(GtkBox *) + * @param child cast=(GtkWidget *) + * @param sibling cast=(GtkWidget *) + */ + public static final native void gtk_box_reorder_child_after(long box, long child, long sibling); + /** + * @param box cast=(GtkBox *) + * @param child cast=(GtkWidget *) + */ + public static final native void gtk_box_remove(long box, long child); /** * @param box cast=(GtkBox *) * @param child cast=(GtkWidget *) @@ -724,6 +735,8 @@ public class GTK4 { public static final native void gtk_image_set_from_paintable(long image, long paintable); /** @param icon_name cast=(const char *) */ public static final native long gtk_image_new_from_icon_name(byte[] icon_name); + /** @param paintable cast=(GdkPaintable *) */ + public static final native long gtk_image_new_from_paintable(long paintable); /** * @param image cast=(GtkImage *) * @param icon_name cast=(const gchar *) @@ -882,5 +895,4 @@ public class GTK4 { * @param gesture cast=(GtkGesture *) */ public static final native long gtk_gesture_get_last_updated_sequence(long gesture); - } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java index edc9eb543ee..a83583b60d2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java @@ -1028,9 +1028,6 @@ public void setID (int id) { */ @Override public void setImage (Image image) { - //TODO: GTK4 Menu images with text are no longer supported - if (GTK.GTK4) return; - checkWidget(); if (this.image == image) return; if ((style & SWT.SEPARATOR) != 0) return; @@ -1053,24 +1050,61 @@ private void _setImage (Image image) { imageList.put (imageIndex, image); surface = imageList.getSurface (imageIndex); } - - if (!GTK3.GTK_IS_MENU_ITEM (handle)) return; - if (OS.SWT_PADDED_MENU_ITEMS && imageHandle != 0) { - GTK3.gtk_image_set_from_surface(imageHandle, surface); - } else { - if (imageHandle == 0) { - imageHandle = GTK3.gtk_image_new_from_surface(surface); - if (imageHandle == 0) error(SWT.ERROR_NO_HANDLES); - - GTK3.gtk_container_add(boxHandle, imageHandle); - GTK3.gtk_box_reorder_child(boxHandle, imageHandle, 0); + if (GTK.GTK4) { + long pixbuf = ImageList.createPixbuf(image); + long texture = GDK.gdk_texture_new_for_pixbuf(pixbuf); + OS.g_object_unref(pixbuf); + if (OS.SWT_PADDED_MENU_ITEMS && imageHandle != 0) { + GTK4.gtk_image_set_from_paintable(imageHandle, texture); } else { + if (imageHandle == 0) { + imageHandle = GTK4.gtk_image_new_from_paintable(texture); + if (imageHandle == 0) error(SWT.ERROR_NO_HANDLES); + if(boxHandle == 0) { + boxHandle = gtk_box_new (GTK.GTK_ORIENTATION_HORIZONTAL, false, 6); + } + + GTK4.gtk_box_append(boxHandle, imageHandle); + GTK4.gtk_box_reorder_child_after(boxHandle, imageHandle, 0); + } else { + GTK4.gtk_image_set_from_paintable(imageHandle, texture); + } + } + return; + } else { + if (!GTK3.GTK_IS_MENU_ITEM (handle)) return; + if (OS.SWT_PADDED_MENU_ITEMS && imageHandle != 0) { GTK3.gtk_image_set_from_surface(imageHandle, surface); + } else { + if (imageHandle == 0) { + imageHandle = GTK3.gtk_image_new_from_surface(surface); + if (imageHandle == 0) error(SWT.ERROR_NO_HANDLES); + + GTK3.gtk_container_add(boxHandle, imageHandle); + GTK3.gtk_box_reorder_child(boxHandle, imageHandle, 0); + } else { + GTK3.gtk_image_set_from_surface(imageHandle, surface); + } } } gtk_widget_show(imageHandle); } else { if (imageHandle != 0) { + if (GTK.GTK4) { + if (OS.SWT_PADDED_MENU_ITEMS) { + GTK4.gtk_box_remove(boxHandle, imageHandle); + imageHandle = GTK.gtk_image_new (); + if (imageHandle == 0) error (SWT.ERROR_NO_HANDLES); + GTK.gtk_image_set_pixel_size (imageHandle, 16); + GTK4.gtk_box_append (boxHandle, imageHandle); + GTK4.gtk_box_append(boxHandle, labelHandle); + gtk_widget_show (imageHandle); + } else { + GTK4.gtk_box_remove(boxHandle, imageHandle); + imageHandle = 0; + } + return; + } if (OS.SWT_PADDED_MENU_ITEMS) { GTK3.gtk_container_remove(boxHandle, imageHandle); imageHandle = GTK.gtk_image_new ();