From 8ef37cccd7b6085318b2a624c53334a3db2b4dc8 Mon Sep 17 00:00:00 2001 From: Patrick Ziegler Date: Sat, 21 Sep 2024 11:07:40 +0200 Subject: [PATCH] [GTK] Harmonize signature of native getWidgetBounds() method This renames the getWidgetBounds() to _gtk_widget_get_allocation() and adapts the signature to expects a GtkAllocation object. On the C layer, this Java object is converted to a C object using the JGtkAllocation struct. This struct keeps track of all fields of the Java class and used to exchange the values with the Java layer. See https://github.com/eclipse-windowbuilder/windowbuilder/issues/871 --- org.eclipse.wb.os.linux/native/gtk/gtk3/rcp.c | 59 ++++++++++++------ .../os/linux/x86_64/libwbp3.so | Bin 22472 -> 22480 bytes .../wb/internal/os/linux/GdkRectangle.java | 35 +++++++++++ .../wb/internal/os/linux/GtkAllocation.java | 19 ++++++ .../wb/internal/os/linux/OSSupportLinux.java | 31 ++++++--- 5 files changed, 117 insertions(+), 27 deletions(-) create mode 100644 org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/GdkRectangle.java create mode 100644 org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/GtkAllocation.java diff --git a/org.eclipse.wb.os.linux/native/gtk/gtk3/rcp.c b/org.eclipse.wb.os.linux/native/gtk/gtk3/rcp.c index 315ac6edb..ed965c577 100644 --- a/org.eclipse.wb.os.linux/native/gtk/gtk3/rcp.c +++ b/org.eclipse.wb.os.linux/native/gtk/gtk3/rcp.c @@ -16,23 +16,44 @@ //////////////////////////////////////////////////////////////////////////// // -// Widget bounds +// GtkAllocation // //////////////////////////////////////////////////////////////////////////// -static void getWidgetBounds(GtkWidget* widget, JNIEnv *envir, jintArray jsizes) { - GtkAllocation a; - // prepare buffer - jsize sizesSize = (*envir)->GetArrayLength(envir, jsizes); - jint *sizes = malloc(sizesSize * sizeof(jint)); - memset(&a, 0, sizeof(GtkAllocation)); - gtk_widget_get_allocation(widget, &a); - *(sizes + 0) = a.x; - *(sizes + 1) = a.y; - *(sizes + 2) = a.width; - *(sizes + 3) = a.height; - // copy dimensions into java array - (*envir)->SetIntArrayRegion(envir, jsizes, 0, sizesSize, sizes); - free(sizes); + +typedef struct JGtkAllocation { + jclass clazz; + jfieldID x; + jfieldID y; + jfieldID width; + jfieldID height; +} JGtkAllocation; +JGtkAllocation GTK_ALLOCATION = { .clazz = NULL}; + +static void init_gtk_allocation(JNIEnv *envir, jobject jallocation) { + if (GTK_ALLOCATION.clazz != NULL) { + return; + } + GTK_ALLOCATION.clazz = (*envir)->GetObjectClass(envir, jallocation); + GTK_ALLOCATION.x = (*envir)->GetFieldID(envir, GTK_ALLOCATION.clazz, "x", "I"); + GTK_ALLOCATION.y = (*envir)->GetFieldID(envir, GTK_ALLOCATION.clazz, "y", "I"); + GTK_ALLOCATION.width = (*envir)->GetFieldID(envir, GTK_ALLOCATION.clazz, "width", "I"); + GTK_ALLOCATION.height = (*envir)->GetFieldID(envir, GTK_ALLOCATION.clazz, "height", "I"); +} + +static void get_gtk_allocation(JNIEnv *envir, jobject jallocation, GtkAllocation *allocation) { + init_gtk_allocation(envir, jallocation); + allocation->x = (*envir)->GetIntField(envir, jallocation, GTK_ALLOCATION.x); + allocation->y = (*envir)->GetIntField(envir, jallocation, GTK_ALLOCATION.y); + allocation->width = (*envir)->GetIntField(envir, jallocation, GTK_ALLOCATION.width); + allocation->height = (*envir)->GetIntField(envir, jallocation, GTK_ALLOCATION.height); +} + +static void set_gtk_allocation(JNIEnv *envir, jobject jallocation, GtkAllocation *allocation) { + init_gtk_allocation(envir, jallocation); + (*envir)->SetIntField(envir, jallocation, GTK_ALLOCATION.x, (jint)allocation->x); + (*envir)->SetIntField(envir, jallocation, GTK_ALLOCATION.y, (jint)allocation->y); + (*envir)->SetIntField(envir, jallocation, GTK_ALLOCATION.width, (jint)allocation->width); + (*envir)->SetIntField(envir, jallocation, GTK_ALLOCATION.height, (jint)allocation->height); } //////////////////////////////////////////////////////////////////////////// @@ -132,9 +153,11 @@ JNIEXPORT JHANDLE JNICALL OS_NATIVE(_1getImageSurface) return (JHANDLE) copyImageSurface((GdkWindow*)(CHANDLE) windowHandle, width, height); } // tab item bounds -JNIEXPORT void JNICALL OS_NATIVE(_1getWidgetBounds) - (JNIEnv *envir, jobject that, JHANDLE jhandle, jintArray jsizes) { - getWidgetBounds((GtkWidget*)(CHANDLE) jhandle, envir, jsizes); +JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1widget_1get_1allocation) + (JNIEnv *envir, jobject that, JHANDLE jhandle, jobject jallocation) { + GtkAllocation allocation; + gtk_widget_get_allocation((GtkWidget*)(CHANDLE) jhandle, &allocation); + set_gtk_allocation(envir, jallocation, &allocation); } // other static jboolean isPlusMinusTreeClick(GtkTreeView *tree, gint x, gint y) { diff --git a/org.eclipse.wb.os.linux/os/linux/x86_64/libwbp3.so b/org.eclipse.wb.os.linux/os/linux/x86_64/libwbp3.so index 06bc75d5a7914f7b06147e7e893d9c705acbe67a..589cde78cc48ddd9fd6869579c466579f6d65860 100755 GIT binary patch delta 4863 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 delta 4445 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 diff --git a/org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/GdkRectangle.java b/org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/GdkRectangle.java new file mode 100644 index 000000000..2bd62bd36 --- /dev/null +++ b/org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/GdkRectangle.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2024 Patrick Ziegler and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Ziegler - initial API and implementation + *******************************************************************************/ +package org.eclipse.wb.internal.os.linux; + +/** + * A GdkRectangle data type for representing rectangles. + * + * GdkRectangle is identical to cairo_rectangle_t. Together with Cairo’s + * cairo_region_t data type, these are the central types for representing sets + * of pixels. + * + * The intersection of two rectangles can be computed with + * gdk_rectangle_intersect(); to find the union of two rectangles use + * gdk_rectangle_union(). + * + * The cairo_region_t type provided by Cairo is usually used for managing + * non-rectangular clipping of graphical operations. + * + * The Graphene library has a number of other data types for regions and volumes + * in 2D and 3D. + */ +public sealed class GdkRectangle permits GtkAllocation { + public int x; + public int y; + public int width; + public int height; +} diff --git a/org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/GtkAllocation.java b/org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/GtkAllocation.java new file mode 100644 index 000000000..f30d934da --- /dev/null +++ b/org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/GtkAllocation.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2024 Patrick Ziegler and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Ziegler - initial API and implementation + *******************************************************************************/ +package org.eclipse.wb.internal.os.linux; + +/** + * A GtkAllocation-struct of a widget represents region which has been allocated + * to the widget by its parent. It is a subregion of its parents allocation. + */ +public final class GtkAllocation extends GdkRectangle { + +} diff --git a/org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/OSSupportLinux.java b/org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/OSSupportLinux.java index a15ae3714..f3f996e0a 100644 --- a/org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/OSSupportLinux.java +++ b/org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/OSSupportLinux.java @@ -261,10 +261,10 @@ public Image makeShot(Control control) throws Exception { * @return the widget's bounds as {@link Rectangle}. */ private Rectangle getWidgetBounds(Object widget) { + GtkAllocation rect = new GtkAllocation(); long widgetHandle = getHandleValue(widget, "handle"); - int[] sizes = new int[4]; - _getWidgetBounds(widgetHandle, sizes); - return new Rectangle(sizes[0], sizes[1], sizes[2], sizes[3]); + _gtk_widget_get_allocation(widgetHandle, rect); + return new Rectangle(rect.x, rect.y, rect.width, rect.height); } /** @@ -510,14 +510,27 @@ public void runAwt(Runnable job) { private static native boolean _isPlusMinusTreeClick(long handle, int x, int y); /** - * Fills the given array of int with bounds as x, y, width, height sequence. * - * @param widgetHandle - * the handle (GtkWidget*) of widget. - * @param bounds - * the array of integer with size 4. + * Retrieves the widget’s allocation. + * + * Note, when implementing a GtkContainer: a widget’s allocation will be its + * “adjusted” allocation, that is, the widget’s parent container typically calls + * gtk_widget_size_allocate() with an allocation, and that allocation is then + * adjusted (to handle margin and alignment for example) before assignment to + * the widget. gtk_widget_get_allocation() returns the adjusted allocation that + * was actually assigned to the widget. The adjusted allocation is guaranteed to + * be completely contained within the gtk_widget_size_allocate() allocation, + * however. So a GtkContainer is guaranteed that its children stay inside the + * assigned bounds, but not that they have exactly the bounds the container + * assigned. There is no way to get the original allocation assigned by + * gtk_widget_size_allocate(), since it isn’t stored; if a container + * implementation needs that information it will have to track it itself. + * + * + * @param widgetHandle the handle (GtkWidget*) of widget. + * @param rect A pointer to a GtkAllocation to copy to. */ - private static native void _getWidgetBounds(long widgetHandle, int[] bounds); + private static native void _gtk_widget_get_allocation(long widgetHandle, GtkAllocation rect); /** * Paints the surface of the given window onto a image. The image is created