#include <objc/objc-runtime.h>
+// Get the window with the focus
+
+WXWidget wxWidgetImpl::FindFocus()
+{
+ NSView* focusedView = nil;
+ NSWindow* keyWindow = [[NSApplication sharedApplication] keyWindow];
+ if ( keyWindow != nil )
+ {
+ NSResponder* responder = [keyWindow firstResponder];
+ if ( [responder isKindOfClass:[NSTextView class]] &&
+ [keyWindow fieldEditor:NO forObject:nil] != nil )
+ {
+ focusedView = [(NSTextView*)responder delegate];
+ }
+ else
+ {
+ if ( [responder isKindOfClass:[NSView class]] )
+ focusedView = (NSView*) responder;
+ }
+ }
+ return focusedView;
+}
+
NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
{
int x, y, w, h ;
NSTrackingRectTag rectTag;
}
-- (BOOL) canBecomeKeyView;
// the tracking tag is needed to track mouse enter / exit events
- (void) setTrackingTag: (NSTrackingRectTag)tag;
- (NSTrackingRectTag) trackingTag;
- (void)setImage:(NSImage *)image;
- (void)setControlSize:(NSControlSize)size;
+- (void)setFont:(NSFont *)fontObject;
+
- (id)contentView;
- (void)setTarget:(id)anObject;
}
}
-- (BOOL) canBecomeKeyView
-{
- return YES;
-}
-
- (void) setTrackingTag: (NSTrackingRectTag)tag
{
rectTag = tag;
impl->controlDoubleAction(self, _cmd, sender);
}
-unsigned int wxWidgetCocoaImpl::draggingEntered(void* s, WXWidget slf, void *_cmd)
+unsigned int wxWidgetCocoaImpl::draggingEntered(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
NSPasteboard *pboard = [sender draggingPasteboard];
return nsresult;
}
-void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget slf, void *_cmd)
+void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
NSPasteboard *pboard = [sender draggingPasteboard];
CFRelease(pboardRef);
}
-unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget slf, void *_cmd)
+unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
NSPasteboard *pboard = [sender draggingPasteboard];
return nsresult;
}
-bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget slf, void *_cmd)
+bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
bool wxWidgetCocoaImpl::acceptsFirstResponder(WXWidget slf, void *_cmd)
{
- // Make sure wxWindows can receive focus by default like they do for other ports.
-
- // FIXME: It'd be nice to have some way to tie this in with AcceptsFocus
- // but that currently causes loops because the call to m_peer->CanFocus()
- // ends up calling this method again. Don't know how to avoid it without
- // making a setter method for focus.
- return YES;
+ if ( m_wxPeer->MacIsUserPane() )
+ return m_wxPeer->AcceptsFocus();
+ else
+ {
+ wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
+ return superimpl(slf, (SEL)_cmd);
+ }
}
bool wxWidgetCocoaImpl::becomeFirstResponder(WXWidget slf, void *_cmd)
{
wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
+ // get the current focus before running becomeFirstResponder
+ NSView* otherView = FindFocus();
+ wxWidgetImpl* otherWindow = FindFromWXWidget(otherView);
BOOL r = superimpl(slf, (SEL)_cmd);
if ( r )
- DoNotifyFocusEvent( true );
+ {
+ DoNotifyFocusEvent( true, otherWindow );
+ }
return r;
}
{
wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
BOOL r = superimpl(slf, (SEL)_cmd);
- if ( r )
- DoNotifyFocusEvent( false );
+ // get the current focus after running resignFirstResponder
+ NSView* otherView = FindFocus();
+ wxWidgetImpl* otherWindow = FindFromWXWidget(otherView);
+ // NSTextViews have an editor as true responder, therefore the might get the
+ // resign notification if their editor takes over, don't trigger any event hen
+ if ( r && otherWindow != this)
+ {
+ DoNotifyFocusEvent( false, otherWindow );
+ }
return r;
}
}
}
-bool wxWidgetCocoaImpl::isFlipped(WXWidget slf, void *_cmd)
+bool wxWidgetCocoaImpl::isFlipped(WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{
return m_isFlipped;
}
#define OSX_DEBUG_DRAWING 0
-void wxWidgetCocoaImpl::drawRect(void* rect, WXWidget slf, void *_cmd)
+void wxWidgetCocoaImpl::drawRect(void* rect, WXWidget slf, void *WXUNUSED(_cmd))
{
CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
CGContextSaveGState( context );
CGContextRestoreGState( context );
}
-void wxWidgetCocoaImpl::controlAction( WXWidget slf, void *_cmd, void *sender)
+void wxWidgetCocoaImpl::controlAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender))
{
wxWindow* wxpeer = (wxWindow*) GetWXPeer();
if ( wxpeer )
wxpeer->OSXHandleClicked(0);
}
-void wxWidgetCocoaImpl::controlDoubleAction( WXWidget slf, void *_cmd, void *sender)
+void wxWidgetCocoaImpl::controlDoubleAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender))
{
}
{
}
-void wxWidgetCocoaImpl::ScrollRect( const wxRect *rect, int dx, int dy )
+void wxWidgetCocoaImpl::ScrollRect( const wxRect *WXUNUSED(rect), int WXUNUSED(dx), int WXUNUSED(dy) )
{
#if 1
SetNeedsDisplay() ;
wxWindowMac* parent = GetWXPeer()->GetParent();
// under Cocoa we might have a contentView in the wxParent to which we have to
// adjust the coordinates
- if (parent)
+ if (parent && [m_osxView superview] != parent->GetHandle() )
{
int cx = 0,cy = 0,cw = 0,ch = 0;
if ( parent->GetPeer() )
y -= cy;
}
}
+ [[m_osxView superview] setNeedsDisplayInRect:[m_osxView frame]];
NSRect r = wxToNSRect( [m_osxView superview], wxRect(x,y,width, height) );
[m_osxView setFrame:r];
+ [[m_osxView superview] setNeedsDisplayInRect:r];
if ([m_osxView respondsToSelector:@selector(trackingTag)] )
{
bool wxWidgetCocoaImpl::HasFocus() const
{
- return ( [[m_osxView window] firstResponder] == m_osxView );
+ return ( FindFocus() == m_osxView );
}
bool wxWidgetCocoaImpl::SetFocus()
{
if ( [m_osxView respondsToSelector:@selector(setTitle:) ] )
{
- wxCFStringRef cf( title , m_wxPeer->GetFont().GetEncoding() );
+ wxCFStringRef cf( title , encoding );
[m_osxView setTitle:cf.AsNSString()];
}
else if ( [m_osxView respondsToSelector:@selector(setStringValue:) ] )
{
- wxCFStringRef cf( title , m_wxPeer->GetFont().GetEncoding() );
+ wxCFStringRef cf( title , encoding );
[m_osxView setStringValue:cf.AsNSString()];
}
}
}
}
-void wxWidgetCocoaImpl::SetupTabs( const wxNotebook& notebook)
+void wxWidgetCocoaImpl::SetupTabs( const wxNotebook& WXUNUSED(notebook))
{
// implementation in subclass
}
{
}
-void wxWidgetCocoaImpl::SetScrollThumb( wxInt32 val, wxInt32 view )
+void wxWidgetCocoaImpl::SetScrollThumb( wxInt32 WXUNUSED(val), wxInt32 WXUNUSED(view) )
{
}
void wxWidgetCocoaImpl::SetFont(wxFont const& font, wxColour const&, long, bool)
{
if ([m_osxView respondsToSelector:@selector(setFont:)])
-#if wxOSX_USE_CORE_TEXT
- [m_osxView setFont: (CTFontRef)font.MacGetCTFont()];
-#else
-
-#endif
+ [m_osxView setFont: font.OSXGetNSFont()];
}
void wxWidgetCocoaImpl::InstallEventHandler( WXWidget control )
return GetWXPeer()->HandleWindowEvent(wxevent);
}
-void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus)
+void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow)
{
wxWindow* thisWindow = GetWXPeer();
if ( thisWindow->MacGetTopLevelWindow() && NeedsFocusRect() )
wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
- // TODO how to find out the targetFocusWindow ?
- // event.SetWindow(targetFocusWindow);
+ if (otherWindow)
+ event.SetWindow(otherWindow->GetWXPeer());
thisWindow->HandleWindowEvent(event) ;
}
else // !receivedFocuss
wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
- // TODO how to find out the targetFocusWindow ?
- // event.SetWindow(targetFocusWindow);
+ if (otherWindow)
+ event.SetWindow(otherWindow->GetWXPeer());
thisWindow->HandleWindowEvent(event) ;
}
}
// Factory methods
//
-wxWidgetImpl* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, wxWindowMac* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
- long style, long extraStyle)
+wxWidgetImpl* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(parent),
+ wxWindowID WXUNUSED(id), const wxPoint& pos, const wxSize& size,
+ long WXUNUSED(style), long WXUNUSED(extraStyle))
{
NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
wxNSView* v = [[wxNSView alloc] initWithFrame:r];