Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Williams2018-12-06 22:16:12 +0000
committerEric Williams2018-12-14 15:20:12 +0000
commit71472c2bbf838e2b785684fd57f0b2db6f2651cd (patch)
tree93383ee8a51298b4782a50ced5fe182223855bc7 /bundles
parent3f082e82f85a793dd42722beda1be7adc0bb09e7 (diff)
downloadeclipse.platform.swt-71472c2bbf838e2b785684fd57f0b2db6f2651cd.tar.gz
eclipse.platform.swt-71472c2bbf838e2b785684fd57f0b2db6f2651cd.tar.xz
eclipse.platform.swt-71472c2bbf838e2b785684fd57f0b2db6f2651cd.zip
Bug 535978: [GTK3] Bad Scrolling behaviour of tables with Checkbox
The issue at hand in this bug is that Tree/Table editing widgets are children of the fixedHandle, which sits above the GtkTreeView in the widget hierarchy. This means that they are siblings of the tree/table, and thus will continue to draw even on top of the tree/table headers. The fix is to calculate the location and size of the header bars and keep track of them in Composite. When editing widgets are drawn using Composite.propagateDraw(), we check to see if the widgets would be about to be drawn over a tree/table header. If they are, we raise/lower the GdkWindow belonging to the editing widgets, depending on whether or not it needs to be drawn or not. Tested on GTK3.24 using the snippet attached to this ticket and also the snippet from bug 531928. No AllNonBrowser JUnit tests fail, and the update sites editor in a child Eclipse seems to be working as intended. Change-Id: I66d90c438a3d44afdd6bf6112deef5af680cd201 Signed-off-by: Eric Williams <ericwill@redhat.com>
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java49
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java16
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java16
3 files changed, 77 insertions, 4 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
index 71c2163023..55d538b20c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
@@ -88,8 +88,23 @@ public class Composite extends Scrollable {
Map<Control, long /*int*/ []> fixClipMap = new HashMap<> ();
static final String NO_INPUT_METHOD = "org.eclipse.swt.internal.gtk.noInputMethod"; //$NON-NLS-1$
-
Shell popupChild;
+ /**
+ * A Rectangle which, if specified, denotes an area where child widgets
+ * should not be drawn. Only relevant if such child widgets are being
+ * drawn via propagateDraw(), such as Tree/Table editing widgets.
+ *
+ * See bug 535978.
+ */
+ Rectangle noChildDrawing = null;
+ /**
+ * A HashMap of child widgets that keeps track of which child has had their
+ * GdkWindow lowered/raised. Only relevant if such child widgets are being
+ * drawn via propagateDraw(), such as Tree/Table editing widgets.
+ *
+ * See bug 535978.
+ */
+ HashMap<Widget, Boolean> childrenLowered = new HashMap<>();
Composite () {
/* Do nothing */
@@ -1416,12 +1431,42 @@ void propagateDraw (long /*int*/ container, long /*int*/ cairo) {
if (child != 0) {
Widget widget = display.getWidget (child);
if (widget != this) {
- GTK.gtk_container_propagate_draw(container, child, cairo);
+ if (noChildDrawing != null) {
+ Boolean childLowered = childrenLowered.get(widget);
+ if (childLowered == null) {
+ childrenLowered.put(widget, false);
+ childLowered = false;
+ }
+ GtkAllocation allocation = new GtkAllocation ();
+ GTK.gtk_widget_get_allocation(child, allocation);
+ if ((allocation.y + allocation.height) < noChildDrawing.height) {
+ if (!childLowered) {
+ long /*int*/ window = gtk_widget_get_window(child);
+ GDK.gdk_window_lower(window);
+ childrenLowered.put(widget, true);
+ }
+ } else {
+ if (childLowered) {
+ long /*int*/ window = gtk_widget_get_window(child);
+ GDK.gdk_window_raise(window);
+ childrenLowered.put(widget, false);
+ }
+ GTK.gtk_container_propagate_draw(container, child, cairo);
+ }
+ } else {
+ GTK.gtk_container_propagate_draw(container, child, cairo);
+ }
}
}
temp = OS.g_list_next (temp);
}
OS.g_list_free (list);
+ /*
+ * Sometimes the sibling widget needs a draw event to remove any mis-drawn
+ * widgets still remaining -- usually only happens when scrolling with the mouse
+ * wheel. See bug 535978.
+ */
+ if (noChildDrawing != null) GTK.gtk_widget_queue_draw(handle);
}
}
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 2998b56a5f..4bbbf7f1a9 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
@@ -92,7 +92,8 @@ public class Table extends Composite {
int topIndex;
double cachedAdjustment, currentAdjustment;
int pixbufHeight, pixbufWidth;
- boolean boundsChangedSinceLastDraw;
+ int headerHeight;
+ boolean boundsChangedSinceLastDraw, headerVisible;
boolean rowActivated;
static final int CHECKED_COLUMN = 0;
@@ -3513,6 +3514,8 @@ public void setHeaderForeground (Color color) {
public void setHeaderVisible (boolean show) {
checkWidget ();
GTK.gtk_tree_view_set_headers_visible (handle, show);
+ this.headerHeight = this.getHeaderHeight();
+ this.headerVisible = show;
}
/**
@@ -4049,6 +4052,17 @@ long /*int*/ windowProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ us
* to them using gtk_container_propagate_draw(). See bug 531928.
*/
if (hasChildren) {
+ /*
+ * If headers are visible, set noChildDrawing to their
+ * dimensions -- this will prevent any child widgets from drawing
+ * over the header buttons. See bug 535978.
+ */
+ if (headerVisible) {
+ GdkRectangle rect = new GdkRectangle ();
+ GDK.gdk_cairo_get_clip_rectangle (arg0, rect);
+ // -1's is for the 1px of padding between the fixedHandle and handle
+ noChildDrawing = new Rectangle(0, 0, rect.width - 1, this.headerHeight - 1);
+ }
propagateDraw(handle, arg0);
}
break;
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 c0d8fe0fe8..dc3483db2a 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
@@ -94,7 +94,8 @@ public class Tree extends Composite {
int drawState, drawFlags;
GdkRGBA background, foreground, drawForegroundRGBA;
boolean ownerDraw, ignoreSize, ignoreAccessibility, pixbufSizeSet, hasChildren;
- int pixbufHeight, pixbufWidth;
+ int pixbufHeight, pixbufWidth, headerHeight;
+ boolean headerVisible;
TreeItem topItem;
double cachedAdjustment, currentAdjustment;
Color headerBackground, headerForeground;
@@ -3577,6 +3578,8 @@ public void setHeaderForeground (Color color) {
public void setHeaderVisible (boolean show) {
checkWidget ();
GTK.gtk_tree_view_set_headers_visible (handle, show);
+ this.headerHeight = this.getHeaderHeight();
+ this.headerVisible = show;
}
/**
@@ -3997,6 +4000,17 @@ long /*int*/ windowProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ us
* to them using gtk_container_propagate_draw(). See bug 531928.
*/
if (hasChildren) {
+ /*
+ * If headers are visible, set noChildDrawing to their
+ * dimensions -- this will prevent any child widgets from drawing
+ * over the header buttons. See bug 535978.
+ */
+ if (headerVisible) {
+ GdkRectangle rect = new GdkRectangle ();
+ GDK.gdk_cairo_get_clip_rectangle (arg0, rect);
+ // -1's is for the 1px of padding between the fixedHandle and handle
+ noChildDrawing = new Rectangle(0, 0, rect.width - 1, this.headerHeight - 1);
+ }
propagateDraw(handle, arg0);
}
break;

Back to the top