From 3cec9fb412741c4b3cf34822ea7211a20d572456 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 10 Dec 2019 08:43:01 -0300 Subject: [PATCH 1/9] [OSX] fix BAD ACCESS (Segmentation Fault) when rapidly trying to open popups quicker than windows can be created. --- native/Avalonia.Native/src/OSX/window.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index c54829d750..cd8c6245ba 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -812,7 +812,13 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent - (void)drawRect:(NSRect)dirtyRect { + if (_parent == nullptr) + { + return; + } + _parent->BaseEvents->RunRenderPriorityJobs(); + @synchronized (self) { if(_swRenderedFrame != NULL) { From bb571a4a0341309411341b9efb0a160fe0a51009 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 10 Dec 2019 09:07:02 -0300 Subject: [PATCH 2/9] [OSX] access scaling and window size in thread safe manner. --- native/Avalonia.Native/src/OSX/gl.mm | 13 ++++---- native/Avalonia.Native/src/OSX/window.h | 2 ++ native/Avalonia.Native/src/OSX/window.mm | 42 +++++++++++++++++------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/gl.mm b/native/Avalonia.Native/src/OSX/gl.mm index 083adc927d..ba5183dfa1 100644 --- a/native/Avalonia.Native/src/OSX/gl.mm +++ b/native/Avalonia.Native/src/OSX/gl.mm @@ -1,6 +1,7 @@ #include "common.h" #include #include +#include "window.h" template char (&ArrayCounter(T (&a)[N]))[N]; #define ARRAY_COUNT(a) (sizeof(ArrayCounter(a))) @@ -181,12 +182,12 @@ extern IAvnGlFeature* GetGlFeature() class AvnGlRenderingSession : public ComSingleObject { - NSView* _view; - NSWindow* _window; + AvnView* _view; + AvnWindow* _window; NSOpenGLContext* _context; public: FORWARD_IUNKNOWN() - AvnGlRenderingSession(NSWindow*window, NSView* view, NSOpenGLContext* context) + AvnGlRenderingSession(AvnWindow*window, AvnView* view, NSOpenGLContext* context) { _context = context; _window = window; @@ -195,14 +196,12 @@ public: virtual HRESULT GetPixelSize(AvnPixelSize* ret) override { - auto fsize = [_view convertSizeToBacking: [_view frame].size]; - ret->Width = (int)fsize.width; - ret->Height = (int)fsize.height; + *ret = [_view getPixelSize]; return S_OK; } virtual HRESULT GetScaling(double* ret) override { - *ret = [_window backingScaleFactor]; + *ret = [_window getScaling]; return S_OK; } diff --git a/native/Avalonia.Native/src/OSX/window.h b/native/Avalonia.Native/src/OSX/window.h index 932bc56a2e..3e626675d2 100644 --- a/native/Avalonia.Native/src/OSX/window.h +++ b/native/Avalonia.Native/src/OSX/window.h @@ -12,6 +12,7 @@ class WindowBaseImpl; -(AvnPoint) translateLocalPoint:(AvnPoint)pt; -(void) setSwRenderedFrame: (AvnFramebuffer* _Nonnull) fb dispose: (IUnknown* _Nonnull) dispose; -(void) onClosed; +-(AvnPixelSize) getPixelSize; @end @interface AvnWindow : NSWindow @@ -22,6 +23,7 @@ class WindowBaseImpl; -(void) restoreParentWindow; -(bool) shouldTryToHandleEvents; -(void) applyMenu:(NSMenu *)menu; +-(double) getScaling; @end struct INSWindowHolder diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index cd8c6245ba..a73ab0a9a9 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -719,6 +719,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isXButton1Pressed, _isXButton2Pressed, _isMouseOver; NSEvent* _lastMouseDownEvent; bool _lastKeyHandled; + AvnPixelSize _lastPixelSize; } - (void)dealloc @@ -730,6 +731,11 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent _parent = NULL; } +-(AvnPixelSize) getPixelSize +{ + return _lastPixelSize; +} + - (NSEvent*) lastMouseDownEvent { return _lastMouseDownEvent; @@ -742,6 +748,8 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent [self setWantsLayer:YES]; _parent = parent; _area = nullptr; + _lastPixelSize.Height = 0; + _lastPixelSize.Width = 0; return self; } @@ -783,6 +791,10 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent [self addTrackingArea:_area]; _parent->UpdateCursor(); + + auto fsize = [self convertSizeToBacking: [self frame].size]; + _lastPixelSize.Width = (int)fsize.width; + _lastPixelSize.Height = (int)fsize.height; _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}); } @@ -885,7 +897,12 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent - (void) viewDidChangeBackingProperties { + auto fsize = [self convertSizeToBacking: [self frame].size]; + _lastPixelSize.Width = (int)fsize.width; + _lastPixelSize.Height = (int)fsize.height; + _parent->BaseEvents->ScalingChanged([_parent->Window backingScaleFactor]); + [super viewDidChangeBackingProperties]; } @@ -1167,6 +1184,12 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent bool _closed; NSMenu* _menu; bool _isAppMenuApplied; + double _lastScaling; +} + +-(double) getScaling +{ + return _lastScaling; } +(void)closeAll @@ -1238,6 +1261,8 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent [self setReleasedWhenClosed:false]; _parent = parent; [self setDelegate:self]; + + _lastScaling = [self backingScaleFactor]; return self; } @@ -1253,6 +1278,11 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent return true; } +- (void)windowDidChangeBackingProperties:(NSNotification *)notification +{ + _lastScaling = [self backingScaleFactor]; +} + - (void)windowWillClose:(NSNotification *)notification { _closed = true; @@ -1412,18 +1442,6 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent _parent->GetPosition(&position); _parent->BaseEvents->PositionChanged(position); } - -// TODO this breaks resizing. -/*- (void)windowDidResize:(NSNotification *)notification -{ - - auto parent = dynamic_cast(_parent.operator->()); - - if(parent != nullptr) - { - parent->WindowStateChanged(); - } -}*/ @end class PopupImpl : public virtual WindowBaseImpl, public IAvnPopup From 6383d4f1ea225e4e47dad7465a60ea1c95b1ebee Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 10 Dec 2019 12:05:49 -0300 Subject: [PATCH 3/9] [OSX] catch exceptions when window closed and tries to lockFocusIfCanDraw. --- native/Avalonia.Native/src/OSX/gl.mm | 11 ++++++++++- native/Avalonia.Native/src/OSX/window.mm | 9 ++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/gl.mm b/native/Avalonia.Native/src/OSX/gl.mm index ba5183dfa1..feb0643654 100644 --- a/native/Avalonia.Native/src/OSX/gl.mm +++ b/native/Avalonia.Native/src/OSX/gl.mm @@ -233,8 +233,17 @@ public: auto f = GetFeature(); if(f == NULL) return E_FAIL; - if(![_view lockFocusIfCanDraw]) + + @try + { + if(![_view lockFocusIfCanDraw]) + return E_ABORT; + } + @catch(NSException* exception) + { return E_ABORT; + } + auto gl = _context; CGLLockContext([_context CGLContextObj]); diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index a73ab0a9a9..a40a181ba7 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -291,7 +291,14 @@ public: { @autoreleasepool { - return [View lockFocusIfCanDraw] == YES; + @try + { + return [View lockFocusIfCanDraw] == YES; + } + @catch (NSException*) + { + return NO; + } } } From f5acf84fb6ae15fa8c5333caaed6cb92a4f8542f Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 10 Dec 2019 13:52:47 -0300 Subject: [PATCH 4/9] initialise closed variable. --- native/Avalonia.Native/src/OSX/window.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index a40a181ba7..08d4515d88 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -1268,6 +1268,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent [self setReleasedWhenClosed:false]; _parent = parent; [self setDelegate:self]; + _closed = false; _lastScaling = [self backingScaleFactor]; return self; From 586e96cd072562af74d0c182ad57853af0002260 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 10 Dec 2019 13:58:09 -0300 Subject: [PATCH 5/9] synchronise acces to lockFocusIfCanDraw. --- native/Avalonia.Native/src/OSX/window.mm | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index 08d4515d88..500bdf8148 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -735,7 +735,23 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent - (void)onClosed { - _parent = NULL; + @synchronized (self) + { + _parent = nullptr; + } +} + +- (BOOL)lockFocusIfCanDraw +{ + @synchronized (self) + { + if(_parent == nullptr) + { + return NO; + } + } + + return [super lockFocusIfCanDraw]; } -(AvnPixelSize) getPixelSize From 8ff1fdecebf7f3170a20747eab246d49802a2cce Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 11 Dec 2019 11:48:48 -0300 Subject: [PATCH 6/9] [OSX] dont override dealloc methods, this is causing wierd stuff to happen. --- native/Avalonia.Native/src/OSX/window.mm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index 500bdf8148..11e4d79830 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -729,10 +729,6 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent AvnPixelSize _lastPixelSize; } -- (void)dealloc -{ -} - - (void)onClosed { @synchronized (self) @@ -1226,10 +1222,6 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent } } -- (void)dealloc -{ -} - - (void)pollModalSession:(nonnull NSModalSession)session { auto response = [NSApp runModalSession:session]; From d1089b62c8baf07c754d0e4140503f1df0452e75 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 11 Dec 2019 11:49:13 -0300 Subject: [PATCH 7/9] [OSX] Dont crash if Window is null when Close is called. --- native/Avalonia.Native/src/OSX/window.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index 11e4d79830..82a275a824 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -195,7 +195,11 @@ public: { @autoreleasepool { - [Window close]; + if (Window != nullptr) + { + [Window close]; + } + return S_OK; } } From aaff106bee3c557d39501e392ba3938d6823c8a7 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 11 Dec 2019 12:55:23 -0300 Subject: [PATCH 8/9] [OSX] remove unnecessary dispatch and code to clear content. --- native/Avalonia.Native/src/OSX/window.mm | 3 --- 1 file changed, 3 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index 82a275a824..ddb722a0ee 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -1313,9 +1313,6 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent [self restoreParentWindow]; parent->BaseEvents->Closed(); [parent->View onClosed]; - dispatch_async(dispatch_get_main_queue(), ^{ - [self setContentView: nil]; - }); } } From 1f9ab92359012741a7e2a41c814d1c6124946eb7 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 11 Dec 2019 13:00:51 -0300 Subject: [PATCH 9/9] [OSX] use sensible initial window size values --- native/Avalonia.Native/src/OSX/window.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index ddb722a0ee..908b9e1022 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -771,8 +771,8 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent [self setWantsLayer:YES]; _parent = parent; _area = nullptr; - _lastPixelSize.Height = 0; - _lastPixelSize.Width = 0; + _lastPixelSize.Height = 100; + _lastPixelSize.Width = 100; return self; }