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