diff --git a/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/MouseListenerService.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/MouseListenerService.cs index 4cc1397..37911c7 100644 --- a/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/MouseListenerService.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/MouseListenerService.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Reactive.Linq; +using System.Reactive.Subjects; using System.Threading; using Serilog; using SharpHook; @@ -15,10 +16,10 @@ namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; public interface IMouseListener : IDisposable { - event EventHandler OnMouseMovedEventHandler; - event EventHandler OnMousePressedEventHandler; - event EventHandler OnMouseReleasedEventHandler; - event EventHandler OnMouseWheelEventHandler; + IObservable OnMouseMovedChanged { get; } + IObservable OnMousePressedChanged { get; } + IObservable OnMouseReleasedChanged { get; } + IObservable OnMouseWheelChanged { get; } void Run(); } @@ -33,10 +34,14 @@ public class MouseListener : IMouseListener private readonly ICurrentWindowService _currentWindowService; private readonly ILogger _log = Log.Logger.ForContext(); private Thread? _thread; - private IDisposable? _mouseMovedDisposable; - private IDisposable? _mousePressedDisposable; - private IDisposable? _mouseReleasedDisposable; - private IDisposable? _mouseWheelDisposable; + private readonly IDisposable? _mouseMovedDisposable; + private readonly IDisposable? _mousePressedDisposable; + private readonly IDisposable? _mouseReleasedDisposable; + private readonly IDisposable? _mouseWheelDisposable; + private readonly Subject _mousePressedSubject; + private readonly Subject _mouseReleasedSubject; + private readonly Subject _mouseMovedSubject; + private readonly Subject _mouseWheelSubject; public MouseListener( IReactiveGlobalHook hook, @@ -47,14 +52,27 @@ ICurrentWindowService currentWindowService _hook = hook; _profilesService = profilesService; _currentWindowService = currentWindowService; + _mousePressedSubject = new Subject(); + _mouseReleasedSubject = new Subject(); + _mouseMovedSubject = new Subject(); + _mouseWheelSubject = new Subject(); - SubscribeToEvents(); + _mouseMovedDisposable = _hook + .MouseMoved.Sample(TimeSpan.FromMilliseconds(100)) + .Subscribe(ConvertMouseMovedEvent); + _mousePressedDisposable = _hook.MousePressed.Subscribe(ConvertMousePressedEvent); + _mouseReleasedDisposable = _hook.MouseReleased.Subscribe(ConvertMouseReleasedEvent); + _mouseWheelDisposable = _hook.MouseWheel.Subscribe(ConvertMouseWheelEvent); } - public event EventHandler? OnMousePressedEventHandler; - public event EventHandler? OnMouseMovedEventHandler; - public event EventHandler? OnMouseReleasedEventHandler; - public event EventHandler? OnMouseWheelEventHandler; + public IObservable OnMousePressedChanged => + _mousePressedSubject.AsObservable(); + public IObservable OnMouseReleasedChanged => + _mouseReleasedSubject.AsObservable(); + public IObservable OnMouseMovedChanged => + _mouseMovedSubject.AsObservable(); + public IObservable OnMouseWheelChanged => + _mouseWheelSubject.AsObservable(); public void Run() { @@ -66,24 +84,6 @@ public void Run() _thread.Start(); } - private void OnMouseReleased(NewMouseHookEventArgs args) - { - var handler = OnMouseReleasedEventHandler; - handler?.Invoke(this, args); - } - - private void OnMousePressed(NewMouseHookEventArgs args) - { - var handler = OnMousePressedEventHandler; - handler?.Invoke(this, args); - } - - private void OnMouseWheel(NewMouseWheelEventArgs args) - { - var handler = OnMouseWheelEventHandler; - handler?.Invoke(this, args); - } - /// /// Whether to suppress the original mouse event from propagating /// @@ -132,16 +132,6 @@ private bool ShouldSuppressEvent(NewMouseHookEventArgs args) => _ => throw new ArgumentOutOfRangeException(), }; - private void SubscribeToEvents() - { - _mouseMovedDisposable = _hook - .MouseMoved.Sample(TimeSpan.FromMilliseconds(100)) - .Subscribe(ConvertMouseMovedEvent); - _mousePressedDisposable = _hook.MousePressed.Subscribe(ConvertMousePressedEvent); - _mouseReleasedDisposable = _hook.MouseReleased.Subscribe(ConvertMouseReleasedEvent); - _mouseWheelDisposable = _hook.MouseWheel.Subscribe(ConvertMouseWheelEvent); - } - private void ConvertMouseWheelEvent(MouseWheelHookEventArgs e) { if (e is null) @@ -151,18 +141,26 @@ private void ConvertMouseWheelEvent(MouseWheelHookEventArgs e) switch (e.Data.Direction) { case MouseWheelScrollDirection.Vertical when e.Data.Rotation > 0: - OnMouseWheel(new NewMouseWheelEventArgs(WheelScrollDirection.VerticalUp)); + _mouseWheelSubject.OnNext( + new NewMouseWheelEventArgs(WheelScrollDirection.VerticalUp) + ); break; case MouseWheelScrollDirection.Vertical when e.Data.Rotation < 0: - OnMouseWheel(new NewMouseWheelEventArgs(WheelScrollDirection.VerticalDown)); + _mouseWheelSubject.OnNext( + new NewMouseWheelEventArgs(WheelScrollDirection.VerticalDown) + ); break; case MouseWheelScrollDirection.Vertical: throw new ArgumentOutOfRangeException($"{e.Data.Direction}\t{e.Data.Rotation}"); case MouseWheelScrollDirection.Horizontal when e.Data.Rotation > 0: - OnMouseWheel(new NewMouseWheelEventArgs(WheelScrollDirection.HorizontalRight)); + _mouseWheelSubject.OnNext( + new NewMouseWheelEventArgs(WheelScrollDirection.HorizontalRight) + ); break; case MouseWheelScrollDirection.Horizontal when e.Data.Rotation < 0: - OnMouseWheel(new NewMouseWheelEventArgs(WheelScrollDirection.HorizontalLeft)); + _mouseWheelSubject.OnNext( + new NewMouseWheelEventArgs(WheelScrollDirection.HorizontalLeft) + ); break; case MouseWheelScrollDirection.Horizontal: throw new ArgumentOutOfRangeException($"{e.Data.Direction}\t{e.Data.Rotation}"); @@ -194,7 +192,7 @@ private void ConvertMouseReleasedEvent(MouseHookEventArgs e) { _log.Information("Not suppressing {Button}: Release", e.Data.Button); } - OnMouseReleased(args); + _mouseReleasedSubject.OnNext(args); } private void ConvertMousePressedEvent(MouseHookEventArgs e) @@ -221,7 +219,7 @@ private void ConvertMousePressedEvent(MouseHookEventArgs e) { _log.Information("Not suppressing {Button}: Press", e.Data.Button); } - OnMousePressed(args); + _mousePressedSubject.OnNext(args); } private void ConvertMouseMovedEvent(MouseHookEventArgs e) @@ -230,27 +228,15 @@ private void ConvertMouseMovedEvent(MouseHookEventArgs e) { return; } - var args = new NewMouseHookMoveEventArgs(e.Data.X, e.Data.Y); - OnMouseMoved(args); + _mouseMovedSubject.OnNext(new NewMouseHookMoveEventArgs(e.Data.X, e.Data.Y)); } - private void OnMouseMoved(NewMouseHookMoveEventArgs args) - { - var handler = OnMouseMovedEventHandler; - handler?.Invoke(this, args); - } - - private void UnsubscribeFromEvents() + public void Dispose() { _mouseMovedDisposable?.Dispose(); _mousePressedDisposable?.Dispose(); _mouseReleasedDisposable?.Dispose(); _mouseWheelDisposable?.Dispose(); - } - - public void Dispose() - { - UnsubscribeFromEvents(); _hook.Dispose(); diff --git a/YMouseButtonControl.Core/Services/KeyboardAndMouse/KeyboardSimulatorWorker.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/KeyboardSimulatorWorker.cs index c43ba42..aa5d93c 100644 --- a/YMouseButtonControl.Core/Services/KeyboardAndMouse/KeyboardSimulatorWorker.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/KeyboardSimulatorWorker.cs @@ -25,39 +25,27 @@ IRightClick rightClick ) : IDisposable { private readonly ILogger _log = Log.Logger.ForContext(); + private IDisposable? _onMousePressedDisposable; + private IDisposable? _onMouseReleasedDisposable; + private IDisposable? _onMouseWheelDisposable; public void Run() { - SubscribeToEvents(); + _onMousePressedDisposable = mouseListener.OnMousePressedChanged.Subscribe(OnMousePressed); + _onMouseReleasedDisposable = mouseListener.OnMouseReleasedChanged.Subscribe( + OnMouseReleased + ); + _onMouseWheelDisposable = mouseListener.OnMouseWheelChanged.Subscribe(OnMouseWheel); } public void Dispose() { - UnsubscribeFromEvents(); + _onMousePressedDisposable?.Dispose(); + _onMouseReleasedDisposable?.Dispose(); + _onMouseWheelDisposable?.Dispose(); } - private void SubscribeToEvents() - { - // mouseListener.OnMouseMovedEventHandler += OnMouseMoved; - mouseListener.OnMousePressedEventHandler += OnMousePressed; - mouseListener.OnMouseReleasedEventHandler += OnMouseReleased; - mouseListener.OnMouseWheelEventHandler += OnMouseWheel; - } - - // private void OnMouseMoved(object? sender, NewMouseHookMoveEventArgs e) - // { - // _log.Information("{X}:{Y}", e.X, e.Y); - // } - - private void UnsubscribeFromEvents() - { - // mouseListener.OnMouseMovedEventHandler -= OnMouseMoved; - mouseListener.OnMousePressedEventHandler -= OnMousePressed; - mouseListener.OnMouseReleasedEventHandler -= OnMouseReleased; - mouseListener.OnMouseWheelEventHandler -= OnMouseWheel; - } - - private void OnMousePressed(object? sender, NewMouseHookEventArgs e) + private void OnMousePressed(NewMouseHookEventArgs e) { foreach (var p in profilesService.Profiles) { @@ -72,7 +60,7 @@ private void OnMousePressed(object? sender, NewMouseHookEventArgs e) } } - private void OnMouseReleased(object? sender, NewMouseHookEventArgs e) + private void OnMouseReleased(NewMouseHookEventArgs e) { foreach (var p in profilesService.Profiles) { @@ -162,5 +150,5 @@ MouseButtonState state } } - private void OnMouseWheel(object? sender, NewMouseWheelEventArgs e) { } + private void OnMouseWheel(NewMouseWheelEventArgs e) { } } diff --git a/YMouseButtonControl.Core/ViewModels/LayerViewModel/LayerViewModel.cs b/YMouseButtonControl.Core/ViewModels/LayerViewModel/LayerViewModel.cs index 1bbd020..bcbd897 100644 --- a/YMouseButtonControl.Core/ViewModels/LayerViewModel/LayerViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/LayerViewModel/LayerViewModel.cs @@ -24,12 +24,15 @@ namespace YMouseButtonControl.Core.ViewModels.LayerViewModel; public interface ILayerViewModel; -public class LayerViewModel : ViewModelBase, ILayerViewModel +public class LayerViewModel : ViewModelBase, ILayerViewModel, IDisposable { private IProfilesService _profilesService; private readonly IThemeService _themeService; private readonly ISettingsService _settingsService; private readonly IMouseListener _mouseListener; + private readonly IDisposable _onMousePressed; + private readonly IDisposable _onMouseReleased; + private readonly IDisposable _onMouseWheel; private int _mb1Index; private int _mb2Index; @@ -183,9 +186,10 @@ IShowSimulatedKeystrokesDialogService showSimulatedKeystrokesDialogService .DistinctUntilChanged() .Subscribe(OnSelectedCurrentProfileChanged); _mouseListener = mouseListener; - _mouseListener.OnMousePressedEventHandler += OnMouseClicked; - _mouseListener.OnMouseReleasedEventHandler += OnMouseReleased; - _mouseListener.OnMouseWheelEventHandler += OnWheelScroll; + _onMousePressed = _mouseListener.OnMousePressedChanged.Subscribe(OnMouseClicked); + _onMouseReleased = _mouseListener.OnMouseReleasedChanged.Subscribe(OnMouseReleased); + _onMouseWheel = _mouseListener.OnMouseWheelChanged.Subscribe(OnWheelScroll); + _wheelUpTimer.Elapsed += delegate { WheelUpBackgroundColor = themeService.CurBackground; @@ -862,7 +866,7 @@ private void OnSelectedCurrentProfileChanged(ProfileVm newProfile) MwrIndex = newProfile.MouseWheelRight.Index; } - private void OnWheelScroll(object? sender, NewMouseWheelEventArgs e) + private void OnWheelScroll(NewMouseWheelEventArgs e) { switch (e.Direction) { @@ -903,7 +907,7 @@ private void OnWheelScroll(object? sender, NewMouseWheelEventArgs e) } } - private void OnMouseReleased(object? sender, NewMouseHookEventArgs e) + private void OnMouseReleased(NewMouseHookEventArgs e) { switch (e.Button) { @@ -935,7 +939,7 @@ private void OnMouseReleased(object? sender, NewMouseHookEventArgs e) } } - private void OnMouseClicked(object? sender, NewMouseHookEventArgs e) + private void OnMouseClicked(NewMouseHookEventArgs e) { switch (e.Button) { @@ -1001,4 +1005,25 @@ private enum ButtonMappings SimulatedKeystrokes, RightClick, } + + public void Dispose() + { + _onMousePressed?.Dispose(); + _onMouseReleased.Dispose(); + _onMouseWheel.Dispose(); + _mouseListener.Dispose(); + _wheelUpTimer.Dispose(); + _wheelDownTimer.Dispose(); + _wheelLeftTimer.Dispose(); + _wheelRightTimer.Dispose(); + MouseButton1ComboSettingCommand.Dispose(); + MouseButton2ComboSettingCommand.Dispose(); + MouseButton3ComboSettingCommand.Dispose(); + MouseButton4ComboSettingCommand.Dispose(); + MouseButton5ComboSettingCommand.Dispose(); + MouseWheelUpComboSettingCommand.Dispose(); + MouseWheelDownComboSettingCommand.Dispose(); + MouseWheelLeftComboSettingCommand.Dispose(); + MouseWheelRightComboSettingCommand.Dispose(); + } } diff --git a/YMouseButtonControl.Core/ViewModels/LayerViewModel/SimulatedKeystrokesDialogViewModel.cs b/YMouseButtonControl.Core/ViewModels/LayerViewModel/SimulatedKeystrokesDialogViewModel.cs index 76e21e6..366ea4d 100644 --- a/YMouseButtonControl.Core/ViewModels/LayerViewModel/SimulatedKeystrokesDialogViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/LayerViewModel/SimulatedKeystrokesDialogViewModel.cs @@ -12,7 +12,7 @@ namespace YMouseButtonControl.Core.ViewModels.LayerViewModel; -public class SimulatedKeystrokesDialogViewModel : DialogBase +public class SimulatedKeystrokesDialogViewModel : DialogBase, IDisposable { private static readonly Dictionary CombinedKeyDict = ModifierKeys .Concat(StandardKeys) @@ -48,8 +48,8 @@ public SimulatedKeystrokesDialogViewModel( _title = $"SimulatedKeystrokes - {buttonName}"; _mouseListener = mouseListener; currentMapping ??= new SimulatedKeystrokeVm(); - _mouseListener.OnMouseMovedEventHandler += MouseListenerOnOnMouseMovedEventHandler; - _description = currentMapping?.PriorityDescription ?? string.Empty; + _mouseListener.OnMouseMovedChanged.Subscribe(MouseListenerOnOnMouseMovedEventHandler); + _description = currentMapping.PriorityDescription ?? string.Empty; _customKeys = currentMapping?.Keys ?? string.Empty; SimulatedKeystrokesType = currentMapping?.SimulatedKeystrokeType ?? new MouseButtonPressedActionTypeVm(); @@ -90,10 +90,7 @@ public SimulatedKeystrokesDialogViewModel( }); } - private void MouseListenerOnOnMouseMovedEventHandler( - object? sender, - NewMouseHookMoveEventArgs e - ) + private void MouseListenerOnOnMouseMovedEventHandler(NewMouseHookMoveEventArgs e) { X = e.X; Y = e.Y; @@ -332,4 +329,11 @@ public BaseButtonMappingVm? CurrentMapping private static IEnumerable GetSimulatedKeystrokesTypes() => SimulatedKeystrokeTypesList.Select(x => x()); + + public void Dispose() + { + _mouseListener.Dispose(); + OkCommand.Dispose(); + SplitButtonCommand.Dispose(); + } } diff --git a/YMouseButtonControl.Core/ViewModels/ProfilesList/ProcessSelectorDialogViewModel.cs b/YMouseButtonControl.Core/ViewModels/ProfilesList/ProcessSelectorDialogViewModel.cs index ada3047..61c30b6 100644 --- a/YMouseButtonControl.Core/ViewModels/ProfilesList/ProcessSelectorDialogViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/ProfilesList/ProcessSelectorDialogViewModel.cs @@ -40,9 +40,7 @@ IThemeService themeService var filteredDisposable = _sourceProcessModels .Connect() .Filter(dynamicFilter) - .RefCount() .Bind(out _filtered) - .DisposeMany() .Subscribe(); RefreshProcessList(); RefreshButtonCommand = ReactiveCommand.Create(RefreshProcessList);