diff --git a/src/Avalonia.Base/Threading/AvaloniaSynchronizationContext.cs b/src/Avalonia.Base/Threading/AvaloniaSynchronizationContext.cs
index 38a23f918f..40cf81358f 100644
--- a/src/Avalonia.Base/Threading/AvaloniaSynchronizationContext.cs
+++ b/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
///
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();
+ }
+
///
/// Controls if SynchronizationContext should be installed in InstallIfNeeded. Used by Designer.
///
@@ -22,7 +38,8 @@ namespace Avalonia.Threading
return;
}
- SetSynchronizationContext(new AvaloniaSynchronizationContext());
+ SetSynchronizationContext(new AvaloniaSynchronizationContext(AvaloniaLocator.Current
+ .GetService()));
}
///
@@ -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);
+ }
}
}
diff --git a/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs b/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs
index f5c673d5f9..931c27c575 100644
--- a/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs
+++ b/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(() =>
{
diff --git a/src/Avalonia.FreeDesktop/DBusHelper.cs b/src/Avalonia.FreeDesktop/DBusHelper.cs
index b445f86613..91c4c28995 100644
--- a/src/Avalonia.FreeDesktop/DBusHelper.cs
+++ b/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; }
diff --git a/src/Markup/Avalonia.Markup/Data/BindingBase.cs b/src/Markup/Avalonia.Markup/Data/BindingBase.cs
index 7c4e7b5efe..3dbc83a7df 100644
--- a/src/Markup/Avalonia.Markup/Data/BindingBase.cs
+++ b/src/Markup/Avalonia.Markup/Data/BindingBase.cs
@@ -137,9 +137,9 @@ namespace Avalonia.Data
{
Contract.Requires(target != null);
- if (!(target is IStyledElement))
+ if (!(target is IDataContextProvider))
{
- target = anchor as IStyledElement;
+ target = anchor as IDataContextProvider;
if (target == null)
{
diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
index 1aec4f0016..392ca31282 100644
--- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
+++ b/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);
diff --git a/src/Windows/Avalonia.Win32/NonPumpingWaitProvider.cs b/src/Windows/Avalonia.Win32/NonPumpingWaitProvider.cs
new file mode 100644
index 0000000000..a0160fcfbd
--- /dev/null
+++ b/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);
+ }
+ }
+}
diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs
index b7bb0e19ba..af6058d197 100644
--- a/src/Windows/Avalonia.Win32/Win32Platform.cs
+++ b/src/Windows/Avalonia.Win32/Win32Platform.cs
@@ -93,6 +93,7 @@ namespace Avalonia.Win32
.Bind().ToConstant(s_instance)
.Bind().ToSingleton()
.Bind().ToConstant(s_instance)
+ .Bind().ToConstant(new NonPumpingWaitProvider())
.Bind().ToConstant(new WindowsMountedVolumeInfoProvider());
if (options.AllowEglInitialization)
diff --git a/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs b/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs
index e533001242..58ddc8ca60 100644
--- a/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs
+++ b/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);
+ }
+ }
}
}