Skip to content

Commit

Permalink
[GTK] Harmonize signature of native getWidgetBounds() method
Browse files Browse the repository at this point in the history
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 #871
  • Loading branch information
ptziegler committed Sep 21, 2024
1 parent a47b47b commit 8ef37cc
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 27 deletions.
59 changes: 41 additions & 18 deletions org.eclipse.wb.os.linux/native/gtk/gtk3/rcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -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) {
Expand Down
Binary file modified org.eclipse.wb.os.linux/os/linux/x86_64/libwbp3.so
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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 {

}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 8ef37cc

Please sign in to comment.