Fix clipping of scrolled windows under macOS Sonoma
We need to use a native clip view for things to behave correctly under this OS version, otherwise scrollbars can be overdrawn by the window contents. Closes #24067. Closes #24073.
This commit is contained in:
parent
8ca312b17c
commit
bcbc31e97f
5 changed files with 98 additions and 4 deletions
|
|
@ -220,9 +220,14 @@ public :
|
||||||
// from the same pimpl class.
|
// from the same pimpl class.
|
||||||
virtual void controlTextDidChange();
|
virtual void controlTextDidChange();
|
||||||
|
|
||||||
|
virtual void AdjustClippingView(wxScrollBar* horizontal, wxScrollBar* vertical) override;
|
||||||
|
virtual void UseClippingView(bool clip) override;
|
||||||
|
virtual WXWidget GetContainer() const override { return m_osxClipView ? m_osxClipView : m_osxView; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
WXWidget m_osxView;
|
WXWidget m_osxView;
|
||||||
|
WXWidget m_osxClipView;
|
||||||
|
|
||||||
// begins processing of native key down event, storing the native event for later wx event generation
|
// begins processing of native key down event, storing the native event for later wx event generation
|
||||||
void BeginNativeKeyDownEvent( NSEvent* event );
|
void BeginNativeKeyDownEvent( NSEvent* event );
|
||||||
// done with the current native key down event
|
// done with the current native key down event
|
||||||
|
|
|
||||||
|
|
@ -365,6 +365,14 @@ public :
|
||||||
|
|
||||||
virtual bool EnableTouchEvents(int eventsMask) = 0;
|
virtual bool EnableTouchEvents(int eventsMask) = 0;
|
||||||
|
|
||||||
|
// scrolling views need a clip subview that acts as parent for native children
|
||||||
|
// (except for the scollbars) which are children of the view itself
|
||||||
|
virtual void AdjustClippingView(wxScrollBar* horizontal, wxScrollBar* vertical);
|
||||||
|
virtual void UseClippingView(bool clip);
|
||||||
|
|
||||||
|
// returns native view which acts as a parent for native children
|
||||||
|
virtual WXWidget GetContainer() const;
|
||||||
|
|
||||||
// Mechanism used to keep track of whether a change should send an event
|
// Mechanism used to keep track of whether a change should send an event
|
||||||
// Do SendEvents(false) when starting actions that would trigger programmatic events
|
// Do SendEvents(false) when starting actions that would trigger programmatic events
|
||||||
// and SendEvents(true) at the end of the block.
|
// and SendEvents(true) at the end of the block.
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ public:
|
||||||
// returns true if children have to clipped to the content area
|
// returns true if children have to clipped to the content area
|
||||||
// (e.g., scrolled windows)
|
// (e.g., scrolled windows)
|
||||||
bool MacClipChildren() const { return m_clipChildren ; }
|
bool MacClipChildren() const { return m_clipChildren ; }
|
||||||
void MacSetClipChildren( bool clip ) { m_clipChildren = clip ; }
|
void MacSetClipChildren( bool clip );
|
||||||
|
|
||||||
// returns true if the grandchildren need to be clipped to the children's content area
|
// returns true if the grandchildren need to be clipped to the children's content area
|
||||||
// (e.g., splitter windows)
|
// (e.g., splitter windows)
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include "wx/textctrl.h"
|
#include "wx/textctrl.h"
|
||||||
#include "wx/combobox.h"
|
#include "wx/combobox.h"
|
||||||
#include "wx/radiobut.h"
|
#include "wx/radiobut.h"
|
||||||
|
#include "wx/scrolbar.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __WXMAC__
|
#ifdef __WXMAC__
|
||||||
|
|
@ -2562,7 +2563,8 @@ wxWidgetImpl( peer, flags )
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
m_osxView = w;
|
m_osxView = w;
|
||||||
|
m_osxClipView = nil;
|
||||||
|
|
||||||
// check if the user wants to create the control initially hidden
|
// check if the user wants to create the control initially hidden
|
||||||
if ( !peer->IsShown() )
|
if ( !peer->IsShown() )
|
||||||
SetVisibility(false);
|
SetVisibility(false);
|
||||||
|
|
@ -3215,6 +3217,21 @@ bool wxWidgetCocoaImpl::CanFocus() const
|
||||||
return canFocus;
|
return canFocus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@interface wxNSClipView : NSClipView
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation wxNSClipView
|
||||||
|
|
||||||
|
#if wxOSX_USE_NATIVE_FLIPPED
|
||||||
|
- (BOOL)isFlipped
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
bool wxWidgetCocoaImpl::HasFocus() const
|
bool wxWidgetCocoaImpl::HasFocus() const
|
||||||
{
|
{
|
||||||
NSView* targetView = m_osxView;
|
NSView* targetView = m_osxView;
|
||||||
|
|
@ -3305,7 +3322,13 @@ void wxWidgetCocoaImpl::RemoveFromParent()
|
||||||
|
|
||||||
void wxWidgetCocoaImpl::Embed( wxWidgetImpl *parent )
|
void wxWidgetCocoaImpl::Embed( wxWidgetImpl *parent )
|
||||||
{
|
{
|
||||||
NSView* container = parent->GetWXWidget() ;
|
NSView* container = nil;
|
||||||
|
|
||||||
|
if ( m_wxPeer->MacIsWindowScrollbar( parent->GetWXPeer()))
|
||||||
|
container = parent->GetWXWidget();
|
||||||
|
else
|
||||||
|
container = parent->GetContainer();
|
||||||
|
|
||||||
wxASSERT_MSG( container != nullptr , wxT("No valid mac container control") ) ;
|
wxASSERT_MSG( container != nullptr , wxT("No valid mac container control") ) ;
|
||||||
[container addSubview:m_osxView];
|
[container addSubview:m_osxView];
|
||||||
|
|
||||||
|
|
@ -4034,6 +4057,41 @@ void wxWidgetCocoaImpl::SetDrawingEnabled(bool enabled)
|
||||||
[[m_osxView window] disableFlushWindow];
|
[[m_osxView window] disableFlushWindow];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxWidgetCocoaImpl::AdjustClippingView(wxScrollBar* horizontal, wxScrollBar* vertical)
|
||||||
|
{
|
||||||
|
if( m_osxClipView )
|
||||||
|
{
|
||||||
|
NSRect bounds = m_osxView.bounds;
|
||||||
|
if( horizontal && horizontal->IsShown() )
|
||||||
|
{
|
||||||
|
int sz = horizontal->GetSize().y;
|
||||||
|
bounds.size.height -= sz;
|
||||||
|
}
|
||||||
|
if( vertical && vertical->IsShown() )
|
||||||
|
{
|
||||||
|
int sz = vertical->GetSize().x;
|
||||||
|
bounds.size.width -= sz;
|
||||||
|
}
|
||||||
|
m_osxClipView.frame = bounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWidgetCocoaImpl::UseClippingView(bool clip)
|
||||||
|
{
|
||||||
|
wxWindow* peer = m_wxPeer;
|
||||||
|
|
||||||
|
if ( peer && m_osxClipView == nil)
|
||||||
|
{
|
||||||
|
m_osxClipView = [[wxNSClipView alloc] initWithFrame: m_osxView.bounds];
|
||||||
|
[(NSClipView*)m_osxClipView setDrawsBackground: NO];
|
||||||
|
[m_osxView addSubview:m_osxClipView];
|
||||||
|
|
||||||
|
// TODO check for additional subwindows which might have to be moved to the clip view ?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Factory methods
|
// Factory methods
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -261,6 +261,13 @@ wxWindowMac::~wxWindowMac()
|
||||||
delete GetPeer() ;
|
delete GetPeer() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxWindowMac::MacSetClipChildren( bool clip )
|
||||||
|
{
|
||||||
|
m_clipChildren = clip ;
|
||||||
|
if ( m_peer )
|
||||||
|
m_peer->UseClippingView(clip);
|
||||||
|
}
|
||||||
|
|
||||||
WXWidget wxWindowMac::GetHandle() const
|
WXWidget wxWindowMac::GetHandle() const
|
||||||
{
|
{
|
||||||
if ( GetPeer() )
|
if ( GetPeer() )
|
||||||
|
|
@ -386,6 +393,8 @@ bool wxWindowMac::Create(wxWindowMac *parent,
|
||||||
{
|
{
|
||||||
SetPeer(wxWidgetImpl::CreateUserPane( this, parent, id, pos, size , style, GetExtraStyle() ));
|
SetPeer(wxWidgetImpl::CreateUserPane( this, parent, id, pos, size , style, GetExtraStyle() ));
|
||||||
MacPostControlCreate(pos, size) ;
|
MacPostControlCreate(pos, size) ;
|
||||||
|
if ( m_clipChildren )
|
||||||
|
m_peer->UseClippingView(m_clipChildren);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxWindowCreateEvent event((wxWindow*)this);
|
wxWindowCreateEvent event((wxWindow*)this);
|
||||||
|
|
@ -2139,6 +2148,7 @@ void wxWindowMac::MacRepositionScrollBars()
|
||||||
m_growBox->Hide();
|
m_growBox->Hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_peer->AdjustClippingView(m_hScrollBar, m_vScrollBar);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2700,3 +2710,16 @@ bool wxWidgetImpl::NeedsFrame() const
|
||||||
void wxWidgetImpl::SetDrawingEnabled(bool WXUNUSED(enabled))
|
void wxWidgetImpl::SetDrawingEnabled(bool WXUNUSED(enabled))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxWidgetImpl::AdjustClippingView(wxScrollBar* WXUNUSED(horizontal), wxScrollBar* WXUNUSED(vertical))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWidgetImpl::UseClippingView(bool WXUNUSED(clip))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WXWidget wxWidgetImpl::GetContainer() const
|
||||||
|
{
|
||||||
|
return GetWXWidget();
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue