Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeo Ufimtsev2018-05-03 18:58:20 +0000
committerLeo Ufimtsev2018-05-03 19:43:41 +0000
commit467296f8e2b8352bd93e9bc7039f9c232e18bee0 (patch)
treed613e3d7eabea4fd75bc4ecfc86aabecec1e2c39
parent00318764ff85d3caa5dcb215a7fcc568e70f47ad (diff)
downloadeclipse.platform.swt-467296f8e2b8352bd93e9bc7039f9c232e18bee0.tar.gz
eclipse.platform.swt-467296f8e2b8352bd93e9bc7039f9c232e18bee0.tar.xz
eclipse.platform.swt-467296f8e2b8352bd93e9bc7039f9c232e18bee0.zip
Bug 515773 – [wayland] Text widget not able to grab focus with
SWT.ON_TOP shell (fixing crash of earlier patch). At the time of the original patch, gdkSeat grab only worked on hidden gdkWindows which were shown with handler, so Ian made gtkWindows invisible before grabbing focus. Having invisible windows leads them to be unrealized and an unrealized window is passed to wayland, which crashes due to a a segfault. In newer gtk3 (3.22) this is no longer the case, seat grabbing works on visible windows, so not hiding windows fixes the gnome crash and doesn't break things. Also I'm making the callback static instead of instance, because otherwise there is a memory leak every time you raise the shell. Tests: - Child eclipse works well, including javadoc and outline. No crashes. - Original bug snippet works well. Bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=515773 Change-Id: Ief9e066bbd488413ffbbe752f2b2c9ce561f532f Signed-off-by: Leo Ufimtsev <lufimtse@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java13
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug515773_GrabShellON_TOP.java113
2 files changed, 121 insertions, 5 deletions
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 c87befb12c..636f30cc7b 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
@@ -131,6 +131,8 @@ public class Shell extends Decorations {
static final int MAXIMUM_TRIM = 128;
static final int BORDER = 3;
+ static Callback gdkSeatGrabCallback; // Wayland only.
+
/**
* Constructs a new instance of this class. This is equivalent
* to calling <code>Shell((Display) null)</code>.
@@ -592,10 +594,9 @@ void bringToTop (boolean force) {
}
} else {
if (GTK.GTK_VERSION >= OS.VERSION(3, 20, 0)) {
- if(GTK.gtk_widget_get_visible(shellHandle)) {
- GTK.gtk_widget_hide(shellHandle);
+ if (gdkSeatGrabCallback == null) {
+ gdkSeatGrabCallback = new Callback(Shell.class, "GdkSeatGrabPrepareFunc", 3); //$NON-NLS-1$
}
- Callback gdkSeatGrabCallback = new Callback(this, "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);
@@ -2872,8 +2873,10 @@ Point getWindowOrigin () {
return super.getWindowOrigin( );
}
-long /*int*/ GdkSeatGrabPrepareFunc (long /*int*/ seat, long /*int*/ window, long /*int*/ data) {
- GTK.gtk_widget_show(data);
+static long /*int*/ GdkSeatGrabPrepareFunc (long /*int*/ gdkSeat, long /*int*/ gdkWindow, long /*int*/ userData_shellHandle) {
+ if (userData_shellHandle != 0) {
+ GTK.gtk_widget_show(userData_shellHandle);
+ }
return 0;
}
}
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug515773_GrabShellON_TOP.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug515773_GrabShellON_TOP.java
new file mode 100644
index 0000000000..e1ba811e50
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug515773_GrabShellON_TOP.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Red Hat 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
+ * available at http://www.gnu.org/licenses/lgpl.html. If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ *
+ * Contributors:
+ * Red Hat - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.tests.gtk.snippets;
+
+import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/*
+ * Title: Shells that are ON_TOP are not getting input focus on Wayland.
+ * How to run: Run snippet, click on button. Try to type stuff.
+ * Expected results: Typing stuff should be typed in the text field. On Wayland this didn't used to work.
+ * GTK Version(s): 3.22 with wayland.
+ */
+public class Bug515773_GrabShellON_TOP {
+
+public static void main (String [] args) {
+ Display display = new Display ();
+ final Shell shell = new Shell (display);
+ shell.setText("Shell");
+ FillLayout fillLayout = new FillLayout();
+ fillLayout.marginWidth = 10;
+ fillLayout.marginHeight = 10;
+ shell.setLayout(fillLayout);
+
+ Button open = new Button (shell, SWT.PUSH);
+ open.setText ("Prompt for a String");
+ open.addSelectionListener(widgetSelectedAdapter(e -> {
+ final Shell dialog = new Shell (shell, SWT.TOOL | SWT.ON_TOP | SWT.RESIZE);
+ dialog.setText("Dialog Shell");
+ FormLayout formLayout = new FormLayout ();
+ formLayout.marginWidth = 10;
+ formLayout.marginHeight = 10;
+ formLayout.spacing = 10;
+ dialog.setLayout (formLayout);
+ dialog.setLocation(26, 52);
+
+ Label label = new Label (dialog, SWT.NONE);
+ label.setText ("Type a String:");
+ FormData data = new FormData ();
+ label.setLayoutData (data);
+
+ Button cancel = new Button (dialog, SWT.PUSH);
+ cancel.setText ("Cancel");
+ data = new FormData ();
+ data.width = 60;
+ data.right = new FormAttachment (100, 0);
+ data.bottom = new FormAttachment (100, 0);
+ cancel.setLayoutData (data);
+ cancel.addSelectionListener (widgetSelectedAdapter(event -> {
+ System.out.println("User cancelled dialog");
+ dialog.close ();
+ }));
+
+ final Text text = new Text(dialog, SWT.SINGLE | SWT.BORDER | SWT.SEARCH
+ | SWT.ICON_CANCEL);
+
+
+ data = new FormData ();
+ data.width = 200;
+ data.left = new FormAttachment (label, 0, SWT.DEFAULT);
+ data.right = new FormAttachment (100, 0);
+ data.top = new FormAttachment (label, 0, SWT.CENTER);
+ data.bottom = new FormAttachment (cancel, 0, SWT.DEFAULT);
+ text.setLayoutData (data);
+
+ Button ok = new Button (dialog, SWT.PUSH);
+ ok.setText ("OK");
+ data = new FormData ();
+ data.width = 60;
+ data.right = new FormAttachment (cancel, 0, SWT.DEFAULT);
+ data.bottom = new FormAttachment (100, 0);
+ ok.setLayoutData (data);
+ ok.addSelectionListener (widgetSelectedAdapter(event -> {
+ dialog.close ();
+ }));
+
+ dialog.setDefaultButton (ok);
+ dialog.pack ();
+ text.setFocus();
+ dialog.open ();
+ System.out.println("dialog at "+dialog.getBounds());
+ }));
+ shell.pack ();
+ shell.open ();
+
+ while (!shell.isDisposed ()) {
+ if (!display.readAndDispatch ()) display.sleep ();
+ }
+ display.dispose ();
+}
+}

Back to the top