Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Williams2018-02-28 21:10:48 +0000
committerEric Williams2018-03-01 15:05:58 +0000
commit272bf0d8ebce8f12e9bb0de2c389d3a18d319afb (patch)
tree80cd8d78c74581898c96273142bed3484ab0203a /bundles/org.eclipse.swt/Eclipse SWT PI/gtk
parent64ef68738d8d1ef74937fc86faea774baa48287d (diff)
downloadeclipse.platform.swt-272bf0d8ebce8f12e9bb0de2c389d3a18d319afb.tar.gz
eclipse.platform.swt-272bf0d8ebce8f12e9bb0de2c389d3a18d319afb.tar.xz
eclipse.platform.swt-272bf0d8ebce8f12e9bb0de2c389d3a18d319afb.zip
Bug 431423: [GTK3] Context menu should appear by pointer when invoked
via mouse Some context menus are positioned incorrectly when the size (number of items) of the menu changes between clicks. The cause of this bug is due to the way SWT populates its menus: often it is done asynchronously outside of SWT based on an SWT.Show listener. The result is that the menu items are added/removed just before showing, and GTK sometimes doesn't have enough time to properly adjust the size of the menu internally. Specifically, the GdkWindow of the toplevel widget (GtkWindow) for the menu lags in height. Since GTK thinks the menu is taller/shorter than it is, the menu is positioned at the wrong y-coordinate. The fix is to check if the number of menu items has changed from one pop-up to the next. If so, calculate the preferred height of the menu and resize the GdkWindow of the menu's toplevel GtkWindow to reflect this change. This way the internal sizing calculations in GTK will be accurate and the menu will be positioned correctly. The bug is fixed on GTK3.22 with X11 only, as this uses the new GTK3.22 GtkMenu API. Older GTK3 versions use the outdated GtkMenu API and fixing these cases would not be worth the effort. Wayland is not affected by this bug. Reliable steps to reproduce the issue can be found here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=431423#c19 Tested JFace/SWT menu snippets, AllNonBrowser JUnit tests, and ControlExample on GTK3.22 with X11. Change-Id: I392983438cc32b9455c53cc464626294f3ec72f9 Signed-off-by: Eric Williams <ericwill@redhat.com>
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT PI/gtk')
-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
4 files changed, 39 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();

Back to the top