Browse Source

Merge branch 'master' into fixes/6577

pull/6581/head
Benedikt Stebner 5 years ago
committed by GitHub
parent
commit
b188cff0f0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      packages/Avalonia/AvaloniaBuildTasks.targets
  2. 15
      src/Avalonia.Controls/Design.cs
  3. 3
      src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs
  4. 2
      src/Avalonia.Themes.Fluent/Controls/NotificationCard.xaml
  5. 6
      src/Avalonia.Themes.Fluent/Controls/ProgressBar.xaml
  6. 33
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
  7. 3
      src/Avalonia.X11/X11Window.cs
  8. 46
      src/Linux/Avalonia.LinuxFramebuffer/LockedFramebuffer.cs
  9. 70
      src/Linux/Avalonia.LinuxFramebuffer/Output/FbDevBackBuffer.cs
  10. 7
      src/Linux/Avalonia.LinuxFramebuffer/Output/FbdevOutput.cs
  11. 25
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  12. 6
      src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

16
packages/Avalonia/AvaloniaBuildTasks.targets

@ -42,12 +42,24 @@
</Target>
<PropertyGroup>
<BuildAvaloniaResourcesDependsOn>$(BuildAvaloniaResourcesDependsOn);AddAvaloniaResources;ResolveReferences</BuildAvaloniaResourcesDependsOn>
<BuildAvaloniaResourcesDependsOn>$(BuildAvaloniaResourcesDependsOn);AddAvaloniaResources;ResolveReferences;_GenerateAvaloniaResourcesDependencyCache</BuildAvaloniaResourcesDependsOn>
</PropertyGroup>
<Target Name="_GenerateAvaloniaResourcesDependencyCache" BeforeTargets="GenerateAvaloniaResources">
<ItemGroup>
<CustomAdditionalGenerateAvaloniaResourcesInputs Include="$(IntermediateOutputPath)/Avalonia/Resources.Inputs.cache" />
</ItemGroup>
<Hash ItemsToHash="@(AvaloniaResource);@(AvaloniaXaml);$(MSBuildAllProjects)">
<Output TaskParameter="HashResult" PropertyName="AvaloniaResourcesDependencyHash" />
</Hash>
<WriteLinesToFile Overwrite="true" File="$(IntermediateOutputPath)/Avalonia/Resources.Inputs.cache" Lines="$(AvaloniaResourcesDependencyHash)" WriteOnlyWhenDifferent="True" />
</Target>
<Target Name="GenerateAvaloniaResources"
BeforeTargets="CoreCompile;CoreResGen"
Inputs="@(AvaloniaResource);@(AvaloniaXaml);$(MSBuildAllProjects)"
Inputs="@(AvaloniaResource);@(AvaloniaXaml);@(CustomAdditionalGenerateAvaloniaResourcesInputs);$(MSBuildAllProjects)"
Outputs="$(AvaloniaResourcesTemporaryFilePath)"
DependsOnTargets="$(BuildAvaloniaResourcesDependsOn)">
<ItemGroup>

15
src/Avalonia.Controls/Design.cs

@ -60,6 +60,19 @@ namespace Avalonia.Controls
return target.GetValue(PreviewWithProperty);
}
public static readonly AttachedProperty<IStyle> DesignStyleProperty = AvaloniaProperty
.RegisterAttached<Control, IStyle>("DesignStyle", typeof(Design));
public static void SetDesignStyle(Control control, IStyle value)
{
control.SetValue(DesignStyleProperty, value);
}
public static IStyle GetDesignStyle(Control control)
{
return control.GetValue(DesignStyleProperty);
}
public static void ApplyDesignModeProperties(Control target, Control source)
{
if (source.IsSet(WidthProperty))
@ -68,6 +81,8 @@ namespace Avalonia.Controls
target.Height = source.GetValue(HeightProperty);
if (source.IsSet(DataContextProperty))
target.DataContext = source.GetValue(DataContextProperty);
if (source.IsSet(DesignStyleProperty))
target.Styles.Add(source.GetValue(DesignStyleProperty));
}
}
}

3
src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs

@ -303,7 +303,8 @@ namespace Avalonia.Controls.Platform
{
item.Parent.SelectedItem.Close();
SelectItemAndAncestors(item);
Open(item, false);
if (item.HasSubMenu)
Open(item, false);
}
else
{

2
src/Avalonia.Themes.Fluent/Controls/NotificationCard.xaml

@ -17,7 +17,7 @@
<Setter Property="Template">
<ControlTemplate>
<LayoutTransformControl Name="PART_LayoutTransformControl" UseRenderTransform="True">
<Border CornerRadius="{DynamicResource ControlCornerRadius}" BoxShadow="0 6 8 0 #4F000000" Margin="5 5 5 10">
<Border CornerRadius="{TemplateBinding CornerRadius}" BoxShadow="0 6 8 0 #4F000000" Margin="5 5 5 10">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"

6
src/Avalonia.Themes.Fluent/Controls/ProgressBar.xaml

@ -23,11 +23,11 @@
<Border x:Name="ProgressBarRoot" ClipToBounds="True" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}">
<Panel>
<Panel x:Name="DeterminateRoot">
<Border CornerRadius="{DynamicResource ControlCornerRadius}" x:Name="PART_Indicator" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />
<Border CornerRadius="{TemplateBinding CornerRadius}" x:Name="PART_Indicator" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />
</Panel>
<Panel x:Name="IndeterminateRoot">
<Border x:Name="IndeterminateProgressBarIndicator" CornerRadius="{DynamicResource ControlCornerRadius}" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />
<Border x:Name="IndeterminateProgressBarIndicator2" CornerRadius="{DynamicResource ControlCornerRadius}" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />
<Border x:Name="IndeterminateProgressBarIndicator" CornerRadius="{TemplateBinding CornerRadius}" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />
<Border x:Name="IndeterminateProgressBarIndicator2" CornerRadius="{TemplateBinding CornerRadius}" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />
</Panel>
</Panel>
</Border>

33
src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

@ -35,6 +35,8 @@ namespace Avalonia.Rendering
private IRef<IDrawOperation> _currentDraw;
private readonly IDeferredRendererLock _lock;
private readonly object _sceneLock = new object();
private readonly object _startStopLock = new object();
private readonly object _renderLoopIsRenderingLock = new object();
private readonly Action _updateSceneIfNeededDelegate;
/// <summary>
@ -139,6 +141,8 @@ namespace Avalonia.Rendering
}
Stop();
// Wait for any in-progress rendering to complete
lock(_renderLoopIsRenderingLock){}
DisposeRenderTarget();
}
@ -233,20 +237,26 @@ namespace Avalonia.Rendering
/// <inheritdoc/>
public void Start()
{
if (!_running && _renderLoop != null)
lock (_startStopLock)
{
_renderLoop.Add(this);
_running = true;
if (!_running && _renderLoop != null)
{
_renderLoop.Add(this);
_running = true;
}
}
}
/// <inheritdoc/>
public void Stop()
{
if (_running && _renderLoop != null)
lock (_startStopLock)
{
_renderLoop.Remove(this);
_running = false;
if (_running && _renderLoop != null)
{
_renderLoop.Remove(this);
_running = false;
}
}
}
@ -255,7 +265,16 @@ namespace Avalonia.Rendering
void IRenderLoopTask.Update(TimeSpan time) => UpdateScene();
void IRenderLoopTask.Render() => Render(false);
void IRenderLoopTask.Render()
{
lock (_renderLoopIsRenderingLock)
{
lock(_startStopLock)
if(!_running)
return;
Render(false);
}
}
/// <inheritdoc/>
Size IVisualBrushRenderer.GetRenderTargetSize(IVisualBrush brush)

3
src/Avalonia.X11/X11Window.cs

@ -805,13 +805,14 @@ namespace Avalonia.X11
if (_handle != IntPtr.Zero)
{
XDestroyWindow(_x11.Display, _handle);
_platform.Windows.Remove(_handle);
_platform.XI2?.OnWindowDestroyed(_handle);
var handle = _handle;
_handle = IntPtr.Zero;
Closed?.Invoke();
_mouse.Dispose();
_touch.Dispose();
XDestroyWindow(_x11.Display, handle);
}
if (_useRenderWindow && _renderHandle != IntPtr.Zero)

46
src/Linux/Avalonia.LinuxFramebuffer/LockedFramebuffer.cs

@ -1,46 +0,0 @@
using System;
using System.Runtime.InteropServices;
using Avalonia.Platform;
namespace Avalonia.LinuxFramebuffer
{
unsafe class LockedFramebuffer : ILockedFramebuffer
{
private readonly int _fb;
private readonly fb_fix_screeninfo _fixedInfo;
private fb_var_screeninfo _varInfo;
private readonly IntPtr _address;
public LockedFramebuffer(int fb, fb_fix_screeninfo fixedInfo, fb_var_screeninfo varInfo, IntPtr address, Vector dpi)
{
_fb = fb;
_fixedInfo = fixedInfo;
_varInfo = varInfo;
_address = address;
Dpi = dpi;
//Use double buffering to avoid flicker
Address = Marshal.AllocHGlobal(RowBytes * Size.Height);
}
void VSync()
{
NativeUnsafeMethods.ioctl(_fb, FbIoCtl.FBIO_WAITFORVSYNC, null);
}
public void Dispose()
{
VSync();
NativeUnsafeMethods.memcpy(_address, Address, new IntPtr(RowBytes * Size.Height));
Marshal.FreeHGlobal(Address);
Address = IntPtr.Zero;
}
public IntPtr Address { get; private set; }
public PixelSize Size => new PixelSize((int)_varInfo.xres, (int) _varInfo.yres);
public int RowBytes => (int) _fixedInfo.line_length;
public Vector Dpi { get; }
public PixelFormat Format => _varInfo.bits_per_pixel == 16 ? PixelFormat.Rgb565 : _varInfo.blue.offset == 16 ? PixelFormat.Rgba8888 : PixelFormat.Bgra8888;
}
}

