Browse Source

Merge branch 'master' into master

pull/8256/head
Max Katz 4 years ago
committed by GitHub
parent
commit
5c4905de04
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 17
      native/Avalonia.Native/src/OSX/AvnWindow.mm
  2. 6
      native/Avalonia.Native/src/OSX/PopupImpl.mm
  3. 3
      native/Avalonia.Native/src/OSX/WindowBaseImpl.h
  4. 52
      native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
  5. 3
      native/Avalonia.Native/src/OSX/WindowImpl.h
  6. 16
      native/Avalonia.Native/src/OSX/WindowImpl.mm
  7. 11
      native/Avalonia.Native/src/OSX/app.mm
  8. 2
      samples/ControlCatalog/MainWindow.xaml.cs
  9. 6
      samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs
  10. 2
      src/Android/Avalonia.Android/AvaloniaView.cs
  11. 2
      src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs
  12. 3
      src/Avalonia.Base/Media/GeometryDrawing.cs
  13. 6
      src/Avalonia.Base/Reactive/TypedBindingAdapter.cs
  14. 3
      src/Avalonia.Controls/Avalonia.Controls.csproj
  15. 7
      src/Avalonia.Controls/Button.cs
  16. 6
      src/Avalonia.Controls/Carousel.cs
  17. 4
      src/Avalonia.Controls/Presenters/CarouselPresenter.cs
  18. 2
      src/Avalonia.Themes.Default/SimpleTheme.cs
  19. 6
      src/Avalonia.Themes.Fluent/FluentTheme.cs
  20. 1
      src/Avalonia.X11/X11Atoms.cs
  21. 10
      src/Avalonia.X11/X11Info.cs
  22. 46
      src/Avalonia.X11/X11Window.cs
  23. 17
      src/Avalonia.X11/XLib.cs
  24. 4
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs
  25. 4
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs
  26. 2
      src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs
  27. 2
      src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs
  28. 4
      src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
  29. 1
      src/Windows/Avalonia.Win32/Interop/Automation/ISelectionItemProvider.cs
  30. 2
      src/Windows/Avalonia.Win32/TrayIconImpl.cs
  31. 2
      src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs
  32. 3
      tests/Avalonia.Benchmarks/TestBindingObservable.cs
  33. 74
      tests/Avalonia.Controls.UnitTests/ButtonTests.cs
  34. 52
      tests/Avalonia.RenderTests/Media/GeometryDrawingTests.cs
  35. 4
      tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs
  36. 4
      tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs

17
native/Avalonia.Native/src/OSX/AvnWindow.mm

