diff --git a/app/AsusMouseSettings.cs b/app/AsusMouseSettings.cs index e7a2d651..d3c3b069 100644 --- a/app/AsusMouseSettings.cs +++ b/app/AsusMouseSettings.cs @@ -51,8 +51,6 @@ namespace GHelper Shown += AsusMouseSettings_Shown; FormClosing += AsusMouseSettings_FormClosing; - mouse.Disconnect += Mouse_Disconnect; - mouse.BatteryUpdated += Mouse_BatteryUpdated; comboProfile.DropDownClosed += ComboProfile_DropDownClosed; sliderDPI.ValueChanged += SliderDPI_ValueChanged; @@ -83,19 +81,40 @@ namespace GHelper comboBoxAutoPowerOff.DropDownClosed += ComboBoxAutoPowerOff_DropDownClosed; InitMouseCapabilities(); - RefreshMouseData(); + Logger.WriteLine(mouse.GetDisplayName() + " (GUI): Initialized capabilities. Synchronizing mouse data"); + Task task = Task.Run((Action)RefreshMouseData); } private void AsusMouseSettings_FormClosing(object? sender, FormClosingEventArgs e) { mouse.BatteryUpdated -= Mouse_BatteryUpdated; mouse.Disconnect -= Mouse_Disconnect; + mouse.MouseReadyChanged -= Mouse_MouseReadyChanged; + } + + private void Mouse_MouseReadyChanged(object? sender, EventArgs e) + { + if (!mouse.IsDeviceReady) + { + this.Invoke(delegate + { + if (Disposing || IsDisposed) + { + return; + } + Close(); + }); + } } private void Mouse_BatteryUpdated(object? sender, EventArgs e) { this.Invoke(delegate { + if (Disposing || IsDisposed) + { + return; + } VisualizeBatteryState(); }); @@ -104,7 +123,7 @@ namespace GHelper private void ComboProfile_DropDownClosed(object? sender, EventArgs e) { mouse.SetProfile(comboProfile.SelectedIndex); - RefreshMouseData(); + Task task = Task.Run((Action)RefreshMouseData); } private void ComboBoxPollingRate_DropDownClosed(object? sender, EventArgs e) @@ -194,6 +213,11 @@ namespace GHelper private void ComboBoxLightingMode_DropDownClosed(object? sender, EventArgs e) { + if (!mouse.HasRGB()) + { + return; + } + LightingMode lm = supportedLightingModes[comboBoxLightingMode.SelectedIndex]; LightingSetting? ls = mouse.LightingSetting; @@ -308,6 +332,10 @@ namespace GHelper //Mouse disconnected. Bye bye. this.Invoke(delegate { + if (Disposing || IsDisposed) + { + return; + } this.Close(); }); @@ -316,8 +344,11 @@ namespace GHelper private void RefreshMouseData() { mouse.SynchronizeDevice(); + + Logger.WriteLine(mouse.GetDisplayName() + " (GUI): Mouse data synchronized"); if (!mouse.IsDeviceReady) { + Logger.WriteLine(mouse.GetDisplayName() + " (GUI): Mouse is not ready. Closing view."); this.Invoke(delegate { this.Close(); @@ -325,9 +356,11 @@ namespace GHelper return; } - - VisualizeMouseSettings(); - VisualizeBatteryState(); + this.Invoke(delegate + { + VisualizeMouseSettings(); + VisualizeBatteryState(); + }); } private void InitMouseCapabilities() @@ -586,20 +619,24 @@ namespace GHelper private void VisualizeDPIButtons() { - if (mouse.HasDPIColors()) + for (int i = 0; i < mouse.DPIProfileCount() && i < 4; ++i) { - for (int i = 0; i < mouse.DPIProfileCount() && i < 4; ++i) + AsusMouseDPI dpi = mouse.DpiSettings[i]; + if (dpi is null) { - AsusMouseDPI dpi = mouse.DpiSettings[i]; - dpiButtons[i].Image = ControlHelper.TintImage(Properties.Resources.lighting_dot_24, dpi.Color); - dpiButtons[i].Activated = (mouse.DpiProfile - 1) == i; - dpiButtons[i].BorderColor = dpi.Color; - dpiButtons[i].Text = "DPI " + (i + 1) + "\n" + dpi.DPI; + continue; } + if (mouse.HasDPIColors()) + { + dpiButtons[i].Image = ControlHelper.TintImage(Properties.Resources.lighting_dot_24, dpi.Color); + dpiButtons[i].BorderColor = dpi.Color; + } + dpiButtons[i].Activated = (mouse.DpiProfile - 1) == i; + dpiButtons[i].Text = "DPI " + (i + 1) + "\n" + dpi.DPI; } - } + private void VisualizeCurrentDPIProfile() { AsusMouseDPI dpi = mouse.DpiSettings[mouse.DpiProfile - 1]; @@ -620,11 +657,16 @@ namespace GHelper } Left = Program.settingsForm.Left - Width - 5; + + + mouse.Disconnect += Mouse_Disconnect; + mouse.BatteryUpdated += Mouse_BatteryUpdated; + mouse.MouseReadyChanged += Mouse_MouseReadyChanged; } private void ButtonSync_Click(object sender, EventArgs e) { - RefreshMouseData(); + Task task = Task.Run((Action)RefreshMouseData); } } } diff --git a/app/Peripherals/Mouse/AsusMouse.cs b/app/Peripherals/Mouse/AsusMouse.cs index 59d92223..35cf9134 100644 --- a/app/Peripherals/Mouse/AsusMouse.cs +++ b/app/Peripherals/Mouse/AsusMouse.cs @@ -102,15 +102,32 @@ namespace GHelper.Peripherals.Mouse public abstract class AsusMouse : Device, IPeripheral { private static string[] POLLING_RATES = { "125 Hz", "250 Hz", "500 Hz", "1000 Hz", "2000 Hz", "4000 Hz", "8000 Hz", "16000 Hz" }; - + internal const bool PACKET_LOGGER_ALWAYS_ON = false; internal const int ASUS_MOUSE_PACKET_SIZE = 65; public event EventHandler? Disconnect; public event EventHandler? BatteryUpdated; + public event EventHandler? MouseReadyChanged; private readonly string path; public bool IsDeviceReady { get; protected set; } + + private void SetDeviceReady(bool ready) + { + bool notify = false; + if (IsDeviceReady != ready) + { + notify = true; + } + IsDeviceReady = ready; + + + if (MouseReadyChanged is not null && notify) + { + MouseReadyChanged(this, EventArgs.Empty); + } + } public bool Wireless { get; protected set; } public int Battery { get; protected set; } public bool Charging { get; protected set; } @@ -161,6 +178,7 @@ namespace GHelper.Peripherals.Mouse public override void Dispose() { + Logger.WriteLine(GetDisplayName() + ": Disposing"); HidSharp.DeviceList.Local.Changed -= Device_Changed; base.Dispose(); } @@ -200,6 +218,7 @@ namespace GHelper.Peripherals.Mouse protected virtual void OnDisconnect() { + Logger.WriteLine(GetDisplayName() + ": OnDisconnect()"); if (Disconnect is not null) { Disconnect(this, EventArgs.Empty); @@ -212,7 +231,7 @@ namespace GHelper.Peripherals.Mouse return true; #else - return AppConfig.Get("usb_packet_logger") == 1; + return AppConfig.Get("usb_packet_logger") == 1 || PACKET_LOGGER_ALWAYS_ON; #endif } @@ -269,10 +288,10 @@ namespace GHelper.Peripherals.Mouse { //Likely only the dongle connected and the mouse is either sleeping or turned off. //The mouse will not respond with proper data, but empty responses at this point - IsDeviceReady = false; + SetDeviceReady(false); return; } - IsDeviceReady = true; + SetDeviceReady(true); ReadProfile(); ReadDPI(); @@ -378,7 +397,13 @@ namespace GHelper.Peripherals.Mouse Charging = ParseChargingState(response); //If the device goes to standby it will not report battery state anymore. - IsDeviceReady = Battery > 0; + SetDeviceReady(Battery > 0); + + if (!IsDeviceReady) + { + Logger.WriteLine(GetDisplayName() + ": Device gone"); + return; + } Logger.WriteLine(GetDisplayName() + ": Got Battery Percentage " + Battery + "% - Charging:" + Charging); @@ -400,7 +425,9 @@ namespace GHelper.Peripherals.Mouse if (HasLowBatteryWarning() || HasAutoPowerOff()) { - Logger.WriteLine(GetDisplayName() + ": Got Auto Power Off: " + PowerOffSetting + " - Low Battery Warnning at: " + LowBatteryWarning + "%"); + string pos = HasAutoPowerOff() ? PowerOffSetting.ToString() : "Not Supported"; + string lbw = HasLowBatteryWarning() ? LowBatteryWarning.ToString() : "Not Supported"; + Logger.WriteLine(GetDisplayName() + ": Got Auto Power Off: " + pos + " - Low Battery Warnning at: " + lbw + "%"); } } @@ -683,6 +710,11 @@ namespace GHelper.Peripherals.Mouse } protected virtual byte[] GetChangeDPIProfilePacket(int profile) + { + return new byte[] { 0x00, 0x51, 0x31, 0x0A, 0x00, (byte)profile }; + } + + protected virtual byte[] GetChangeDPIProfilePacket2(int profile) { return new byte[] { 0x00, 0x51, 0x31, 0x09, 0x00, (byte)profile }; } @@ -703,6 +735,8 @@ namespace GHelper.Peripherals.Mouse //The first DPI profile is 1 WriteForResponse(GetChangeDPIProfilePacket(profile)); + //For whatever reason that is required or the mouse will not store the change and reverts once you power it off. + WriteForResponse(GetChangeDPIProfilePacket2(profile)); FlushSettings(); Logger.WriteLine(GetDisplayName() + ": DPI Profile set to " + profile); diff --git a/app/Settings.cs b/app/Settings.cs index 13227154..31ec67c7 100644 --- a/app/Settings.cs +++ b/app/Settings.cs @@ -1093,13 +1093,11 @@ namespace GHelper { b.Text = m.GetDisplayName() + "\n" + m.Battery + "%" + (m.Charging ? "(" + Properties.Strings.Charging + ")" : ""); - b.Enabled = true; } else { //Mouse is either not connected or in standby b.Text = m.GetDisplayName() + "\n(" + Properties.Strings.NotConnected + ")"; - b.Enabled = false; } switch (m.DeviceType()) @@ -1141,7 +1139,7 @@ namespace GHelper if (iph.DeviceType() == PeripheralType.Mouse) { AsusMouse? am = iph as AsusMouse; - if (am is null) + if (am is null || !am.IsDeviceReady) { //Should not happen if all device classes are implemented correctly. But better safe than sorry. return;