Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXi Yan2018-08-09 14:19:10 +0000
committerEric Williams2018-08-13 14:19:42 +0000
commit26b042e525d770ec2bb9884d4d12f3a6e98d6210 (patch)
tree022e219dcfb5697cf9b0d21322874694f59758d5
parentb0b855a69bd088c5c0d1188dab9d6024daba112f (diff)
downloadeclipse.platform.swt-26b042e525d770ec2bb9884d4d12f3a6e98d6210.tar.gz
eclipse.platform.swt-26b042e525d770ec2bb9884d4d12f3a6e98d6210.tar.xz
eclipse.platform.swt-26b042e525d770ec2bb9884d4d12f3a6e98d6210.zip
Bug 534554 - [Wayland] Javadoc doesn't dissapear via Esc until you
clicked into it Added constants for GdkSeatCapabilities. Passed GDK_SEAT_CAPABILITY_KEYBOARD to gdk_seat_grab instead of 1 to grab keyboard focus instead of pointer focus. Implemented isMappedToPopup to check if a shell's parent is a popup. Note: Calling gdk_seat_grab on visible window causes caret to get stuck in Eclipse after closing Javadoc using only gdk_seat_ungrab. The fix is to hide GtkWindow before grabbing. GtkWindow should only be hidden for a popup window whose parent is a top most window to prevent gdk warnings and shells not showing. Tested with child Eclipse on Wayland. Pressing F2 makes Javadoc popup, pressing UP/DOWN arrow scrolls, pressing ESC closes Javadoc. Completion popup works with tab. Snippet with bug 515773 works as before. Change-Id: I2a6cca4062379c2b52ca93ec1c8bccfab9e1aebb Signed-off-by: Xi Yan <xixiyan@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java8
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java34
2 files changed, 34 insertions, 8 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java
index 0313ced176..2fca22577f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java
@@ -209,6 +209,14 @@ public class GDK extends OS {
public static final int GDK_SB_H_DOUBLE_ARROW = 0x6c;
public static final int GDK_SB_UP_ARROW = 0x72;
public static final int GDK_SB_V_DOUBLE_ARROW = 0x74;
+ public static final int GDK_SEAT_CAPABILITY_NONE = 0;
+ public static final int GDK_SEAT_CAPABILITY_POINTER = 1 << 0;
+ public static final int GDK_SEAT_CAPABILITY_TOUCH = 1 << 1;
+ public static final int GDK_SEAT_CAPABILITY_TABLET_STYLUS = 1 << 2;
+ public static final int GDK_SEAT_CAPABILITY_KEYBOARD = 1 << 3;
+ public static final int GDK_SEAT_CAPABILITY_TABLET_PAD = 1 << 4;
+ public static final int GDK_SEAT_CAPABILITY_ALL_POINTING = GDK_SEAT_CAPABILITY_POINTER | GDK_SEAT_CAPABILITY_TOUCH | GDK_SEAT_CAPABILITY_TABLET_STYLUS;
+ public static final int GDK_SEAT_CAPABILITY_ALL = GDK_SEAT_CAPABILITY_ALL_POINTING | GDK_SEAT_CAPABILITY_KEYBOARD;
public static final int GDK_SCROLL_UP = 0;
public static final int GDK_SCROLL_DOWN = 1;
public static final int GDK_SCROLL_LEFT = 2;
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 0d37faccc4..23568edbae 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
@@ -573,7 +573,7 @@ void bringToTop (boolean force) {
* Feature in GTK. When the shell is an override redirect
* window, gdk_window_focus() does not give focus to the
* window. The fix is to use XSetInputFocus() to force
- * the focus, or gtk_grab_add() for Wayland.
+ * the focus, or gtk_grab_add() for GTK > 3.20.
*/
long /*int*/ window = gtk_widget_get_window (shellHandle);
if ((xFocus || (style & SWT.ON_TOP) != 0)) {
@@ -597,14 +597,20 @@ void bringToTop (boolean force) {
}
} else {
if (GTK.GTK_VERSION >= OS.VERSION(3, 20, 0)) {
+ GTK.gtk_grab_add(shellHandle);
+ /*
+ * 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.
+ */
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);
- GTK.gtk_grab_add(shellHandle);
long /*int*/ seat = GDK.gdk_display_get_default_seat(GDK.gdk_window_get_display(window));
- GDK.gdk_seat_grab(seat, window, 1, true, 0, 0, gdkSeatGrabPrepareFunc, shellHandle);
+ 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);
}
}
} else {
@@ -945,6 +951,15 @@ public boolean isVisible () {
return getVisible ();
}
+/**
+ * Determines whether a Shell's parent is a popup window. See bug 534554.
+ *
+ * @return true if the parent of this Shell has style SWT.ON_TOP, false otherwise.
+ */
+boolean isMappedToPopup () {
+ return parent != null && (parent.style & SWT.ON_TOP) != 0;
+}
+
@Override
void register () {
super.register ();
@@ -1326,8 +1341,9 @@ long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event) {
*/
if (!OS.isX11() && GTK.GTK_VERSION >= OS.VERSION(3, 20, 0)) {
if ((style & SWT.ON_TOP) != 0 && (style & SWT.NO_FOCUS) == 0) {
+ long /*int*/ seat = GDK.gdk_event_get_seat(event);
+ GDK.gdk_seat_ungrab(seat);
GTK.gtk_grab_remove(shellHandle);
- GDK.gdk_seat_ungrab(GDK.gdk_event_get_seat(event));
GTK.gtk_widget_hide(shellHandle);
}
}
@@ -2549,9 +2565,10 @@ public void setVisible (boolean visible) {
// the hidden widget and can never be returned.
if (!OS.isX11() && GTK.GTK_VERSION >= OS.VERSION(3, 20, 0)) {
if ((style & SWT.ON_TOP) != 0 && (style & SWT.NO_FOCUS) == 0) {
+ long /*int*/ window = gtk_widget_get_window (shellHandle);
+ long /*int*/ seat = GDK.gdk_display_get_default_seat(GDK.gdk_window_get_display(window));
+ GDK.gdk_seat_ungrab(seat);
GTK.gtk_grab_remove(shellHandle);
- GDK.gdk_seat_ungrab(GDK.gdk_display_get_default_seat(
- GDK.gdk_window_get_display(GTK.gtk_widget_get_window(shellHandle))));
}
}
GTK.gtk_widget_hide (shellHandle);
@@ -2799,9 +2816,10 @@ public void dispose () {
fixActiveShell ();
if (!OS.isX11() && GTK.GTK_VERSION >= OS.VERSION(3, 20, 0)) {
if ((style & SWT.ON_TOP) != 0 && (style & SWT.NO_FOCUS) == 0) {
+ long /*int*/ window = gtk_widget_get_window (shellHandle);
+ long /*int*/ seat = GDK.gdk_display_get_default_seat(GDK.gdk_window_get_display(window));
+ GDK.gdk_seat_ungrab(seat);
GTK.gtk_grab_remove(shellHandle);
- GDK.gdk_seat_ungrab(GDK.gdk_display_get_default_seat(
- GDK.gdk_window_get_display(GTK.gtk_widget_get_window(shellHandle))));
}
}
GTK.gtk_widget_hide (shellHandle);

Back to the top