Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeo Ufimtsev2015-05-20 16:09:43 -0400
committerLeo Ufimtsev2015-08-07 11:21:23 -0400
commit4fde7cedde999951b9699d8958f188e6cf10d51a (patch)
treeaaadb48620b431839e423aea754ec5f0c62ee3e9
parentd6ef85197d68f95f9257978f831a2bd2d6df2061 (diff)
downloadeclipse.platform.swt-4fde7cedde999951b9699d8958f188e6cf10d51a.tar.gz
eclipse.platform.swt-4fde7cedde999951b9699d8958f188e6cf10d51a.tar.xz
eclipse.platform.swt-4fde7cedde999951b9699d8958f188e6cf10d51a.zip
Bug 457476 - [GTK3] DND issue with overlapping widgets w/ absolute
positioning. Fixed *_forall(..) traversal of child widgets in swtFixed. Incorrect direction of the traversal caused things like DnD Drop & DnD Motion to find the incorrect widget as destination in the case of overlapping widgets with absolute positioning (bottom of stack instead of top). This fix has a wide reach. If you notice issues with overlapping widgets, this may affect it's behaviour. This may also affect layout of internals of a widget, if you observe odd behaviour (e.g layout is in inverse of what you expect), please re-open this bug. Tests carried out: (Gtk2/Gtk3.14): - DnD with overlapping widgets. - SWT Juint tests. - running an Eclipse, fast-view and the application as a whole. - LayoutExample, (Row/Column/Fill/Grid/FormAttach/Stack). - Control Example. I did a code inspection of code that can be affected. All seems good. Change-Id: Ide88c6b80f69aadd87f0dc0cb68f65317b9587cb Signed-off-by: Leo Ufimtsev <lufimtse@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c29
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java4
2 files changed, 32 insertions, 1 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c
index 6f135b1f35..70245229fe 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c
@@ -563,6 +563,13 @@ static void swt_fixed_map (GtkWidget *widget) {
}
}
if (gtk_widget_get_has_window (widget)) {
+ //NOTE: contrary to most of GTK, swt_fixed_* container does not raise windows upon showing them.
+ //This has the effect that widgets are drawn *beneath* the previous one.
+ //E.g if this line is changed to gdk_window_show (..) then widgets are drawn on top of the previous one.
+ //This affects mostly only the absolute layout with overlapping widgets, e.g minimizied panels that
+ //pop-out in Eclipse (aka fast-view).
+ //As such, be attentive to swt_fixed_forall(..); traversing children may need to be done in reverse in some
+ //cases.
gdk_window_show_unraised (gtk_widget_get_window (widget));
}
}
@@ -696,10 +703,30 @@ static void swt_fixed_forall (GtkContainer *container, gboolean include_internal
GList *list;
list = priv->children;
+
+ // NOTE: The direction of the list traversal is conditional.
+ //
+ // 1) When we do a *_foreach() traversal (i.e, include_internals==FALSE), we traverse the list as normal
+ // from front to back.
+ // This is used to layout higher level widgets inside containers (e.g row/grid etc..) in the expected way.
+ // If for a non-internal traversal we were to go in reverse, then widgets would get laid out in inverse order.
+ // 2) When we do a *_forall() traversal (i.e, include_internals==TRUE), we traverse the list in *reverse* order.
+ // This is an internal traversal of the internals of a widget. Reverse traversal is necessary for things like
+ // DnD Drop and DnD Motion events to find the correct widget in the case of overlapping widgets on an absolute layout.
+ // Reversal is required because in swt_fixed_map(..) we do not raise the widget when we show it, as a result
+ // the stack is in reverse.
+ if (include_internals)
+ list = g_list_last(list);
+
while (list) {
SwtFixedChild *child_data = list->data;
GtkWidget *child = child_data->widget;
- list = list->next;
+
+ if (include_internals)
+ list = list->prev;
+ else
+ list = list->next;
+
(* callback) (child, callback_data);
}
}
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 4114367e95..efebac1646 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
@@ -7232,6 +7232,10 @@ public static final void gtk_container_add(long /*int*/ container, long /*int*/
lock.unlock();
}
}
+
+//Do not confuse this function with gtk_container_foreach(..).
+//Make sure you know what you are doing when using this. Please be attentive to swt_fixed_forall(..)
+// found in os_custom.c, which overrides this function for swtFixed container with custom behaviour.
/**
* @param container cast=(GtkContainer *)
* @param callback cast=(GtkCallback)

Back to the top