Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXi Yan2018-11-15 19:48:38 +0000
committerXi Yan2018-11-26 14:38:52 +0000
commit4f1dc4d293b947f57c46577c047c26655532a383 (patch)
treeef278b2a1ae70419b53bab1ec02de40cfc6c341e
parent6a1ac083ec74438453fbf8f14fcbaee4db59be2f (diff)
downloadeclipse.platform.swt-4f1dc4d293b947f57c46577c047c26655532a383.tar.gz
eclipse.platform.swt-4f1dc4d293b947f57c46577c047c26655532a383.tar.xz
eclipse.platform.swt-4f1dc4d293b947f57c46577c047c26655532a383.zip
Bug 541185 - [Wayland] Help popup close after a click
1) Wayland sends an extra focus out event when clicking into the popup after grabbing keyboard focus, which causes popup to be closed. Workaround is to ignore this extra focus out event to fix the issue with javadoc close after a click. 2) Current workaround that hides shell before grabbing focus is not necessary for normal popups without a child. Deal with the case a popup has a popup child separately in bringToTop(). This patch fixes the issue with clicking into Javadoc links, and highlighting text in Javadoc popups. However, there is still some remaining issues (perhaps unrelated) with auto-completion: use Tab to switch focus to the completion details page, clicking works but highlighting the text closes the popup. (but this issue doesn't happen if we use mouse to switch focus to completion details page) Change-Id: Ic095b64c2eaafdeeca65b6e61937c7d31256c97f Signed-off-by: Xi Yan <xixiyan@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java35
2 files changed, 26 insertions, 11 deletions
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 8b2f346c76..a71af47b72 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
@@ -89,6 +89,8 @@ public class Composite extends Scrollable {
static final String NO_INPUT_METHOD = "org.eclipse.swt.internal.gtk.noInputMethod"; //$NON-NLS-1$
+ boolean hasPopupChild; // Wayland only, see Shell#bringToTop()
+
Composite () {
/* Do nothing */
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
index b239ee4c6a..7b82b91916 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
@@ -129,6 +129,7 @@ public class Shell extends Decorations {
Control lastActive;
ToolTip [] toolTips;
boolean ignoreFocusOut, ignoreFocusIn;
+ boolean ignoreFocusOutAfterGrab;
Region originalRegion;
static final int MAXIMUM_TRIM = 128;
@@ -594,19 +595,30 @@ void bringToTop (boolean force) {
} else {
if (GTK.GTK_VERSION >= OS.VERSION(3, 20, 0)) {
GTK.gtk_grab_add(shellHandle);
+ long /*int*/ seat = GDK.gdk_display_get_default_seat(GDK.gdk_window_get_display(window));
/*
- * On Wayland, calling gdk_seat_grab on visible window causes caret to get stuck in Eclipse
- * after closing Javadoc/completion popup. Workaround is to hide the immediate popup mapped
- * to a top level window before grabbing, and show it using gdkSeatGrabPrepareFunc callback.
+ * NOTE: Using gdk_seat_grab to get the keyboard focus needs to be handled differently
+ * for cases with a single popup, and for cases with multiple popup
+ * 1) For normal popups without a child popup (i.e. F2 Javadoc), showing GdkWindow and
+ * grabbing focus does the job
+ * 2) For popups with a child popup attached to it (i.e. auto-completion), using (1)
+ * makes pressing Tab close the popup instead of changing focus.
+ * Current best workaround is to hide the immediate popup mapped to a top level window
+ * before grabbing, and show it using gdkSeatGrabPrepareFunc callback.
*/
- if (gdkSeatGrabCallback == null) {
- gdkSeatGrabCallback = new Callback(Shell.class, "GdkSeatGrabPrepareFunc", 3); //$NON-NLS-1$
+ if (!hasPopupChild) {
+ GDK.gdk_window_show(window);
+ GDK.gdk_seat_grab(seat, window, GDK.GDK_SEAT_CAPABILITY_KEYBOARD, true, 0, 0, 0, 0);
+ } else {
+ if (gdkSeatGrabCallback == null) {
+ gdkSeatGrabCallback = new Callback(Shell.class, "GdkSeatGrabPrepareFunc", 3); //$NON-NLS-1$
+ }
+ long /*int*/ gdkSeatGrabPrepareFunc = gdkSeatGrabCallback.getAddress();
+ if (gdkSeatGrabPrepareFunc == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+ if (GTK.gtk_widget_get_visible(shellHandle) && !isMappedToPopup()) GTK.gtk_widget_hide(shellHandle);
+ GDK.gdk_seat_grab(seat, window, GDK.GDK_SEAT_CAPABILITY_KEYBOARD, true, 0, 0, gdkSeatGrabPrepareFunc, shellHandle);
}
- long /*int*/ gdkSeatGrabPrepareFunc = gdkSeatGrabCallback.getAddress();
- if (gdkSeatGrabPrepareFunc == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
- long /*int*/ seat = GDK.gdk_display_get_default_seat(GDK.gdk_window_get_display(window));
- if (GTK.gtk_widget_get_visible(shellHandle) && !isMappedToPopup()) GTK.gtk_widget_hide(shellHandle);
- GDK.gdk_seat_grab(seat, window, GDK.GDK_SEAT_CAPABILITY_KEYBOARD, true, 0, 0, gdkSeatGrabPrepareFunc, shellHandle);
+ ignoreFocusOutAfterGrab = true;
}
}
} else {
@@ -740,6 +752,7 @@ void createHandle (int index) {
}
long /*int*/ parentDestroyedFunc = parentDestroyedCallback.getAddress();
OS.g_signal_connect(parent.topHandle(), OS.destroy, parentDestroyedFunc, shellHandle);
+ parent.hasPopupChild = true;
}
} else {
GTK.gtk_window_set_transient_for (shellHandle, parent.topHandle ());
@@ -1476,7 +1489,7 @@ long /*int*/ gtk_focus_out_event (long /*int*/ widget, long /*int*/ event) {
return super.gtk_focus_out_event (widget, event);
}
Display display = this.display;
- if (!ignoreFocusOut) {
+ if (!ignoreFocusOut && !ignoreFocusOutAfterGrab) {
sendEvent (SWT.Deactivate);
setActiveControl (null);
}

Back to the top