Skip to content

Commit

Permalink
Fix headless screens (#16348)
Browse files Browse the repository at this point in the history
* Fix headless screens being null

* Remove unused properties
  • Loading branch information
maxkatz6 authored Jul 17, 2024
1 parent 05ac6d2 commit 460a354
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ public TopLevelImpl(AvaloniaView avaloniaView, bool placeOnTop = false)
internal InvalidationAwareSurfaceView InternalView => _view;

public double DesktopScaling => RenderScaling;
public IScreenImpl? Screen { get; }
public IPlatformHandle Handle => _view;

public IEnumerable<object> Surfaces { get; }
Expand Down
4 changes: 3 additions & 1 deletion src/Avalonia.Controls/Screens.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ public Screens(IScreenImpl iScreenImpl)
var tl = visual.PointToScreen(visual.Bounds.TopLeft);
var br = visual.PointToScreen(visual.Bounds.BottomRight);

return ScreenFromBounds(new PixelRect(tl, br));
// Attempt to get screen from the physical position on any screen first. Fallback to the screen hosting top level.
return ScreenFromBounds(new PixelRect(tl, br))
?? ScreenFromTopLevel(topLevel);
}
else
{
Expand Down
1 change: 0 additions & 1 deletion src/Browser/Avalonia.Browser/BrowserTopLevelImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> tran
}

public double DesktopScaling => RenderScaling;
public IScreenImpl? Screen { get; }
public IPlatformHandle? Handle { get; }
public Size ClientSize => _surface?.ClientSize ?? new Size(1, 1);
public Size? FrameSize => null;
Expand Down
10 changes: 8 additions & 2 deletions src/Headless/Avalonia.Headless/HeadlessWindowImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ internal class HeadlessWindowImpl : IWindowImpl, IPopupImpl, IFramebufferPlatfor
private static int _nextGlobalZOrder = 1;

private readonly IKeyboardDevice _keyboard;
private readonly IScreenImpl _screen;
private readonly Stopwatch _st = Stopwatch.StartNew();
private readonly Pointer _mousePointer;
private WriteableBitmap? _lastRenderedFrame;
Expand All @@ -32,6 +33,7 @@ public HeadlessWindowImpl(bool isPopup, PixelFormat frameBufferFormat)
IsPopup = isPopup;
Surfaces = new object[] { this };
_keyboard = AvaloniaLocator.Current.GetRequiredService<IKeyboardDevice>();
_screen = new HeadlessScreensStub();
_mousePointer = new Pointer(Pointer.GetNextFreeId(), PointerType.Mouse, true);
MouseDevice = new MouseDevice(_mousePointer);
ClientSize = new Size(1024, 768);
Expand Down Expand Up @@ -150,7 +152,6 @@ public void SetTopmost(bool value)

}

public IScreenImpl Screen { get; } = new HeadlessScreensStub();
public WindowState WindowState { get; set; }
public Action<WindowState>? WindowStateChanged { get; set; }
public void SetTitle(string? title)
Expand Down Expand Up @@ -266,11 +267,16 @@ public ILockedFramebuffer Lock()
public AcrylicPlatformCompensationLevels AcrylicCompensationLevels => new AcrylicPlatformCompensationLevels(1, 1, 1);
public object? TryGetFeature(Type featureType)
{
if(featureType == typeof(IClipboard))
if (featureType == typeof(IClipboard))
{
return AvaloniaLocator.Current.GetRequiredService<IClipboard>();
}

if (featureType == typeof(IScreenImpl))
{
return _screen;
}

return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public void SetCursor(ICursorImpl cursor)
}

public double DesktopScaling => 1;
public IScreenImpl Screen { get; }
public IPlatformHandle Handle { get; }
public Size ClientSize => ScaledSize;
public Size? FrameSize => null;
Expand Down
1 change: 0 additions & 1 deletion src/Tizen/Avalonia.Tizen/TopLevelImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public TopLevelImpl(ITizenView view, IEnumerable<object> surfaces)
}

public double DesktopScaling => RenderScaling;
public IScreenImpl? Screen { get; }
public IPlatformHandle? Handle { get; }

public Size ClientSize => _view.ClientSize;
Expand Down
1 change: 0 additions & 1 deletion src/iOS/Avalonia.iOS/AvaloniaView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,6 @@ public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> tran
}

public double DesktopScaling => RenderScaling;
public IScreenImpl? Screen { get; }
public IPlatformHandle? Handle { get; }
public Size ClientSize => new Size(_view.Bounds.Width, _view.Bounds.Height);
public Size? FrameSize => null;
Expand Down
29 changes: 29 additions & 0 deletions tests/Avalonia.Headless.UnitTests/ServicesTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Reactive.Disposables;
using System.Threading;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Threading;

namespace Avalonia.Headless.UnitTests;

public class ServicesTests
{
#if NUNIT
[AvaloniaTest, Timeout(10000)]
#elif XUNIT
[AvaloniaFact(Timeout = 10000)]
#endif
public void Can_Access_Screens()
{
var window = new Window();
var screens = window.Screens;
Assert.NotNull(screens);

var currentScreenFromWindow = screens.ScreenFromWindow(window);
var currentScreenFromVisual = screens.ScreenFromVisual(window);

Assert.True(ReferenceEquals(currentScreenFromWindow, currentScreenFromVisual));
}
}
1 change: 0 additions & 1 deletion tests/Avalonia.UnitTests/CompositorTestServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ public void Dispose()
}

public double DesktopScaling => 1;
public IScreenImpl Screen { get; }
public IPlatformHandle Handle { get; }
public Size ClientSize { get; }
public Size? FrameSize { get; }
Expand Down

0 comments on commit 460a354

Please sign in to comment.