From 04415f2d54d35626761ea499bb9f708bf14e64a9 Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Fri, 6 Dec 2019 23:22:31 +0200 Subject: [PATCH 01/22] fix typo of point parse --- src/Avalonia.Visuals/Point.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Point.cs b/src/Avalonia.Visuals/Point.cs index d92f8b0fc4c..27ac7a30263 100644 --- a/src/Avalonia.Visuals/Point.cs +++ b/src/Avalonia.Visuals/Point.cs @@ -175,7 +175,7 @@ public static implicit operator Vector(Point p) /// Parses a string. /// /// The string. - /// The . + /// The . public static Point Parse(string s) { using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Point.")) From 30eaf3bc72ac0bc10c44050a4ffe0256f24888dc Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Fri, 6 Dec 2019 23:23:33 +0200 Subject: [PATCH 02/22] add vector parse --- src/Avalonia.Visuals/Vector.cs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Visuals/Vector.cs b/src/Avalonia.Visuals/Vector.cs index 576d2daaaae..d99fbe8e65e 100644 --- a/src/Avalonia.Visuals/Vector.cs +++ b/src/Avalonia.Visuals/Vector.cs @@ -4,6 +4,7 @@ using System; using System.Globalization; using Avalonia.Animation.Animators; +using Avalonia.Utilities; using JetBrains.Annotations; namespace Avalonia @@ -85,6 +86,22 @@ public static explicit operator Point(Vector a) public static Vector operator /(Vector vector, double scale) => Divide(vector, scale); + /// + /// Parses a string. + /// + /// The string. + /// The . + public static Vector Parse(string s) + { + using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Vector.")) + { + return new Vector( + tokenizer.ReadDouble(), + tokenizer.ReadDouble() + ); + } + } + /// /// Length of the vector /// @@ -166,9 +183,9 @@ public override int GetHashCode() } /// - /// Returns the string representation of the point. + /// Returns the string representation of the vector. /// - /// The string representation of the point. + /// The string representation of the vector. public override string ToString() { return string.Format(CultureInfo.InvariantCulture, "{0}, {1}", _x, _y); From 7a66d360f043b179f5c80d86ef9daeeff579f2be Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Fri, 6 Dec 2019 23:38:46 +0200 Subject: [PATCH 03/22] add transform parse --- src/Avalonia.Visuals/Media/Transform.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Avalonia.Visuals/Media/Transform.cs b/src/Avalonia.Visuals/Media/Transform.cs index 7a70657ce00..30a07d47efc 100644 --- a/src/Avalonia.Visuals/Media/Transform.cs +++ b/src/Avalonia.Visuals/Media/Transform.cs @@ -28,6 +28,16 @@ static Transform() /// public abstract Matrix Value { get; } + /// + /// Parses a string. + /// + /// The string. + /// The . + public static Transform Parse(string s) + { + return new MatrixTransform(Matrix.Parse(s)); + } + /// /// Raises the event. /// @@ -35,5 +45,14 @@ protected void RaiseChanged() { Changed?.Invoke(this, EventArgs.Empty); } + + /// + /// Returns a String representing this transform matrix instance. + /// + /// The string representation. + public override string ToString() + { + return Value.ToString(); + } } } From 29be26a88240a0bc2b533dd5096495bac10b5305 Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Fri, 6 Dec 2019 23:48:43 +0200 Subject: [PATCH 04/22] add relativepoint tostring --- src/Avalonia.Visuals/RelativePoint.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Avalonia.Visuals/RelativePoint.cs b/src/Avalonia.Visuals/RelativePoint.cs index 2e8fb16bc10..ebd0ba93514 100644 --- a/src/Avalonia.Visuals/RelativePoint.cs +++ b/src/Avalonia.Visuals/RelativePoint.cs @@ -177,5 +177,16 @@ public static RelativePoint Parse(string s) unit); } } + + /// + /// Returns a String representing this RelativePoint instance. + /// + /// The string representation. + public override string ToString() + { + return _unit == RelativeUnit.Absolute ? + _point.ToString() : + string.Format(CultureInfo.InvariantCulture, "{0}%, {1}%", _point.X * 100, _point.Y * 100); + } } } From 1f2b2e965279fb8cdcb57712780f7a6c1d1f90a4 Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Mon, 9 Dec 2019 18:15:39 +0200 Subject: [PATCH 05/22] document transform.parse --- src/Avalonia.Visuals/Media/Transform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Media/Transform.cs b/src/Avalonia.Visuals/Media/Transform.cs index 30a07d47efc..8253d11ff1b 100644 --- a/src/Avalonia.Visuals/Media/Transform.cs +++ b/src/Avalonia.Visuals/Media/Transform.cs @@ -31,7 +31,7 @@ static Transform() /// /// Parses a string. /// - /// The string. + /// Six comma-delimited double values that describe the new . For details check /// The . public static Transform Parse(string s) { From 78b790e6ebb400efb79a2988052a7b340e51c5dc Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Mon, 9 Dec 2019 18:17:47 +0200 Subject: [PATCH 06/22] document matrix.parse --- src/Avalonia.Visuals/Matrix.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Matrix.cs b/src/Avalonia.Visuals/Matrix.cs index 92b7dae9040..d05dbac5744 100644 --- a/src/Avalonia.Visuals/Matrix.cs +++ b/src/Avalonia.Visuals/Matrix.cs @@ -306,7 +306,7 @@ public Matrix Invert() /// /// Parses a string. /// - /// The string. + /// Six comma-delimited double values (m11, m12, m21, m22, offsetX, offsetY) that describe the new /// The . public static Matrix Parse(string s) { From 3cec9fb412741c4b3cf34822ea7211a20d572456 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 10 Dec 2019 08:43:01 -0300 Subject: [PATCH 07/22] [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 c54829d7501..cd8c6245ba6 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -812,7 +812,13 @@ - (void) drawFb: (AvnFramebuffer*) fb - (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 08/22] [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 083adc927de..ba5183dfa10 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 @@ virtual HRESULT ObtainImmediateContext(IAvnGlContext**retOut) override 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 @@ virtual HRESULT ObtainImmediateContext(IAvnGlContext**retOut) override 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 932bc56a2e2..3e626675d27 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 cd8c6245ba6..a73ab0a9a9f 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -719,6 +719,7 @@ @implementation AvnView bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isXButton1Pressed, _isXButton2Pressed, _isMouseOver; NSEvent* _lastMouseDownEvent; bool _lastKeyHandled; + AvnPixelSize _lastPixelSize; } - (void)dealloc @@ -730,6 +731,11 @@ - (void)onClosed _parent = NULL; } +-(AvnPixelSize) getPixelSize +{ + return _lastPixelSize; +} + - (NSEvent*) lastMouseDownEvent { return _lastMouseDownEvent; @@ -742,6 +748,8 @@ -(AvnView*) initWithParent: (WindowBaseImpl*) parent [self setWantsLayer:YES]; _parent = parent; _area = nullptr; + _lastPixelSize.Height = 0; + _lastPixelSize.Width = 0; return self; } @@ -783,6 +791,10 @@ -(void)setFrameSize:(NSSize)newSize [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 @@ - (AvnPoint)toAvnPoint:(CGPoint)p - (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 @@ @implementation AvnWindow bool _closed; NSMenu* _menu; bool _isAppMenuApplied; + double _lastScaling; +} + +-(double) getScaling +{ + return _lastScaling; } +(void)closeAll @@ -1238,6 +1261,8 @@ -(AvnWindow*) initWithParent: (WindowBaseImpl*) parent [self setReleasedWhenClosed:false]; _parent = parent; [self setDelegate:self]; + + _lastScaling = [self backingScaleFactor]; return self; } @@ -1253,6 +1278,11 @@ - (BOOL)windowShouldClose:(NSWindow *)sender return true; } +- (void)windowDidChangeBackingProperties:(NSNotification *)notification +{ + _lastScaling = [self backingScaleFactor]; +} + - (void)windowWillClose:(NSNotification *)notification { _closed = true; @@ -1412,18 +1442,6 @@ - (void)windowDidMove:(NSNotification *)notification _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 09/22] [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 ba5183dfa10..feb06436548 100644 --- a/native/Avalonia.Native/src/OSX/gl.mm +++ b/native/Avalonia.Native/src/OSX/gl.mm @@ -233,8 +233,17 @@ virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) override 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 a73ab0a9a9f..a40a181ba78 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -291,7 +291,14 @@ virtual bool TryLock() override { @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 10/22] 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 a40a181ba78..08d4515d88c 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -1268,6 +1268,7 @@ -(AvnWindow*) initWithParent: (WindowBaseImpl*) parent [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 11/22] 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 08d4515d88c..500bdf81482 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -735,7 +735,23 @@ - (void)dealloc - (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 12/22] [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 e72fefe3ce1..5d701dc8df0 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -353,6 +353,11 @@ public void SetTopmost(bool value) 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 13/22] [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 500bdf81482..11e4d798305 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -729,10 +729,6 @@ @implementation AvnView AvnPixelSize _lastPixelSize; } -- (void)dealloc -{ -} - - (void)onClosed { @synchronized (self) @@ -1226,10 +1222,6 @@ +(void)closeAll } } -- (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 14/22] [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 11e4d798305..82a275a8245 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -195,7 +195,11 @@ virtual HRESULT Close() override { @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 15/22] [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 82a275a8245..ddb722a0ee5 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -1313,9 +1313,6 @@ - (void)windowWillClose:(NSNotification *)notification [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 16/22] [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 ddb722a0ee5..908b9e1022c 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -771,8 +771,8 @@ -(AvnView*) initWithParent: (WindowBaseImpl*) parent [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 17/22] 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 8081528e558..f9737b461d4 100644 --- a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs +++ b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs @@ -47,7 +47,8 @@ private void Poll(long _) 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 18/22] 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 1ceef5c824c..3e1d85a9130 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs @@ -45,7 +45,8 @@ public override object ProvideValue(IServiceProvider serviceProvider) Source = Source, StringFormat = StringFormat, RelativeSource = RelativeSource, - DefaultAnchor = new WeakReference(GetDefaultAnchor(descriptorContext)) + DefaultAnchor = new WeakReference(GetDefaultAnchor(descriptorContext)), + TargetNullValue = TargetNullValue }; } @@ -83,5 +84,7 @@ private static object GetDefaultAnchor(ITypeDescriptorContext context) 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 19/22] [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 3010a3d8a83..90b86739e93 100644 --- a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs +++ b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs @@ -305,7 +305,7 @@ public static void ConfigurePosition(ref this PopupPositionerParameters position 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 20/22] [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 90b86739e93..f0358ec04fa 100644 --- a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs +++ b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs @@ -305,8 +305,8 @@ public static void ConfigurePosition(ref this PopupPositionerParameters position 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 21/22] 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 c3bc649abba..fa7e7ead28f 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs @@ -38,6 +38,27 @@ public void BindingExtension_Binds_To_Source() 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 22/22] !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 fa7e7ead28f..88c8034e52c 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs @@ -47,19 +47,29 @@ public void BindingExtension_Binds_To_TargetNullValue() 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(