From c8dcc9b878cf663b494fa64990c53f01eb5f9274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Mon, 25 May 2026 18:56:43 +0300 Subject: [PATCH 1/2] [Gtk4] Clip Composite children to parent bounds In GTK3, calling gtk_widget_set_has_window(true) on a SwtFixed widget created a backing GdkWindow that automatically clipped all child widgets to the parent's allocated rectangle. GTK4 removed per-widget GdkWindows, so children render freely beyond the parent by default (GTK_OVERFLOW_VISIBLE), causing custom-drawn widgets such as CTabFolder to let their content controls draw completely outside the folder bounds. --- .../org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c | 10 ++++++++++ .../Eclipse SWT PI/gtk/library/gtk4_stats.h | 1 + .../gtk/org/eclipse/swt/internal/gtk4/GTK4.java | 8 ++++++++ .../gtk/org/eclipse/swt/widgets/Composite.java | 5 +++++ 4 files changed, 24 insertions(+) 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 6cac3b925ea..a18e0d218d4 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 @@ -2829,6 +2829,16 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1set_1focusable) } #endif +#ifndef NO_gtk_1widget_1set_1overflow +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1set_1overflow) + (JNIEnv *env, jclass that, jlong arg0, jint arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1widget_1set_1overflow_FUNC); + gtk_widget_set_overflow((GtkWidget *)arg0, (GtkOverflow)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1widget_1set_1overflow_FUNC); +} +#endif + #ifndef NO_gtk_1widget_1set_1size_1request JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1set_1size_1request) (JNIEnv *env, jclass that, jlong arg0, jint arg1, jint arg2) 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 1a5c5c9312b..567bf82c6f7 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 @@ -230,6 +230,7 @@ typedef enum { gtk_1widget_1pick_FUNC, gtk_1widget_1set_1cursor_FUNC, gtk_1widget_1set_1focusable_FUNC, + gtk_1widget_1set_1overflow_FUNC, gtk_1widget_1set_1size_1request_FUNC, gtk_1widget_1size_1allocate_FUNC, gtk_1widget_1snapshot_1child_FUNC, 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 9147dea5547..b06cdfd907f 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 @@ -26,6 +26,9 @@ public class GTK4 { public static final int GTK_EVENT_SEQUENCE_CLAIMED = 1; public static final int GTK_EVENT_SEQUENCE_DENIED = 2; + public static final int GTK_OVERFLOW_VISIBLE = 0; + public static final int GTK_OVERFLOW_HIDDEN = 1; + public static final int GTK_PICK_DEFAULT = 0; public static final int GTK_PICK_INSENSITIVE = 1; public static final int GTK_PICK_NON_TARGETABLE = 2; @@ -707,6 +710,11 @@ public class GTK4 { * @param focusable cast=(gboolean) */ public static final native void gtk_widget_set_focusable(long widget, boolean focusable); + /** + * @param widget cast=(GtkWidget *) + * @param overflow cast=(GtkOverflow) + */ + public static final native void gtk_widget_set_overflow(long widget, int overflow); /** @param widget cast=(GtkWidget *) */ public static final native long gtk_widget_get_clipboard(long widget); /** diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java index 5e090cebb26..960ced3ac68 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java @@ -343,6 +343,11 @@ void createHandle (int index, boolean fixed, boolean scrolled) { if (GTK.GTK4) { GTK4.gtk_widget_set_focusable(handle, true); + /* + * Without GTK_OVERFLOW_HIDDEN children can + * draw freely outside the parent, reproducing the GTK3 clipping behaviour. + */ + GTK4.gtk_widget_set_overflow(handle, GTK4.GTK_OVERFLOW_HIDDEN); } else { GTK3.gtk_widget_set_has_window(handle, true); } From a2c6ae11e9a4916d7d6324912590d14f1503a24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Tue, 26 May 2026 17:17:49 +0300 Subject: [PATCH 2/2] Clarify comment from review Co-authored-by: Jonah Graham --- .../Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java index 960ced3ac68..f5749593fe2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java @@ -344,8 +344,8 @@ void createHandle (int index, boolean fixed, boolean scrolled) { if (GTK.GTK4) { GTK4.gtk_widget_set_focusable(handle, true); /* - * Without GTK_OVERFLOW_HIDDEN children can - * draw freely outside the parent, reproducing the GTK3 clipping behaviour. + * Without GTK_OVERFLOW_HIDDEN, children can draw freely outside the parent. + * With GTK_OVERFLOW_HIDDEN we reproduce the GTK3 clipping behaviour. */ GTK4.gtk_widget_set_overflow(handle, GTK4.GTK_OVERFLOW_HIDDEN); } else {