Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c25
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java12
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java46
5 files changed, 85 insertions, 0 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 428d448027..7cddab1bdb 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
@@ -13328,6 +13328,31 @@ JNIEXPORT jintLong JNICALL GTK_NATIVE(_1gtk_1widget_1get_1parent_1window)
}
#endif
+#ifndef NO__1gtk_1widget_1get_1preferred_1height
+JNIEXPORT void JNICALL GTK_NATIVE(_1gtk_1widget_1get_1preferred_1height)
+ (JNIEnv *env, jclass that, jintLong arg0, jintArray arg1, jintArray arg2)
+{
+ jint *lparg1=NULL;
+ jint *lparg2=NULL;
+ GTK_NATIVE_ENTER(env, that, _1gtk_1widget_1get_1preferred_1height_FUNC);
+ if (arg1) if ((lparg1 = (*env)->GetIntArrayElements(env, arg1, NULL)) == NULL) goto fail;
+ if (arg2) if ((lparg2 = (*env)->GetIntArrayElements(env, arg2, NULL)) == NULL) goto fail;
+/*
+ gtk_widget_get_preferred_height(arg0, lparg1, lparg2);
+*/
+ {
+ GTK_LOAD_FUNCTION(fp, gtk_widget_get_preferred_height)
+ if (fp) {
+ ((void (CALLING_CONVENTION*)(jintLong, jint *, jint *))fp)(arg0, lparg1, lparg2);
+ }
+ }
+fail:
+ if (arg2 && lparg2) (*env)->ReleaseIntArrayElements(env, arg2, lparg2, 0);
+ if (arg1 && lparg1) (*env)->ReleaseIntArrayElements(env, arg1, lparg1, 0);
+ GTK_NATIVE_EXIT(env, that, _1gtk_1widget_1get_1preferred_1height_FUNC);
+}
+#endif
+
#ifndef NO__1gtk_1widget_1get_1preferred_1height_1for_1width
JNIEXPORT void JNICALL GTK_NATIVE(_1gtk_1widget_1get_1preferred_1height_1for_1width)
(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jintArray arg2, jintArray arg3)
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 ddb326eacf..43acdb330e 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
@@ -1068,6 +1068,7 @@ char * GTK_nativeFunctionNames[] = {
"_1gtk_1widget_1get_1pango_1context",
"_1gtk_1widget_1get_1parent",
"_1gtk_1widget_1get_1parent_1window",
+ "_1gtk_1widget_1get_1preferred_1height",
"_1gtk_1widget_1get_1preferred_1height_1for_1width",
"_1gtk_1widget_1get_1preferred_1size",
"_1gtk_1widget_1get_1preferred_1width_1for_1height",
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 f8fd88f489..2038eea393 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
@@ -1066,6 +1066,7 @@ typedef enum {
_1gtk_1widget_1get_1pango_1context_FUNC,
_1gtk_1widget_1get_1parent_FUNC,
_1gtk_1widget_1get_1parent_1window_FUNC,
+ _1gtk_1widget_1get_1preferred_1height_FUNC,
_1gtk_1widget_1get_1preferred_1height_1for_1width_FUNC,
_1gtk_1widget_1get_1preferred_1size_FUNC,
_1gtk_1widget_1get_1preferred_1width_1for_1height_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java
index a343cfef7f..a324248031 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java
@@ -1143,6 +1143,18 @@ public class GTK extends OS {
/**
* @method flags=dynamic
*/
+ public static final native void _gtk_widget_get_preferred_height(long /*int*/ widget, int[] minimum_size, int[] natural_size);
+ public static final void gtk_widget_get_preferred_height(long /*int*/ widget, int[] minimum_size, int[] natural_size) {
+ lock.lock();
+ try {
+ _gtk_widget_get_preferred_height(widget, 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();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
index d6ddbbcd35..6620fbc796 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
@@ -45,6 +45,7 @@ public class Menu extends Widget {
Decorations parent;
long /*int*/ imItem, imSeparator, imHandle;
ImageList imageList;
+ int poppedUpCount;
/**
* Constructs a new instance of this class given its parent,
@@ -278,9 +279,11 @@ void _setVisible (boolean visible) {
}
}
}
+ verifyMenuPosition(getItemCount());
GTK.gtk_menu_popup_at_pointer (handle, eventPtr);
GDK.gdk_event_free (eventPtr);
}
+ poppedUpCount = getItemCount();
} else {
sendEvent (SWT.Hide);
}
@@ -1125,6 +1128,49 @@ void setOrientation (boolean create) {
}
/**
+ * Feature in GTK3 on X11: context menus in SWT are populated
+ * dynamically, sometimes asynchronously outside of SWT
+ * (i.e. in Platform UI). This means that items are added and
+ * removed just before the menu is shown. This method of
+ * changing the menu content can sometimes cause sizing issues
+ * internally in GTK, specifically with the height of the
+ * toplevel GdkWindow. <p>
+ *
+ * The fix is to cache the number of items popped up previously,
+ * and if the number of items in the current menu (to be popped up)
+ * is different, then:<ul>
+ * <li>get the preferred height of the menu</li>
+ * <li>set the toplevel GdkWindow to that height</li></ul>
+ *
+ * @param itemCount the current number of items in the menu, just
+ * before it's about to be shown/popped-up
+ */
+void verifyMenuPosition (int itemCount) {
+ if (GTK.GTK3 && OS.isX11()) {
+ if (itemCount != poppedUpCount && poppedUpCount != 0) {
+ int [] naturalHeight = new int [1];
+ /*
+ * We need to "show" the menu before fetching the preferred height.
+ * Note, this does not actually pop-up the menu.
+ */
+ GTK.gtk_widget_show(handle);
+ /*
+ * Menus are height-for-width only: use gtk_widget_get_preferred_height()
+ * instead of gtk_widget_get_preferred_size().
+ */
+ GTK.gtk_widget_get_preferred_height(handle, null, naturalHeight);
+ if (naturalHeight[0] > 0) {
+ long /*int*/ topLevelWidget = GTK.gtk_widget_get_toplevel(handle);
+ long /*int*/ topLevelWindow = GTK.gtk_widget_get_window(topLevelWidget);
+ int width = GDK.gdk_window_get_width(topLevelWindow);
+ GDK.gdk_window_resize(topLevelWindow, width, naturalHeight[0]);
+ }
+ }
+ }
+ return;
+}
+
+/**
* Marks the receiver as visible if the argument is <code>true</code>,
* and marks it invisible otherwise.
* <p>

Back to the top