diff --git a/src/Avalonia.Native/Avalonia.Native.csproj b/src/Avalonia.Native/Avalonia.Native.csproj
index 65c2a75b1c..1a2bdeef1e 100644
--- a/src/Avalonia.Native/Avalonia.Native.csproj
+++ b/src/Avalonia.Native/Avalonia.Native.csproj
@@ -19,8 +19,9 @@
-
-
+
+
+
diff --git a/src/Avalonia.Native/CallbackBase.cs b/src/Avalonia.Native/CallbackBase.cs
index 67c383f6ae..1356dd58ff 100644
--- a/src/Avalonia.Native/CallbackBase.cs
+++ b/src/Avalonia.Native/CallbackBase.cs
@@ -2,11 +2,13 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
+using System.Runtime.ExceptionServices;
using SharpGen.Runtime;
+using Avalonia.Platform;
namespace Avalonia.Native
{
- public class CallbackBase : SharpGen.Runtime.IUnknown
+ public class CallbackBase : SharpGen.Runtime.IUnknown, IExceptionCallback
{
private uint _refCount;
private bool _disposed;
@@ -76,5 +78,15 @@ namespace Avalonia.Native
{
}
+
+ public void RaiseException(Exception e)
+ {
+ if (AvaloniaLocator.Current.GetService() is PlatformThreadingInterface threadingInterface)
+ {
+ threadingInterface.TerminateNativeApp();
+
+ threadingInterface.DispatchException(ExceptionDispatchInfo.Capture(e));
+ }
+ }
}
}
diff --git a/src/Avalonia.Native/PlatformThreadingInterface.cs b/src/Avalonia.Native/PlatformThreadingInterface.cs
index 353124a9d1..5ddaf83ed4 100644
--- a/src/Avalonia.Native/PlatformThreadingInterface.cs
+++ b/src/Avalonia.Native/PlatformThreadingInterface.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
+using System.Runtime.ExceptionServices;
using System.Threading;
using Avalonia.Native.Interop;
using Avalonia.Platform;
@@ -43,6 +44,8 @@ namespace Avalonia.Native
}
readonly IAvnPlatformThreadingInterface _native;
+ private ExceptionDispatchInfo _exceptionDispatchInfo;
+ private CancellationTokenSource _exceptionCancellationSource;
public PlatformThreadingInterface(IAvnPlatformThreadingInterface native)
{
@@ -57,32 +60,48 @@ namespace Avalonia.Native
public void RunLoop(CancellationToken cancellationToken)
{
- if (cancellationToken.CanBeCanceled == false)
- _native.RunLoop(null);
- else
+ var l = new object();
+ _exceptionCancellationSource = new CancellationTokenSource();
+
+ var compositeCancellation = CancellationTokenSource
+ .CreateLinkedTokenSource(cancellationToken, _exceptionCancellationSource.Token).Token;
+
+ var cancellation = _native.CreateLoopCancellation();
+ compositeCancellation.Register(() =>
{
- var l = new object();
- var cancellation = _native.CreateLoopCancellation();
- cancellationToken.Register(() =>
+ lock (l)
{
- lock (l)
- {
- cancellation?.Cancel();
- }
- });
- try
- {
- _native.RunLoop(cancellation);
+ cancellation?.Cancel();
}
- finally
+ });
+
+ try
+ {
+ _native.RunLoop(cancellation);
+ }
+ finally
+ {
+ lock (l)
{
- lock(l)
- {
- cancellation?.Dispose();
- cancellation = null;
- }
+ cancellation?.Dispose();
+ cancellation = null;
}
}
+
+ if (_exceptionDispatchInfo != null)
+ {
+ _exceptionDispatchInfo.Throw();
+ }
+ }
+
+ public void DispatchException (ExceptionDispatchInfo exceptionInfo)
+ {
+ _exceptionDispatchInfo = exceptionInfo;
+ }
+
+ public void TerminateNativeApp()
+ {
+ _exceptionCancellationSource?.Cancel();
}
public void Signal(DispatcherPriority priority)
diff --git a/src/Avalonia.X11/X11Framebuffer.cs b/src/Avalonia.X11/X11Framebuffer.cs
index 00288f300d..94f930e9ec 100644
--- a/src/Avalonia.X11/X11Framebuffer.cs
+++ b/src/Avalonia.X11/X11Framebuffer.cs
@@ -14,6 +14,10 @@ namespace Avalonia.X11
public X11Framebuffer(IntPtr display, IntPtr xid, int depth, int width, int height, double factor)
{
+ // HACK! Please fix renderer, should never ask for 0x0 bitmap.
+ width = Math.Max(1, width);
+ height = Math.Max(1, height);
+
_display = display;
_xid = xid;
_depth = depth;
diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs
index 6ff5b96f12..919abae243 100644
--- a/src/Avalonia.X11/X11Window.cs
+++ b/src/Avalonia.X11/X11Window.cs
@@ -102,7 +102,7 @@ namespace Avalonia.X11
valueMask |= SetWindowValuemask.ColorMap;
}
- int defaultWidth = 300, defaultHeight = 200;
+ int defaultWidth = 0, defaultHeight = 0;
if (!_popup && Screen != null)
{
@@ -117,6 +117,10 @@ namespace Avalonia.X11
}
}
+ // check if the calculated size is zero then compensate to hardcoded resolution
+ defaultWidth = Math.Max(defaultWidth, 300);
+ defaultHeight = Math.Max(defaultHeight, 200);
+
_handle = XCreateWindow(_x11.Display, _x11.RootWindow, 10, 10, defaultWidth, defaultHeight, 0,
depth,
(int)CreateWindowArgs.InputOutput,
@@ -133,7 +137,7 @@ namespace Avalonia.X11
_renderHandle = _handle;
Handle = new PlatformHandle(_handle, "XID");
- _realSize = new PixelSize(300, 200);
+ _realSize = new PixelSize(defaultWidth, defaultHeight);
platform.Windows[_handle] = OnEvent;
XEventMask ignoredMask = XEventMask.SubstructureRedirectMask
| XEventMask.ResizeRedirectMask
diff --git a/src/Shared/PlatformSupport/StandardRuntimePlatform.cs b/src/Shared/PlatformSupport/StandardRuntimePlatform.cs
index 8a5a725594..a23c31ca64 100644
--- a/src/Shared/PlatformSupport/StandardRuntimePlatform.cs
+++ b/src/Shared/PlatformSupport/StandardRuntimePlatform.cs
@@ -75,7 +75,7 @@ namespace Avalonia.Shared.PlatformSupport
lock (_btlock)
Backtraces.Remove(_backtrace);
#endif
- _plat.Free(_address, Size);
+ _plat?.Free(_address, Size);
GC.RemoveMemoryPressure(Size);
IsDisposed = true;
_address = IntPtr.Zero;