From: Stefan Csomor Date: Wed, 25 Mar 2009 10:24:51 +0000 (+0000) Subject: focus handling streamlined X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/f06e0fea676e558dd010bda2e82822f7d9653771 focus handling streamlined git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59835 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/osx/carbon/private.h b/include/wx/osx/carbon/private.h index 2d0f7ea0a8..7a10d3bf29 100644 --- a/include/wx/osx/carbon/private.h +++ b/include/wx/osx/carbon/private.h @@ -38,7 +38,6 @@ typedef SInt32 SRefCon; bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec); #endif -WXDLLIMPEXP_CORE wxWindowMac * wxFindWindowFromWXWidget(WXWidget inControl ); // TODO REMOVE WXDLLIMPEXP_CORE wxNonOwnedWindow* wxFindWindowFromWXWindow( WXWindow inWindow ); #endif // wxUSE_GUI diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index b514797d89..ca5405dcf8 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -32,6 +32,8 @@ wxString WXDLLIMPEXP_CORE wxMacMakeStringFromPascal( const unsigned char * from #if wxUSE_GUI +WXDLLIMPEXP_CORE wxWindowMac * wxFindWindowFromWXWidget(WXWidget inControl ); + #if wxOSX_USE_IPHONE #include #else @@ -258,6 +260,8 @@ public : static void Associate( WXWidget control, wxWidgetImpl *impl ); + static WXWidget FindFocus(); + // static creation methods, must be implemented by all toolkits static wxWidgetImplType* CreateUserPane( wxWindowMac* wxpeer, diff --git a/src/osx/carbon/window.cpp b/src/osx/carbon/window.cpp index e4ff772b8f..b1293cfa17 100644 --- a/src/osx/carbon/window.cpp +++ b/src/osx/carbon/window.cpp @@ -79,6 +79,14 @@ #define wxMAC_DEBUG_REDRAW 0 #endif +// Get the window with the focus +WXWidget wxWidgetImpl::FindFocus() +{ + ControlRef control = NULL ; + GetKeyboardFocus( GetUserFocusWindow() , &control ) ; + return control; +} + // --------------------------------------------------------------------------- // Carbon Events // --------------------------------------------------------------------------- diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index 399db3f0df..cf91905014 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -31,6 +31,29 @@ #include +// 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 ; @@ -47,7 +70,6 @@ NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const NSTrackingRectTag rectTag; } -- (BOOL) canBecomeKeyView; // the tracking tag is needed to track mouse enter / exit events - (void) setTrackingTag: (NSTrackingRectTag)tag; - (NSTrackingRectTag) trackingTag; @@ -439,11 +461,6 @@ void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent ) } } -- (BOOL) canBecomeKeyView -{ - return YES; -} - - (void) setTrackingTag: (NSTrackingRectTag)tag { rectTag = tag; @@ -793,22 +810,26 @@ bool wxWidgetCocoaImpl::performKeyEquivalent(WX_NSEvent event, WXWidget slf, voi bool wxWidgetCocoaImpl::acceptsFirstResponder(WXWidget slf, void *_cmd) { - // FIXME: We need to find a way to query AcceptsFocus here, but when we do it - // it calls native APIs which lead us back here and into a loop. - wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd]; - return superimpl(slf, (SEL)_cmd); + 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 - NSResponder* currentResponder = [[NSApp keyWindow] firstResponder]; - NSView* otherView = (currentResponder != nil && [currentResponder isKindOfClass:[NSView class]]) ? (NSView*) currentResponder : NULL; + NSView* otherView = FindFocus(); wxWidgetImpl* otherWindow = FindFromWXWidget(otherView); BOOL r = superimpl(slf, (SEL)_cmd); if ( r ) + { DoNotifyFocusEvent( true, otherWindow ); + } return r; } @@ -817,11 +838,14 @@ bool wxWidgetCocoaImpl::resignFirstResponder(WXWidget slf, void *_cmd) wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd]; BOOL r = superimpl(slf, (SEL)_cmd); // get the current focus after running resignFirstResponder - NSResponder* currentResponder = [[NSApp keyWindow] firstResponder]; - NSView* otherView = (currentResponder != nil && [currentResponder isKindOfClass:[NSView class]]) ? (NSView*) currentResponder : NULL; + NSView* otherView = FindFocus(); wxWidgetImpl* otherWindow = FindFromWXWidget(otherView); - if ( 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 hen + if ( r && otherWindow != this) + { DoNotifyFocusEvent( false, otherWindow ); + } return r; } @@ -1163,7 +1187,7 @@ bool wxWidgetCocoaImpl::CanFocus() const bool wxWidgetCocoaImpl::HasFocus() const { - return ( [[m_osxView window] firstResponder] == m_osxView ); + return ( FindFocus() == m_osxView ); } bool wxWidgetCocoaImpl::SetFocus() diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 4f99e89bc1..da9e32a5e1 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -200,10 +200,6 @@ WXWidget wxWindowMac::GetHandle() const return NULL; } -// -// TODO END move to window_osx.cpp -// - // --------------------------------------------------------------------------- // Utility Routines to move between different coordinate systems // --------------------------------------------------------------------------- @@ -1515,16 +1511,9 @@ void wxWindowMac::MacOnScroll( wxScrollEvent &event ) } } -// Get the window with the focus wxWindow *wxWindowBase::DoFindFocus() { -#if wxOSX_USE_CARBON - ControlRef control ; - GetKeyboardFocus( GetUserFocusWindow() , &control ) ; - return wxFindWindowFromWXWidget( (WXWidget) control ) ; -#else - return NULL; -#endif + return wxFindWindowFromWXWidget(wxWidgetImpl::FindFocus()); } void wxWindowMac::OnInternalIdle() @@ -2006,7 +1995,10 @@ void wxWindowMac::MacRepositionScrollBars() bool wxWindowMac::AcceptsFocus() const { - return m_peer->CanFocus() && wxWindowBase::AcceptsFocus(); + if ( MacIsUserPane() ) + return wxWindowBase::AcceptsFocus(); + else + return m_peer->CanFocus(); } void wxWindowMac::MacSuperChangedPosition()