Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXi Yan2018-11-08 17:08:55 +0000
committerXi Yan2018-11-13 16:49:09 +0000
commit9f9824044a4a853020c6186a2c02ef0245e1564d (patch)
tree5d7a147d3e8264adf6da6d58d200b3a51cbdf365
parent3b7eb3f193cc83cb2504be23c625c6c994ba7cae (diff)
downloadeclipse.platform.swt-9f9824044a4a853020c6186a2c02ef0245e1564d.tar.gz
eclipse.platform.swt-9f9824044a4a853020c6186a2c02ef0245e1564d.tar.xz
eclipse.platform.swt-9f9824044a4a853020c6186a2c02ef0245e1564d.zip
Bug 540166 - [GTK3][Wayland] Non-closable popup when using Ctrl+1
When a GTK_WINDOW_POPUP is attached to another GTK_WINDOW_POPUP, we require the child POPUP's transient parent to be a GTK_WINDOW_TOPLEVEL surface to position the child correctly (see Bug 530138). Setting it's transient parent to its logical parent popup causes issues with auto-complete, incorrect position, etc.. However, when its parent popup is destroyed, the child popup sometimes does not get destroyed and is stuck until its transient top level parent gets destroyed. This patch implements a similar gtk_window_set_destroy_with_parent with its *logical* popup parent by connecting a "destroy" signal. Also fixes a small issue with auto-completion rendered with offset. Tested with auto-completion, Ctrl+1 popup on Wayland Change-Id: Idfb59271180ca114d84d84ed3eed856020a1c789 Signed-off-by: Xi Yan <xixiyan@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c10
-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.java13
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java39
6 files changed, 60 insertions, 5 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 4c51edc571..1d4fbfedca 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
@@ -12412,6 +12412,16 @@ JNIEXPORT void JNICALL GTK_NATIVE(_1gtk_1window_1resize)
}
#endif
+#ifndef NO__1gtk_1window_1set_1attached_1to
+JNIEXPORT void JNICALL GTK_NATIVE(_1gtk_1window_1set_1attached_1to)
+ (JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+ GTK_NATIVE_ENTER(env, that, _1gtk_1window_1set_1attached_1to_FUNC);
+ gtk_window_set_attached_to((GtkWindow *)arg0, (GtkWidget *)arg1);
+ GTK_NATIVE_EXIT(env, that, _1gtk_1window_1set_1attached_1to_FUNC);
+}
+#endif
+
#ifndef NO__1gtk_1window_1set_1decorated
JNIEXPORT void JNICALL GTK_NATIVE(_1gtk_1window_1set_1decorated)
(JNIEnv *env, jclass that, jintLong arg0, jboolean arg1)
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 934d73a324..7476eb450c 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
@@ -1107,6 +1107,7 @@ char * GTK_nativeFunctionNames[] = {
"_1gtk_1window_1new",
"_1gtk_1window_1remove_1accel_1group",
"_1gtk_1window_1resize",
+ "_1gtk_1window_1set_1attached_1to",
"_1gtk_1window_1set_1decorated",
"_1gtk_1window_1set_1default",
"_1gtk_1window_1set_1destroy_1with_1parent",
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 ac83cad7d1..70e255b2d0 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
@@ -1105,6 +1105,7 @@ typedef enum {
_1gtk_1window_1new_FUNC,
_1gtk_1window_1remove_1accel_1group_FUNC,
_1gtk_1window_1resize_FUNC,
+ _1gtk_1window_1set_1attached_1to_FUNC,
_1gtk_1window_1set_1decorated_FUNC,
_1gtk_1window_1set_1default_FUNC,
_1gtk_1window_1set_1destroy_1with_1parent_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 3549909025..9fda0c823e 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
@@ -9088,6 +9088,19 @@ public class GTK extends OS {
}
/**
* @param window cast=(GtkWindow *)
+ * @param attach_widget cast=(GtkWidget *)
+ */
+ public static final native void _gtk_window_set_attached_to(long /*int*/ window, long /*int*/ attach_widget);
+ public static final void gtk_window_set_attached_to(long /*int*/ window, long /*int*/ attach_widget) {
+ lock.lock();
+ try {
+ _gtk_window_set_attached_to(window, attach_widget);
+ } finally {
+ lock.unlock();
+ }
+ }
+ /**
+ * @param window cast=(GtkWindow *)
* @param widget cast=(GtkWidget *)
*/
public static final native void _gtk_window_set_default(long /*int*/ window, long /*int*/ widget);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
index afb90f30bd..e4ffe943a0 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
@@ -284,6 +284,7 @@ public class OS extends C {
public static final byte[] copy_clipboard = ascii("copy-clipboard");
public static final byte[] cut_clipboard = ascii("cut-clipboard");
public static final byte[] create_menu_proxy = ascii("create-menu-proxy");
+ public static final byte[] destroy = ascii("destroy");
public static final byte[] delete_event = ascii("delete-event");
public static final byte[] delete_from_cursor = ascii("delete-from-cursor");
public static final byte[] day_selected = ascii("day-selected");
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 d9bf7100a8..a888dc9c86 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
@@ -134,7 +134,7 @@ public class Shell extends Decorations {
static final int MAXIMUM_TRIM = 128;
static final int BORDER = 3;
- static Callback gdkSeatGrabCallback; // Wayland only.
+ static Callback gdkSeatGrabCallback, parentDestroyedCallback; // Wayland only.
/**
* Constructs a new instance of this class. This is equivalent
@@ -704,16 +704,38 @@ void createHandle (int index) {
if (shellHandle == 0) error (SWT.ERROR_NO_HANDLES);
if (parent != null) {
/*
- * Bug 530138: On Wayland, GTK_WINDOW_POPUP attached to a GTK_WINDOW_POPUP parent
+ * Problems with GTK_WINDOW_POPUP attached to another GTK_WINDOW_POPUP parent
+ * 1) Bug 530138: GTK_WINDOW_POPUP attached to a GTK_WINDOW_POPUP parent
* gets positioned relatively to the GTK_WINDOW_POPUP. We want to position it
- * relatively to the GTK_WINDOW_TOPLEVEL surface.
+ * relatively to the GTK_WINDOW_TOPLEVEL surface. Fix is to set the child popup's transient
+ * parent to the top level window.
+ *
+ * 2) Bug 540166: When a parent popup is destroyed, the child popup sometimes does not
+ * get destroyed and is stuck until its transient top level parent gets destroyed.
+ * Fix is to implement a similar gtk_window_set_destroy_with_parent with its *logical*
+ * parent by connecting a "destroy" signal.
*/
if (!OS.isX11()) {
Composite topLevelParent = parent;
while (topLevelParent != null && (topLevelParent.style & SWT.ON_TOP) != 0) {
topLevelParent = parent.getParent();
}
- GTK.gtk_window_set_transient_for(shellHandle, topLevelParent.topHandle());
+ // transient parent must be the a toplevel window to position correctly
+ if (topLevelParent != null) {
+ GTK.gtk_window_set_transient_for(shellHandle, topLevelParent.topHandle());
+ } else {
+ GTK.gtk_window_set_transient_for(shellHandle, parent.topHandle());
+ }
+ // this marks the logical parent
+ GTK.gtk_window_set_attached_to (shellHandle, parent.topHandle());
+ // implements the gtk_window_set_destroy_with_parent for the *logical* parent
+ if (parent != topLevelParent && isMappedToPopup()) {
+ if (parentDestroyedCallback == null) {
+ parentDestroyedCallback = new Callback(Shell.class, "ParentDestroyedCallbackFunc", 2);
+ }
+ long /*int*/ parentDestroyedFunc = parentDestroyedCallback.getAddress();
+ OS.g_signal_connect(parent.topHandle(), OS.destroy, parentDestroyedFunc, shellHandle);
+ }
} else {
GTK.gtk_window_set_transient_for (shellHandle, parent.topHandle ());
}
@@ -1018,7 +1040,7 @@ void forceResize (int width, int height) {
int [] dest_x = new int[1];
int [] dest_y = new int[1];
GTK.gtk_widget_translate_coordinates(vboxHandle, shellHandle, 0, 0, dest_x, dest_y);
- if (dest_x[0] != -1 && dest_y[0] != -1) {
+ if (dest_x[0] != -1 && dest_y[0] != -1 && !isMappedToPopup()) {
allocation.x += dest_x[0];
allocation.y += dest_y[0];
}
@@ -2918,6 +2940,13 @@ Point getWindowOrigin () {
return super.getWindowOrigin( );
}
+static long /*int*/ ParentDestroyedCallbackFunc (long /*int*/ parent, long /*int*/ child) {
+ if (child != 0 && GTK.GTK_IS_WINDOW(child)) {
+ GTK.gtk_widget_destroy(child);
+ }
+ return 0;
+}
+
static long /*int*/ GdkSeatGrabPrepareFunc (long /*int*/ gdkSeat, long /*int*/ gdkWindow, long /*int*/ userData_shellHandle) {
if (userData_shellHandle != 0) {
GTK.gtk_widget_show(userData_shellHandle);

Back to the top