Browse Source

Add nullable reference checking to X11Window.

pull/10600/head
Steven Kirk 4 years ago
parent
commit
1143b335d6
  1. 2
      src/Avalonia.Controls/Platform/IPopupImpl.cs
  2. 2
      src/Avalonia.Controls/Primitives/PopupRoot.cs
  3. 76
      src/Avalonia.X11/X11Window.cs

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

@ -9,7 +9,7 @@ namespace Avalonia.Platform
[Unstable] [Unstable]
public interface IPopupImpl : IWindowBaseImpl public interface IPopupImpl : IWindowBaseImpl
{ {
IPopupPositioner PopupPositioner { get; } IPopupPositioner? PopupPositioner { get; }
void SetWindowManagerAddShadowHint(bool enabled); void SetWindowManagerAddShadowHint(bool enabled);
} }

2
src/Avalonia.Controls/Primitives/PopupRoot.cs

@ -95,7 +95,7 @@ namespace Avalonia.Controls.Primitives
private void UpdatePosition() private void UpdatePosition()
{ {
PlatformImpl?.PopupPositioner.Update(_positionerParameters); PlatformImpl?.PopupPositioner?.Update(_positionerParameters);
} }
public void ConfigurePosition(Visual target, PlacementMode placement, Point offset, public void ConfigurePosition(Visual target, PlacementMode placement, Point offset,

76
src/Avalonia.X11/X11Window.cs

@ -25,6 +25,9 @@ using Avalonia.X11.NativeDialogs;
using static Avalonia.X11.XLib; using static Avalonia.X11.XLib;
// ReSharper disable IdentifierTypo // ReSharper disable IdentifierTypo
// ReSharper disable StringLiteralTypo // ReSharper disable StringLiteralTypo
#nullable enable
namespace Avalonia.X11 namespace Avalonia.X11
{ {
internal unsafe partial class X11Window : IWindowImpl, IPopupImpl, IXI2Client internal unsafe partial class X11Window : IWindowImpl, IPopupImpl, IXI2Client
@ -35,11 +38,11 @@ namespace Avalonia.X11
private XConfigureEvent? _configure; private XConfigureEvent? _configure;
private PixelPoint? _configurePoint; private PixelPoint? _configurePoint;
private bool _triggeredExpose; private bool _triggeredExpose;
private IInputRoot _inputRoot; private IInputRoot? _inputRoot;
private readonly MouseDevice _mouse; private readonly MouseDevice _mouse;
private readonly TouchDevice _touch; private readonly TouchDevice _touch;
private readonly IKeyboardDevice _keyboard; private readonly IKeyboardDevice _keyboard;
private readonly ITopLevelNativeMenuExporter _nativeMenuExporter; private readonly ITopLevelNativeMenuExporter? _nativeMenuExporter;
private readonly IStorageProvider _storageProvider; private readonly IStorageProvider _storageProvider;
private readonly X11NativeControlHost _nativeControlHost; private readonly X11NativeControlHost _nativeControlHost;
private PixelPoint? _position; private PixelPoint? _position;
@ -54,8 +57,8 @@ namespace Avalonia.X11
private bool _wasMappedAtLeastOnce = false; private bool _wasMappedAtLeastOnce = false;
private double? _scalingOverride; private double? _scalingOverride;
private bool _disabled; private bool _disabled;
private TransparencyHelper _transparencyHelper; private TransparencyHelper? _transparencyHelper;
private RawEventGrouper _rawEventGrouper; private RawEventGrouper? _rawEventGrouper;
private bool _useRenderWindow = false; private bool _useRenderWindow = false;
private bool _usePositioningFlags = false; private bool _usePositioningFlags = false;
@ -66,7 +69,7 @@ namespace Avalonia.X11
WaitPaint WaitPaint
} }
public X11Window(AvaloniaX11Platform platform, IWindowImpl popupParent) public X11Window(AvaloniaX11Platform platform, IWindowImpl? popupParent)
{ {
_platform = platform; _platform = platform;
_popup = popupParent != null; _popup = popupParent != null;
@ -196,7 +199,7 @@ namespace Avalonia.X11
XFlush(_x11.Display); XFlush(_x11.Display);
if(_popup) if(_popup)
PopupPositioner = new ManagedPopupPositioner(new ManagedPopupPositionerPopupImplHelper(popupParent, MoveResize)); PopupPositioner = new ManagedPopupPositioner(new ManagedPopupPositionerPopupImplHelper(popupParent!, MoveResize));
if (platform.Options.UseDBusMenu) if (platform.Options.UseDBusMenu)
_nativeMenuExporter = DBusMenuExporter.TryCreateTopLevelNativeMenu(_handle); _nativeMenuExporter = DBusMenuExporter.TryCreateTopLevelNativeMenu(_handle);
_nativeControlHost = new X11NativeControlHost(_platform, this); _nativeControlHost = new X11NativeControlHost(_platform, this);
@ -214,7 +217,7 @@ namespace Avalonia.X11
_storageProvider = new CompositeStorageProvider(new[] _storageProvider = new CompositeStorageProvider(new[]
{ {
() => _platform.Options.UseDBusFilePicker ? DBusSystemDialog.TryCreateAsync(Handle) : Task.FromResult<IStorageProvider>(null), () => _platform.Options.UseDBusFilePicker ? DBusSystemDialog.TryCreateAsync(Handle) : Task.FromResult<IStorageProvider?>(null),
() => GtkSystemDialog.TryCreate(this) () => GtkSystemDialog.TryCreate(this)
}); });
} }
@ -351,17 +354,17 @@ namespace Avalonia.X11
public double DesktopScaling => RenderScaling; public double DesktopScaling => RenderScaling;
public IEnumerable<object> Surfaces { get; } public IEnumerable<object> Surfaces { get; }
public Action<RawInputEventArgs> Input { get; set; } public Action<RawInputEventArgs>? Input { get; set; }
public Action<Rect> Paint { get; set; } public Action<Rect>? Paint { get; set; }
public Action<Size, PlatformResizeReason> Resized { get; set; } public Action<Size, PlatformResizeReason>? Resized { get; set; }
//TODO //TODO
public Action<double> ScalingChanged { get; set; } public Action<double>? ScalingChanged { get; set; }
public Action Deactivated { get; set; } public Action? Deactivated { get; set; }
public Action Activated { get; set; } public Action? Activated { get; set; }
public Func<WindowCloseReason, bool> Closing { get; set; } public Func<WindowCloseReason, bool>? Closing { get; set; }
public Action<WindowState> WindowStateChanged { get; set; } public Action<WindowState>? WindowStateChanged { get; set; }
public Action<WindowTransparencyLevel> TransparencyLevelChanged public Action<WindowTransparencyLevel>? TransparencyLevelChanged
{ {
get => _transparencyHelper?.TransparencyLevelChanged; get => _transparencyHelper?.TransparencyLevelChanged;
set set
@ -371,7 +374,7 @@ namespace Avalonia.X11
} }
} }
public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; } public Action<bool>? ExtendClientAreaToDecorationsChanged { get; set; }
public Thickness ExtendedMargins { get; } = new Thickness(); public Thickness ExtendedMargins { get; } = new Thickness();
@ -379,15 +382,18 @@ namespace Avalonia.X11
public bool IsClientAreaExtendedToDecorations { get; } public bool IsClientAreaExtendedToDecorations { get; }
public Action Closed { get; set; } public Action? Closed { get; set; }
public Action<PixelPoint> PositionChanged { get; set; } public Action<PixelPoint>? PositionChanged { get; set; }
public Action LostFocus { get; set; } public Action? LostFocus { get; set; }
public IRenderer CreateRenderer(IRenderRoot root) => public IRenderer CreateRenderer(IRenderRoot root) =>
new CompositingRenderer(root, _platform.Compositor, () => Surfaces); new CompositingRenderer(root, _platform.Compositor, () => Surfaces);
private void OnEvent(ref XEvent ev) private void OnEvent(ref XEvent ev)
{ {
if (_inputRoot is null)
return;
if (ev.type == XEventName.MapNotify) if (ev.type == XEventName.MapNotify)
{ {
_mapped = true; _mapped = true;
@ -434,7 +440,8 @@ namespace Avalonia.X11
2 => RawPointerEventType.MiddleButtonDown, 2 => RawPointerEventType.MiddleButtonDown,
3 => RawPointerEventType.RightButtonDown, 3 => RawPointerEventType.RightButtonDown,
8 => RawPointerEventType.XButton1Down, 8 => RawPointerEventType.XButton1Down,
9 => RawPointerEventType.XButton2Down 9 => RawPointerEventType.XButton2Down,
_ => throw new NotSupportedException("Unexepected RawPointerEventType.")
}, },
ref ev, ev.ButtonEvent.state); ref ev, ev.ButtonEvent.state);
else else
@ -462,7 +469,8 @@ namespace Avalonia.X11
2 => RawPointerEventType.MiddleButtonUp, 2 => RawPointerEventType.MiddleButtonUp,
3 => RawPointerEventType.RightButtonUp, 3 => RawPointerEventType.RightButtonUp,
8 => RawPointerEventType.XButton1Up, 8 => RawPointerEventType.XButton1Up,
9 => RawPointerEventType.XButton2Up 9 => RawPointerEventType.XButton2Up,
_ => throw new NotSupportedException("Unexepected RawPointerEventType.")
}, },
ref ev, ev.ButtonEvent.state); ref ev, ev.ButtonEvent.state);
} }
@ -618,7 +626,7 @@ namespace Avalonia.X11
{ {
// Occurs once the window has been mapped, which is the earliest the extents // Occurs once the window has been mapped, which is the earliest the extents
// can be retrieved, so invoke event to force update of TopLevel.FrameSize. // can be retrieved, so invoke event to force update of TopLevel.FrameSize.
Resized.Invoke(ClientSize, PlatformResizeReason.Unspecified); Resized?.Invoke(ClientSize, PlatformResizeReason.Unspecified);
} }
if (atom == _x11.Atoms._NET_WM_STATE) if (atom == _x11.Atoms._NET_WM_STATE)
@ -712,6 +720,8 @@ namespace Avalonia.X11
private void DispatchInput(RawInputEventArgs args) private void DispatchInput(RawInputEventArgs args)
{ {
if (_inputRoot is null)
return;
Input?.Invoke(args); Input?.Invoke(args);
if (!args.Handled && args is RawKeyEventArgsWithText text && !string.IsNullOrEmpty(text.Text)) if (!args.Handled && args is RawKeyEventArgsWithText text && !string.IsNullOrEmpty(text.Text))
Input?.Invoke(new RawTextInputEventArgs(_keyboard, args.Timestamp, _inputRoot, text.Text)); Input?.Invoke(new RawTextInputEventArgs(_keyboard, args.Timestamp, _inputRoot, text.Text));
@ -744,11 +754,13 @@ namespace Avalonia.X11
if (args is RawDragEvent drag) if (args is RawDragEvent drag)
drag.Location = drag.Location / RenderScaling; drag.Location = drag.Location / RenderScaling;
_rawEventGrouper.HandleEvent(args); _rawEventGrouper?.HandleEvent(args);
} }
private void MouseEvent(RawPointerEventType type, ref XEvent ev, XModifierMask mods) private void MouseEvent(RawPointerEventType type, ref XEvent ev, XModifierMask mods)
{ {
if (_inputRoot is null)
return;
var mev = new RawPointerEventArgs( var mev = new RawPointerEventArgs(
_mouse, (ulong)ev.ButtonEvent.time.ToInt64(), _inputRoot, _mouse, (ulong)ev.ButtonEvent.time.ToInt64(), _inputRoot,
type, new Point(ev.ButtonEvent.x, ev.ButtonEvent.y), TranslateModifiers(mods)); type, new Point(ev.ButtonEvent.x, ev.ButtonEvent.y), TranslateModifiers(mods));
@ -783,7 +795,7 @@ namespace Avalonia.X11
} }
public IInputRoot InputRoot => _inputRoot; public IInputRoot? InputRoot => _inputRoot;
public void SetInputRoot(IInputRoot inputRoot) public void SetInputRoot(IInputRoot inputRoot)
{ {
@ -795,7 +807,7 @@ namespace Avalonia.X11
Cleanup(); Cleanup();
} }
public virtual object TryGetFeature(Type featureType) public virtual object? TryGetFeature(Type featureType)
{ {
if (featureType == typeof(ITopLevelNativeMenuExporter)) if (featureType == typeof(ITopLevelNativeMenuExporter))
{ {
@ -953,7 +965,7 @@ namespace Avalonia.X11
UpdateSizeHints(null); UpdateSizeHints(null);
} }
public void SetCursor(ICursorImpl cursor) public void SetCursor(ICursorImpl? cursor)
{ {
if (cursor == null) if (cursor == null)
XDefineCursor(_x11.Display, _handle, _x11.DefaultCursor); XDefineCursor(_x11.Display, _handle, _x11.DefaultCursor);
@ -996,7 +1008,7 @@ namespace Avalonia.X11
public IMouseDevice MouseDevice => _mouse; public IMouseDevice MouseDevice => _mouse;
public TouchDevice TouchDevice => _touch; public TouchDevice TouchDevice => _touch;
public IPopupImpl CreatePopup() public IPopupImpl? CreatePopup()
=> _platform.Options.OverlayPopups ? null : new X11Window(_platform, this); => _platform.Options.OverlayPopups ? null : new X11Window(_platform, this);
public void Activate() public void Activate()
@ -1082,7 +1094,7 @@ namespace Avalonia.X11
BeginMoveResize(side, e); BeginMoveResize(side, e);
} }
public void SetTitle(string title) public void SetTitle(string? title)
{ {
if (string.IsNullOrEmpty(title)) if (string.IsNullOrEmpty(title))
{ {
@ -1161,9 +1173,9 @@ namespace Avalonia.X11
{ {
} }
public Action GotInputWhenDisabled { get; set; } public Action? GotInputWhenDisabled { get; set; }
public void SetIcon(IWindowIconImpl icon) public void SetIcon(IWindowIconImpl? icon)
{ {
if (icon != null) if (icon != null)
{ {
@ -1218,7 +1230,7 @@ namespace Avalonia.X11
); );
} }
public IPopupPositioner PopupPositioner { get; } public IPopupPositioner? PopupPositioner { get; }
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) => public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) =>
_transparencyHelper?.SetTransparencyRequest(transparencyLevel); _transparencyHelper?.SetTransparencyRequest(transparencyLevel);

Loading…
Cancel
Save