Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLakshmi Shanmugam2017-08-18 03:05:45 -0400
committerLakshmi Shanmugam2017-08-18 03:06:22 -0400
commitf28f8cb0510c91905751bee0f128e0912d8324c8 (patch)
treee5a4dc21a9cf65776de8ad8b6c5c240615c22751 /bundles/org.eclipse.swt
parentd60568a68b732473a302c525248b0c667707e8d4 (diff)
downloadeclipse.platform.swt-f28f8cb0510c91905751bee0f128e0912d8324c8.tar.gz
eclipse.platform.swt-f28f8cb0510c91905751bee0f128e0912d8324c8.tar.xz
eclipse.platform.swt-f28f8cb0510c91905751bee0f128e0912d8324c8.zip
Bug 508129 - [10.11]PaintEvent.GC.copyArea () crashes Eclipse Neon on
OSX 10.11 and above When a GC is created with a control as the Drawable and GC.copyArea() is called, a SWT.Paint event is sent unexpectedly. This happens because NSView.cacheDisplayInRect() calls drawRect() which causes a SWT.Paint event to be sent. The fix is to ignore this paint event and prevent SWT from sending it to the clients. This is handled by creating a custom callback for cacheDisplayInRect, setting the ignorePaint flag and then calling the Cocoa implementation of cacheDisplayInRect. The ignorePaint flag is reset after the call. Change-Id: I4c2e2986b83868082295ea187b543376bf4c8a7e
Diffstat (limited to 'bundles/org.eclipse.swt')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c20
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.c1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.h1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java4
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java18
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java7
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java4
8 files changed, 57 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c
index b62f41243f..b1162fdf9a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c
@@ -135,6 +135,26 @@ JNIEXPORT jintLong JNICALL OS_NATIVE(CALLBACK_1attributedSubstringFromRange_1)
}
#endif
+#ifndef NO_CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1
+static jintLong CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1;
+static void proc_CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1(id arg0, SEL arg1, NSRect arg2, NSBitmapImageRep* arg3) {
+ ((void (*)(id, SEL, NSRect*, NSBitmapImageRep*))CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1)(arg0, arg1, &arg2, arg3);
+}
+static jintLong CALLBACK_cacheDisplayInRect_toBitmapImageRep_(jintLong func) {
+ CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1 = func;
+ return (jintLong)proc_CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1;
+}
+JNIEXPORT jintLong JNICALL OS_NATIVE(CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1)
+ (JNIEnv *env, jclass that, jintLong arg0)
+{
+ jintLong rc = 0;
+ OS_NATIVE_ENTER(env, that, CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1_FUNC);
+ rc = (jintLong)CALLBACK_cacheDisplayInRect_toBitmapImageRep_(arg0);
+ OS_NATIVE_EXIT(env, that, CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_CALLBACK_1canDragRowsWithIndexes_1atPoint_1
static jintLong CALLBACK_1canDragRowsWithIndexes_1atPoint_1;
static BOOL proc_CALLBACK_1canDragRowsWithIndexes_1atPoint_1(id arg0, SEL arg1, NSIndexSet* arg2, NSPoint arg3) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.c
index bac2ebb6a5..951fa0111e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.c
@@ -23,6 +23,7 @@ char * OS_nativeFunctionNames[] = {
"CALLBACK_1NSTextAttachmentCell_1cellSize",
"CALLBACK_1accessibilityHitTest_1",
"CALLBACK_1attributedSubstringFromRange_1",
+ "CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1",
"CALLBACK_1canDragRowsWithIndexes_1atPoint_1",
"CALLBACK_1cellBaselineOffset",
"CALLBACK_1cellSize",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.h
index 3fcc56dfe6..b3aca449a3 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.h
@@ -33,6 +33,7 @@ typedef enum {
CALLBACK_1NSTextAttachmentCell_1cellSize_FUNC,
CALLBACK_1accessibilityHitTest_1_FUNC,
CALLBACK_1attributedSubstringFromRange_1_FUNC,
+ CALLBACK_1cacheDisplayInRect_1toBitmapImageRep_1_FUNC,
CALLBACK_1canDragRowsWithIndexes_1atPoint_1_FUNC,
CALLBACK_1cellBaselineOffset_FUNC,
CALLBACK_1cellSize_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
index 9e6ce3da39..531dcf55cc 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
@@ -680,6 +680,8 @@ public static final native void objc_msgSend_stret(NSSize result, long /*int*/ i
public static final native long /*int*/ CALLBACK_accessibilityHitTest_(long /*int*/ func);
/** @method callback_types=NSAttributedString*;id;SEL;NSRange;,callback_flags=none;none;none;struct; */
public static final native long /*int*/ CALLBACK_attributedSubstringFromRange_(long /*int*/ func);
+/** @method callback_types=void;id;SEL;NSRect;NSBitmapImageRep*;,callback_flags=none;none;none;struct;none; */
+public static final native long /*int*/ CALLBACK_cacheDisplayInRect_toBitmapImageRep_(long /*int*/ func);
/** @method callback_types=BOOL;id;SEL;NSIndexSet*;NSPoint;,callback_flags=none;none;none;none;struct; */
public static final native long /*int*/ CALLBACK_canDragRowsWithIndexes_atPoint_(long /*int*/ func);
/** @method callback_types=NSSize;id;SEL;,callback_flags=struct;none;none; */
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java
index 802653a116..b61b83ef78 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java
@@ -457,6 +457,10 @@ public void copyArea(Image image, int x, int y) {
rect.height = size.height;
NSBitmapImageRep imageRep = topView.bitmapImageRepForCachingDisplayInRect(rect);
imageRep.setSize(size);
+ /*
+ * NSView.cacheDisplayInRect will cause an unexpected SWT.Paint event to be sent.
+ * This is handled by Control.cacheDisplayInRect_toBitmapImageRep().
+ */
topView.cacheDisplayInRect(rect, imageRep);
NSBitmapImageRep rep = image.getRepresentation();
image.handle.addRepresentation(imageRep);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java
index 2fbacd7b75..9cc52654fe 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java
@@ -69,6 +69,7 @@ public abstract class Control extends Widget implements Drawable {
NSBezierPath regionPath;
long /*int*/ visibleRgn;
Accessible accessible;
+ boolean ignorePaint;
boolean touchEnabled;
final static int CLIPPING = 1 << 10;
@@ -1259,6 +1260,7 @@ boolean drawsBackground() {
@Override
void drawWidget (long /*int*/ id, NSGraphicsContext context, NSRect rect) {
+ if (ignorePaint) return;
if (id != paintView().id) return;
if (!hooks (SWT.Paint) && !filters (SWT.Paint)) return;
@@ -3963,6 +3965,22 @@ void setFrameSize (long /*int*/ id, long /*int*/ sel, NSSize size) {
}
}
+@Override
+void cacheDisplayInRect_toBitmapImageRep (long id, long sel, NSRect rect, long rep) {
+ /*
+ * When a GC is created with a control as the Drawable and GC.copyArea() is
+ * called, a SWT.Paint event will be sent, unexpectedly. This happens because
+ * NSView.cacheDisplayInRect() calls drawRect() which causes a SWT.Paint event
+ * to be sent. The fix is to ignore this paint event and prevent SWT from
+ * sending it to the clients.
+ * In the callback, set the ignorePaint flag, then call the Cocoa
+ * implementation of cacheDisplayInRect_toBitmapImageRep(), then reset the ignorePaint flag.
+ */
+ ignorePaint = true;
+ super.cacheDisplayInRect_toBitmapImageRep(id, sel, rect, rep);
+ ignorePaint = false;
+}
+
/**
* Sets the layout data associated with the receiver to the argument.
*
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
index 4bed47a96d..e9f51eac3a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
@@ -2473,6 +2473,7 @@ void initClasses () {
long /*int*/ setNeedsDisplayInRectProc = OS.CALLBACK_setNeedsDisplayInRect_(proc3);
long /*int*/ expansionFrameWithFrameProc = OS.CALLBACK_expansionFrameWithFrame_inView_ (proc4);
long /*int*/ focusRingMaskBoundsForFrameProc = OS.CALLBACK_focusRingMaskBoundsForFrame_inView_ (proc4);
+ long /*int*/ cacheDisplayInRect_toBitmapImageRepProc = OS.CALLBACK_cacheDisplayInRect_toBitmapImageRep_ (proc4);
long /*int*/ sizeOfLabelProc = OS.CALLBACK_sizeOfLabel_ (proc3);
long /*int*/ drawLabelInRectProc = OS.CALLBACK_drawLabel_inRect_ (proc4);
long /*int*/ drawViewBackgroundInRectProc = OS.CALLBACK_drawViewBackgroundInRect_(proc3);
@@ -2547,6 +2548,7 @@ void initClasses () {
OS.class_addMethod(cls, OS.sel_readSelectionFromPasteboard_, proc3, "@:@");
OS.class_addMethod(cls, OS.sel_writeSelectionToPasteboard_types_, proc4, "@:@@");
OS.class_addMethod(cls, OS.sel_viewWillMoveToWindow_, proc3, "@:@");
+ OS.class_addMethod(cls, OS.sel_cacheDisplayInRect_toBitmapImageRep_, cacheDisplayInRect_toBitmapImageRepProc, "@:{NSRect}@");
addEventMethods(cls, proc2, proc3, drawRectProc, hitTestProc, setNeedsDisplayInRectProc);
addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
@@ -2727,6 +2729,7 @@ void initClasses () {
OS.class_addMethod(cls, OS.sel_pageUp_, proc3, "@:@");
OS.class_addMethod(cls, OS.sel_reflectScrolledClipView_, proc3, "@:@");
OS.class_addMethod(cls, OS.sel_scrollClipView_toPoint_, scrollClipView_ToPointProc, "@:@{NSPoint}");
+ OS.class_addMethod(cls, OS.sel_cacheDisplayInRect_toBitmapImageRep_, cacheDisplayInRect_toBitmapImageRepProc, "@:{NSRect}@");
addEventMethods(cls, proc2, proc3, drawRectProc, hitTestProc, setNeedsDisplayInRectProc);
addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc);
@@ -6046,6 +6049,10 @@ static long /*int*/ windowProc(long /*int*/ id, long /*int*/ sel, long /*int*/ a
widget.menu_willHighlightItem(id, sel, arg0, arg1);
} else if (sel == OS.sel_setMarkedText_selectedRange_) {
widget.setMarkedText_selectedRange (id, sel, arg0, arg1);
+ } else if (sel == OS.sel_cacheDisplayInRect_toBitmapImageRep_) {
+ NSRect rect = new NSRect ();
+ OS.memmove (rect, arg0, NSRect.sizeof);
+ widget.cacheDisplayInRect_toBitmapImageRep(id, sel, rect, arg1);
} else if (sel == OS.sel_drawInteriorWithFrame_inView_) {
NSRect rect = new NSRect ();
OS.memmove (rect, arg0, NSRect.sizeof);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java
index 4f72e1ba22..8b54afb794 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java
@@ -214,6 +214,10 @@ long /*int*/ attributedSubstringFromRange (long /*int*/ id, long /*int*/ sel, lo
return 0;
}
+void cacheDisplayInRect_toBitmapImageRep (long id, long sel, NSRect rect, long imageRep) {
+ callSuper(id, sel, rect, imageRep);
+}
+
void callSuper(long /*int*/ id, long /*int*/ sel) {
objc_super super_struct = new objc_super();
super_struct.receiver = id;

Back to the top