diff options
| author | Eric Williams | 2018-04-03 17:50:54 +0000 |
|---|---|---|
| committer | Eric Williams | 2018-04-03 18:01:37 +0000 |
| commit | 6186fb3eb3c00dde36a5ef7b90a15abcb46b5dcf (patch) | |
| tree | 873f7d5f8fc87cb8e79c15ce019bf8c503b3baf5 | |
| parent | 32a4ec463315fd2e2cc607aeeefcd084d8768804 (diff) | |
| download | eclipse.platform.swt-6186fb3eb3c00dde36a5ef7b90a15abcb46b5dcf.tar.gz eclipse.platform.swt-6186fb3eb3c00dde36a5ef7b90a15abcb46b5dcf.tar.xz eclipse.platform.swt-6186fb3eb3c00dde36a5ef7b90a15abcb46b5dcf.zip | |
Bug 529431: [GTK3.10+] Snippet294 fails to draw Region
Allow GtkWindow (usually Shells) to be shaped using
gdk_window_shape_combine_region() instead of cairo_clip. GtkWindow
is unaffected by the changes in GTK3.10 so this is fine.
A snippet has been added to test this functionality, and to test for the
case mentioned in comment 8 of bug 529431.
Change-Id: I40c80599e015553576fc8979181577c1170146d2
Signed-off-by: Eric Williams <ericwill@redhat.com>
6 files changed, 101 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 5fc92d0de9..565ee2ac1c 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 @@ -4228,6 +4228,18 @@ JNIEXPORT jintLong JNICALL GTK_NATIVE(_1GTK_1TYPE_1WIDGET) } #endif +#ifndef NO__1GTK_1TYPE_1WINDOW +JNIEXPORT jintLong JNICALL GTK_NATIVE(_1GTK_1TYPE_1WINDOW) + (JNIEnv *env, jclass that) +{ + jintLong rc = 0; + GTK_NATIVE_ENTER(env, that, _1GTK_1TYPE_1WINDOW_FUNC); + rc = (jintLong)GTK_TYPE_WINDOW; + GTK_NATIVE_EXIT(env, that, _1GTK_1TYPE_1WINDOW_FUNC); + return rc; +} +#endif + #ifndef NO__1GTK_1WIDGET_1SET_1FLAGS JNIEXPORT void JNICALL GTK_NATIVE(_1GTK_1WIDGET_1SET_1FLAGS) (JNIEnv *env, jclass that, jintLong arg0, jint 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 98f36e68bb..01f966424d 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 @@ -321,6 +321,7 @@ char * GTK_nativeFunctionNames[] = { "_1GTK_1TYPE_1IM_1MULTICONTEXT", "_1GTK_1TYPE_1MENU", "_1GTK_1TYPE_1WIDGET", + "_1GTK_1TYPE_1WINDOW", "_1GTK_1WIDGET_1SET_1FLAGS", "_1GTK_1WIDGET_1UNSET_1FLAGS", "_1gtk_1accel_1group_1new", 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 97f4d144ee..64a3069337 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 @@ -319,6 +319,7 @@ typedef enum { _1GTK_1TYPE_1IM_1MULTICONTEXT_FUNC, _1GTK_1TYPE_1MENU_FUNC, _1GTK_1TYPE_1WIDGET_FUNC, + _1GTK_1TYPE_1WINDOW_FUNC, _1GTK_1WIDGET_1SET_1FLAGS_FUNC, _1GTK_1WIDGET_1UNSET_1FLAGS_FUNC, _1gtk_1accel_1group_1new_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 ae31f7be36..ff3427fa12 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 @@ -478,6 +478,16 @@ public class GTK extends OS { lock.unlock(); } } + /** @method flags=const */ + public static final native long /*int*/ _GTK_TYPE_WINDOW(); + public static final long /*int*/ GTK_TYPE_WINDOW() { + lock.lock(); + try { + return _GTK_TYPE_WINDOW(); + } finally { + lock.unlock(); + } + } public static final native void _GTK_WIDGET_SET_FLAGS(long /*int*/ wid, int flag); public static final void GTK_WIDGET_SET_FLAGS(long /*int*/ wid, int flag) { lock.lock(); 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 7df9fe52fb..b16a51a9b7 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,7 +64,7 @@ public abstract class Control extends Widget implements Drawable { Accessible accessible; Control labelRelation; String cssBackground, cssForeground = " "; - boolean reparentOnVisibility; + boolean drawRegion; LinkedList <Event> dragDetectionQueue; @@ -1343,11 +1343,16 @@ public void setRegion (Region region) { if (region != null && region.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT); long /*int*/ shape_region = (region == null) ? 0 : region.handle; this.region = region; - // Only call gdk_window_shape_combine_region on GTK3.8- - if (GTK.GTK_VERSION < OS.VERSION(3, 9, 0)) { - long /*int*/ window = gtk_widget_get_window (topHandle ()); + long /*int*/ topHandle = topHandle (); + /* + * Only call gdk_window_shape_combine_region on GTK3.10-, or if the widget is + * a GtkWindow. + */ + if (GTK.GTK_VERSION < OS.VERSION(3, 10, 0) || OS.G_OBJECT_TYPE(topHandle) == GTK.GTK_TYPE_WINDOW()) { + long /*int*/ window = gtk_widget_get_window (topHandle); GDK.gdk_window_shape_combine_region (window, shape_region, 0, 0); } else { + drawRegion = (this.region != null && this.region.handle != 0); GTK.gtk_widget_queue_draw(topHandle()); } } @@ -3536,7 +3541,7 @@ long /*int*/ gtk_draw (long /*int*/ widget, long /*int*/ cairo) { * Doesn't modify input handling at this time. * See bug 529431. */ - if (this.region != null && this.region.handle != 0 && GTK.GTK_VERSION >= OS.VERSION(3, 10, 0)) { + if (drawRegion) { long /*int*/ regionHandle = this.region.handle; GdkRectangle regionRect = new GdkRectangle(); /* diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug529431_ShellSetRegion.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug529431_ShellSetRegion.java new file mode 100644 index 0000000000..65b0f428eb --- /dev/null +++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug529431_ShellSetRegion.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.tests.gtk.snippets; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Region; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/* + * Title: Bug 529431: [GTK3.10+] Snippet294 fails to draw Region + * How to run: launch snippet and look for the resulting Shell + * Bug description: the Shell is a 200 x 200 square with no region set + * Expected results: the Shell is circle with inner circular regions + * GTK Version(s): GTK3.10+ + */ +public class Bug529431_ShellSetRegion { + + static int[] circle(int r, int offsetX, int offsetY) { + int[] polygon = new int[8 * r + 4]; + // x^2 + y^2 = r^2 + for (int i = 0; i < 2 * r + 1; i++) { + int x = i - r; + int y = (int)Math.sqrt(r*r - x*x); + polygon[2*i] = offsetX + x; + polygon[2*i+1] = offsetY + y; + polygon[8*r - 2*i - 2] = offsetX + x; + polygon[8*r - 2*i - 1] = offsetY - y; + } + return polygon; + } + + public static void main(String[] args) { + final Display display = new Display(); + + final Shell shell = new Shell(display, SWT.NO_TRIM | SWT.ON_TOP + | SWT.NO_FOCUS | SWT.TOOL); + + shell.setSize(200,200); + + // define a region that looks like a circle with two holes in it + Region region = new Region(); + region.add(circle(67, 87, 77)); + region.subtract(circle(20, 87, 47)); + region.subtract(circle(20, 87, 113)); + + // define the shape of the shell using setRegion + shell.setRegion(region); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + region.dispose(); + display.dispose(); + } + +} |
