Browse Source

Merge branch 'master' into color-slider-previewer

pull/8050/head
robloo 4 years ago
parent
commit
2d764ec3c5
  1. 2
      src/Avalonia.Controls/ItemsControl.cs
  2. 2
      src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs
  3. 75
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  4. 15
      src/Windows/Avalonia.Win32/TrayIconImpl.cs
  5. 45
      tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs

2
src/Avalonia.Controls/ItemsControl.cs

@ -518,7 +518,7 @@ namespace Avalonia.Controls
}
c = result;
} while (c != null && c != from);
} while (c != null && c != from && direction != NavigationDirection.First && direction != NavigationDirection.Last);
return null;
}

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

@ -417,7 +417,7 @@ namespace Avalonia.Controls.Platform
protected internal virtual void MenuOpened(object? sender, RoutedEventArgs e)
{
if (e.Source == Menu)
if (e.Source is Menu)
{
Menu?.MoveSelection(NavigationDirection.First, true);
}

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

@ -914,9 +914,9 @@ namespace Avalonia.Win32.Interop
[DllImport("user32.dll")]
public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip,
MonitorEnumDelegate lpfnEnum, IntPtr dwData);
public delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr dwData);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetDC(IntPtr hWnd);
@ -1007,7 +1007,7 @@ namespace Avalonia.Win32.Interop
public static uint GetWindowLong(IntPtr hWnd, int nIndex)
{
if(IntPtr.Size == 4)
if (IntPtr.Size == 4)
{
return GetWindowLong32b(hWnd, nIndex);
}
@ -1034,7 +1034,7 @@ namespace Avalonia.Win32.Interop
return (uint)SetWindowLong64b(hWnd, nIndex, new IntPtr((uint)value)).ToInt32();
}
}
public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr handle)
{
if (IntPtr.Size == 4)
@ -1068,14 +1068,14 @@ namespace Avalonia.Win32.Interop
[DllImport("user32.dll")]
public static extern bool InvalidateRect(IntPtr hWnd, RECT* lpRect, bool bErase);
[DllImport("user32.dll")]
public static extern bool ValidateRect(IntPtr hWnd, IntPtr lpRect);
[DllImport("user32.dll")]
public static extern bool IsWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern bool IsWindowEnabled(IntPtr hWnd);
@ -1102,22 +1102,25 @@ namespace Avalonia.Win32.Interop
[DllImport("user32")]
public static extern IntPtr GetMessageExtraInfo();
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "RegisterClassExW")]
public static extern ushort RegisterClassEx(ref WNDCLASSEX lpwcx);
[DllImport("user32.dll")]
public static extern void RegisterTouchWindow(IntPtr hWnd, int flags);
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll", SetLastError = true)]
public static extern uint RegisterWindowMessage(string lpString);
[DllImport("user32.dll")]
public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetActiveWindow();
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetActiveWindow(IntPtr hWnd);
@ -1304,7 +1307,7 @@ namespace Avalonia.Win32.Interop
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadLibrary(string fileName);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadLibraryEx(string fileName, IntPtr hFile, int flags);
@ -1348,7 +1351,7 @@ namespace Avalonia.Win32.Interop
[DllImport("user32.dll")]
public static extern IntPtr MonitorFromWindow(IntPtr hwnd, MONITOR dwFlags);
[DllImport("user32", EntryPoint = "GetMonitorInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetMonitorInfo([In] IntPtr hMonitor, ref MONITORINFO lpmi);
@ -1356,14 +1359,14 @@ namespace Avalonia.Win32.Interop
[DllImport("user32")]
public static extern unsafe bool GetTouchInputInfo(
IntPtr hTouchInput,
uint cInputs,
uint cInputs,
TOUCHINPUT* pInputs,
int cbSize
int cbSize
);
[DllImport("user32")]
public static extern bool CloseTouchInputHandle(IntPtr hTouchInput);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "PostMessageW")]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
@ -1372,7 +1375,7 @@ namespace Avalonia.Win32.Interop
public static extern int SetDIBitsToDevice(IntPtr hdc, int XDest, int YDest, uint
dwWidth, uint dwHeight, int XSrc, int YSrc, uint uStartScan, uint cScanLines,
IntPtr lpvBits, [In] ref BITMAPINFOHEADER lpbmi, uint fuColorUse);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
@ -1387,27 +1390,27 @@ namespace Avalonia.Win32.Interop
[DllImport("gdi32.dll")]
public static extern int ChoosePixelFormat(IntPtr hdc, ref PixelFormatDescriptor pfd);
[DllImport("gdi32.dll")]
public static extern int DescribePixelFormat(IntPtr hdc, ref PixelFormatDescriptor pfd);
[DllImport("gdi32.dll")]
public static extern int SetPixelFormat(IntPtr hdc, int iPixelFormat, ref PixelFormatDescriptor pfd);
[DllImport("gdi32.dll")]
public static extern int DescribePixelFormat(IntPtr hdc, int iPixelFormat, int bytes, ref PixelFormatDescriptor pfd);
[DllImport("gdi32.dll")]
public static extern bool SwapBuffers(IntPtr hdc);
[DllImport("opengl32.dll")]
public static extern IntPtr wglCreateContext(IntPtr hdc);
[DllImport("opengl32.dll")]
public static extern bool wglDeleteContext(IntPtr context);
[DllImport("opengl32.dll")]
public static extern bool wglMakeCurrent(IntPtr hdc, IntPtr context);
@ -1428,9 +1431,9 @@ namespace Avalonia.Win32.Interop
uint dwMaximumSizeLow,
string lpName);
[DllImport("msvcrt.dll", EntryPoint="memcpy", SetLastError = false, CallingConvention=CallingConvention.Cdecl)]
public static extern IntPtr CopyMemory(IntPtr dest, IntPtr src, UIntPtr count);
[DllImport("msvcrt.dll", EntryPoint = "memcpy", SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr CopyMemory(IntPtr dest, IntPtr src, UIntPtr count);
[DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern HRESULT RegisterDragDrop(IntPtr hwnd, IntPtr target);
@ -1472,10 +1475,10 @@ namespace Avalonia.Win32.Interop
[DllImport("dwmapi.dll")]
public static extern void DwmFlush();
[DllImport("dwmapi.dll")]
public static extern bool DwmDefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam, ref IntPtr plResult);
[DllImport("dwmapi.dll")]
public static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);
@ -1542,8 +1545,8 @@ namespace Avalonia.Win32.Interop
throw new Exception("RtlGetVersion failed!");
}
}
[DllImport("kernel32", EntryPoint="WaitForMultipleObjectsEx", SetLastError = true, CharSet = CharSet.Auto)]
[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);
@ -1551,7 +1554,7 @@ namespace Avalonia.Win32.Interop
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)
if (result == WAIT_FAILED)
{
throw new Win32Exception();
}
@ -1699,7 +1702,7 @@ namespace Avalonia.Win32.Interop
DrawLeftBorder = 0x20,
DrawTopBorder = 0x40,
DrawRightBorder = 0x80,
DrawBottomBorder = 0x100,
DrawBottomBorder = 0x100,
}
[StructLayout(LayoutKind.Sequential)]
@ -1767,9 +1770,9 @@ namespace Avalonia.Win32.Interop
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
}
}
public enum ClipboardFormat
public enum ClipboardFormat
{
/// <summary>
/// Text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. Use this format for ANSI text.
@ -1820,7 +1823,7 @@ namespace Avalonia.Win32.Interop
public int X;
public int Y;
}
public struct SIZE
{
public int X;
@ -2021,7 +2024,7 @@ namespace Avalonia.Win32.Interop
OFN_NOREADONLYRETURN = 0x00008000,
OFN_OVERWRITEPROMPT = 0x00000002
}
public enum HRESULT : uint
{
S_FALSE = 0x0001,

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

@ -24,6 +24,7 @@ namespace Avalonia.Win32
private readonly Win32NativeToManagedMenuExporter _exporter;
private static readonly Dictionary<int, TrayIconImpl> s_trayIcons = new Dictionary<int, TrayIconImpl>();
private bool _disposedValue;
private static readonly uint WM_TASKBARCREATED = UnmanagedMethods.RegisterWindowMessage("TaskbarCreated");
public TrayIconImpl()
{
@ -44,6 +45,18 @@ namespace Avalonia.Win32
{
s_trayIcons[wParam.ToInt32()].WndProc(hWnd, msg, wParam, lParam);
}
if (msg == WM_TASKBARCREATED)
{
foreach (var tray in s_trayIcons.Values)
{
if (tray._iconAdded)
{
tray.UpdateIcon(true);
tray.UpdateIcon();
}
}
}
}
public void SetIcon(IWindowIconImpl? icon)
@ -145,7 +158,7 @@ namespace Avalonia.Win32
private enum CustomWindowsMessage : uint
{
WM_TRAYICON = WindowsMessage.WM_APP + 1024,
WM_TRAYMOUSE = WindowsMessage.WM_USER + 1024
WM_TRAYMOUSE = WindowsMessage.WM_USER + 1024,
}
private class TrayIconMenuFlyoutPresenter : MenuFlyoutPresenter, IStyleable

45
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs

@ -6,6 +6,7 @@ using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Disposables;
using System.Threading.Tasks;
using Avalonia.Collections;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
@ -1614,6 +1615,50 @@ namespace Avalonia.Controls.UnitTests.Primitives
target.MoveSelection(NavigationDirection.Next, true);
}
[Fact(Timeout = 2000)]
public async Task MoveSelection_Does_Not_Hang_With_No_Focusable_Controls_And_Moving_Selection_To_The_First_Item()
{
var target = new TestSelector
{
Template = Template(),
Items = new[]
{
new ListBoxItem { Focusable = false },
new ListBoxItem(),
}
};
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
// Timeout in xUnit doesen't work with synchronous methods so we need to apply hack below.
// https://github.com/xunit/xunit/issues/2222
await Task.Run(() => target.MoveSelection(NavigationDirection.First, true));
Assert.Equal(-1, target.SelectedIndex);
}
[Fact(Timeout = 2000)]
public async Task MoveSelection_Does_Not_Hang_With_No_Focusable_Controls_And_Moving_Selection_To_The_Last_Item()
{
var target = new TestSelector
{
Template = Template(),
Items = new[]
{
new ListBoxItem(),
new ListBoxItem { Focusable = false },
}
};
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
// Timeout in xUnit doesen't work with synchronous methods so we need to apply hack below.
// https://github.com/xunit/xunit/issues/2222
await Task.Run(() => target.MoveSelection(NavigationDirection.Last, true));
Assert.Equal(-1, target.SelectedIndex);
}
[Fact]
public void MoveSelection_Does_Select_Disabled_Controls()
{

Loading…
Cancel
Save