70
src/Linux/Avalonia.LinuxFramebuffer/Output/FbDevBackBuffer.cs

@ -0,0 +1,70 @@
using System;
using System.Runtime.InteropServices;
using System.Threading;
using Avalonia.Platform;
namespace Avalonia.LinuxFramebuffer.Output
{
internal unsafe class FbDevBackBuffer : IDisposable
{
private readonly int _fb;
private readonly fb_fix_screeninfo _fixedInfo;
private readonly fb_var_screeninfo _varInfo;
private readonly IntPtr _targetAddress;
private readonly object _lock = new object();
public FbDevBackBuffer(int fb, fb_fix_screeninfo fixedInfo, fb_var_screeninfo varInfo, IntPtr targetAddress)
{
_fb = fb;
_fixedInfo = fixedInfo;
_varInfo = varInfo;
_targetAddress = targetAddress;
Address = Marshal.AllocHGlobal(RowBytes * Size.Height);
}
public void Dispose()
{
if (Address != IntPtr.Zero)
{
Marshal.FreeHGlobal(Address);
Address = IntPtr.Zero;
}
}
public ILockedFramebuffer Lock(Vector dpi)
{
Monitor.Enter(_lock);
try
{
return new LockedFramebuffer(Address,
new PixelSize((int)_varInfo.xres, (int)_varInfo.yres),
(int)_fixedInfo.line_length, dpi,
_varInfo.bits_per_pixel == 16 ? PixelFormat.Rgb565
: _varInfo.blue.offset == 16 ? PixelFormat.Rgba8888
: PixelFormat.Bgra8888,
() =>
{
try
{
NativeUnsafeMethods.ioctl(_fb, FbIoCtl.FBIO_WAITFORVSYNC, null);
NativeUnsafeMethods.memcpy(_targetAddress, Address, new IntPtr(RowBytes * Size.Height));
}
finally
{
Monitor.Exit(_lock);
}
});
}
catch
{
Monitor.Exit(_lock);
throw;
}
}
public IntPtr Address { get; private set; }
public PixelSize Size => new PixelSize((int)_varInfo.xres, (int) _varInfo.yres);
public int RowBytes => (int) _fixedInfo.line_length;
}
}

7
src/Linux/Avalonia.LinuxFramebuffer/Output/FbdevOutput.cs

@ -14,6 +14,7 @@ namespace Avalonia.LinuxFramebuffer
private fb_var_screeninfo _varInfo;
private IntPtr _mappedLength;
private IntPtr _mappedAddress;
private FbDevBackBuffer _backBuffer;
public double Scaling { get; set; }
/// <summary>
@ -146,7 +147,9 @@ namespace Avalonia.LinuxFramebuffer
{
if (_fd <= 0)
throw new ObjectDisposedException("LinuxFramebuffer");
return new LockedFramebuffer(_fd, _fixedInfo, _varInfo, _mappedAddress, new Vector(96, 96) * Scaling);
return (_backBuffer ??=
new FbDevBackBuffer(_fd, _fixedInfo, _varInfo, _mappedAddress))
.Lock(new Vector(96, 96) * Scaling);
}
@ -165,6 +168,8 @@ namespace Avalonia.LinuxFramebuffer
public void Dispose()
{
_backBuffer?.Dispose();
_backBuffer = null;
ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}

25
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@ -808,6 +808,31 @@ namespace Avalonia.Win32.Interop
MNC_SELECT = 3
}
public enum SysCommands
{
SC_SIZE = 0xF000,
SC_MOVE = 0xF010,
SC_MINIMIZE = 0xF020,
SC_MAXIMIZE = 0xF030,
SC_NEXTWINDOW = 0xF040,
SC_PREVWINDOW = 0xF050,
SC_CLOSE = 0xF060,
SC_VSCROLL = 0xF070,
SC_HSCROLL = 0xF080,
SC_MOUSEMENU = 0xF090,
SC_KEYMENU = 0xF100,
SC_ARRANGE = 0xF110,
SC_RESTORE = 0xF120,
SC_TASKLIST = 0xF130,
SC_SCREENSAVE = 0xF140,
SC_HOTKEY = 0xF150,
SC_DEFAULT = 0xF160,
SC_MONITORPOWER = 0xF170,
SC_CONTEXTHELP = 0xF180,
SC_SEPARATOR = 0xF00F,
SCF_ISSECURE = 0x00000001,
}
[StructLayout(LayoutKind.Sequential)]
public struct RGBQUAD
{

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

@ -123,6 +123,12 @@ namespace Avalonia.Win32
break;
}
case WindowsMessage.WM_SYSCOMMAND:
// Disable system handling of Alt/F10 menu keys.
if ((SysCommands)wParam == SysCommands.SC_KEYMENU && HighWord(ToInt32(lParam)) <= 0)
return IntPtr.Zero;
break;
case WindowsMessage.WM_MENUCHAR:
{
// mute the system beep

Loading…
Cancel
Save