Browse Source

Merge branch 'master' into fixes/x11-compose-key

pull/10950/head
Nikita Tsukanov 4 years ago
committed by GitHub
parent
commit
a2c10a9d06
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/Avalonia.Base/Media/DrawingContext.cs
  2. 14
      src/Avalonia.Controls/TopLevel.cs
  3. 2
      src/Avalonia.Headless/AvaloniaHeadlessPlatform.cs
  4. 19
      src/Avalonia.X11/X11Window.cs
  5. 15
      src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
  6. 11
      src/Windows/Avalonia.Win32/WindowImpl.cs
  7. 51
      tests/Avalonia.RenderTests/Media/BoxShadowTests.cs
  8. BIN
      tests/TestFiles/Skia/Media/BoxShadow/BoxShadowShouldBeRenderedEvenWithNullBrushAndPen.expected.png

4
src/Avalonia.Base/Media/DrawingContext.cs

@ -132,7 +132,7 @@ namespace Avalonia.Media
double radiusX = 0, double radiusY = 0, double radiusX = 0, double radiusY = 0,
BoxShadows boxShadows = default) BoxShadows boxShadows = default)
{ {
if (brush == null && !PenIsVisible(pen)) if (brush == null && !PenIsVisible(pen) && boxShadows.Count == 0)
return; return;
if (!MathUtilities.IsZero(radiusX)) if (!MathUtilities.IsZero(radiusX))
{ {
@ -160,7 +160,7 @@ namespace Avalonia.Media
/// </remarks> /// </remarks>
public void DrawRectangle(IBrush? brush, IPen? pen, RoundedRect rrect, BoxShadows boxShadows = default) public void DrawRectangle(IBrush? brush, IPen? pen, RoundedRect rrect, BoxShadows boxShadows = default)
{ {
if (brush == null && !PenIsVisible(pen)) if (brush == null && !PenIsVisible(pen) && boxShadows.Count == 0)
return; return;
DrawRectangleCore(brush, pen, rrect, boxShadows); DrawRectangleCore(brush, pen, rrect, boxShadows);
} }

14
src/Avalonia.Controls/TopLevel.cs

@ -527,6 +527,13 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
protected virtual void HandleClosed() protected virtual void HandleClosed()
{ {
Renderer.SceneInvalidated -= SceneInvalidated;
// We need to wait for the renderer to complete any in-flight operations
Renderer.Dispose();
// The PlatformImpl is completely invalid at this point
PlatformImpl = null;
if (_globalStyles is object) if (_globalStyles is object)
{ {
_globalStyles.GlobalStylesAdded -= ((IStyleHost)this).StylesAdded; _globalStyles.GlobalStylesAdded -= ((IStyleHost)this).StylesAdded;
@ -536,10 +543,7 @@ namespace Avalonia.Controls
{ {
_applicationThemeHost.ActualThemeVariantChanged -= GlobalActualThemeVariantChanged; _applicationThemeHost.ActualThemeVariantChanged -= GlobalActualThemeVariantChanged;
} }
Renderer.SceneInvalidated -= SceneInvalidated;
Renderer.Dispose();
_layoutDiagnosticBridge?.Dispose(); _layoutDiagnosticBridge?.Dispose();
_layoutDiagnosticBridge = null; _layoutDiagnosticBridge = null;
@ -547,8 +551,6 @@ namespace Avalonia.Controls
_pointerOverPreProcessorSubscription?.Dispose(); _pointerOverPreProcessorSubscription?.Dispose();
_backGestureSubscription?.Dispose(); _backGestureSubscription?.Dispose();
PlatformImpl = null;
var logicalArgs = new LogicalTreeAttachmentEventArgs(this, this, null); var logicalArgs = new LogicalTreeAttachmentEventArgs(this, this, null);
((ILogical)this).NotifyDetachedFromLogicalTree(logicalArgs); ((ILogical)this).NotifyDetachedFromLogicalTree(logicalArgs);

2
src/Avalonia.Headless/AvaloniaHeadlessPlatform.cs

@ -43,6 +43,8 @@ namespace Avalonia.Headless
_framesPerSecond = framesPerSecond; _framesPerSecond = framesPerSecond;
} }
public override bool RunsInBackground => false;
public void ForceTick() => _forceTick?.Invoke(); public void ForceTick() => _forceTick?.Invoke();
} }

19
src/Avalonia.X11/X11Window.cs

@ -48,6 +48,7 @@ namespace Avalonia.X11
private readonly X11NativeControlHost _nativeControlHost; private readonly X11NativeControlHost _nativeControlHost;
private PixelPoint? _position; private PixelPoint? _position;
private PixelSize _realSize; private PixelSize _realSize;
private bool _cleaningUp;
private IntPtr _handle; private IntPtr _handle;
private IntPtr _xic; private IntPtr _xic;
private IntPtr _renderHandle; private IntPtr _renderHandle;
@ -522,7 +523,7 @@ namespace Avalonia.X11
else if (ev.type == XEventName.DestroyNotify else if (ev.type == XEventName.DestroyNotify
&& ev.DestroyWindowEvent.window == _handle) && ev.DestroyWindowEvent.window == _handle)
{ {
Cleanup(); Cleanup(true);
} }
else if (ev.type == XEventName.ClientMessage) else if (ev.type == XEventName.ClientMessage)
{ {
@ -816,7 +817,7 @@ namespace Avalonia.X11
public void Dispose() public void Dispose()
{ {
Cleanup(); Cleanup(false);
} }
public virtual object? TryGetFeature(Type featureType) public virtual object? TryGetFeature(Type featureType)
@ -849,8 +850,17 @@ namespace Avalonia.X11
return null; return null;
} }
private void Cleanup() private void Cleanup(bool fromDestroyNotification)
{ {
// Prevent reentrancy
if(_cleaningUp)
return;
_cleaningUp = true;
// Before doing anything else notify the TopLevel that ITopLevelImpl is no longer valid
if (_handle != IntPtr.Zero)
Closed?.Invoke();
if (_rawEventGrouper != null) if (_rawEventGrouper != null)
{ {
_rawEventGrouper.Dispose(); _rawEventGrouper.Dispose();
@ -891,7 +901,8 @@ namespace Avalonia.X11
Closed?.Invoke(); Closed?.Invoke();
_mouse.Dispose(); _mouse.Dispose();
_touch.Dispose(); _touch.Dispose();
XDestroyWindow(_x11.Display, handle); if (!fromDestroyNotification)
XDestroyWindow(_x11.Display, handle);
} }
if (_useRenderWindow && _renderHandle != IntPtr.Zero) if (_useRenderWindow && _renderHandle != IntPtr.Zero)

15
src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

@ -85,6 +85,9 @@ namespace Avalonia.Win32
case WindowsMessage.WM_DESTROY: case WindowsMessage.WM_DESTROY:
{ {
// The first and foremost thing to do - notify the TopLevel
Closed?.Invoke();
if (UiaCoreTypesApi.IsNetComInteropAvailable) if (UiaCoreTypesApi.IsNetComInteropAvailable)
{ {
UiaCoreProviderApi.UiaReturnRawElementProvider(_hwnd, IntPtr.Zero, IntPtr.Zero, null); UiaCoreProviderApi.UiaReturnRawElementProvider(_hwnd, IntPtr.Zero, IntPtr.Zero, null);
@ -95,6 +98,18 @@ namespace Avalonia.Win32
{ {
Imm32InputMethod.Current.ClearLanguageAndWindow(); Imm32InputMethod.Current.ClearLanguageAndWindow();
} }
// Cleanup render targets
(_gl as IDisposable)?.Dispose();
if (_dropTarget != null)
{
OleContext.Current?.UnregisterDragDrop(Handle);
_dropTarget.Dispose();
_dropTarget = null;
}
_framebuffer.Dispose();
//Window doesn't exist anymore //Window doesn't exist anymore
_hwnd = IntPtr.Zero; _hwnd = IntPtr.Zero;

11
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -624,15 +624,6 @@ namespace Avalonia.Win32
public void Dispose() public void Dispose()
{ {
(_gl as IDisposable)?.Dispose();
if (_dropTarget != null)
{
OleContext.Current?.UnregisterDragDrop(Handle);
_dropTarget.Dispose();
_dropTarget = null;
}
if (_hwnd != IntPtr.Zero) if (_hwnd != IntPtr.Zero)
{ {
// Detect if we are being closed programmatically - this would mean that WM_CLOSE was not called // Detect if we are being closed programmatically - this would mean that WM_CLOSE was not called
@ -645,8 +636,6 @@ namespace Avalonia.Win32
DestroyWindow(_hwnd); DestroyWindow(_hwnd);
_hwnd = IntPtr.Zero; _hwnd = IntPtr.Zero;
} }
_framebuffer.Dispose();
} }
public void Invalidate(Rect rect) public void Invalidate(Rect rect)

51
tests/Avalonia.RenderTests/Media/BoxShadowTests.cs

@ -0,0 +1,51 @@
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Media;
using Xunit;
#pragma warning disable CS0649
#if AVALONIA_SKIA
namespace Avalonia.Skia.RenderTests;
public class BoxShadowTests : TestBase
{
public BoxShadowTests() : base(@"Media\BoxShadow")
{
}
[Fact]
public async Task BoxShadowShouldBeRenderedEvenWithNullBrushAndPen()
{
var target = new Border
{
Width = 200,
Height = 200,
Background = null,
Child = new Border()
{
Background = null,
Margin = new Thickness(40),
BoxShadow = new BoxShadows(new BoxShadow
{
Blur = 0,
Color = Colors.Blue,
OffsetX = 10,
OffsetY = 15,
Spread = 0
}),
Child = new Border
{
Background = Brushes.Red
}
}
};
await RenderToFile(target);
CompareImages();
}
}
#endif

BIN
tests/TestFiles/Skia/Media/BoxShadow/BoxShadowShouldBeRenderedEvenWithNullBrushAndPen.expected.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

Loading…
Cancel
Save