#include "wx/frame.h"
#include "wx/log.h"
#include "wx/textctrl.h"
+ #include "wx/combobox.h"
#endif
#ifdef __WXMAC__
WXWidget wxWidgetImpl::FindFocus()
{
- return GetFocusedViewInWindow( [[NSApplication sharedApplication] keyWindow] );
+ return GetFocusedViewInWindow( [NSApp keyWindow] );
}
NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
// see http://lists.apple.com/archives/cocoa-dev/2007/Feb/msg00050.html
@interface NSEvent (DeviceDelta)
-- (float)deviceDeltaX;
-- (float)deviceDeltaY;
+- (CGFloat)deviceDeltaX;
+- (CGFloat)deviceDeltaY;
@end
void wxWidgetCocoaImpl::SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent )
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)
{
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
if (impl == NULL)
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);
}
typedef BOOL (*wxOSX_PerformKeyEventHandlerPtr)(NSView* self, SEL _cmd, NSEvent *event);
typedef BOOL (*wxOSX_FocusHandlerPtr)(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)
{
// is resigning
NSView* otherView = FindFocus();
wxWidgetImpl* otherWindow = FindFromWXWidget(otherView);
+
+ // It doesn't make sense to notify about the loss of focus if we're not
+ // really losing it and the window which has just gained focus is the same
+ // one as this window itself. Of course, this should never happen in the
+ // first place but somehow it does in wxGrid code and without this check we
+ // enter into an infinite recursion, see #12267.
+ if ( otherWindow == this )
+ return r;
+
// NSTextViews have an editor as true responder, therefore the might get the
// resign notification if their editor takes over, don't trigger any event then
if ( r && !m_hasEditor)
void wxWidgetCocoaImpl::drawRect(void* rect, WXWidget slf, void *WXUNUSED(_cmd))
{
- CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
- CGContextSaveGState( context );
-
-#if OSX_DEBUG_DRAWING
- CGContextBeginPath( context );
- CGContextMoveToPoint(context, 0, 0);
- NSRect bounds = [self bounds];
- CGContextAddLineToPoint(context, 10, 0);
- CGContextMoveToPoint(context, 0, 0);
- CGContextAddLineToPoint(context, 0, 10);
- CGContextMoveToPoint(context, bounds.size.width, bounds.size.height);
- CGContextAddLineToPoint(context, bounds.size.width, bounds.size.height-10);
- CGContextMoveToPoint(context, bounds.size.width, bounds.size.height);
- CGContextAddLineToPoint(context, bounds.size.width-10, bounds.size.height);
- CGContextClosePath( context );
- CGContextStrokePath(context);
-#endif
-
- if ( !m_isFlipped )
- {
- CGContextTranslateCTM( context, 0, [m_osxView bounds].size.height );
- CGContextScaleCTM( context, 1, -1 );
- }
-
+ // preparing the update region
+
wxRegion updateRgn;
const NSRect *rects;
NSInteger count;
}
wxWindow* wxpeer = GetWXPeer();
+
+ if ( wxpeer->MacGetLeftBorderSize() != 0 || wxpeer->MacGetTopBorderSize() != 0 )
+ {
+ // as this update region is in native window locals we must adapt it to wx window local
+ updateRgn.Offset( wxpeer->MacGetLeftBorderSize() , wxpeer->MacGetTopBorderSize() );
+ }
+
if ( wxpeer->MacGetTopLevelWindow()->GetWindowStyle() & wxFRAME_SHAPED )
{
int xoffset = 0, yoffset = 0;
}
wxpeer->GetUpdateRegion() = updateRgn;
+
+ // setting up the drawing context
+
+ CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
+ CGContextSaveGState( context );
+
+#if OSX_DEBUG_DRAWING
+ CGContextBeginPath( context );
+ CGContextMoveToPoint(context, 0, 0);
+ NSRect bounds = [slf bounds];
+ CGContextAddLineToPoint(context, 10, 0);
+ CGContextMoveToPoint(context, 0, 0);
+ CGContextAddLineToPoint(context, 0, 10);
+ CGContextMoveToPoint(context, bounds.size.width, bounds.size.height);
+ CGContextAddLineToPoint(context, bounds.size.width, bounds.size.height-10);
+ CGContextMoveToPoint(context, bounds.size.width, bounds.size.height);
+ CGContextAddLineToPoint(context, bounds.size.width-10, bounds.size.height);
+ CGContextClosePath( context );
+ CGContextStrokePath(context);
+#endif
+
+ if ( !m_isFlipped )
+ {
+ CGContextTranslateCTM( context, 0, [m_osxView bounds].size.height );
+ CGContextScaleCTM( context, 1, -1 );
+ }
+
wxpeer->MacSetCGContextRef( context );
bool handled = wxpeer->MacDoRedraw( 0 );
wxWindow* wxpeer = (wxWindow*)GetWXPeer();
if ( wxpeer )
{
- wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, wxpeer->GetId());
- event.SetEventObject( wxpeer );
- event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
- wxpeer->HandleWindowEvent( event );
+ // since native rtti doesn't have to be enabled and wx' rtti is not aware of the mixin wxTextEntry, workaround is needed
+ wxTextCtrl *tc = wxDynamicCast( wxpeer , wxTextCtrl );
+ wxComboBox *cb = wxDynamicCast( wxpeer , wxComboBox );
+ if ( tc )
+ tc->SendTextUpdatedEventIfAllowed();
+ else if ( cb )
+ cb->SendTextUpdatedEventIfAllowed();
+ else
+ {
+ wxFAIL_MSG("Unexpected class for controlTextDidChange event");
+ }
}
}