diff options
author | Silenio Quarti <silenio_quarti@ca.ibm.com> | 2013-03-23 10:51:35 -0400 |
---|---|---|
committer | Silenio Quarti <silenio_quarti@ca.ibm.com> | 2013-03-25 12:55:09 -0400 |
commit | d453cf5437fbe11ecd8d5bdf8ed46b521a6689e4 (patch) | |
tree | a6dd47eb1cb90131f7404b7984833f95c735eb51 | |
parent | 3462638b4d08f5602683f1e8dd1eecfd9fd908ff (diff) | |
download | eclipse.platform.swt-d453cf5437fbe11ecd8d5bdf8ed46b521a6689e4.tar.gz eclipse.platform.swt-d453cf5437fbe11ecd8d5bdf8ed46b521a6689e4.tar.xz eclipse.platform.swt-d453cf5437fbe11ecd8d5bdf8ed46b521a6689e4.zip |
Bug 397107 - [GTK3] CTabFolder rendering hangs
11 files changed, 193 insertions, 27 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c index 51ae3117bc..f9eb5cb146 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c @@ -18178,6 +18178,31 @@ JNIEXPORT jintLong JNICALL OS_NATIVE(_1gtk_1widget_1get_1parent_1window) } #endif +#ifndef NO__1gtk_1widget_1get_1preferred_1height_1for_1width +JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1widget_1get_1preferred_1height_1for_1width) + (JNIEnv *env, jclass that, jintLong arg0, jint arg1, jintArray arg2, jintArray arg3) +{ + jint *lparg2=NULL; + jint *lparg3=NULL; + OS_NATIVE_ENTER(env, that, _1gtk_1widget_1get_1preferred_1height_1for_1width_FUNC); + if (arg2) if ((lparg2 = (*env)->GetIntArrayElements(env, arg2, NULL)) == NULL) goto fail; + if (arg3) if ((lparg3 = (*env)->GetIntArrayElements(env, arg3, NULL)) == NULL) goto fail; +/* + gtk_widget_get_preferred_height_for_width(arg0, arg1, lparg2, lparg3); +*/ + { + OS_LOAD_FUNCTION(fp, gtk_widget_get_preferred_height_for_width) + if (fp) { + ((void (CALLING_CONVENTION*)(jintLong, jint, jint *, jint *))fp)(arg0, arg1, lparg2, lparg3); + } + } +fail: + if (arg3 && lparg3) (*env)->ReleaseIntArrayElements(env, arg3, lparg3, 0); + if (arg2 && lparg2) (*env)->ReleaseIntArrayElements(env, arg2, lparg2, 0); + OS_NATIVE_EXIT(env, that, _1gtk_1widget_1get_1preferred_1height_1for_1width_FUNC); +} +#endif + #ifndef NO__1gtk_1widget_1get_1preferred_1size JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1widget_1get_1preferred_1size) (JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jobject arg2) @@ -18203,6 +18228,31 @@ fail: } #endif +#ifndef NO__1gtk_1widget_1get_1preferred_1width_1for_1height +JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1widget_1get_1preferred_1width_1for_1height) + (JNIEnv *env, jclass that, jintLong arg0, jint arg1, jintArray arg2, jintArray arg3) +{ + jint *lparg2=NULL; + jint *lparg3=NULL; + OS_NATIVE_ENTER(env, that, _1gtk_1widget_1get_1preferred_1width_1for_1height_FUNC); + if (arg2) if ((lparg2 = (*env)->GetIntArrayElements(env, arg2, NULL)) == NULL) goto fail; + if (arg3) if ((lparg3 = (*env)->GetIntArrayElements(env, arg3, NULL)) == NULL) goto fail; +/* + gtk_widget_get_preferred_width_for_height(arg0, arg1, lparg2, lparg3); +*/ + { + OS_LOAD_FUNCTION(fp, gtk_widget_get_preferred_width_for_height) + if (fp) { + ((void (CALLING_CONVENTION*)(jintLong, jint, jint *, jint *))fp)(arg0, arg1, lparg2, lparg3); + } + } +fail: + if (arg3 && lparg3) (*env)->ReleaseIntArrayElements(env, arg3, lparg3, 0); + if (arg2 && lparg2) (*env)->ReleaseIntArrayElements(env, arg2, lparg2, 0); + OS_NATIVE_EXIT(env, that, _1gtk_1widget_1get_1preferred_1width_1for_1height_FUNC); +} +#endif + #ifndef NO__1gtk_1widget_1get_1realized JNIEXPORT jboolean JNICALL OS_NATIVE(_1gtk_1widget_1get_1realized) (JNIEnv *env, jclass that, jintLong arg0) @@ -21015,6 +21065,16 @@ JNIEXPORT void JNICALL OS_NATIVE(_1swt_1fixed_1move) } #endif +#ifndef NO__1swt_1fixed_1resize +JNIEXPORT void JNICALL OS_NATIVE(_1swt_1fixed_1resize) + (JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jint arg2, jint arg3) +{ + OS_NATIVE_ENTER(env, that, _1swt_1fixed_1resize_FUNC); + swt_fixed_resize((SwtFixed*)arg0, (GtkWidget*)arg1, arg2, arg3); + OS_NATIVE_EXIT(env, that, _1swt_1fixed_1resize_FUNC); +} +#endif + #ifndef NO__1swt_1fixed_1restack JNIEXPORT void JNICALL OS_NATIVE(_1swt_1fixed_1restack) (JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2, jboolean arg3) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c index 8152b8c7a7..d6189fb0e8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c @@ -539,11 +539,8 @@ static void swt_fixed_size_allocate (GtkWidget *widget, GtkAllocation *allocatio child_allocation.y += allocation->y; } - /* - * Use the requested size if it is set. This is the GTK 2 behavior of - * gtk_widget_get_child_requisition(). - */ - gtk_widget_get_size_request (child, &w, &h); + w = child_data->width; + h = child_data->height; if (w == -1 || h == -1) { gtk_widget_get_preferred_size (child, &requisition, NULL); if (w == -1) w = requisition.width; @@ -573,6 +570,23 @@ void swt_fixed_move (SwtFixed *fixed, GtkWidget *widget, gint x, gint y) { } } +void swt_fixed_resize (SwtFixed *fixed, GtkWidget *widget, gint width, gint height) { + SwtFixedPrivate *priv = fixed->priv; + GList *list; + + list = priv->children; + while (list) { + SwtFixedChild *child_data = list->data; + GtkWidget *child = child_data->widget; + if (child == widget) { + child_data->width = width; + child_data->height = height; + break; + } + list = list->next; + } +} + static void swt_fixed_add (GtkContainer *container, GtkWidget *child) { GtkWidget *widget = GTK_WIDGET (container); SwtFixed *fixed = SWT_FIXED (container); @@ -582,6 +596,7 @@ static void swt_fixed_add (GtkContainer *container, GtkWidget *child) { child_data = g_new (SwtFixedChild, 1); child_data->widget = child; child_data->x = child_data->y = 0; + child_data->width = child_data->height = -1; priv->children = g_list_append (priv->children, child_data); gtk_widget_set_parent (child, widget); diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h index f1b60cd0a0..e31fe11b51 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h @@ -529,6 +529,8 @@ #define gtk_widget_override_color_LIB LIB_GTK #define gtk_widget_override_background_color_LIB LIB_GTK #define gtk_widget_override_font_LIB LIB_GTK +#define gtk_widget_get_preferred_height_for_width_LIB LIB_GTK +#define gtk_widget_get_preferred_width_for_height_LIB LIB_GTK #define gtk_style_context_get_font_LIB LIB_GTK #define gtk_style_context_get_color_LIB LIB_GTK #define gtk_style_context_get_background_color_LIB LIB_GTK @@ -737,6 +739,7 @@ GType swt_fixed_get_type (void) G_GNUC_CONST; void swt_fixed_restack(SwtFixed *fixed, GtkWidget *widget, GtkWidget *sibling, gboolean above); void swt_fixed_move(SwtFixed *fixed, GtkWidget *widget, gint x, gint y); +void swt_fixed_resize(SwtFixed *fixed, GtkWidget *widget, gint width, gint height); #endif diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c index cf200b60b1..736669da93 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c @@ -1338,7 +1338,9 @@ char * OS_nativeFunctionNames[] = { "_1gtk_1widget_1get_1pango_1context", "_1gtk_1widget_1get_1parent", "_1gtk_1widget_1get_1parent_1window", + "_1gtk_1widget_1get_1preferred_1height_1for_1width", "_1gtk_1widget_1get_1preferred_1size", + "_1gtk_1widget_1get_1preferred_1width_1for_1height", "_1gtk_1widget_1get_1realized", "_1gtk_1widget_1get_1sensitive", "_1gtk_1widget_1get_1size_1request", @@ -1550,6 +1552,7 @@ char * OS_nativeFunctionNames[] = { "_1pango_1tab_1array_1set_1tab", "_1swt_1fixed_1get_1type", "_1swt_1fixed_1move", + "_1swt_1fixed_1resize", "_1swt_1fixed_1restack", "_1ubuntu_1menu_1proxy_1get", "g_1main_1context_1wakeup", diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h index 2153d5c936..5ceb219a25 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h @@ -1348,7 +1348,9 @@ typedef enum { _1gtk_1widget_1get_1pango_1context_FUNC, _1gtk_1widget_1get_1parent_FUNC, _1gtk_1widget_1get_1parent_1window_FUNC, + _1gtk_1widget_1get_1preferred_1height_1for_1width_FUNC, _1gtk_1widget_1get_1preferred_1size_FUNC, + _1gtk_1widget_1get_1preferred_1width_1for_1height_FUNC, _1gtk_1widget_1get_1realized_FUNC, _1gtk_1widget_1get_1sensitive_FUNC, _1gtk_1widget_1get_1size_1request_FUNC, @@ -1560,6 +1562,7 @@ typedef enum { _1pango_1tab_1array_1set_1tab_FUNC, _1swt_1fixed_1get_1type_FUNC, _1swt_1fixed_1move_FUNC, + _1swt_1fixed_1resize_FUNC, _1swt_1fixed_1restack_FUNC, _1ubuntu_1menu_1proxy_1get_FUNC, g_1main_1context_1wakeup_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_structs.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_structs.c index 25256f9a26..1fa8f1d9c1 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_structs.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_structs.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. All rights reserved. + * Copyright (c) 2000, 2013 IBM Corporation and others. All rights reserved. * The contents of this file are made available under the terms * of the GNU Lesser General Public License (LGPL) Version 2.1 that * accompanies this distribution (lgpl-v21.txt). The LGPL is also diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java index df440a752f..901d98e0ce 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java @@ -6352,6 +6352,30 @@ public static final void gtk_widget_get_preferred_size(long /*int*/ widget, GtkR lock.unlock(); } } +/** + * @method flags=dynamic + */ +public static final native void _gtk_widget_get_preferred_height_for_width(long /*int*/ widget, int width, int[] minimum_size, int[] natural_size); +public static final void gtk_widget_get_preferred_height_for_width(long /*int*/ widget, int width, int[] minimum_size, int[] natural_size) { + lock.lock(); + try { + _gtk_widget_get_preferred_height_for_width(widget, width, minimum_size, natural_size); + } finally { + lock.unlock(); + } +} +/** + * @method flags=dynamic + */ +public static final native void _gtk_widget_get_preferred_width_for_height(long /*int*/ widget, int height, int[] minimum_size, int[] natural_size); +public static final void gtk_widget_get_preferred_width_for_height(long /*int*/ widget, int height, int[] minimum_size, int[] natural_size) { + lock.lock(); + try { + _gtk_widget_get_preferred_width_for_height(widget, height, minimum_size, natural_size); + } finally { + lock.unlock(); + } +} public static final native long /*int*/ _gtk_cell_renderer_pixbuf_new(); public static final long /*int*/ gtk_cell_renderer_pixbuf_new() { lock.lock(); @@ -16160,4 +16184,17 @@ public static final void swt_fixed_move(long /*int*/ fixed, long /*int*/ widget, lock.unlock(); } } +/** + * @param fixed cast=(SwtFixed*) + * @param widget cast=(GtkWidget*) + */ +public static final native void _swt_fixed_resize(long /*int*/ fixed, long /*int*/ widget, int width, int height); +public static final void swt_fixed_resize(long /*int*/ fixed, long /*int*/ widget, int width, int height) { + lock.lock(); + try { + _swt_fixed_resize(fixed, widget, width, height); + } finally { + lock.unlock(); + } +} } 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 08768703cc..fb70ae8257 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 @@ -1356,7 +1356,13 @@ void reskinChildren (int flags) { void resizeHandle (int width, int height) { super.resizeHandle (width, height); - if (socketHandle != 0) OS.gtk_widget_set_size_request (socketHandle, width, height); + if (socketHandle != 0) { + if (OS.GTK3) { + OS.swt_fixed_resize (handle, socketHandle, width, height); + } else { + OS.gtk_widget_set_size_request (socketHandle, width, height); + } + } } /** diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index f8bf2aa47a..0229d47fe8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -702,7 +702,25 @@ public Point computeSize (int wHint, int hHint, boolean changed) { Point computeNativeSize (long /*int*/ h, int wHint, int hHint, boolean changed) { int width = wHint, height = hHint; - if (wHint == SWT.DEFAULT && hHint == SWT.DEFAULT && !OS.GTK3) { + if (OS.GTK3){ + if (wHint == SWT.DEFAULT && hHint == SWT.DEFAULT) { + GtkRequisition requisition = new GtkRequisition (); + OS.gtk_widget_get_preferred_size (h, requisition, null); + width = requisition.width; + height = requisition.height; + } else if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) { + int [] minimum_size = new int [1]; + if (wHint == SWT.DEFAULT) { + OS.gtk_widget_get_preferred_width_for_height (h, height, minimum_size, null); + width = minimum_size [0]; + } else { + OS.gtk_widget_get_preferred_height_for_width (h, width, minimum_size, null); + height = minimum_size [0]; + } + } + return new Point(width, height); + } + if (wHint == SWT.DEFAULT && hHint == SWT.DEFAULT) { GtkRequisition requisition = new GtkRequisition (); gtk_widget_size_request (h, requisition); width = OS.GTK_WIDGET_REQUISITION_WIDTH (h); @@ -861,30 +879,37 @@ void modifyStyle (long /*int*/ handle, long /*int*/ style) { void moveHandle (int x, int y) { long /*int*/ topHandle = topHandle (); long /*int*/ parentHandle = parent.parentingHandle (); - /* - * Feature in GTK. Calling gtk_fixed_move() to move a child causes - * the whole parent to redraw. This is a performance problem. The - * fix is temporarily mark the parent not visible during the move. - * - * NOTE: Because every widget in SWT has an X window, the new and - * old bounds of the child are correctly redrawn. - * - * NOTE: There is no API in GTK 3 to only set the GTK_VISIBLE bit. - */ - if (!OS.GTK3) { + if (OS.GTK3) { + OS.swt_fixed_move (parentHandle, topHandle, x, y); + } else { + /* + * Feature in GTK. Calling gtk_fixed_move() to move a child causes + * the whole parent to redraw. This is a performance problem. The + * fix is temporarily mark the parent not visible during the move. + * + * NOTE: Because every widget in SWT has an X window, the new and + * old bounds of the child are correctly redrawn. + * + * NOTE: There is no API in GTK 3 to only set the GTK_VISIBLE bit. + */ boolean reset = gtk_widget_get_visible (parentHandle); gtk_widget_set_visible (parentHandle, false); OS.gtk_fixed_move (parentHandle, topHandle, x, y); gtk_widget_set_visible (parentHandle, reset); - } else { - OS.swt_fixed_move (parentHandle, topHandle, x, y); } } void resizeHandle (int width, int height) { long /*int*/ topHandle = topHandle (); - OS.gtk_widget_set_size_request (topHandle, width, height); - if (topHandle != handle) OS.gtk_widget_set_size_request (handle, width, height); + if (OS.GTK3) { + OS.swt_fixed_resize (OS.gtk_widget_get_parent (topHandle), topHandle, width, height); + if (topHandle != handle) { + OS.swt_fixed_resize (OS.gtk_widget_get_parent (handle), handle, width, height); + } + } else { + OS.gtk_widget_set_size_request (topHandle, width, height); + if (topHandle != handle) OS.gtk_widget_set_size_request (handle, width, height); + } } int setBounds (int x, int y, int width, int height, boolean move, boolean resize) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Label.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Label.java index 5bc4d3b8d5..6192bb829c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Label.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Label.java @@ -384,8 +384,14 @@ void releaseWidget () { } void resizeHandle (int width, int height) { - OS.gtk_widget_set_size_request (fixedHandle, width, height); - OS.gtk_widget_set_size_request (frameHandle != 0 ? frameHandle : handle, width, height); + if (OS.GTK3) { + OS.swt_fixed_resize (OS.gtk_widget_get_parent (fixedHandle), fixedHandle, width, height); + long /*int*/ child = frameHandle != 0 ? frameHandle : handle; + OS.swt_fixed_resize (OS.gtk_widget_get_parent (child), child, width, height); + } else { + OS.gtk_widget_set_size_request (fixedHandle, width, height); + OS.gtk_widget_set_size_request (frameHandle != 0 ? frameHandle : handle, width, height); + } } /** diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java index 8955b53b86..d38014710f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java @@ -434,8 +434,16 @@ void releaseChildren (boolean destroy) { } void resizeHandle (int width, int height) { - if (fixedHandle != 0) OS.gtk_widget_set_size_request (fixedHandle, width, height); - OS.gtk_widget_set_size_request (scrolledHandle != 0 ? scrolledHandle : handle, width, height); + if (OS.GTK3) { + if (fixedHandle != 0) { + OS.swt_fixed_resize (OS.gtk_widget_get_parent(fixedHandle), fixedHandle, width, height); + } + long /*int*/ child = scrolledHandle != 0 ? scrolledHandle : handle; + OS.swt_fixed_resize (OS.gtk_widget_get_parent(child), child, width, height); + } else { + if (fixedHandle != 0) OS.gtk_widget_set_size_request (fixedHandle, width, height); + OS.gtk_widget_set_size_request (scrolledHandle != 0 ? scrolledHandle : handle, width, height); + } } void showWidget () { |