From 6abf2259d0c871bbb099c55d9ea2ea312ccc4b9e 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: Thu, 18 Dec 2025 18:57:10 +0200 Subject: [PATCH] [Gtk4] Fix Shell.computeSize to take header bar into account HeaderBar is part of the regular window size in Gtk 4 on Wayland BUT gtk_window_get_headerbar returns 0 if it is not set by the application but drawn internally by Gtk itself and thus it's size can not be queried. Add a "default" GtkHeaderBar explicitly for that and take its size into account when computing Shell size. --- .../Eclipse SWT PI/gtk/library/gtk4.c | 46 +++++++++++++++++++ .../Eclipse SWT PI/gtk/library/gtk4_stats.h | 4 ++ .../org/eclipse/swt/internal/gtk4/GTK4.java | 17 +++++++ .../gtk/org/eclipse/swt/widgets/Shell.java | 17 +++++++ 4 files changed, 84 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 5240b3c85c3..952eee46226 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 @@ -1844,6 +1844,18 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1gesture_1zoom_1new) } #endif +#ifndef NO_gtk_1header_1bar_1new +JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1header_1bar_1new) + (JNIEnv *env, jclass that) +{ + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1header_1bar_1new_FUNC); + rc = (jlong)gtk_header_bar_new(); + GTK4_NATIVE_EXIT(env, that, gtk_1header_1bar_1new_FUNC); + return rc; +} +#endif + #ifndef NO_gtk_1hsv_1to_1rgb JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1hsv_1to_1rgb) (JNIEnv *env, jclass that, jfloat arg0, jfloat arg1, jfloat arg2, jfloatArray arg3, jfloatArray arg4, jfloatArray arg5) @@ -2509,6 +2521,18 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1widget_1get_1first_1child) } #endif +#ifndef NO_gtk_1widget_1get_1height +JNIEXPORT jint JNICALL GTK4_NATIVE(gtk_1widget_1get_1height) + (JNIEnv *env, jclass that, jlong arg0) +{ + jint rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1widget_1get_1height_FUNC); + rc = (jint)gtk_widget_get_height((GtkWidget *)arg0); + GTK4_NATIVE_EXIT(env, that, gtk_1widget_1get_1height_FUNC); + return rc; +} +#endif + #ifndef NO_gtk_1widget_1get_1last_1child JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1widget_1get_1last_1child) (JNIEnv *env, jclass that, jlong arg0) @@ -2598,6 +2622,18 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1get_1size_1request) } #endif +#ifndef NO_gtk_1widget_1get_1width +JNIEXPORT jint JNICALL GTK4_NATIVE(gtk_1widget_1get_1width) + (JNIEnv *env, jclass that, jlong arg0) +{ + jint rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1widget_1get_1width_FUNC); + rc = (jint)gtk_widget_get_width((GtkWidget *)arg0); + GTK4_NATIVE_EXIT(env, that, gtk_1widget_1get_1width_FUNC); + return rc; +} +#endif + #ifndef NO_gtk_1widget_1insert_1after JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1insert_1after) (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2) @@ -2843,6 +2879,16 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1window_1set_1icon_1name) } #endif +#ifndef NO_gtk_1window_1set_1titlebar +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1window_1set_1titlebar) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1window_1set_1titlebar_FUNC); + gtk_window_set_titlebar((GtkWindow *)arg0, (GtkWidget *)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1window_1set_1titlebar_FUNC); +} +#endif + #ifndef NO_gtk_1window_1unminimize JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1window_1unminimize) (JNIEnv *env, jclass that, jlong arg0) 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 efc66650c7d..818331a2819 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 @@ -151,6 +151,7 @@ typedef enum { gtk_1gesture_1rotate_1new_FUNC, gtk_1gesture_1set_1sequence_1state_FUNC, gtk_1gesture_1zoom_1new_FUNC, + gtk_1header_1bar_1new_FUNC, gtk_1hsv_1to_1rgb_FUNC, gtk_1icon_1paintable_1get_1file_FUNC, gtk_1icon_1theme_1get_1for_1display_FUNC, @@ -204,6 +205,7 @@ typedef enum { gtk_1widget_1class_1add_1binding_1signal_FUNC, gtk_1widget_1get_1clipboard_FUNC, gtk_1widget_1get_1first_1child_FUNC, + gtk_1widget_1get_1height_FUNC, gtk_1widget_1get_1last_1child_FUNC, gtk_1widget_1get_1native_FUNC, gtk_1widget_1get_1next_1sibling_FUNC, @@ -211,6 +213,7 @@ typedef enum { gtk_1widget_1get_1receives_1default_FUNC, gtk_1widget_1get_1root_FUNC, gtk_1widget_1get_1size_1request_FUNC, + gtk_1widget_1get_1width_FUNC, gtk_1widget_1insert_1after_FUNC, gtk_1widget_1insert_1before_FUNC, gtk_1widget_1measure_FUNC, @@ -232,5 +235,6 @@ typedef enum { gtk_1window_1set_1child_FUNC, gtk_1window_1set_1default_1widget_FUNC, gtk_1window_1set_1icon_1name_FUNC, + gtk_1window_1set_1titlebar_FUNC, gtk_1window_1unminimize_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 3c03bc15386..4b95050adcf 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 @@ -464,6 +464,11 @@ public class GTK4 { /** @param window cast=(GtkWindow *) */ public static final native long gtk_window_get_titlebar(long window); + /** @param window cast=(GtkWindow *) + * @param titlebar cast=(GtkWidget *) + **/ + public static final native void gtk_window_set_titlebar(long window, long titlebar); + /** @param window cast=(GtkWindow *) */ public static final native void gtk_window_present(long window) ; @@ -1064,4 +1069,16 @@ public class GTK4 { */ public static final native long gtk_gesture_get_last_updated_sequence(long gesture); + /** + * @param widget cast=(GtkWidget *) + */ + public static final native int gtk_widget_get_width(long widget); + + /** + * @param widget cast=(GtkWidget *) + */ + public static final native int gtk_widget_get_height(long widget); + + public static final native long gtk_header_bar_new(); + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java index 669781e986e..9270d1a3370 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java @@ -728,6 +728,14 @@ Rectangle computeTrimInPixels (int x, int y, int width, int height) { trim.y -= menuBarHeight; trim.height += menuBarHeight; } + if (GTK.GTK4 && OS.isWayland()) { + long titlebar = GTK4.gtk_window_get_titlebar(shellHandle); + if (titlebar != 0) { + int titleBarHeight = GTK4.gtk_widget_get_height (titlebar); + trim.y -= titleBarHeight; + trim.height += titleBarHeight; + } + } return trim; } @@ -743,6 +751,15 @@ void createHandle (int index) { if (GTK.GTK4) { // TODO: GTK4 need to handle for GTK_WINDOW_POPUP type shellHandle = GTK4.gtk_window_new(); + if (OS.isWayland()) { + long headerbar = GTK4.gtk_window_get_titlebar(shellHandle); + if (headerbar == 0) { + // Force-install a headerbar if none exists in order to be able to qurey its size later + // If none set by the app gtk_window_get_titlebar returns 0 but Gtk still draws one internally + long hb = GTK4.gtk_header_bar_new(); + GTK4.gtk_window_set_titlebar(shellHandle, hb); + } + } } else { shellHandle = GTK3.gtk_window_new(type); }