Fix change the shaped of a shaped window under Mac

The shape path was not reset when another region shape was set, so add
a workaround to trigger a recalculation of the TLW’s outer shape.

Closes #18775.
This commit is contained in:
Stefan Csomor
2020-07-21 08:54:28 +02:00
committed by Vadim Zeitlin
parent d58e3e3ce6
commit e93e9558f4
2 changed files with 18 additions and 4 deletions

View File

@@ -997,6 +997,13 @@ void wxNonOwnedWindowCocoaImpl::GetContentArea( int& left, int &top, int &width,
bool wxNonOwnedWindowCocoaImpl::SetShape(const wxRegion& WXUNUSED(region)) bool wxNonOwnedWindowCocoaImpl::SetShape(const wxRegion& WXUNUSED(region))
{ {
// macOS caches the contour of the drawn area, so when the region is changed and the content view redrawn
// the shape of the tlw does not change, this is a workaround I found that leads to a contour-refresh ...
NSRect formerFrame = [m_macWindow frame];
NSSize formerSize = [NSWindow contentRectForFrameRect:formerFrame styleMask:[m_macWindow styleMask]].size;
[m_macWindow setContentSize:NSMakeSize(10,10)];
[m_macWindow setContentSize:formerSize];
[m_macWindow setOpaque:NO]; [m_macWindow setOpaque:NO];
[m_macWindow setBackgroundColor:[NSColor clearColor]]; [m_macWindow setBackgroundColor:[NSColor clearColor]];

View File

@@ -510,6 +510,7 @@ void *wxNonOwnedWindow::OSXGetViewOrWindow() const
bool wxNonOwnedWindow::DoClearShape() bool wxNonOwnedWindow::DoClearShape()
{ {
m_shape.Clear(); m_shape.Clear();
m_shapePath = wxGraphicsPath();
wxSize sz = GetClientSize(); wxSize sz = GetClientSize();
wxRegion region(0, 0, sz.x, sz.y); wxRegion region(0, 0, sz.x, sz.y);
@@ -519,11 +520,13 @@ bool wxNonOwnedWindow::DoClearShape()
bool wxNonOwnedWindow::DoSetRegionShape(const wxRegion& region) bool wxNonOwnedWindow::DoSetRegionShape(const wxRegion& region)
{ {
m_shapePath = wxGraphicsPath();
m_shape = region; m_shape = region;
// set the native content view to transparency, this is an implementation detail // set the native content view to transparency, this is an implementation detail
// no reflected in the wx BackgroundStyle // no reflected in the wx BackgroundStyle
GetPeer()->SetBackgroundStyle(wxBG_STYLE_TRANSPARENT); GetPeer()->SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
GetPeer()->SetNeedsDisplay();
return m_nowpeer->SetShape(region); return m_nowpeer->SetShape(region);
} }
@@ -534,8 +537,6 @@ bool wxNonOwnedWindow::DoSetRegionShape(const wxRegion& region)
bool wxNonOwnedWindow::DoSetPathShape(const wxGraphicsPath& path) bool wxNonOwnedWindow::DoSetPathShape(const wxGraphicsPath& path)
{ {
m_shapePath = path;
// Convert the path to wxRegion by rendering the path on a window-sized // Convert the path to wxRegion by rendering the path on a window-sized
// bitmap, creating a mask from it and finally creating the region from // bitmap, creating a mask from it and finally creating the region from
// this mask. // this mask.
@@ -548,12 +549,18 @@ bool wxNonOwnedWindow::DoSetPathShape(const wxGraphicsPath& path)
wxScopedPtr<wxGraphicsContext> context(wxGraphicsContext::Create(dc)); wxScopedPtr<wxGraphicsContext> context(wxGraphicsContext::Create(dc));
context->SetBrush(*wxWHITE); context->SetBrush(*wxWHITE);
context->FillPath(m_shapePath); context->FillPath(path);
} }
bmp.SetMask(new wxMask(bmp, *wxBLACK)); bmp.SetMask(new wxMask(bmp, *wxBLACK));
return DoSetRegionShape(wxRegion(bmp)); // the shape path has to be set AFTER the region is set, because that method
// clears any former path
bool success = DoSetRegionShape(wxRegion(bmp));
if ( success )
m_shapePath = path;
return success;
} }
void void