Skip to content

Commit 601425d

Browse files
authored
Nullable annotations for LinuxFramebuffer (#17489)
1 parent bef43ce commit 601425d

18 files changed

+74
-63
lines changed

src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@
1010
<Compile Include="..\..\Shared\RawEventGrouping.cs" />
1111
</ItemGroup>
1212
<Import Project="..\..\..\build\TrimmingEnable.props" />
13+
<Import Project="..\..\..\build\NullableEnable.props" />
1314
</Project>

src/Linux/Avalonia.LinuxFramebuffer/EpollDispatcherImpl.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Avalonia.LinuxFramebuffer;
1111
internal unsafe class EpollDispatcherImpl : IControlledDispatcherImpl
1212
{
1313
private readonly ManagedDispatcherImpl.IManagedDispatcherInputProvider _inputProvider;
14-
private Thread _mainThread;
14+
private readonly Thread _mainThread;
1515

1616
[StructLayout(LayoutKind.Explicit)]
1717
private struct epoll_data
@@ -161,6 +161,7 @@ public void RunLoop(CancellationToken cancellationToken)
161161

162162
itimerspec timer = new()
163163
{
164+
it_interval = default,
164165
it_value = new()
165166
{
166167
tv_sec = new IntPtr(Math.Min((int)waitFor.TotalSeconds, 100)),
@@ -219,8 +220,8 @@ public void Signal()
219220

220221
public bool CurrentThreadIsLoopThread => Thread.CurrentThread == _mainThread;
221222

222-
public event Action Signaled;
223-
public event Action Timer;
223+
public event Action? Signaled;
224+
public event Action? Timer;
224225

225226
public void UpdateTimer(long? dueTimeInMs)
226227
{

src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs

+13-14
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using Avalonia.LinuxFramebuffer.Input;
77
using Avalonia.LinuxFramebuffer.Output;
88
using Avalonia.Platform;
9-
using Avalonia.Rendering;
109
using Avalonia.Rendering.Composition;
1110
using Avalonia.Threading;
1211

@@ -18,7 +17,7 @@ class FramebufferToplevelImpl : ITopLevelImpl, IScreenInfoProvider
1817
private readonly IInputBackend _inputBackend;
1918
private readonly RawEventGrouper _inputQueue;
2019

21-
public IInputRoot InputRoot { get; private set; }
20+
public IInputRoot? InputRoot { get; private set; }
2221

2322
public FramebufferToplevelImpl(IOutputBackend outputBackend, IInputBackend inputBackend)
2423
{
@@ -49,28 +48,28 @@ public void SetInputRoot(IInputRoot inputRoot)
4948

5049
public PixelPoint PointToScreen(Point p) => PixelPoint.FromPoint(p, 1);
5150

52-
public void SetCursor(ICursorImpl cursor)
51+
public void SetCursor(ICursorImpl? cursor)
5352
{
5453
}
5554

5655
public double DesktopScaling => 1;
57-
public IPlatformHandle Handle { get; }
56+
public IPlatformHandle? Handle => null;
5857
public Size ClientSize => ScaledSize;
5958
public Size? FrameSize => null;
60-
public IMouseDevice MouseDevice => new MouseDevice();
61-
public IPopupImpl CreatePopup() => null;
59+
public IMouseDevice MouseDevice { get; } = new MouseDevice();
60+
public IPopupImpl? CreatePopup() => null;
6261

6362
public double RenderScaling => _outputBackend.Scaling;
6463
public IEnumerable<object> Surfaces { get; }
65-
public Action<RawInputEventArgs> Input { get; set; }
66-
public Action<Rect> Paint { get; set; }
67-
public Action<Size, WindowResizeReason> Resized { get; set; }
68-
public Action<double> ScalingChanged { get; set; }
64+
public Action<RawInputEventArgs>? Input { get; set; }
65+
public Action<Rect>? Paint { get; set; }
66+
public Action<Size, WindowResizeReason>? Resized { get; set; }
67+
public Action<double>? ScalingChanged { get; set; }
6968

70-
public Action<WindowTransparencyLevel> TransparencyLevelChanged { get; set; }
69+
public Action<WindowTransparencyLevel>? TransparencyLevelChanged { get; set; }
7170

72-
public Action Closed { get; set; }
73-
public Action LostFocus { get; set; }
71+
public Action? Closed { get; set; }
72+
public Action? LostFocus { get; set; }
7473

7574
public Size ScaledSize => _outputBackend.PixelSize.ToSize(RenderScaling);
7675

@@ -81,6 +80,6 @@ public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> tran
8180
public void SetFrameThemeVariant(PlatformThemeVariant themeVariant) { }
8281

8382
public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(1, 1, 1);
84-
public object TryGetFeature(Type featureType) => null;
83+
public object? TryGetFeature(Type featureType) => null;
8584
}
8685
}

src/Linux/Avalonia.LinuxFramebuffer/Input/EvDev/EvDevBackend.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ public class EvDevBackend : IInputBackend
1212
private readonly EvDevDeviceDescription[] _deviceDescriptions;
1313
private readonly List<EvDevDeviceHandler> _handlers = new List<EvDevDeviceHandler>();
1414
private int _epoll;
15-
private Action<RawInputEventArgs> _onInput;
16-
private IInputRoot _inputRoot;
15+
private Action<RawInputEventArgs>? _onInput;
16+
private IInputRoot? _inputRoot;
1717

1818
public EvDevBackend(EvDevDeviceDescription[] devices)
1919
{
@@ -53,7 +53,7 @@ public void Initialize(IScreenInfoProvider info, Action<RawInputEventArgs> onInp
5353
for (var c = 0; c < _deviceDescriptions.Length; c++)
5454
{
5555
var description = _deviceDescriptions[c];
56-
var dev = EvDevDevice.Open(description.Path);
56+
var dev = EvDevDevice.Open(description.Path ?? string.Empty);
5757
EvDevDeviceHandler handler;
5858
if (description is EvDevTouchScreenDeviceDescription touch)
5959
handler = new EvDevSingleTouchScreen(dev, touch, info) { InputRoot = _inputRoot };
@@ -86,7 +86,7 @@ public static EvDevBackend CreateFromEnvironment()
8686
{
8787
if (key.StartsWith("AVALONIA_EVDEV_DEVICE_"))
8888
{
89-
var value = (string)env[key];
89+
var value = (string)env[key]!;
9090
deviceDescriptions.Add(EvDevDeviceDescription.ParseFromEnv(value));
9191
}
9292
}

src/Linux/Avalonia.LinuxFramebuffer/Input/EvDev/EvDevDevice.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.IO;
4-
using System.Linq;
53
using System.Runtime.InteropServices;
64

75
namespace Avalonia.LinuxFramebuffer.Input.EvDev
@@ -10,7 +8,7 @@ unsafe class EvDevDevice
108
{
119
public int Fd { get; }
1210
private IntPtr _dev;
13-
public string Name { get; }
11+
public string? Name { get; }
1412
public List<EvType> EventTypes { get; private set; } = new List<EvType>();
1513
public input_absinfo? AbsX { get; }
1614
public input_absinfo? AbsY { get; }

src/Linux/Avalonia.LinuxFramebuffer/Input/EvDev/EvDevDeviceDescription.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ protected internal EvDevDeviceDescription()
1010

1111
}
1212

13-
public string Path { get; set; }
13+
public string? Path { get; set; }
1414

1515
internal static EvDevDeviceDescription ParseFromEnv(string env)
1616
{

src/Linux/Avalonia.LinuxFramebuffer/Input/EvDev/EvDevTouchScreen.cs

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics.CodeAnalysis;
23
using Avalonia.Input;
34
using Avalonia.Input.Raw;
45

@@ -90,14 +91,23 @@ void RaiseEvent(RawPointerEventType type, ulong timestamp)
9091

9192
internal abstract class EvDevDeviceHandler
9293
{
93-
public event Action<RawInputEventArgs> OnEvent;
94+
private IInputRoot? _inputRoot;
95+
96+
public event Action<RawInputEventArgs>? OnEvent;
97+
9498
public EvDevDeviceHandler(EvDevDevice device)
9599
{
96100
Device = device;
97101
}
98102

99103
public EvDevDevice Device { get; }
100-
public IInputRoot InputRoot { get; set; }
104+
105+
[AllowNull]
106+
public IInputRoot InputRoot
107+
{
108+
get => _inputRoot ?? throw new InvalidOperationException($"{nameof(InputRoot)} hasn't been set");
109+
set => _inputRoot = value;
110+
}
101111

102112
public void HandleEvents()
103113
{

src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.Pointer.cs

+11-11
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,35 @@ private void HandlePointer(IntPtr ev, LibInputEventType type)
1616
{
1717
var modifiers = RawInputModifiers.None; //TODO: support input modifiers
1818
var pev = libinput_event_get_pointer_event(ev);
19-
var info = _screen.ScaledSize;
19+
var info = _screen!.ScaledSize;
2020
var ts = libinput_event_pointer_get_time_usec(pev) / 1000;
2121
switch (type)
2222
{
2323
case LibInputEventType.LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
2424
_mousePosition = new Point(libinput_event_pointer_get_absolute_x_transformed(pev, (int)info.Width),
2525
libinput_event_pointer_get_absolute_y_transformed(pev, (int)info.Height));
26-
ScheduleInput(new RawPointerEventArgs(_mouse, ts, _inputRoot, RawPointerEventType.Move, _mousePosition,
26+
ScheduleInput(new RawPointerEventArgs(_mouse, ts, InputRoot, RawPointerEventType.Move, _mousePosition,
2727
modifiers));
2828
break;
2929
case LibInputEventType.LIBINPUT_EVENT_POINTER_BUTTON:
3030
{
3131
var button = (EvKey)libinput_event_pointer_get_button(pev);
3232
var buttonState = libinput_event_pointer_get_button_state(pev);
3333

34-
RawPointerEventArgs evnt = button switch
34+
RawPointerEventArgs? evnt = button switch
3535
{
3636
EvKey.BTN_LEFT when buttonState == 1
37-
=> new(_mouse, ts, _inputRoot, RawPointerEventType.LeftButtonDown, _mousePosition, modifiers),
37+
=> new(_mouse, ts, InputRoot, RawPointerEventType.LeftButtonDown, _mousePosition, modifiers),
3838
EvKey.BTN_LEFT when buttonState == 0
39-
=> new(_mouse, ts, _inputRoot, RawPointerEventType.LeftButtonUp, _mousePosition, modifiers),
39+
=> new(_mouse, ts, InputRoot, RawPointerEventType.LeftButtonUp, _mousePosition, modifiers),
4040
EvKey.BTN_RIGHT when buttonState == 1
41-
=> new(_mouse, ts, _inputRoot, RawPointerEventType.RightButtonUp, _mousePosition, modifiers),
41+
=> new(_mouse, ts, InputRoot, RawPointerEventType.RightButtonUp, _mousePosition, modifiers),
4242
EvKey.BTN_RIGHT when buttonState == 2
43-
=> new(_mouse, ts, _inputRoot, RawPointerEventType.RightButtonDown, _mousePosition, modifiers),
43+
=> new(_mouse, ts, InputRoot, RawPointerEventType.RightButtonDown, _mousePosition, modifiers),
4444
EvKey.BTN_MIDDLE when buttonState == 1
45-
=> new(_mouse, ts, _inputRoot, RawPointerEventType.MiddleButtonDown, _mousePosition, modifiers),
45+
=> new(_mouse, ts, InputRoot, RawPointerEventType.MiddleButtonDown, _mousePosition, modifiers),
4646
EvKey.BTN_MIDDLE when buttonState == 2
47-
=> new(_mouse, ts, _inputRoot, RawPointerEventType.MiddleButtonUp, _mousePosition, modifiers),
47+
=> new(_mouse, ts, InputRoot, RawPointerEventType.MiddleButtonUp, _mousePosition, modifiers),
4848
_ => default,
4949
};
5050
if (evnt is not null)
@@ -70,7 +70,7 @@ private void HandlePointer(IntPtr ev, LibInputEventType type)
7070
LibInputPointerAxis.LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
7171
ScheduleInput(new RawMouseWheelEventArgs(_mouse
7272
, ts
73-
, _inputRoot
73+
, InputRoot
7474
, _mousePosition
7575
, new Vector(0, -value)
7676
, modifiers));
@@ -94,7 +94,7 @@ private void HandlePointer(IntPtr ev, LibInputEventType type)
9494
LibInputPointerAxis.LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) / 120);
9595
ScheduleInput(new RawMouseWheelEventArgs(_mouse
9696
, ts
97-
, _inputRoot
97+
, InputRoot
9898
, _mousePosition
9999
, value
100100
, modifiers));

src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.Touch.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ private void HandleTouch(IntPtr ev, LibInputEventType type)
1818
return;
1919
if (type < LibInputEventType.LIBINPUT_EVENT_TOUCH_FRAME)
2020
{
21-
var info = _screen.ScaledSize;
21+
var info = _screen!.ScaledSize;
2222
var slot = libinput_event_touch_get_slot(tev);
2323
Point pt;
2424

src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#nullable enable
21
using System;
32
using System.IO;
43
using System.Threading;
@@ -25,6 +24,9 @@ public LibInputBackend(LibInputBackendOptions options)
2524
_options = options;
2625
}
2726

27+
private IInputRoot InputRoot
28+
=> _inputRoot ?? throw new InvalidOperationException($"{nameof(InputRoot)} hasn't been set");
29+
2830
private unsafe void InputThread(IntPtr ctx, LibInputBackendOptions options)
2931
{
3032
var fd = libinput_get_fd(ctx);

src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputNativeUnsafeMethods.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ unsafe class LibInputNativeUnsafeMethods
1313

1414
static int OpenRestricted(IntPtr path, int flags, IntPtr userData)
1515
{
16-
var fd = NativeUnsafeMethods.open(Marshal.PtrToStringAnsi(path), flags, 0);
16+
var fd = NativeUnsafeMethods.open(Marshal.PtrToStringAnsi(path) ?? string.Empty, flags, 0);
1717
if (fd == -1)
1818
return -Marshal.GetLastWin32Error();
1919

@@ -31,7 +31,7 @@ static LibInputNativeUnsafeMethods()
3131
{
3232
s_Interface = (IntPtr*)Marshal.AllocHGlobal(IntPtr.Size * 2);
3333

34-
IntPtr Convert<TDelegate>(TDelegate del)
34+
IntPtr Convert<TDelegate>(TDelegate del) where TDelegate : notnull
3535
{
3636
GCHandle.Alloc(del);
3737
return Marshal.GetFunctionPointerForDelegate(del);

src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs

-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Diagnostics;
43
using System.Diagnostics.CodeAnalysis;
54
using System.IO;
65
using System.Threading;
76
using Avalonia;
87
using Avalonia.Controls;
98
using Avalonia.Controls.ApplicationLifetimes;
109
using Avalonia.Controls.Embedding;
11-
using Avalonia.Controls.Platform;
1210
using Avalonia.Input;
1311
using Avalonia.Input.Platform;
1412
using Avalonia.LinuxFramebuffer;
@@ -21,8 +19,6 @@
2119
using Avalonia.Rendering.Composition;
2220
using Avalonia.Threading;
2321

24-
#nullable enable
25-
2622
namespace Avalonia.LinuxFramebuffer
2723
{
2824
internal class LinuxFramebufferIconLoaderStub : IPlatformIconLoader

src/Linux/Avalonia.LinuxFramebuffer/Output/DrmBindings.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ internal DrmModeInfo(ref drmModeModeInfo info)
6363
public PixelSize Resolution => new PixelSize(Mode.hdisplay, Mode.vdisplay);
6464
public bool IsPreferred => Mode.type.HasAllFlags(DrmModeType.DRM_MODE_TYPE_PREFERRED);
6565

66-
public string Name { get; }
66+
public string? Name { get; }
6767
}
6868

6969
unsafe class DrmEncoder
@@ -141,7 +141,7 @@ void Print(int off, string s)
141141
public unsafe class DrmCard : IDisposable
142142
{
143143
public int Fd { get; private set; }
144-
public DrmCard(string path = null)
144+
public DrmCard(string? path = null)
145145
{
146146
if (path == null)
147147
{

0 commit comments

Comments
 (0)