Move GetWindowsZOrder to IWindowingPlatform (#20633)
* Move GetWindowsZOrder to IWindowingPlatform * Update API suppressions
This commit is contained in:
committed by
GitHub
parent
cdb91f7f78
commit
816fb91d4e
@@ -1225,6 +1225,18 @@
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Controls.Window.SortWindowsByZOrder(Avalonia.Controls.Window[])</Target>
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Platform.IWindowImpl.GetWindowsZOrder(System.Span{Avalonia.Controls.Window},System.Span{System.Int64})</Target>
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Platform.Screen.#ctor(System.Double,Avalonia.PixelRect,Avalonia.PixelRect,System.Boolean)</Target>
|
||||
@@ -2125,6 +2137,18 @@
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Controls.Window.SortWindowsByZOrder(Avalonia.Controls.Window[])</Target>
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Platform.IWindowImpl.GetWindowsZOrder(System.Span{Avalonia.Controls.Window},System.Span{System.Int64})</Target>
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Platform.Screen.#ctor(System.Double,Avalonia.PixelRect,Avalonia.PixelRect,System.Boolean)</Target>
|
||||
@@ -2377,6 +2401,12 @@
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>M:Avalonia.Platform.IWindowingPlatform.GetWindowsZOrder(System.ReadOnlySpan{Avalonia.Platform.IWindowImpl},System.Span{System.Int64})</Target>
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize})</Target>
|
||||
@@ -2575,6 +2605,12 @@
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>M:Avalonia.Platform.IWindowingPlatform.GetWindowsZOrder(System.ReadOnlySpan{Avalonia.Platform.IWindowImpl},System.Span{System.Int64})</Target>
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>M:Avalonia.OpenGL.IGlExternalSemaphore.SignalTimelineSemaphore(Avalonia.OpenGL.IGlExternalImageTexture,System.UInt64)</Target>
|
||||
|
||||
@@ -12,6 +12,8 @@ namespace Avalonia.Android
|
||||
public IWindowImpl CreateEmbeddableWindow() => throw new NotSupportedException();
|
||||
|
||||
public ITrayIconImpl? CreateTrayIcon() => null;
|
||||
|
||||
public void GetWindowsZOrder(ReadOnlySpan<IWindowImpl> windows, Span<long> zOrder) => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
internal class PlatformIconLoaderStub : IPlatformIconLoader
|
||||
|
||||
@@ -153,14 +153,5 @@ namespace Avalonia.Platform
|
||||
/// </summary>
|
||||
/// <param name="titleBarHeight">-1 for platform default, otherwise the height in DIPs.</param>
|
||||
void SetExtendClientAreaTitleBarHeightHint(double titleBarHeight);
|
||||
|
||||
/// <summary>
|
||||
/// Fills zOrder with numbers that represent the relative order of the windows in the z-order.
|
||||
/// The topmost window should have the highest number.
|
||||
/// Both the windows and zOrder lists are expected to be the same length.
|
||||
/// </summary>
|
||||
/// <param name="windows">A span of windows to get their z-order</param>
|
||||
/// <param name="zOrder">Span to be filled with associated window z-order</param>
|
||||
void GetWindowsZOrder(Span<Window> windows, Span<long> zOrder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using Avalonia.Metadata;
|
||||
|
||||
namespace Avalonia.Platform
|
||||
@@ -12,5 +13,14 @@ namespace Avalonia.Platform
|
||||
IWindowImpl CreateEmbeddableWindow();
|
||||
|
||||
ITrayIconImpl? CreateTrayIcon();
|
||||
|
||||
/// <summary>
|
||||
/// Fills a span with numbers that represent the relative order of the windows in the z-order.
|
||||
/// The topmost window should have the highest number.
|
||||
/// Both the <paramref name="windows"/> and <paramref name="zOrder"/> lists are expected to be the same length.
|
||||
/// </summary>
|
||||
/// <param name="windows">A span of windows to get their z-order.</param>
|
||||
/// <param name="zOrder">The span to be filled with the associated window z-order.</param>
|
||||
void GetWindowsZOrder(ReadOnlySpan<IWindowImpl> windows, Span<long> zOrder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -903,24 +903,25 @@ namespace Avalonia.Controls
|
||||
/// <summary>
|
||||
/// Sorts the windows ascending by their Z order - the topmost window will be the last in the list.
|
||||
/// </summary>
|
||||
/// <param name="windows"></param>
|
||||
public static void SortWindowsByZOrder(Window[] windows)
|
||||
/// <param name="windows">The windows to sort.</param>
|
||||
public static void SortWindowsByZOrder(Span<Window> windows)
|
||||
{
|
||||
if (windows.Length == 0)
|
||||
if (windows.Length <= 1)
|
||||
return;
|
||||
|
||||
if (windows[0].PlatformImpl is not { } platformImpl)
|
||||
throw new InvalidOperationException("Window.PlatformImpl is null");
|
||||
var platform = AvaloniaLocator.Current.GetRequiredService<IWindowingPlatform>();
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
Span<long> zOrder = stackalloc long[windows.Length];
|
||||
platformImpl.GetWindowsZOrder(windows, zOrder);
|
||||
zOrder.Sort(windows.AsSpan());
|
||||
#else
|
||||
long[] zOrder = new long[windows.Length];
|
||||
platformImpl.GetWindowsZOrder(windows, zOrder);
|
||||
Array.Sort(zOrder, windows);
|
||||
#endif
|
||||
var windowImpls = new IWindowImpl[windows.Length];
|
||||
for (var i = 0; i < windows.Length; ++i)
|
||||
{
|
||||
windowImpls[i] = windows[i].PlatformImpl ??
|
||||
throw new ArgumentException($"Invalid window at index {i}", nameof(windows));
|
||||
}
|
||||
|
||||
const int stackAllocThreshold = 128;
|
||||
var zOrder = windows.Length > stackAllocThreshold ? new long[windows.Length] : stackalloc long[windows.Length];
|
||||
platform.GetWindowsZOrder(windowImpls, zOrder);
|
||||
zOrder.Sort(windows);
|
||||
}
|
||||
|
||||
private void UpdateEnabled()
|
||||
|
||||
@@ -170,7 +170,5 @@ namespace Avalonia.DesignerSupport.Remote
|
||||
public void SetExtendClientAreaTitleBarHeightHint(double titleBarHeight)
|
||||
{
|
||||
}
|
||||
|
||||
public void GetWindowsZOrder(Span<Window> windows, Span<long> zOrder) => throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ namespace Avalonia.DesignerSupport.Remote
|
||||
return s_lastWindow;
|
||||
}
|
||||
|
||||
public void GetWindowsZOrder(ReadOnlySpan<IWindowImpl> windows, Span<long> zOrder)
|
||||
=> zOrder.Clear();
|
||||
|
||||
public static void Initialize(IAvaloniaRemoteTransportConnection transport)
|
||||
{
|
||||
s_transport = transport;
|
||||
|
||||
@@ -182,8 +182,6 @@ namespace Avalonia.DesignerSupport.Remote
|
||||
{
|
||||
}
|
||||
|
||||
public void GetWindowsZOrder(Span<Window> windows, Span<long> zOrder) => throw new NotSupportedException();
|
||||
|
||||
public IPopupPositioner? PopupPositioner { get; }
|
||||
|
||||
public Action? GotInputWhenDisabled { get; set; }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Avalonia.Compatibility;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Controls.Platform;
|
||||
using Avalonia.Input;
|
||||
@@ -210,5 +211,13 @@ namespace Avalonia.Native
|
||||
{
|
||||
return new EmbeddableTopLevelImpl(_factory);
|
||||
}
|
||||
|
||||
public void GetWindowsZOrder(ReadOnlySpan<IWindowImpl> windows, Span<long> zOrder)
|
||||
{
|
||||
for (var i = 0; i < windows.Length; i++)
|
||||
{
|
||||
zOrder[i] = (windows[i] as WindowImpl)?.ZOrder?.ToInt64() ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,13 +271,5 @@ namespace Avalonia.Native
|
||||
|
||||
return base.TryGetFeature(featureType);
|
||||
}
|
||||
|
||||
public void GetWindowsZOrder(Span<Window> windows, Span<long> zOrder)
|
||||
{
|
||||
for (int i = 0; i < windows.Length; i++)
|
||||
{
|
||||
zOrder[i] = (windows[i].PlatformImpl as WindowImpl)?.ZOrder?.ToInt64() ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +230,83 @@ namespace Avalonia.X11
|
||||
|
||||
throw new InvalidOperationException($"{nameof(X11PlatformOptions)}.{nameof(X11PlatformOptions.RenderingMode)} has a value of \"{string.Join(", ", opts.RenderingMode)}\", but no options were applied.");
|
||||
}
|
||||
|
||||
public void GetWindowsZOrder(ReadOnlySpan<IWindowImpl> windows, Span<long> outputZOrder)
|
||||
{
|
||||
// a mapping of parent windows to their children, sorted by z-order (bottom to top)
|
||||
var windowsChildren = new Dictionary<IntPtr, List<IntPtr>>();
|
||||
|
||||
var indexInWindowsSpan = new Dictionary<IntPtr, int>();
|
||||
for (var i = 0; i < windows.Length; i++)
|
||||
if (windows[i] is X11Window { Handle: { } handle })
|
||||
indexInWindowsSpan[handle.Handle] = i;
|
||||
|
||||
foreach (var window in windows)
|
||||
{
|
||||
if (window is not X11Window x11Window)
|
||||
continue;
|
||||
|
||||
var node = x11Window.Handle.Handle;
|
||||
while (node != IntPtr.Zero)
|
||||
{
|
||||
if (windowsChildren.ContainsKey(node))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (XQueryTree(Info.Display, node, out _, out var parent,
|
||||
out var childrenPtr, out var childrenCount) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (childrenPtr != IntPtr.Zero)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var children = (IntPtr*)childrenPtr;
|
||||
windowsChildren[node] = new List<IntPtr>(childrenCount);
|
||||
for (var i = 0; i < childrenCount; i++)
|
||||
{
|
||||
windowsChildren[node].Add(children[i]);
|
||||
}
|
||||
|
||||
XFree(childrenPtr);
|
||||
}
|
||||
}
|
||||
|
||||
node = parent;
|
||||
}
|
||||
}
|
||||
|
||||
var stack = new Stack<IntPtr>();
|
||||
var zOrder = 0;
|
||||
stack.Push(Info.RootWindow);
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var currentWindow = stack.Pop();
|
||||
|
||||
if (!windowsChildren.TryGetValue(currentWindow, out var children))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (indexInWindowsSpan.TryGetValue(currentWindow, out var index))
|
||||
{
|
||||
outputZOrder[index] = zOrder;
|
||||
}
|
||||
|
||||
zOrder++;
|
||||
|
||||
// Children are returned bottom to top, so we need to push them in reverse order
|
||||
// In order to traverse bottom children first
|
||||
for (int i = children.Count - 1; i >= 0; i--)
|
||||
{
|
||||
stack.Push(children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1557,80 +1557,6 @@ namespace Avalonia.X11
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void GetWindowsZOrder(Span<Window> windows, Span<long> outputZOrder)
|
||||
{
|
||||
// a mapping of parent windows to their children, sorted by z-order (bottom to top)
|
||||
var windowsChildren = new Dictionary<IntPtr, List<IntPtr>>();
|
||||
|
||||
var indexInWindowsSpan = new Dictionary<IntPtr, int>();
|
||||
for (var i = 0; i < windows.Length; i++)
|
||||
if (windows[i].PlatformImpl is { Handle: { } handle })
|
||||
indexInWindowsSpan[handle.Handle] = i;
|
||||
|
||||
foreach (var window in windows)
|
||||
{
|
||||
if (window.PlatformImpl is not X11Window x11Window)
|
||||
continue;
|
||||
|
||||
var node = x11Window.Handle.Handle;
|
||||
while (node != IntPtr.Zero)
|
||||
{
|
||||
if (windowsChildren.ContainsKey(node))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (XQueryTree(_x11.Display, node, out _, out var parent,
|
||||
out var childrenPtr, out var childrenCount) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (childrenPtr != IntPtr.Zero)
|
||||
{
|
||||
var children = (IntPtr*)childrenPtr;
|
||||
windowsChildren[node] = new List<IntPtr>(childrenCount);
|
||||
for (var i = 0; i < childrenCount; i++)
|
||||
{
|
||||
windowsChildren[node].Add(children[i]);
|
||||
}
|
||||
XFree(childrenPtr);
|
||||
}
|
||||
|
||||
node = parent;
|
||||
}
|
||||
}
|
||||
|
||||
var stack = new Stack<IntPtr>();
|
||||
var zOrder = 0;
|
||||
stack.Push(_x11.RootWindow);
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var currentWindow = stack.Pop();
|
||||
|
||||
if (!windowsChildren.TryGetValue(currentWindow, out var children))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (indexInWindowsSpan.TryGetValue(currentWindow, out var index))
|
||||
{
|
||||
outputZOrder[index] = zOrder;
|
||||
}
|
||||
|
||||
zOrder++;
|
||||
|
||||
// Children are returned bottom to top, so we need to push them in reverse order
|
||||
// In order to traverse bottom children first
|
||||
for (int i = children.Count - 1; i >= 0; i--)
|
||||
{
|
||||
stack.Push(children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void TakeFocus()
|
||||
{
|
||||
// TODO: Not yet implemented: need to check if this is required on X11 or not.
|
||||
|
||||
@@ -74,6 +74,9 @@ internal class BrowserWindowingPlatform : IWindowingPlatform
|
||||
return null;
|
||||
}
|
||||
|
||||
public void GetWindowsZOrder(ReadOnlySpan<IWindowImpl> windows, Span<long> zOrder)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public static KeyboardDevice Keyboard => s_keyboard ??
|
||||
throw new InvalidOperationException("BrowserWindowingPlatform not registered.");
|
||||
|
||||
|
||||
@@ -63,6 +63,14 @@ namespace Avalonia.Headless
|
||||
public IWindowImpl CreateEmbeddableWindow() => throw new PlatformNotSupportedException();
|
||||
|
||||
public ITrayIconImpl? CreateTrayIcon() => null;
|
||||
|
||||
public void GetWindowsZOrder(ReadOnlySpan<IWindowImpl> windows, Span<long> zOrder)
|
||||
{
|
||||
for (var i = 0; i < windows.Length; ++i)
|
||||
{
|
||||
zOrder[i] = (windows[i] as HeadlessWindowImpl)?.ZOrder ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Initialize(AvaloniaHeadlessPlatformOptions opts)
|
||||
|
||||
@@ -25,7 +25,6 @@ namespace Avalonia.Headless
|
||||
private WriteableBitmap? _lastRenderedFrame;
|
||||
private readonly object _sync = new object();
|
||||
private readonly PixelFormat _frameBufferFormat;
|
||||
private int _zOrder;
|
||||
public bool IsPopup { get; }
|
||||
|
||||
public HeadlessWindowImpl(bool isPopup, PixelFormat frameBufferFormat)
|
||||
@@ -59,6 +58,8 @@ namespace Avalonia.Headless
|
||||
|
||||
public Compositor Compositor => AvaloniaHeadlessPlatform.Compositor!;
|
||||
|
||||
public int ZOrder { get; private set; }
|
||||
|
||||
public void SetInputRoot(IInputRoot inputRoot)
|
||||
{
|
||||
InputRoot = inputRoot;
|
||||
@@ -82,7 +83,7 @@ namespace Avalonia.Headless
|
||||
{
|
||||
if (activate)
|
||||
{
|
||||
_zOrder = _nextGlobalZOrder++;
|
||||
ZOrder = _nextGlobalZOrder++;
|
||||
Dispatcher.UIThread.Post(() => Activated?.Invoke(), DispatcherPriority.Input);
|
||||
}
|
||||
}
|
||||
@@ -96,7 +97,7 @@ namespace Avalonia.Headless
|
||||
public Action<PixelPoint>? PositionChanged { get; set; }
|
||||
public void Activate()
|
||||
{
|
||||
_zOrder = _nextGlobalZOrder++;
|
||||
ZOrder = _nextGlobalZOrder++;
|
||||
Dispatcher.UIThread.Post(() => Activated?.Invoke(), DispatcherPriority.Input);
|
||||
}
|
||||
|
||||
@@ -430,15 +431,6 @@ namespace Avalonia.Headless
|
||||
|
||||
}
|
||||
|
||||
public void GetWindowsZOrder(Span<Window> windows, Span<long> zOrder)
|
||||
{
|
||||
for (int i = 0; i < windows.Length; ++i)
|
||||
{
|
||||
if (windows[i].PlatformImpl is HeadlessWindowImpl headlessWindowImpl)
|
||||
zOrder[i] = headlessWindowImpl._zOrder;
|
||||
}
|
||||
}
|
||||
|
||||
public void TakeFocus()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -323,5 +323,33 @@ namespace Avalonia.Win32
|
||||
if (dpiAwareness != Win32DpiAwareness.Unaware)
|
||||
SetProcessDPIAware();
|
||||
}
|
||||
|
||||
public void GetWindowsZOrder(ReadOnlySpan<IWindowImpl> windows, Span<long> zOrder)
|
||||
{
|
||||
var handlesToIndex = new Dictionary<IntPtr, int>(windows.Length);
|
||||
var outputArray = new long[windows.Length];
|
||||
|
||||
for (int i = 0; i < windows.Length; i++)
|
||||
{
|
||||
if (windows[i] is WindowImpl platformImpl)
|
||||
handlesToIndex.Add(platformImpl.Handle.Handle, i);
|
||||
}
|
||||
|
||||
long nextZOrder = 0;
|
||||
bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam)
|
||||
{
|
||||
if (handlesToIndex.TryGetValue(hWnd, out var index))
|
||||
{
|
||||
// We negate the z-order so that the topmost window has the highest number.
|
||||
outputArray[index] = -nextZOrder;
|
||||
nextZOrder++;
|
||||
}
|
||||
return nextZOrder < outputArray.Length;
|
||||
}
|
||||
|
||||
EnumChildWindows(IntPtr.Zero, EnumWindowsProc, IntPtr.Zero);
|
||||
|
||||
outputArray.CopyTo(zOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1613,38 +1613,6 @@ namespace Avalonia.Win32
|
||||
ExtendClientArea();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void GetWindowsZOrder(Span<Window> windows, Span<long> zOrder)
|
||||
{
|
||||
var handlesToIndex = new Dictionary<IntPtr, int>(windows.Length);
|
||||
var outputArray = new long[windows.Length];
|
||||
|
||||
for (int i = 0; i < windows.Length; i++)
|
||||
{
|
||||
if (windows[i].PlatformImpl is WindowImpl platformImpl)
|
||||
handlesToIndex.Add(platformImpl.Handle.Handle, i);
|
||||
}
|
||||
|
||||
long nextZOrder = 0;
|
||||
bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam)
|
||||
{
|
||||
if (handlesToIndex.TryGetValue(hWnd, out var index))
|
||||
{
|
||||
// We negate the z-order so that the topmost window has the highest number.
|
||||
outputArray[index] = -nextZOrder;
|
||||
nextZOrder++;
|
||||
}
|
||||
return nextZOrder < outputArray.Length;
|
||||
}
|
||||
|
||||
EnumChildWindows(IntPtr.Zero, EnumWindowsProc, IntPtr.Zero);
|
||||
|
||||
for (int i = 0; i < windows.Length; i++)
|
||||
{
|
||||
zOrder[i] = outputArray[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsClientAreaExtendedToDecorations => _isClientAreaExtended;
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ namespace Avalonia.iOS
|
||||
public IWindowImpl CreateEmbeddableWindow() => throw new NotSupportedException();
|
||||
|
||||
public ITrayIconImpl? CreateTrayIcon() => null;
|
||||
|
||||
public void GetWindowsZOrder(ReadOnlySpan<IWindowImpl> windows, Span<long> zOrder)
|
||||
=> throw new NotSupportedException();
|
||||
}
|
||||
|
||||
internal class PlatformIconLoaderStub : IPlatformIconLoader
|
||||
|
||||
@@ -162,5 +162,8 @@ namespace Avalonia.UnitTests
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void GetWindowsZOrder(ReadOnlySpan<IWindowImpl> windows, Span<long> zOrder)
|
||||
=> zOrder.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user