From 8a745bffa40230e73fb229950d6d0520b474c8f3 Mon Sep 17 00:00:00 2001 From: Eric Williams Date: Tue, 13 Feb 2018 14:25:46 -0500 Subject: Bug 511133: [GTK3.10+] Some critical icons missing on Ubuntu 16.04 This patch fixes Table/Tree drawing in EGit. It patch reverts the changes introduced for bug 438505, which causes this regression. This patch also contains fixes to prevent bug 438505 from being re-introduced. EGit drawing was broken because TableItem.getBounds() was taking the position of the header into account. This is because we were drawing on the fixedHandle instead of the GtkTreeView. The positioning of the Table header broke simple drawing cases like Snippet051TableCenteredImage (JFace snippet). Reverting the fix back to drawing on the handle has fixed that issue. Unfortunately this means bug 438505 is re-introduced. To fix that issue I have tweaked the re-parenting logic found in Table/Tree.setParentWindow(). GTK3.10+ onward only draws on toplevel or native GdkWindows. This means the Text widgets used for Table/Tree editing continue to get events, but they are not drawn. The solution to this problem is call gdk_window_raise/lower on these Text widgets when setVisible() is called. This raises and lowers the Text's GdkWindow when the widget's visibility is changed, ensuring that it actually is drawn when visible, and not when hidden. This isn't a huge change as the GdkWindow re-parenting already existed in Table/Tree.setParentWindow(), this patch just builds on that. I have tested against the following cases/snippets: Snippet88 Snippet019 (JFace snippets) Snippet025 (JFace snippets) Snippet026 (JFace snippets) Snippet051 (JFace snippets) use case from bug 438505 use case from bug 436324 use case from bug 460581 use case from bug 458630 Additionally, using a child Eclipse I have verified that the missing EGit icons have returned. No AllNonBrowser JUnit tests fail. Change-Id: I02b3fb30037a8f0f74de79144f8e563f5284d571 Signed-off-by: Eric Williams --- .../gtk/org/eclipse/swt/widgets/Control.java | 19 +++++++++++++-- .../gtk/org/eclipse/swt/widgets/Table.java | 28 ++++++++++++---------- .../gtk/org/eclipse/swt/widgets/TableItem.java | 3 --- .../gtk/org/eclipse/swt/widgets/Tree.java | 28 ++++++++++++---------- .../gtk/org/eclipse/swt/widgets/TreeItem.java | 3 --- 5 files changed, 49 insertions(+), 32 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index 5bb916a..e29d144 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -64,6 +64,7 @@ public abstract class Control extends Widget implements Drawable { Accessible accessible; Control labelRelation; String cssBackground, cssForeground = " "; + boolean reparentOnVisibility; LinkedList dragDetectionQueue; @@ -5286,7 +5287,7 @@ void setParentBackground () { if (fixedHandle != 0) setBackgroundColor (fixedHandle, null); } -void setParentWindow (long /*int*/ widget) { +void setParentWindow (Control child) { } boolean setRadioSelection (boolean value) { @@ -5491,6 +5492,13 @@ public void setVisible (boolean visible) { state &= ~HIDDEN; if ((state & (ZERO_WIDTH | ZERO_HEIGHT)) == 0) { if (enableWindow != 0) OS.gdk_window_show_unraised (enableWindow); + /* + * Raise this widget's GdkWindow if the reparentOnVisibility + * flag has been set and visible is true. See bug 511133. + */ + if (reparentOnVisibility && OS.GTK3) { + OS.gdk_window_raise(gtk_widget_get_window(topHandle)); + } OS.gtk_widget_show (topHandle); } } else { @@ -5527,6 +5535,13 @@ public void setVisible (boolean visible) { OS.gtk_widget_hide (topHandle); if (isDisposed ()) return; if (enableWindow != 0) OS.gdk_window_hide (enableWindow); + /* + * Lower this widget's GdkWindow if the reparentOnVisibility + * flag has been set and visible is false. See bug 511133. + */ + if (reparentOnVisibility && OS.GTK3) { + OS.gdk_window_lower(gtk_widget_get_window(topHandle)); + } sendEvent (SWT.Hide); } } @@ -5682,7 +5697,7 @@ void showWidget () { state |= ZERO_WIDTH | ZERO_HEIGHT; long /*int*/ topHandle = topHandle (); long /*int*/ parentHandle = parent.parentingHandle (); - parent.setParentWindow (topHandle); + parent.setParentWindow (this); OS.gtk_container_add (parentHandle, topHandle); if (handle != 0 && handle != topHandle) OS.gtk_widget_show (handle); if ((state & (ZERO_WIDTH | ZERO_HEIGHT)) == 0) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java index e3d1441..b664f29 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java @@ -1205,9 +1205,6 @@ Rectangle getClientAreaInPixels () { int width = (state & ZERO_WIDTH) != 0 ? 0 : allocation.width; int height = (state & ZERO_HEIGHT) != 0 ? 0 : allocation.height; Rectangle rect = new Rectangle (fixedX [0] - binX [0], fixedY [0] - binY [0], width, height); - if (getHeaderVisible() && OS.GTK_VERSION > OS.VERSION(3, 9, 0)) { - rect.y += getHeaderHeightInPixels(); - } return rect; } @@ -1601,9 +1598,6 @@ TableItem getItemInPixels (Point point) { long /*int*/ [] path = new long /*int*/ [1]; OS.gtk_widget_realize (handle); int y = point.y; - if (getHeaderVisible() && OS.GTK_VERSION > OS.VERSION(3, 9, 0)) { - y -= getHeaderHeightInPixels(); - } if (!OS.gtk_tree_view_get_path_at_pos (handle, point.x, y, path, null, null, null)) return null; if (path [0] == 0) return null; long /*int*/ indices = OS.gtk_tree_path_get_indices (path [0]); @@ -2453,10 +2447,6 @@ boolean mnemonicMatch (char key) { @Override long /*int*/ paintWindow () { OS.gtk_widget_realize (handle); - if (fixedHandle != 0 && OS.GTK_VERSION > OS.VERSION(3, 9, 0)) { - OS.gtk_widget_realize (fixedHandle); - return OS.gtk_widget_get_window(fixedHandle); - } return OS.gtk_tree_view_get_bin_window (handle); } @@ -3659,9 +3649,23 @@ void setParentBackground () { } @Override -void setParentWindow (long /*int*/ widget) { +void setParentWindow (Control child) { long /*int*/ window = eventWindow (); - OS.gtk_widget_set_parent_window (widget, window); + OS.gtk_widget_set_parent_window (child.topHandle(), window); + /* + * Feature in GTK3: all children of Table have their GdkWindows + * re-parented so they are siblings of the parent Table + * (i.e. on the same level in the z-order). + * + * To fix table editing in GTK3: raise/lower the + * GdkWindow of these child widgets to make them visible when + * setVisible() is called on them. This ensures they are properly + * drawn when setVisible(true) is called, and properly hidden + * when setVisible(false) is called. See bug 511133. + */ + if (child != null && OS.GTK3) { + child.reparentOnVisibility = true; + } } @Override diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableItem.java index 6efb227..f904159 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableItem.java @@ -403,9 +403,6 @@ Rectangle getBoundsInPixels (int index) { } int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; Rectangle r = new Rectangle (rect.x, rect.y, width, rect.height + 1); - if (parent.getHeaderVisible() && OS.GTK_VERSION > OS.VERSION(3, 9, 0)) { - r.y += parent.getHeaderHeightInPixels(); - } return r; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java index 58e0382..2428361 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java @@ -1203,9 +1203,6 @@ Rectangle getClientAreaInPixels () { int width = (state & ZERO_WIDTH) != 0 ? 0 : allocation.width; int height = (state & ZERO_HEIGHT) != 0 ? 0 : allocation.height; Rectangle rect = new Rectangle (fixedX [0] - binX [0], fixedY [0] - binY [0], width, height); - if (getHeaderVisible() && OS.GTK_VERSION > OS.VERSION(3, 9, 0)) { - rect.y += getHeaderHeightInPixels(); - } return rect; } @@ -1610,9 +1607,6 @@ TreeItem getItemInPixels (Point point) { OS.gtk_widget_realize (handle); int x = point.x; int y = point.y; - if (getHeaderVisible() && OS.GTK_VERSION > OS.VERSION(3, 9, 0)) { - y -= getHeaderHeightInPixels(); - } if ((style & SWT.MIRRORED) != 0) x = getClientWidth () - x; long /*int*/ [] columnHandle = new long /*int*/ [1]; if (!OS.gtk_tree_view_get_path_at_pos (handle, x, y, path, columnHandle, null, null)) return null; @@ -2596,10 +2590,6 @@ boolean mnemonicMatch (char key) { @Override long /*int*/ paintWindow () { OS.gtk_widget_realize (handle); - if (fixedHandle != 0 && OS.GTK_VERSION > OS.VERSION(3, 9, 0)) { - OS.gtk_widget_realize (fixedHandle); - return OS.gtk_widget_get_window(fixedHandle); - } return OS.gtk_tree_view_get_bin_window (handle); } @@ -3664,9 +3654,23 @@ void setParentBackground () { } @Override -void setParentWindow (long /*int*/ widget) { +void setParentWindow (Control child) { long /*int*/ window = eventWindow (); - OS.gtk_widget_set_parent_window (widget, window); + OS.gtk_widget_set_parent_window (child.topHandle(), window); + /* + * Feature in GTK3: all children of Tree have their GdkWindows + * re-parented so they are siblings of the parent Tree + * (i.e. on the same level in the z-order). + * + * To fix table editing in GTK3: raise/lower the + * GdkWindow of these child widgets to make them visible when + * setVisible() is called on them. This ensures they are properly + * drawn when setVisible(true) is called, and properly hidden + * when setVisible(false) is called. See bug 511133. + */ + if (child != null && OS.GTK3) { + child.reparentOnVisibility = true; + } } void setScrollWidth (long /*int*/ column, TreeItem item) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java index 25bb96b..802a1f9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java @@ -453,9 +453,6 @@ Rectangle getBoundsInPixels (int index) { } int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; Rectangle r = new Rectangle (rect.x, rect.y, width, rect.height + 1); - if (parent.getHeaderVisible() && OS.GTK_VERSION > OS.VERSION(3, 9, 0)) { - r.y += parent.getHeaderHeightInPixels(); - } return r; } -- cgit v1.1