From 3cec9fb412741c4b3cf34822ea7211a20d572456 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 10 Dec 2019 08:43:01 -0300 Subject: [PATCH 01/20] [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 02/20] [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 03/20] [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 04/20] 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 05/20] 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 c907172b8f07dace7801ddd0848f4c982cb8f794 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 11 Dec 2019 10:06:12 -0300 Subject: [PATCH 06/20] [OSX] null check to prevent NRE when window closes. --- src/Avalonia.Native/WindowImplBase.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index e72fefe3ce..5d701dc8df 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -353,6 +353,11 @@ namespace Avalonia.Native public void SetCursor(IPlatformHandle cursor) { + if (_native == null) + { + return; + } + var newCursor = cursor as AvaloniaNativeCursor; newCursor = newCursor ?? (_cursorFactory.GetCursor(StandardCursorType.Arrow) as AvaloniaNativeCursor); _native.Cursor = newCursor.Cursor; From 8ff1fdecebf7f3170a20747eab246d49802a2cce Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 11 Dec 2019 11:48:48 -0300 Subject: [PATCH 07/20] [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 08/20] [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 09/20] [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 10/20] [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; } From bd51fa0cd0540bc2f08fef6c5a6080634e6762a7 Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Wed, 11 Dec 2019 23:59:05 +0800 Subject: [PATCH 11/20] Exclude snap directories in dev mount. --- src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs index 8081528e55..f9737b461d 100644 --- a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs +++ b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs @@ -47,7 +47,8 @@ namespace Avalonia.FreeDesktop var fProcMounts = File.ReadAllLines(ProcMountsDir) .Select(x => x.Split(' ')) - .Select(x => (x[0], x[1])); + .Select(x => (x[0], x[1])) + .Where(x => !x.Item2.StartsWith("/snap/", StringComparison.InvariantCultureIgnoreCase)); var labelDirEnum = Directory.Exists(DevByLabelDir) ? new DirectoryInfo(DevByLabelDir).GetFiles() : Enumerable.Empty(); From b1e9c028286809c0f84130773654003ab0fc91dd Mon Sep 17 00:00:00 2001 From: "Luis v.d.Eltz" Date: Wed, 11 Dec 2019 18:09:53 +0100 Subject: [PATCH 12/20] Adding TargetNullValue to BindingExtension --- .../MarkupExtensions/BindingExtension.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs index 1ceef5c824..3e1d85a913 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs @@ -45,7 +45,8 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions Source = Source, StringFormat = StringFormat, RelativeSource = RelativeSource, - DefaultAnchor = new WeakReference(GetDefaultAnchor(descriptorContext)) + DefaultAnchor = new WeakReference(GetDefaultAnchor(descriptorContext)), + TargetNullValue = TargetNullValue }; } @@ -83,5 +84,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions public string StringFormat { get; set; } public RelativeSource RelativeSource { get; set; } + + public object TargetNullValue { get; set; } } } From a29404c3f7e435a81f483996545233981b1889b0 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 11 Dec 2019 16:17:51 -0300 Subject: [PATCH 13/20] [Popup] opens under mouse as 0.8 release did. Prevents rapid opening and closing. --- .../Primitives/PopupPositioning/IPopupPositioner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs index 3010a3d8a8..90b86739e9 100644 --- a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs +++ b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs @@ -305,7 +305,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning positionerParameters.ConstraintAdjustment = PopupPositionerConstraintAdjustment.All; if (placement == PlacementMode.Pointer) { - positionerParameters.AnchorRectangle = new Rect(pointer, new Size(1, 1)); + positionerParameters.AnchorRectangle = new Rect(pointer, new Size(0, 0)); positionerParameters.Anchor = PopupPositioningEdge.BottomRight; positionerParameters.Gravity = PopupPositioningEdge.BottomRight; } From 69b7bc20416a01b88b446e845b5d25514eaeb809 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 11 Dec 2019 16:26:43 -0300 Subject: [PATCH 14/20] [Popup] Use anchor and gravity to get the correct positioning under the mouse. --- .../Primitives/PopupPositioning/IPopupPositioner.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs index 90b86739e9..f0358ec04f 100644 --- a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs +++ b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs @@ -305,8 +305,8 @@ namespace Avalonia.Controls.Primitives.PopupPositioning positionerParameters.ConstraintAdjustment = PopupPositionerConstraintAdjustment.All; if (placement == PlacementMode.Pointer) { - positionerParameters.AnchorRectangle = new Rect(pointer, new Size(0, 0)); - positionerParameters.Anchor = PopupPositioningEdge.BottomRight; + positionerParameters.AnchorRectangle = new Rect(pointer, new Size(1, 1)); + positionerParameters.Anchor = PopupPositioningEdge.TopLeft; positionerParameters.Gravity = PopupPositioningEdge.BottomRight; } else From e89d5af718f4e6614ecafb8f16a82ffbf4a8c571 Mon Sep 17 00:00:00 2001 From: "Luis v.d.Eltz" Date: Thu, 12 Dec 2019 10:29:28 +0100 Subject: [PATCH 15/20] Adding unit test --- .../MarkupExtensions/BindingExtensionTests.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs index c3bc649abb..fa7e7ead28 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs @@ -38,6 +38,27 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions Assert.Equal("foobar", textBlock.Text); } } + + [Fact] + public void BindingExtension_Binds_To_TargetNullValue() + { + using (StyledWindow()) + { + var xaml = @" + + +"; + + var loader = new AvaloniaXamlLoader(); + var window = (Window)loader.Load(xaml); + var textBlock = window.FindControl("textBlock"); + + window.Show(); + + Assert.Equal("foobar", textBlock.Text); + } + } private IDisposable StyledWindow(params (string, string)[] assets) { From d88640b1eacfa6b79ff5c9a36abe093f432ac261 Mon Sep 17 00:00:00 2001 From: Luis von der Eltz Date: Thu, 12 Dec 2019 11:33:37 +0100 Subject: [PATCH 16/20] !B Fixing test --- .../MarkupExtensions/BindingExtensionTests.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs index fa7e7ead28..88c8034e52 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs @@ -47,19 +47,29 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions var xaml = @" - + + foobar + + + "; var loader = new AvaloniaXamlLoader(); var window = (Window)loader.Load(xaml); var textBlock = window.FindControl("textBlock"); + window.DataContext = new FooBar(); window.Show(); Assert.Equal("foobar", textBlock.Text); } } + private class FooBar + { + public object Foo { get; } = null; + } + private IDisposable StyledWindow(params (string, string)[] assets) { var services = TestServices.StyledWindow.With( From 6fabfdc5612657c3f0a63b1b70e59fc3cf52bc7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro?= Date: Fri, 13 Dec 2019 23:43:15 +0000 Subject: [PATCH 17/20] Fixed BindingExtension.TargetNullValue default value. --- .../MarkupExtensions/BindingExtension.cs | 4 ++-- .../MarkupExtensions/BindingExtensionTests.cs | 24 ++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs index 3073f913f4..c77ccd64f2 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs @@ -87,7 +87,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions public string StringFormat { get; set; } public RelativeSource RelativeSource { get; set; } - - public object TargetNullValue { get; set; } + + public object TargetNullValue { get; set; } = AvaloniaProperty.UnsetValue; } } diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs index 88c8034e52..76edf9a17a 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs @@ -38,7 +38,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions Assert.Equal("foobar", textBlock.Text); } } - + [Fact] public void BindingExtension_Binds_To_TargetNullValue() { @@ -65,6 +65,28 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions } } + [Fact] + public void BindingExtension_TargetNullValue_UnsetByDefault() + { + using (StyledWindow()) + { + var xaml = @" + + +"; + + var loader = new AvaloniaXamlLoader(); + var window = (Window)loader.Load(xaml); + var textBlock = window.FindControl("textBlock"); + + window.DataContext = new FooBar(); + window.Show(); + + Assert.Equal(false, textBlock.IsVisible); + } + } + private class FooBar { public object Foo { get; } = null; From fb1dcc11b47446ba9b122c2a3b7e60ca11d3000f Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 16 Dec 2019 20:45:52 +0100 Subject: [PATCH 18/20] Fix loading EGL functions on GLX. This fixes apps refusing to run on Arch Linux. --- src/Avalonia.X11/Glx/Glx.cs | 18 +++++++++++++++++- src/Avalonia.X11/Glx/GlxDisplay.cs | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.X11/Glx/Glx.cs b/src/Avalonia.X11/Glx/Glx.cs index c3a2fd2050..a059e92210 100644 --- a/src/Avalonia.X11/Glx/Glx.cs +++ b/src/Avalonia.X11/Glx/Glx.cs @@ -84,8 +84,24 @@ namespace Avalonia.X11.Glx [GlEntryPoint("glGetError")] public GlGetError GetError { get; } - public GlxInterface() : base(GlxGetProcAddress) + public GlxInterface() : base(SafeGetProcAddress) { } + + // Ignores egl functions. + // On some Linux systems, glXGetProcAddress will return valid pointers for even EGL functions. + // This makes Skia try to load some data from EGL, + // which can then cause segmentation faults because they return garbage. + public static IntPtr SafeGetProcAddress(string proc, bool optional) + { + if (proc.StartsWith("egl")) + { + return IntPtr.Zero; + } + + return GlxConverted(proc, optional); + } + + private static readonly Func GlxConverted = ConvertNative(GlxGetProcAddress); } } diff --git a/src/Avalonia.X11/Glx/GlxDisplay.cs b/src/Avalonia.X11/Glx/GlxDisplay.cs index 04f2a7137c..22eb0792e8 100644 --- a/src/Avalonia.X11/Glx/GlxDisplay.cs +++ b/src/Avalonia.X11/Glx/GlxDisplay.cs @@ -87,7 +87,7 @@ namespace Avalonia.X11.Glx ImmediateContext.MakeCurrent(); var err = Glx.GetError(); - GlInterface = new GlInterface(GlxInterface.GlxGetProcAddress); + GlInterface = new GlInterface(GlxInterface.SafeGetProcAddress); if (GlInterface.Version == null) throw new OpenGlException("GL version string is null, aborting"); if (GlInterface.Renderer == null) From fc5ada5e23dc01610ad59c6407db4c85fc7de8f9 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Tue, 17 Dec 2019 19:13:06 +0100 Subject: [PATCH 19/20] Use invariant culture. --- src/Avalonia.X11/Glx/Glx.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.X11/Glx/Glx.cs b/src/Avalonia.X11/Glx/Glx.cs index a059e92210..714a592f2b 100644 --- a/src/Avalonia.X11/Glx/Glx.cs +++ b/src/Avalonia.X11/Glx/Glx.cs @@ -94,7 +94,7 @@ namespace Avalonia.X11.Glx // which can then cause segmentation faults because they return garbage. public static IntPtr SafeGetProcAddress(string proc, bool optional) { - if (proc.StartsWith("egl")) + if (proc.StartsWith("egl", StringComparison.InvariantCulture)) { return IntPtr.Zero; } From 4c2b77fdb6b738881520edebb31302d7eb2655bd Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 19 Dec 2019 15:37:37 +0100 Subject: [PATCH 20/20] Snapshot undo text after paste. Fixes #2732 --- src/Avalonia.Controls/TextBox.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 3d472fca18..c3eec851b9 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -390,8 +390,10 @@ namespace Avalonia.Controls { return; } + _undoRedoHelper.Snapshot(); HandleTextInput(text); + _undoRedoHelper.Snapshot(); } protected override void OnKeyDown(KeyEventArgs e)