Browse Source

Merge branch 'master' into fixes/4293-listbox-remove-item-selection

pull/4294/head
Jumar Macato 6 years ago
committed by GitHub
parent
commit
b3e351367e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      src/Avalonia.Base/Threading/AvaloniaSynchronizationContext.cs
  2. 2
      src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs
  3. 2
      src/Avalonia.FreeDesktop/DBusHelper.cs
  4. 4
      src/Markup/Avalonia.Markup/Data/BindingBase.cs
  5. 17
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  6. 15
      src/Windows/Avalonia.Win32/NonPumpingWaitProvider.cs
  7. 1
      src/Windows/Avalonia.Win32/Win32Platform.cs
  8. 18
      tests/Avalonia.Controls.UnitTests/ApplicationTests.cs

27
src/Avalonia.Base/Threading/AvaloniaSynchronizationContext.cs

@ -1,3 +1,5 @@
using System;
using System.Runtime.ConstrainedExecution;
using System.Threading;
namespace Avalonia.Threading
@ -7,6 +9,20 @@ namespace Avalonia.Threading
/// </summary>
public class AvaloniaSynchronizationContext : SynchronizationContext
{
public interface INonPumpingPlatformWaitProvider
{
int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout);
}
private readonly INonPumpingPlatformWaitProvider _waitProvider;
public AvaloniaSynchronizationContext(INonPumpingPlatformWaitProvider waitProvider)
{
_waitProvider = waitProvider;
if (_waitProvider != null)
SetWaitNotificationRequired();
}
/// <summary>
/// Controls if SynchronizationContext should be installed in InstallIfNeeded. Used by Designer.
/// </summary>
@ -22,7 +38,8 @@ namespace Avalonia.Threading
return;
}
SetSynchronizationContext(new AvaloniaSynchronizationContext());
SetSynchronizationContext(new AvaloniaSynchronizationContext(AvaloniaLocator.Current
.GetService<INonPumpingPlatformWaitProvider>()));
}
/// <inheritdoc/>
@ -39,5 +56,13 @@ namespace Avalonia.Threading
else
Dispatcher.UIThread.InvokeAsync(() => d(state), DispatcherPriority.Send).Wait();
}
[PrePrepareMethod]
public override int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)
{
if (_waitProvider != null)
return _waitProvider.Wait(waitHandles, waitAll, millisecondsTimeout);
return base.Wait(waitHandles, waitAll, millisecondsTimeout);
}
}
}

2
src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs

@ -192,7 +192,7 @@ namespace Avalonia.Controls.Remote.Server
GetAvaloniaInputModifiers(pressed.Modifiers)));
}, DispatcherPriority.Input);
}
if (obj is PointerPressedEventMessage released)
if (obj is PointerReleasedEventMessage released)
{
Dispatcher.UIThread.Post(() =>
{

2
src/Avalonia.FreeDesktop/DBusHelper.cs

@ -43,7 +43,7 @@ namespace Avalonia.FreeDesktop
public void Initialized()
{
lock (_lock)
_ctx = new AvaloniaSynchronizationContext();
_ctx = new AvaloniaSynchronizationContext(null);
}
}
public static Connection Connection { get; private set; }

4
src/Markup/Avalonia.Markup/Data/BindingBase.cs

@ -137,9 +137,9 @@ namespace Avalonia.Data
{
Contract.Requires<ArgumentNullException>(target != null);
if (!(target is IStyledElement))
if (!(target is IDataContextProvider))
{
target = anchor as IStyledElement;
target = anchor as IDataContextProvider;
if (target == null)
{

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

@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -1382,6 +1383,22 @@ namespace Avalonia.Win32.Interop
throw new Exception("RtlGetVersion failed!");
}
}
[DllImport("kernel32", EntryPoint="WaitForMultipleObjectsEx", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int IntWaitForMultipleObjectsEx(int nCount, IntPtr[] pHandles, bool bWaitAll, int dwMilliseconds, bool bAlertable);
public const int WAIT_FAILED = unchecked((int)0xFFFFFFFF);
internal static int WaitForMultipleObjectsEx(int nCount, IntPtr[] pHandles, bool bWaitAll, int dwMilliseconds, bool bAlertable)
{
int result = IntWaitForMultipleObjectsEx(nCount, pHandles, bWaitAll, dwMilliseconds, bAlertable);
if(result == WAIT_FAILED)
{
throw new Win32Exception();
}
return result;
}
[DllImport("user32.dll")]
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);

15
src/Windows/Avalonia.Win32/NonPumpingWaitProvider.cs

@ -0,0 +1,15 @@
using System;
using Avalonia.Threading;
using Avalonia.Win32.Interop;
namespace Avalonia.Win32
{
internal class NonPumpingWaitProvider : AvaloniaSynchronizationContext.INonPumpingPlatformWaitProvider
{
public int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)
{
return UnmanagedMethods.WaitForMultipleObjectsEx(waitHandles.Length, waitHandles, waitAll,
millisecondsTimeout, false);
}
}
}

1
src/Windows/Avalonia.Win32/Win32Platform.cs

@ -93,6 +93,7 @@ namespace Avalonia.Win32
.Bind<IWindowingPlatform>().ToConstant(s_instance)
.Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>()
.Bind<IPlatformIconLoader>().ToConstant(s_instance)
.Bind<AvaloniaSynchronizationContext.INonPumpingPlatformWaitProvider>().ToConstant(new NonPumpingWaitProvider())
.Bind<IMountedVolumeInfoProvider>().ToConstant(new WindowsMountedVolumeInfoProvider());
if (options.AllowEglInitialization)

18
tests/Avalonia.Controls.UnitTests/ApplicationTests.cs

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using Avalonia.Threading;
using Avalonia.Data;
using Avalonia.UnitTests;
using Xunit;
@ -32,5 +31,20 @@ namespace Avalonia.Controls.UnitTests
Assert.True(raised);
}
}
[Fact]
public void Can_Bind_To_DataContext()
{
using (UnitTestApplication.Start())
{
var application = Application.Current;
application.DataContext = "Test";
application.Bind(Application.NameProperty, new Binding("."));
Assert.Equal("Test", Application.Current.Name);
}
}
}
}

Loading…
Cancel
Save