From 6749ca7405ba2d9c5b7671b75a511056e3a4f543 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 18 May 2014 10:44:24 +0000 Subject: [PATCH] Refactoring to common code for focus set and lost events, so that changes can be made a single place See #14269. (this is a backport of 2b99f92 from master) --- include/wx/osx/cocoa/private.h | 2 ++ src/osx/cocoa/window.mm | 52 ++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index e5c9fcf209..94cca7d4df 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -129,6 +129,8 @@ public : virtual bool DoHandleMouseEvent(NSEvent *event); virtual bool DoHandleKeyEvent(NSEvent *event); virtual bool DoHandleCharEvent(NSEvent *event, NSString *text); + virtual void DoNotifyFocusSet(); + virtual void DoNotifyFocusLost(); virtual void DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow); virtual void SetupKeyEvent(wxKeyEvent &wxevent, NSEvent * nsEvent, NSString* charString = NULL); diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index ede8ebf778..517ae4a53a 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -1513,15 +1513,9 @@ bool wxWidgetCocoaImpl::acceptsFirstResponder(WXWidget slf, void *_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, otherWindow ); - } + DoNotifyFocusSet(); return r; } @@ -1530,23 +1524,13 @@ bool wxWidgetCocoaImpl::resignFirstResponder(WXWidget slf, void *_cmd) { wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd]; BOOL r = superimpl(slf, (SEL)_cmd); - - NSResponder * responder = wxNonOwnedWindowCocoaImpl::GetNextFirstResponder(); - NSView* otherView = wxOSXGetViewFromResponder(responder); - - wxWidgetImpl* otherWindow = FindBestFromWXWidget(otherView); - // It doesn't make sense to notify about the loss of focus if it's the same - // control in the end, and just a different subview - 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 + // wxNSTextFields and wxNSComboBoxes have an editor as real responder, therefore they get + // a resign notification when their editor takes over, don't trigger event here, the control + // gets a controlTextDidEndEditing notification which will send a focus kill. if ( r && !m_hasEditor) - { - DoNotifyFocusEvent( false, otherWindow ); - } + DoNotifyFocusLost(); + return r; } @@ -2793,6 +2777,30 @@ bool wxWidgetCocoaImpl::DoHandleMouseEvent(NSEvent *event) return result; } +void wxWidgetCocoaImpl::DoNotifyFocusSet() +{ + NSResponder* responder = wxNonOwnedWindowCocoaImpl::GetFormerFirstResponder(); + NSView* otherView = wxOSXGetViewFromResponder(responder); + wxWidgetImpl* otherWindow = FindFromWXWidget(otherView); + + // It doesn't make sense to notify about the focus set if it's the same + // control in the end, and just a different subview + if ( otherWindow != this ) + DoNotifyFocusEvent(true, otherWindow); +} + +void wxWidgetCocoaImpl::DoNotifyFocusLost() +{ + NSResponder * responder = wxNonOwnedWindowCocoaImpl::GetNextFirstResponder(); + NSView* otherView = wxOSXGetViewFromResponder(responder); + wxWidgetImpl* otherWindow = FindBestFromWXWidget(otherView); + + // It doesn't make sense to notify about the loss of focus if it's the same + // control in the end, and just a different subview + if ( otherWindow != this ) + DoNotifyFocusEvent( false, otherWindow ); +} + void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow) { wxWindow* thisWindow = GetWXPeer();