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 06bc75d5a..589cde78c 100755 Binary files a/org.eclipse.wb.os.linux/os/linux/x86_64/libwbp3.so and b/org.eclipse.wb.os.linux/os/linux/x86_64/libwbp3.so differ 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