From 497b6e0742d43b59ada55d5cb36024f173d2e8d9 Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Tue, 25 Apr 2023 00:14:35 +0100 Subject: [PATCH 1/3] wip: try to fix input id on linux i need this code on my linux machine to test --- .../Providers/Input/Enums/LinuxDeviceType.cs | 1 + .../Providers/Input/LinuxInputDevice.cs | 39 ++++--------------- .../Providers/Input/LinuxInputDeviceFinder.cs | 36 +++++++++++++++-- .../Providers/Input/LinuxInputProvider.cs | 4 +- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/src/Artemis.UI.Linux/Providers/Input/Enums/LinuxDeviceType.cs b/src/Artemis.UI.Linux/Providers/Input/Enums/LinuxDeviceType.cs index e0d1d0381..7eb5c4976 100644 --- a/src/Artemis.UI.Linux/Providers/Input/Enums/LinuxDeviceType.cs +++ b/src/Artemis.UI.Linux/Providers/Input/Enums/LinuxDeviceType.cs @@ -2,6 +2,7 @@ public enum LinuxDeviceType { + Unknown, Keyboard, Mouse, Gamepad diff --git a/src/Artemis.UI.Linux/Providers/Input/LinuxInputDevice.cs b/src/Artemis.UI.Linux/Providers/Input/LinuxInputDevice.cs index 6771d2a2b..fa6b23e43 100644 --- a/src/Artemis.UI.Linux/Providers/Input/LinuxInputDevice.cs +++ b/src/Artemis.UI.Linux/Providers/Input/LinuxInputDevice.cs @@ -19,7 +19,7 @@ public class LinuxInputDevice switch (dataType) { case 'I': - InputId = new LinuxInputId(data); + InputId = data; break; case 'N': Name = data.Replace("\"", "").Replace("Name=", ""); @@ -27,14 +27,16 @@ public class LinuxInputDevice case 'H': Handlers = data.Replace("Handlers=", "").Split(" "); - if (Handlers?.Any(h => h.Contains("mouse")) == true) + if (Handlers.Any(h => h.Contains("mouse"))) DeviceType = LinuxDeviceType.Mouse; - else if (Handlers?.Any(h => h.Contains("kbd")) == true) + else if (Handlers.Any(h => h.Contains("kbd"))) DeviceType = LinuxDeviceType.Keyboard; - else if (Handlers?.Any(h => h.Contains("js")) == true) + else if (Handlers.Any(h => h.Contains("js"))) DeviceType = LinuxDeviceType.Gamepad; + else + DeviceType = LinuxDeviceType.Unknown; - string evt = Handlers!.First(h => h.Contains("event")); + string evt = Handlers.First(h => h.Contains("event")); EventPath = $"/dev/input/{evt}"; break; @@ -45,7 +47,7 @@ public class LinuxInputDevice throw new ArtemisLinuxInputProviderException("Linux device definition did not contain necessary data"); } - public LinuxInputId InputId { get; } + public string InputId { get; } public string Name { get; } public string[] Handlers { get; } public string EventPath { get; } @@ -60,29 +62,4 @@ public class LinuxInputDevice } #endregion - - public class LinuxInputId - { - public LinuxInputId(string line) - { - Dictionary components = line.Split(" ") - .Select(c => c.Split('=')) - .ToDictionary(c => c[0], c => c[1]); - - Bus = components["Bus"]; - Vendor = components["Vendor"]; - Product = components["Product"]; - Version = components["Version"]; - } - - public string Bus { get; } - public string Vendor { get; } - public string Product { get; } - public string Version { get; } - - public override string ToString() - { - return $"Bus={Bus} Vendor={Vendor} Product={Product} Version={Version}"; - } - } } \ No newline at end of file diff --git a/src/Artemis.UI.Linux/Providers/Input/LinuxInputDeviceFinder.cs b/src/Artemis.UI.Linux/Providers/Input/LinuxInputDeviceFinder.cs index be532d250..e8e6dfbc5 100644 --- a/src/Artemis.UI.Linux/Providers/Input/LinuxInputDeviceFinder.cs +++ b/src/Artemis.UI.Linux/Providers/Input/LinuxInputDeviceFinder.cs @@ -11,9 +11,37 @@ public static class LinuxInputDeviceFinder public static IEnumerable Find() { - return File.ReadAllLines(DEVICES_FILE) - .PartitionBy(s => s?.Length == 0) //split on empty lines - .Select(lineGroup => new LinuxInputDevice(lineGroup)); + var lineGroups = File.ReadAllLines(DEVICES_FILE) + .PartitionBy(s => s?.Length == 0); //split on empty lines + + foreach (var lineGroup in lineGroups) + { + LinuxInputDevice device; + + try + { + device = new LinuxInputDevice(lineGroup); + } + catch + { + continue; + //some devices don't have all the required data, we can ignore those + } + + if (ShouldReadDevice(device)) + { + yield return device; + } + } + } + + private static bool ShouldReadDevice(LinuxInputDevice device) + { + if (device.DeviceType == LinuxDeviceType.Unknown) + return false; + //possibly add more checks here + + return true; } //https://stackoverflow.com/questions/56623354 @@ -34,7 +62,7 @@ public static class LinuxInputDeviceFinder return groupNumber; }; return a - .Select(x => new {Value = x, GroupNumber = getGroupNumber(predicate(x))}) + .Select(x => new { Value = x, GroupNumber = getGroupNumber(predicate(x)) }) .Where(x => x.GroupNumber != null) .GroupBy(x => x.GroupNumber) .Select(g => g.Select(x => x.Value)); diff --git a/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs b/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs index 62866cb00..5c4349231 100644 --- a/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs +++ b/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs @@ -75,7 +75,7 @@ public class LinuxInputProvider : InputProvider //_logger.Verbose($"Keyboard Key: {(LinuxKeyboardKeyCodes)args.Code} | Down: {isDown}"); - LinuxInputDevice.LinuxInputId identifier = keyboard.InputId; + string identifier = keyboard.InputId; OnIdentifierReceived(identifier, InputDeviceType.Keyboard); ArtemisDevice? device = null; @@ -93,7 +93,7 @@ public class LinuxInputProvider : InputProvider private void HandleMouseData(LinuxInputDevice mouse, LinuxInputEventArgs args) { - LinuxInputDevice.LinuxInputId identifier = mouse.InputId; + string identifier = mouse.InputId; OnIdentifierReceived(identifier, InputDeviceType.Mouse); ArtemisDevice? device = null; From 97b858b332a9d54ca12258b8bea15c18ec1a684d Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Tue, 25 Apr 2023 00:58:47 +0100 Subject: [PATCH 2/3] Linux - input identification fixes --- src/Artemis.UI.Linux/Utilities/InputUtilities.cs | 4 ++-- .../Screens/Device/DeviceDetectInputViewModel.cs | 14 +++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Artemis.UI.Linux/Utilities/InputUtilities.cs b/src/Artemis.UI.Linux/Utilities/InputUtilities.cs index f898ebb1e..1b567245a 100644 --- a/src/Artemis.UI.Linux/Utilities/InputUtilities.cs +++ b/src/Artemis.UI.Linux/Utilities/InputUtilities.cs @@ -52,7 +52,7 @@ public static class InputUtilities LinuxKeyboardKeyCodes.KEY_APOSTROPHE => KeyboardKey.OemQuotes, LinuxKeyboardKeyCodes.KEY_GRAVE => KeyboardKey.OemTilde, LinuxKeyboardKeyCodes.KEY_LEFTSHIFT => KeyboardKey.LeftShift, - LinuxKeyboardKeyCodes.KEY_BACKSLASH => KeyboardKey.OemBackslash, + LinuxKeyboardKeyCodes.KEY_BACKSLASH => KeyboardKey.OemPipe, LinuxKeyboardKeyCodes.KEY_Z => KeyboardKey.Z, LinuxKeyboardKeyCodes.KEY_X => KeyboardKey.X, LinuxKeyboardKeyCodes.KEY_C => KeyboardKey.C, @@ -94,7 +94,7 @@ public static class InputUtilities LinuxKeyboardKeyCodes.KEY_KP0 => KeyboardKey.NumPad0, LinuxKeyboardKeyCodes.KEY_KPDOT => KeyboardKey.NumPadDecimal, // LinuxKeyboardKeyCodes.KEY_ZENKAKUHANKAKU => expr, - // LinuxKeyboardKeyCodes.KEY_102ND => expr, + LinuxKeyboardKeyCodes.KEY_102ND => KeyboardKey.OemBackslash, LinuxKeyboardKeyCodes.KEY_F11 => KeyboardKey.F11, LinuxKeyboardKeyCodes.KEY_F12 => KeyboardKey.F12, //LinuxKeyboardKeyCodes.KEY_RO => expr, diff --git a/src/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs b/src/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs index ee5d0922a..b915e14c6 100644 --- a/src/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs +++ b/src/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs @@ -7,6 +7,7 @@ using Artemis.Core.Services; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.Builders; +using Avalonia.Threading; using FluentAvalonia.UI.Controls; using ReactiveUI; using RGB.NET.Core; @@ -57,10 +58,13 @@ public class DeviceDetectInputViewModel : ContentDialogViewModelBase private void InputServiceOnDeviceIdentified() { - ContentDialog?.Hide(ContentDialogResult.Primary); - _notificationService.CreateNotification() - .WithMessage($"{Device.RgbDevice.DeviceInfo.DeviceName} identified 😁") - .WithSeverity(NotificationSeverity.Success) - .Show(); + Dispatcher.UIThread.Post(() => + { + ContentDialog?.Hide(ContentDialogResult.Primary); + _notificationService.CreateNotification() + .WithMessage($"{Device.RgbDevice.DeviceInfo.DeviceName} identified 😁") + .WithSeverity(NotificationSeverity.Success) + .Show(); + }); } } \ No newline at end of file From becc6e0715f6da061964ca4962505bc2f632bf7f Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Sat, 6 May 2023 15:39:47 +0100 Subject: [PATCH 3/3] Linux - cleanup initialization --- src/Artemis.UI.Linux/App.axaml.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Artemis.UI.Linux/App.axaml.cs b/src/Artemis.UI.Linux/App.axaml.cs index 1a6cd64a5..52f729727 100644 --- a/src/Artemis.UI.Linux/App.axaml.cs +++ b/src/Artemis.UI.Linux/App.axaml.cs @@ -22,18 +22,20 @@ public class App : Application Program.CreateLogger(_container); RxApp.MainThreadScheduler = AvaloniaScheduler.Instance; AvaloniaXamlLoader.Load(this); - - RegisterProviders(); } public override void OnFrameworkInitializationCompleted() { if (Design.IsDesignMode) return; - + + if (ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop) + return; + ArtemisBootstrapper.Initialize(); - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - _applicationStateManager = new ApplicationStateManager(_container!, desktop.Args); + + _applicationStateManager = new ApplicationStateManager(_container!, desktop.Args); + RegisterProviders(); } private void RegisterProviders()