@ -33,6 +33,7 @@
bool _isEnabled;
bool _canBecomeKeyWindow;
bool _isExtended;
bool _isTransitioningToFullScreen;
AvnMenu* _menu;
}
@ -175,6 +176,7 @@
[self setBackgroundColor: [NSColor clearColor]];
_isExtended = false;
_isTransitioningToFullScreen = false;
if(self.isDialog)
{
@ -282,6 +284,14 @@
- (void)windowDidBecomeKey:(NSNotification *_Nonnull)notification
{
_parent->BringToFront();
dispatch_async(dispatch_get_main_queue(), ^{
@try {
[self invalidateShadow];
}
@finally{
}
});
}
- (void)windowDidMiniaturize:(NSNotification *_Nonnull)notification
@ -349,6 +359,7 @@
- (void)windowWillEnterFullScreen:(NSNotification *_Nonnull)notification
{
_isTransitioningToFullScreen = true;
auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
if(parent != nullptr)
@ -359,6 +370,7 @@
- (void)windowDidEnterFullScreen:(NSNotification *_Nonnull)notification
{
_isTransitioningToFullScreen = false;
auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
if(parent != nullptr)
@ -441,7 +453,10 @@
_parent->BaseEvents->RawMouseEvent(NonClientLeftButtonDown, static_cast<uint32>([event timestamp] * 1000), AvnInputModifiersNone, point, delta);
}
_parent->BringToFront();
if(!_isTransitioningToFullScreen)
{
_parent->BringToFront();
}
}
break;

6
native/Avalonia.Native/src/OSX/PopupImpl.mm

@ -26,17 +26,13 @@ private:
PopupImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
{
WindowEvents = events;
[Window setLevel:NSPopUpMenuWindowLevel];
}
protected:
virtual NSWindowStyleMask GetStyle() override
{
return NSWindowStyleMaskBorderless;
}
virtual void OnInitialiseNSWindow () override
{
[Window setLevel:NSPopUpMenuWindowLevel];
}
public:
virtual bool ShouldTakeFocusOnShow() override

3
native/Avalonia.Native/src/OSX/WindowBaseImpl.h

@ -106,13 +106,10 @@ protected:
virtual NSWindowStyleMask GetStyle();
void UpdateStyle();
virtual void OnInitialiseNSWindow ();
private:
void CreateNSWindow (bool isDialog);
void CleanNSWindow ();
void InitialiseNSWindow ();
NSCursor *cursor;
ComPtr<IAvnGlContext> _glContext;

52
native/Avalonia.Native/src/OSX/WindowBaseImpl.mm

@ -39,7 +39,16 @@ WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, IAvnGlContext *gl,
lastMenu = nullptr;
CreateNSWindow(usePanel);
InitialiseNSWindow();
[Window setContentView:StandardContainer];
[Window setStyleMask:NSWindowStyleMaskBorderless];
[Window setBackingType:NSBackingStoreBuffered];
[Window setContentMinSize:lastMinSize];
[Window setContentMaxSize:lastMaxSize];
[Window setOpaque:false];
[Window setHasShadow:true];
}
HRESULT WindowBaseImpl::ObtainNSViewHandle(void **ret) {
@ -90,8 +99,8 @@ HRESULT WindowBaseImpl::Show(bool activate, bool isDialog) {
START_COM_CALL;
@autoreleasepool {
InitialiseNSWindow();
[Window setContentSize:lastSize];
if(hasPosition)
{
SetPosition(lastPositionSet);
@ -101,6 +110,8 @@ HRESULT WindowBaseImpl::Show(bool activate, bool isDialog) {
}
UpdateStyle();
[Window invalidateShadow];
if (ShouldTakeFocusOnShow() && activate) {
[Window orderFront:Window];
@ -292,8 +303,7 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso
if (!_shown) {
BaseEvents->Resized(AvnSize{x, y}, reason);
}
if(Window != nullptr) {
else if(Window != nullptr) {
[Window setContentSize:lastSize];
[Window invalidateShadow];
}
@ -569,38 +579,6 @@ void WindowBaseImpl::CreateNSWindow(bool isDialog) {
}
}
void WindowBaseImpl::OnInitialiseNSWindow()
{
}
void WindowBaseImpl::InitialiseNSWindow() {
if(Window != nullptr) {
[Window setContentView:StandardContainer];
[Window setStyleMask:NSWindowStyleMaskBorderless];
[Window setBackingType:NSBackingStoreBuffered];
[Window setContentSize:lastSize];
[Window setContentMinSize:lastMinSize];
[Window setContentMaxSize:lastMaxSize];
[Window setOpaque:false];
[Window setHasShadow:true];
[Window invalidateShadow];
if (lastMenu != nullptr) {
[GetWindowProtocol() applyMenu:lastMenu];
if ([Window isKeyWindow]) {
[GetWindowProtocol() showWindowMenuWithAppMenu];
}
}
OnInitialiseNSWindow();
}
}
id <AvnWindowProtocol> WindowBaseImpl::GetWindowProtocol() {
if(Window == nullptr)
{

3
native/Avalonia.Native/src/OSX/WindowImpl.h

@ -93,8 +93,6 @@ BEGIN_INTERFACE_MAP()
virtual bool IsDialog() override;
virtual void OnInitialiseNSWindow() override;
virtual void BringToFront () override;
bool CanBecomeKeyWindow ();
@ -103,6 +101,7 @@ protected:
virtual NSWindowStyleMask GetStyle() override;
private:
void OnInitialiseNSWindow();
NSString *_lastTitle;
};

16
native/Avalonia.Native/src/OSX/WindowImpl.mm

@ -24,6 +24,8 @@ WindowImpl::WindowImpl(IAvnWindowEvents *events, IAvnGlContext *gl) : WindowBase
_lastTitle = @"";
_parent = nullptr;
WindowEvents = events;
OnInitialiseNSWindow();
}
void WindowImpl::HideOrShowTrafficLights() {
@ -32,15 +34,16 @@ void WindowImpl::HideOrShowTrafficLights() {
}
bool wantsChrome = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
bool hasTrafficLights = _isClientAreaExtended ? wantsChrome : _decorations != SystemDecorationsFull;
bool hasTrafficLights = _isClientAreaExtended ? wantsChrome : _decorations == SystemDecorationsFull;
[[Window standardWindowButton:NSWindowCloseButton] setHidden:hasTrafficLights];
[[Window standardWindowButton:NSWindowMiniaturizeButton] setHidden:hasTrafficLights];
[[Window standardWindowButton:NSWindowZoomButton] setHidden:hasTrafficLights];
[[Window standardWindowButton:NSWindowCloseButton] setHidden:!hasTrafficLights];
[[Window standardWindowButton:NSWindowMiniaturizeButton] setHidden:!hasTrafficLights];
[[Window standardWindowButton:NSWindowZoomButton] setHidden:!hasTrafficLights];
}
void WindowImpl::OnInitialiseNSWindow(){
[GetWindowProtocol() setCanBecomeKeyWindow:true];
[Window disableCursorRects];
[Window setTabbingMode:NSWindowTabbingModeDisallowed];
[Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
@ -52,11 +55,6 @@ void WindowImpl::OnInitialiseNSWindow(){
[GetWindowProtocol() setIsExtended:true];
SetExtendClientArea(true);
}
if(_parent != nullptr)
{
SetParent(_parent);
}
}
HRESULT WindowImpl::Show(bool activate, bool isDialog) {

11
native/Avalonia.Native/src/OSX/app.mm

@ -82,6 +82,17 @@ ComPtr<IAvnApplicationEvents> _events;
_isHandlingSendEvent = oldHandling;
}
}
// This is needed for certain embedded controls DO NOT REMOVE..
- (BOOL) isHandlingSendEvent
{
return _isHandlingSendEvent;
}
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent
{
_isHandlingSendEvent = handlingSendEvent;
}
@end
extern void InitializeAvnApp(IAvnApplicationEvents* events)

2
samples/ControlCatalog/MainWindow.xaml.cs

@ -29,8 +29,6 @@ namespace ControlCatalog
DataContext = new MainWindowViewModel(_notificationArea);
_recentMenu = ((NativeMenu.GetMenu(this).Items[0] as NativeMenuItem).Menu.Items[2] as NativeMenuItem).Menu;
ExtendClientAreaChromeHints = Avalonia.Platform.ExtendClientAreaChromeHints.OSXThickTitleBar;
}
public static string MenuQuitHeader => RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "Quit Avalonia" : "E_xit";

6
samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs

@ -45,12 +45,12 @@ namespace ControlCatalog.ViewModels
public List<Bitmap> Images { get; } = new List<Bitmap>();
private Bitmap? _SelectedImage;
private Bitmap _SelectedImage;
/// <summary>
/// Gets or Sets the selected image
/// </summary>
public Bitmap? SelectedImage
public Bitmap SelectedImage
{
get { return _SelectedImage; }
set { this.RaiseAndSetIfChanged(ref _SelectedImage, value); }
@ -293,7 +293,7 @@ namespace ControlCatalog.ViewModels
/// <remarks>
/// Any one of the parameters may be null, but not both.
/// </remarks>
private static IVisual GetVisualParent(IVisual? from, IVisual? to)
private static IVisual GetVisualParent(IVisual from, IVisual to)
{
var p1 = (from ?? to)!.VisualParent;
var p2 = (to ?? from)!.VisualParent;

2
src/Android/Avalonia.Android/AvaloniaView.cs

@ -15,7 +15,7 @@ namespace Avalonia.Android
private EmbeddableControlRoot _root;
private readonly ViewImpl _view;
private IDisposable? _timerSubscription;
private IDisposable _timerSubscription;
public AvaloniaView(Context context) : base(context)
{

2
src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs

@ -30,7 +30,7 @@ namespace Avalonia.Android.Platform.Specific.Helpers
return DispatchKeyEventInternal(e, out callBase);
}
string? UnicodeTextInput(KeyEvent keyEvent)
string UnicodeTextInput(KeyEvent keyEvent)
{
return keyEvent.Action == KeyEventActions.Multiple
&& keyEvent.RepeatCount == 0

3
src/Avalonia.Base/Media/GeometryDrawing.cs

@ -68,7 +68,8 @@ namespace Avalonia.Media
public override Rect GetBounds()
{
return Geometry?.GetRenderBounds(s_boundsPen) ?? Rect.Empty;
IPen pen = Pen ?? s_boundsPen;
return Geometry?.GetRenderBounds(pen) ?? Rect.Empty;
}
}
}

6
src/Avalonia.Base/Reactive/TypedBindingAdapter.cs

@ -30,13 +30,15 @@ namespace Avalonia.Reactive
}
catch (InvalidCastException e)
{
var unwrappedValue = value.HasValue ? value.Value : null;
Logger.TryGet(LogEventLevel.Error, LogArea.Binding)?.Log(
_target,
"Binding produced invalid value for {$Property} ({$PropertyType}): {$Value} ({$ValueType})",
_property.Name,
_property.PropertyType,
value.Value,
value.Value?.GetType());
unwrappedValue,
unwrappedValue?.GetType());
PublishNext(BindingValue<T>.BindingError(e));
}
}

3
src/Avalonia.Controls/Avalonia.Controls.csproj

@ -2,9 +2,6 @@
<PropertyGroup>
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Avalonia.Base\Metadata\NullableAttributes.cs" Link="NullableAttributes.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
<ProjectReference Include="..\Avalonia.Remote.Protocol\Avalonia.Remote.Protocol.csproj" />

7
src/Avalonia.Controls/Button.cs

@ -232,6 +232,13 @@ namespace Avalonia.Controls
StopListeningForDefault(inputElement);
}
}
if (IsCancel)
{
if (e.Root is IInputElement inputElement)
{
StopListeningForCancel(inputElement);
}
}
}
/// <inheritdoc/>

6
src/Avalonia.Controls/Carousel.cs

@ -20,8 +20,8 @@ namespace Avalonia.Controls
/// <summary>
/// Defines the <see cref="PageTransition"/> property.
/// </summary>
public static readonly StyledProperty<IPageTransition> PageTransitionProperty =
AvaloniaProperty.Register<Carousel, IPageTransition>(nameof(PageTransition));
public static readonly StyledProperty<IPageTransition?> PageTransitionProperty =
AvaloniaProperty.Register<Carousel, IPageTransition?>(nameof(PageTransition));
/// <summary>
/// The default value of <see cref="ItemsControl.ItemsPanelProperty"/> for
@ -54,7 +54,7 @@ namespace Avalonia.Controls
/// <summary>
/// Gets or sets the transition to use when moving between pages.
/// </summary>
public IPageTransition PageTransition
public IPageTransition? PageTransition
{
get { return GetValue(PageTransitionProperty); }
set { SetValue(PageTransitionProperty, value); }

4
src/Avalonia.Controls/Presenters/CarouselPresenter.cs

@ -31,7 +31,7 @@ namespace Avalonia.Controls.Presenters
/// <summary>
/// Defines the <see cref="PageTransition"/> property.
/// </summary>
public static readonly StyledProperty<IPageTransition> PageTransitionProperty =
public static readonly StyledProperty<IPageTransition?> PageTransitionProperty =
Carousel.PageTransitionProperty.AddOwner<CarouselPresenter>();
private int _selectedIndex = -1;
@ -85,7 +85,7 @@ namespace Avalonia.Controls.Presenters
/// <summary>
/// Gets or sets a transition to use when switching pages.
/// </summary>
public IPageTransition PageTransition
public IPageTransition? PageTransition
{
get { return GetValue(PageTransitionProperty); }
set { SetValue(PageTransitionProperty, value); }

2
src/Avalonia.Themes.Default/SimpleTheme.cs

@ -44,7 +44,7 @@ namespace Avalonia.Themes.Default
InitStyles(_baseUri);
}
public event EventHandler OwnerChanged
public event EventHandler? OwnerChanged
{
add
{

6
src/Avalonia.Themes.Fluent/FluentTheme.cs

@ -50,7 +50,9 @@ namespace Avalonia.Themes.Fluent
/// <param name="serviceProvider">The XAML service provider.</param>
public FluentTheme(IServiceProvider serviceProvider)
{
_baseUri = ((IUriContext)serviceProvider.GetService(typeof(IUriContext))).BaseUri;
var ctx = serviceProvider.GetService(typeof(IUriContext)) as IUriContext
?? throw new NullReferenceException("Unable retrive UriContext");
_baseUri = ctx.BaseUri;
InitStyles(_baseUri);
}
@ -146,7 +148,7 @@ namespace Avalonia.Themes.Fluent
IReadOnlyList<IStyle> IStyle.Children => _loaded?.Children ?? Array.Empty<IStyle>();
public event EventHandler OwnerChanged
public event EventHandler? OwnerChanged
{
add
{

1
src/Avalonia.X11/X11Atoms.cs

@ -155,6 +155,7 @@ namespace Avalonia.X11
public readonly IntPtr _NET_FRAME_EXTENTS;
public readonly IntPtr _NET_WM_PING;
public readonly IntPtr _NET_WM_SYNC_REQUEST;
public readonly IntPtr _NET_WM_SYNC_REQUEST_COUNTER;
public readonly IntPtr _NET_SYSTEM_TRAY_S;
public readonly IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
public readonly IntPtr _NET_SYSTEM_TRAY_OPCODE;

10
src/Avalonia.X11/X11Info.cs

@ -33,6 +33,7 @@ namespace Avalonia.X11
public IntPtr LastActivityTimestamp { get; set; }
public XVisualInfo? TransparentVisualInfo { get; set; }
public bool HasXim { get; set; }
public bool HasXSync { get; set; }
public IntPtr DefaultFontSet { get; set; }
public unsafe X11Info(IntPtr display, IntPtr deferredDisplay, bool useXim)
@ -101,6 +102,15 @@ namespace Avalonia.X11
{
//Ignore, XI is not supported
}
try
{
HasXSync = XSyncInitialize(display, out _, out _) != Status.Success;
}
catch
{
//Ignore, XSync is not supported
}
}
}
}

46
src/Avalonia.X11/X11Window.cs

@ -45,6 +45,8 @@ namespace Avalonia.X11
private IntPtr _handle;
private IntPtr _xic;
private IntPtr _renderHandle;
private IntPtr _xSyncCounter;
private XSyncValue _xSyncValue;
private bool _mapped;
private bool _wasMappedAtLeastOnce = false;
private double? _scalingOverride;
@ -190,6 +192,16 @@ namespace Avalonia.X11
NativeMenuExporter = DBusMenuExporter.TryCreateTopLevelNativeMenu(_handle);
NativeControlHost = new X11NativeControlHost(_platform, this);
InitializeIme();
XChangeProperty(_x11.Display, _handle, _x11.Atoms.WM_PROTOCOLS, _x11.Atoms.XA_ATOM, 32,
PropertyMode.Replace, new[] { _x11.Atoms.WM_DELETE_WINDOW, _x11.Atoms._NET_WM_SYNC_REQUEST }, 2);
if (_x11.HasXSync)
{
_xSyncCounter = XSyncCreateCounter(_x11.Display, _xSyncValue);
XChangeProperty(_x11.Display, _handle, _x11.Atoms._NET_WM_SYNC_REQUEST_COUNTER,
_x11.Atoms.XA_CARDINAL, 32, PropertyMode.Replace, ref _xSyncCounter, 1);
}
}
class SurfaceInfo : EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo
@ -383,15 +395,7 @@ namespace Avalonia.X11
(ev.type == XEventName.VisibilityNotify &&
ev.VisibilityEvent.state < 2))
{
if (!_triggeredExpose)
{
_triggeredExpose = true;
Dispatcher.UIThread.Post(() =>
{
_triggeredExpose = false;
DoPaint();
}, DispatcherPriority.Render);
}
EnqueuePaint();
}
else if (ev.type == XEventName.FocusIn)
{
@ -503,6 +507,7 @@ namespace Avalonia.X11
if (_useRenderWindow)
XConfigureResizeWindow(_x11.Display, _renderHandle, ev.ConfigureEvent.width,
ev.ConfigureEvent.height);
EnqueuePaint();
}
else if (ev.type == XEventName.DestroyNotify
&& ev.DestroyWindowEvent.window == _handle)
@ -518,7 +523,11 @@ namespace Avalonia.X11
if (Closing?.Invoke() != true)
Dispose();
}
else if (ev.ClientMessageEvent.ptr1 == _x11.Atoms._NET_WM_SYNC_REQUEST)
{
_xSyncValue.Lo = new UIntPtr(ev.ClientMessageEvent.ptr3.ToPointer()).ToUInt32();
_xSyncValue.Hi = ev.ClientMessageEvent.ptr4.ToInt32();
}
}
}
else if (ev.type == XEventName.KeyPress || ev.type == XEventName.KeyRelease)
@ -730,9 +739,24 @@ namespace Avalonia.X11
ScheduleInput(mev, ref ev);
}
void EnqueuePaint()
{
if (!_triggeredExpose)
{
_triggeredExpose = true;
Dispatcher.UIThread.Post(() =>
{
_triggeredExpose = false;
DoPaint();
}, DispatcherPriority.Render);
}
}
void DoPaint()
{
Paint?.Invoke(new Rect());
if (_xSyncCounter != IntPtr.Zero)
XSyncSetCounter(_x11.Display, _xSyncCounter, _xSyncValue);
}
public void Invalidate(Rect rect)
@ -1160,7 +1184,7 @@ namespace Avalonia.X11
}
public IntPtr Handle => _owner._renderHandle;
public string? HandleDescriptor => "XID";
public string HandleDescriptor => "XID";
}
}
}

17
src/Avalonia.X11/XLib.cs

@ -542,6 +542,18 @@ namespace Avalonia.X11
public static extern int XRRQueryExtension (IntPtr dpy,
out int event_base_return,
out int error_base_return);
[DllImport(libX11Ext)]
public static extern Status XSyncInitialize(IntPtr dpy, out int event_base_return, out int error_base_return);
[DllImport(libX11Ext)]
public static extern IntPtr XSyncCreateCounter(IntPtr dpy, XSyncValue initialValue);
[DllImport(libX11Ext)]
public static extern int XSyncDestroyCounter(IntPtr dpy, IntPtr counter);
[DllImport(libX11Ext)]
public static extern int XSyncSetCounter(IntPtr dpy, IntPtr counter, XSyncValue value);
[DllImport(libX11Randr)]
public static extern int XRRQueryVersion(IntPtr dpy,
@ -627,6 +639,11 @@ namespace Avalonia.X11
public int bw;
public int d;
}
public struct XSyncValue {
public int Hi;
public uint Lo;
}
public static bool XGetGeometry(IntPtr display, IntPtr window, out XGeometry geo)
{

4
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Text;
using Avalonia.Data;
using Avalonia.Data.Core;
using Avalonia.Data.Core.Plugins;
@ -174,7 +172,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
WeakEvents.CollectionChanged.Unsubscribe(incc, this);
}
public void OnEvent(object? sender, WeakEvent ev, NotifyCollectionChangedEventArgs args)
public void OnEvent(object sender, WeakEvent ev, NotifyCollectionChangedEventArgs args)
{
if (ShouldNotifyListeners(args))
{

4
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs

@ -42,7 +42,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
bool IResourceNode.HasResources => Loaded.HasResources;
public event EventHandler OwnerChanged
public event EventHandler? OwnerChanged
{
add => Loaded.OwnerChanged += value;
remove => Loaded.OwnerChanged -= value;
@ -52,7 +52,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
{
if (!_isLoading)
{
return Loaded.TryGetResource(key, out value);
return Loaded.TryGetResource(key, out value);
}
value = null;

2
src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs

@ -64,7 +64,7 @@ namespace Avalonia.Markup.Xaml.Styling
IReadOnlyList<IStyle> IStyle.Children => _loaded ?? Array.Empty<IStyle>();
public event EventHandler OwnerChanged
public event EventHandler? OwnerChanged
{
add
{

2
src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs

@ -42,7 +42,7 @@ namespace Avalonia.Win32.Automation
return GetOrCreate(focus);
}
public void FocusChanged(object sender, EventArgs e)
public void FocusChanged(object? sender, EventArgs e)
{
RaiseFocusChanged(GetOrCreate(Peer.GetFocus()));
}

4
src/Windows/Avalonia.Win32/Avalonia.Win32.csproj

@ -18,4 +18,8 @@
</ItemGroup>
<Import Project="$(MSBuildThisFileDirectory)\..\..\..\build\System.Drawing.Common.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" />
<PropertyGroup Label="Warnings">
<NoWarn Condition="'$(NoWarn)' == ''">CA1416</NoWarn>
<NoWarn Condition="'$(NoWarn)' != ''">$(NoWarn),CA1416</NoWarn>
</PropertyGroup>
</Project>

1
src/Windows/Avalonia.Win32/Interop/Automation/ISelectionItemProvider.cs

@ -1,3 +1,4 @@
#nullable enable
using System;
using System.Runtime.InteropServices;

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

@ -195,7 +195,7 @@ namespace Avalonia.Win32
ShowActivated = true;
}
private void TrayPopupRoot_Deactivated(object sender, EventArgs e)
private void TrayPopupRoot_Deactivated(object? sender, EventArgs e)
{
Close();
}

2
src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs

@ -109,7 +109,7 @@ namespace Avalonia.Win32
if (_owner is Window window)
{
var visual = window.Renderer.HitTestFirst(position, _owner as Window, x =>
var visual = window.Renderer.HitTestFirst(position, _owner, x =>
{
if (x is IInputElement ie && (!ie.IsHitTestVisible || !ie.IsVisible))
{

3
tests/Avalonia.Benchmarks/TestBindingObservable.cs

@ -1,4 +1,5 @@
using System;
#nullable enable
using System;
using Avalonia.Data;
namespace Avalonia.Benchmarks

74
tests/Avalonia.Controls.UnitTests/ButtonTests.cs

@ -309,6 +309,80 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(0, raised);
}
[Fact]
public void Button_IsDefault_Works()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var raised = 0;
var target = new Button();
var window = new Window { Content = target };
window.Show();
target.Click += (s, e) => ++raised;
target.IsDefault = false;
window.RaiseEvent(CreateKeyDownEvent(Key.Enter));
Assert.Equal(0, raised);
target.IsDefault = true;
window.RaiseEvent(CreateKeyDownEvent(Key.Enter));
Assert.Equal(1, raised);
target.IsDefault = false;
window.RaiseEvent(CreateKeyDownEvent(Key.Enter));
Assert.Equal(1, raised);
target.IsDefault = true;
window.RaiseEvent(CreateKeyDownEvent(Key.Enter));
Assert.Equal(2, raised);
window.Content = null;
// To check if handler was raised on the button, when it's detached, we need to pass it as a source manually.
window.RaiseEvent(CreateKeyDownEvent(Key.Enter, target));
Assert.Equal(2, raised);
}
}
[Fact]
public void Button_IsCancel_Works()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var raised = 0;
var target = new Button();
var window = new Window { Content = target };
window.Show();
target.Click += (s, e) => ++raised;
target.IsCancel = false;
window.RaiseEvent(CreateKeyDownEvent(Key.Escape));
Assert.Equal(0, raised);
target.IsCancel = true;
window.RaiseEvent(CreateKeyDownEvent(Key.Escape));
Assert.Equal(1, raised);
target.IsCancel = false;
window.RaiseEvent(CreateKeyDownEvent(Key.Escape));
Assert.Equal(1, raised);
target.IsCancel = true;
window.RaiseEvent(CreateKeyDownEvent(Key.Escape));
Assert.Equal(2, raised);
window.Content = null;
window.RaiseEvent(CreateKeyDownEvent(Key.Escape, target));
Assert.Equal(2, raised);
}
}
private KeyEventArgs CreateKeyDownEvent(Key key, IInteractive source = null)
{
return new KeyEventArgs { RoutedEvent = InputElement.KeyDownEvent, Key = key, Source = source };
}
private class TestButton : Button, IRenderRoot
{

52
tests/Avalonia.RenderTests/Media/GeometryDrawingTests.cs

@ -0,0 +1,52 @@
using Avalonia.Media;
using Xunit;
#if AVALONIA_SKIA
namespace Avalonia.Skia.RenderTests
#else
using Avalonia.Direct2D1.RenderTests;
namespace Avalonia.Direct2D1.RenderTests.Media
#endif
{
public class GeometryDrawingTests : TestBase
{
public GeometryDrawingTests()
: base(@"Media\GeometryDrawing")
{
}
private GeometryDrawing CreateGeometryDrawing()
{
GeometryDrawing geometryDrawing = new GeometryDrawing();
EllipseGeometry ellipse = new EllipseGeometry();
ellipse.RadiusX = 100;
ellipse.RadiusY = 100;
geometryDrawing.Geometry = ellipse;
return geometryDrawing;
}
[Fact]
public void DrawingGeometry_WithPen()
{
GeometryDrawing geometryDrawing = CreateGeometryDrawing();
geometryDrawing.Pen = new Pen(new SolidColorBrush(Color.FromArgb(255, 0, 0, 0)), 10);
Assert.Equal(210, geometryDrawing.GetBounds().Height);
Assert.Equal(210, geometryDrawing.GetBounds().Width);
}
[Fact]
public void DrawingGeometry_WithoutPen()
{
GeometryDrawing geometryDrawing = CreateGeometryDrawing();
Assert.Equal(200, geometryDrawing.GetBounds().Height);
Assert.Equal(200, geometryDrawing.GetBounds().Width);
}
}
}

4
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs

@ -602,7 +602,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
private class EndOfLineTextSource : ITextSource
{
public TextRun? GetTextRun(int textSourceIndex)
public TextRun GetTextRun(int textSourceIndex)
{
return new TextEndOfLine();
}
@ -617,7 +617,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
_text = text;
}
public TextRun? GetTextRun(int textSourceIndex)
public TextRun GetTextRun(int textSourceIndex)
{
if (textSourceIndex >= _text.Length + TextRun.DefaultTextSourceLength + _text.Length)
{

4
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs

@ -639,7 +639,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
{
const string Text = "_A_A";
public TextRun? GetTextRun(int textSourceIndex)
public TextRun GetTextRun(int textSourceIndex)
{
switch (textSourceIndex)
{
@ -907,7 +907,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
_textRuns = textRuns;
}
public TextRun? GetTextRun(int textSourceIndex)
public TextRun GetTextRun(int textSourceIndex)
{
var currentPosition = 0;

Loading…
Cancel
Save