Draw wxTextCtrl focus ring natively on Mac

NSTextView doesn't display focus ring by default, which is why wxOSX
did draw it manually, but this behavior can be overriden since OS X
10.3 with NSView.focusRingType property.

The HITheme-based rendering suffered from a number of non-nativeness
issues:
- didn't respect macOS 10.14+ accent colors
- not animated as the native focus ring
- subtly different shape of the outline
- noticeably different outline shape on macOS 11

Remove NeedsFocusRect() and associated workaround for manually drawing
focus ring inside NSTextView (i.e. multiline text controls). This
private interface was only used for wxTextCtrl and nothing else, so
this shouldn't have any impact elsewhere.
This commit is contained in:
Václav Slavík
2020-08-27 18:12:18 +02:00
parent 9e68df224f
commit 58c94d9ec0
7 changed files with 10 additions and 35 deletions

View File

@@ -111,6 +111,8 @@ public :
virtual void SetNeedsDisplay( const wxRect* where = NULL ) wxOVERRIDE;
virtual bool GetNeedsDisplay() const wxOVERRIDE;
virtual void EnableFocusRing(bool enabled) wxOVERRIDE;
virtual void SetDrawingEnabled(bool enabled) wxOVERRIDE;
virtual bool CanFocus() const wxOVERRIDE;

View File

@@ -301,8 +301,7 @@ public :
virtual void SetNeedsDisplay( const wxRect* where = NULL ) = 0;
virtual bool GetNeedsDisplay() const = 0;
virtual bool NeedsFocusRect() const;
virtual void SetNeedsFocusRect( bool needs );
virtual void EnableFocusRing(bool WXUNUSED(enabled)) {}
virtual bool NeedsFrame() const;
virtual void SetNeedsFrame( bool needs );
@@ -598,7 +597,6 @@ protected :
bool m_wantsUserKey;
bool m_wantsUserMouse;
wxWindowMac* m_wxPeer;
bool m_needsFocusRect;
bool m_needsFrame;
bool m_shouldSendEvents;

View File

@@ -462,7 +462,7 @@ void wxGridCellTextEditor::DoCreate(wxWindow* parent,
#ifdef __WXOSX__
wxWidgetImpl* impl = m_control->GetPeer();
impl->SetNeedsFocusRect(false);
impl->EnableFocusRing(false);
#endif
// set max length allowed in the textctrl, if the parameter was set
if ( m_maxChars != 0 )

View File

@@ -1590,7 +1590,7 @@ wxWidgetImplType* wxWidgetImpl::CreateTextControl( wxTextCtrl* wxpeer,
v = [[wxNSTextScrollView alloc] initWithFrame:r];
wxNSTextViewControl* t = new wxNSTextViewControl( wxpeer, v, style );
c = t;
c->SetNeedsFocusRect( true );
c->EnableFocusRing( true );
t->SetStringValue(str);
}

View File

@@ -3849,10 +3849,6 @@ void wxWidgetCocoaImpl::DoNotifyFocusLost()
void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow)
{
wxWindow* thisWindow = GetWXPeer();
if ( thisWindow->MacGetTopLevelWindow() && NeedsFocusRect() )
{
thisWindow->MacInvalidateBorders();
}
if ( receivedFocus )
{
@@ -3925,6 +3921,11 @@ void wxWidgetCocoaImpl::SetFlipped(bool flipped)
#endif
void wxWidgetCocoaImpl::EnableFocusRing(bool enabled)
{
[m_osxView setFocusRingType:enabled ? NSFocusRingTypeExterior : NSFocusRingTypeNone];
}
void wxWidgetCocoaImpl::SetDrawingEnabled(bool enabled)
{
if ( [m_osxView window] == nil )

View File

@@ -642,10 +642,6 @@ void wxWidgetIPhoneImpl::InstallEventHandler( WXWidget control )
void wxWidgetIPhoneImpl::DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow)
{
wxWindow* thisWindow = GetWXPeer();
if ( thisWindow->MacGetTopLevelWindow() && NeedsFocusRect() )
{
thisWindow->MacInvalidateBorders();
}
if ( receivedFocus )
{

View File

@@ -938,9 +938,6 @@ void wxWindowMac::MacInvalidateBorders()
int outerBorder = MacGetLeftBorderSize() ;
if ( GetPeer()->NeedsFocusRect() )
outerBorder += 4 ;
if ( outerBorder == 0 )
return ;
@@ -1578,8 +1575,6 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right
#if wxOSX_USE_COCOA_OR_CARBON
{
const bool hasFocus = GetPeer()->NeedsFocusRect() && HasFocus();
CGRect cgrect = CGRectMake( tx-1 , ty-1 , tw+2 ,
th+2 ) ;
@@ -1594,7 +1589,6 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right
info.version = 0 ;
info.kind = 0 ;
info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
info.isFocused = hasFocus ;
if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
{
@@ -1607,11 +1601,6 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right
HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
}
}
if ( hasFocus )
{
HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
}
}
#endif // wxOSX_USE_COCOA_OR_CARBON
}
@@ -2746,20 +2735,9 @@ void wxWidgetImpl::Init()
m_wantsUserKey = false;
m_wantsUserMouse = false;
m_wxPeer = NULL;
m_needsFocusRect = false;
m_needsFrame = true;
}
void wxWidgetImpl::SetNeedsFocusRect( bool needs )
{
m_needsFocusRect = needs;
}
bool wxWidgetImpl::NeedsFocusRect() const
{
return m_needsFocusRect;
}
void wxWidgetImpl::SetNeedsFrame( bool needs )
{
m_needsFrame = needs;