Avoid using wx GDI classes from non-main thread in wxOSX/Cocoa.
OS X uses a background thread for pulsing the default button and we intercept the draw requests from it. As our drawing code is not MT-safe, executing it from the non-main thread can result in crashes. Avoid this by simply not doing anything fancy when called from a background thread and simply deferring to the superclass instead. Closes #12407. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66041 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -784,12 +784,34 @@ BOOL wxOSX_isFlipped(NSView* self, SEL _cmd)
|
|||||||
return impl->isFlipped(self, _cmd) ? YES:NO;
|
return impl->isFlipped(self, _cmd) ? YES:NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef void (*wxOSX_DrawRectHandlerPtr)(NSView* self, SEL _cmd, NSRect rect);
|
||||||
|
|
||||||
void wxOSX_drawRect(NSView* self, SEL _cmd, NSRect rect)
|
void wxOSX_drawRect(NSView* self, SEL _cmd, NSRect rect)
|
||||||
{
|
{
|
||||||
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
|
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
|
||||||
if (impl == NULL)
|
if (impl == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef wxUSE_THREADS
|
||||||
|
// OS X starts a NSUIHeartBeatThread for animating the default button in a
|
||||||
|
// dialog. This causes a drawRect of the active dialog from outside the
|
||||||
|
// main UI thread. This causes an occasional crash since the wx drawing
|
||||||
|
// objects (like wxPen) are not thread safe.
|
||||||
|
//
|
||||||
|
// Notice that NSUIHeartBeatThread seems to be undocumented and doing
|
||||||
|
// [NSWindow setAllowsConcurrentViewDrawing:NO] does not affect it.
|
||||||
|
if ( !wxThread::IsMain() )
|
||||||
|
{
|
||||||
|
// just call the superclass handler, we don't need any custom wx drawing
|
||||||
|
// here and it seems to work fine:
|
||||||
|
wxOSX_DrawRectHandlerPtr
|
||||||
|
superimpl = (wxOSX_DrawRectHandlerPtr)
|
||||||
|
[[self superclass] instanceMethodForSelector:_cmd];
|
||||||
|
superimpl(self, _cmd, rect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // wxUSE_THREADS
|
||||||
|
|
||||||
return impl->drawRect(&rect, self, _cmd);
|
return impl->drawRect(&rect, self, _cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -960,7 +982,6 @@ typedef void (*wxOSX_EventHandlerPtr)(NSView* self, SEL _cmd, NSEvent *event);
|
|||||||
typedef BOOL (*wxOSX_PerformKeyEventHandlerPtr)(NSView* self, SEL _cmd, NSEvent *event);
|
typedef BOOL (*wxOSX_PerformKeyEventHandlerPtr)(NSView* self, SEL _cmd, NSEvent *event);
|
||||||
typedef BOOL (*wxOSX_FocusHandlerPtr)(NSView* self, SEL _cmd);
|
typedef BOOL (*wxOSX_FocusHandlerPtr)(NSView* self, SEL _cmd);
|
||||||
typedef BOOL (*wxOSX_ResetCursorRectsHandlerPtr)(NSView* self, SEL _cmd);
|
typedef BOOL (*wxOSX_ResetCursorRectsHandlerPtr)(NSView* self, SEL _cmd);
|
||||||
typedef void (*wxOSX_DrawRectHandlerPtr)(NSView* self, SEL _cmd, NSRect rect);
|
|
||||||
|
|
||||||
void wxWidgetCocoaImpl::mouseEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
|
void wxWidgetCocoaImpl::mouseEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user