diff --git a/src/Avalonia.X11/X11TrayIconImpl.cs b/src/Avalonia.X11/X11TrayIconImpl.cs index 20599c4629..160537cb26 100644 --- a/src/Avalonia.X11/X11TrayIconImpl.cs +++ b/src/Avalonia.X11/X11TrayIconImpl.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Diagnostics; using System.Reactive.Disposables; using System.Runtime.CompilerServices; @@ -15,11 +17,10 @@ namespace Avalonia.X11 { internal class X11TrayIconImpl : ITrayIconImpl { - private static int s_trayIconInstanceId; - private static int GetTID() => s_trayIconInstanceId++; + private static int trayIconInstanceId; private readonly ObjectPath _dbusMenuPath; private StatusNotifierItemDbusObj _statusNotifierItemDbusObj; - private readonly Connection _con; + private readonly Connection _connection; private DbusPixmap _icon; private IStatusNotifierWatcher _statusNotifierWatcher; @@ -35,9 +36,9 @@ namespace Avalonia.X11 public X11TrayIconImpl() { - _con = DBusHelper.TryGetConnection(); + _connection = DBusHelper.TryGetConnection(); - if (_con is null) + if (_connection is null) { Logger.TryGet(LogEventLevel.Error, LogArea.X11Platform) ?.Log(this, "Unable to get a dbus connection for system tray icons."); @@ -45,27 +46,27 @@ namespace Avalonia.X11 } _dbusMenuPath = DBusMenuExporter.GenerateDBusMenuObjPath; - MenuExporter = DBusMenuExporter.TryCreateDetachedNativeMenu(_dbusMenuPath, _con); + MenuExporter = DBusMenuExporter.TryCreateDetachedNativeMenu(_dbusMenuPath, _connection); CreateTrayIcon(); _ctorFinished = true; } public async void CreateTrayIcon() { - if (_con is null) return; + if (_connection is null) return; - _statusNotifierWatcher = _con.CreateProxy("org.kde.StatusNotifierWatcher", + _statusNotifierWatcher = _connection.CreateProxy("org.kde.StatusNotifierWatcher", "/StatusNotifierWatcher"); var pid = Process.GetCurrentProcess().Id; - var tid = GetTID(); + var tid = trayIconInstanceId++; _sysTrayServiceName = $"org.kde.StatusNotifierItem-{pid}-{tid}"; _statusNotifierItemDbusObj = new StatusNotifierItemDbusObj(_dbusMenuPath); - await _con.RegisterObjectAsync(_statusNotifierItemDbusObj); + await _connection.RegisterObjectAsync(_statusNotifierItemDbusObj); - await _con.RegisterServiceAsync(_sysTrayServiceName); + await _connection.RegisterServiceAsync(_sysTrayServiceName); await _statusNotifierWatcher.RegisterStatusNotifierItemAsync(_sysTrayServiceName); @@ -82,10 +83,10 @@ namespace Avalonia.X11 public async void DestroyTrayIcon() { - if (_con is null) return; + if (_connection is null) return; - _con.UnregisterObject(_statusNotifierItemDbusObj); - await _con.UnregisterServiceAsync(_sysTrayServiceName); + _connection.UnregisterObject(_statusNotifierItemDbusObj); + await _connection.UnregisterServiceAsync(_sysTrayServiceName); _isActive = false; } @@ -93,30 +94,28 @@ namespace Avalonia.X11 { _isDisposed = true; DestroyTrayIcon(); - _con?.Dispose(); + _connection?.Dispose(); } public void SetIcon(IWindowIconImpl icon) { - if (_con is null || _isDisposed) return; + if (_connection is null || _isDisposed) return; if (!(icon is X11IconData x11icon)) return; var w = (int)x11icon.Data[0]; var h = (int)x11icon.Data[1]; - var rx = x11icon.Data.AsSpan(2); var pixLength = w * h; - var pixByteArrayCounter = 0; var pixByteArray = new byte[w * h * 4]; for (var i = 0; i < pixLength; i++) { - var u = rx[i].ToUInt32(); - pixByteArray[pixByteArrayCounter++] = (byte)((u & 0xFF000000) >> 24); - pixByteArray[pixByteArrayCounter++] = (byte)((u & 0xFF0000) >> 16); - pixByteArray[pixByteArrayCounter++] = (byte)((u & 0xFF00) >> 8); - pixByteArray[pixByteArrayCounter++] = (byte)(u & 0xFF); + var rawPixel = x11icon.Data[i+2].ToUInt32(); + pixByteArray[pixByteArrayCounter++] = (byte)((rawPixel & 0xFF000000) >> 24); + pixByteArray[pixByteArrayCounter++] = (byte)((rawPixel & 0xFF0000) >> 16); + pixByteArray[pixByteArrayCounter++] = (byte)((rawPixel & 0xFF00) >> 8); + pixByteArray[pixByteArrayCounter++] = (byte)(rawPixel & 0xFF); } _icon = new DbusPixmap(w, h, pixByteArray); @@ -125,7 +124,7 @@ namespace Avalonia.X11 public void SetIsVisible(bool visible) { - if (_con is null || _isDisposed || !_ctorFinished) return; + if (_connection is null || _isDisposed || !_ctorFinished) return; if (visible & !_isActive) { @@ -140,7 +139,7 @@ namespace Avalonia.X11 public void SetToolTipText(string text) { - if (_con is null || _isDisposed) return; + if (_connection is null || _isDisposed) return; _tooltipText = text; _statusNotifierItemDbusObj?.SetTitleAndTooltip(_tooltipText); } @@ -179,17 +178,17 @@ namespace Avalonia.X11 InvalidateAll(); } - public Task ContextMenuAsync(int X, int Y) => Task.CompletedTask; + public Task ContextMenuAsync(int x, int y) => Task.CompletedTask; - public Task ActivateAsync(int X, int Y) + public Task ActivateAsync(int x, int y) { ActivationDelegate?.Invoke(); return Task.CompletedTask; } - public Task SecondaryActivateAsync(int X, int Y) => Task.CompletedTask; + public Task SecondaryActivateAsync(int x, int y) => Task.CompletedTask; - public Task ScrollAsync(int Delta, string Orientation) => Task.CompletedTask; + public Task ScrollAsync(int delta, string orientation) => Task.CompletedTask; public void InvalidateAll() { @@ -276,10 +275,10 @@ namespace Avalonia.X11 [DBusInterface("org.kde.StatusNotifierItem")] internal interface IStatusNotifierItem : IDBusObject { - Task ContextMenuAsync(int X, int Y); - Task ActivateAsync(int X, int Y); - Task SecondaryActivateAsync(int X, int Y); - Task ScrollAsync(int Delta, string Orientation); + Task ContextMenuAsync(int x, int y); + Task ActivateAsync(int x, int y); + Task SecondaryActivateAsync(int x, int y); + Task ScrollAsync(int delta, string orientation); Task WatchNewTitleAsync(Action handler, Action onError = null); Task WatchNewIconAsync(Action handler, Action onError = null); Task WatchNewAttentionIconAsync(Action handler, Action onError = null); @@ -337,7 +336,7 @@ namespace Avalonia.X11 private static readonly DbusPixmap[] s_blank = { - new DbusPixmap(0, 0, new byte[] { }), new DbusPixmap(0, 0, new byte[] { }) + new DbusPixmap(0, 0, Array.Empty()), new DbusPixmap(0, 0, Array.Empty()) }; public ToolTip(string message) : this("", s_blank, message, "")