diff --git a/CommonHelpers/Dispatcher.cs b/CommonHelpers/Dispatcher.cs new file mode 100644 index 0000000..d264774 --- /dev/null +++ b/CommonHelpers/Dispatcher.cs @@ -0,0 +1,17 @@ +namespace CommonHelpers +{ + public static class Dispatcher + { + public static CancellationTokenSource RunWithDelay(int delayMs, Action action) + { + var cancellationTokenSource = new CancellationTokenSource(); + + Task.Delay(1000, cancellationTokenSource.Token).ContinueWith(_ => + { + System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(action); + }); + + return cancellationTokenSource; + } + } +} diff --git a/PowerControl/Menu/MenuItemWithOptions.cs b/PowerControl/Menu/MenuItemWithOptions.cs index 5928c34..bb2a55a 100644 --- a/PowerControl/Menu/MenuItemWithOptions.cs +++ b/PowerControl/Menu/MenuItemWithOptions.cs @@ -49,7 +49,7 @@ namespace PowerControl.Menu if (resetOption == null || resetOption == ActiveOption) return; - Set(resetOption, 0); + Set(resetOption, true, false); } public override void Update() @@ -81,7 +81,7 @@ namespace PowerControl.Menu ActiveOption = Options.First(); } - public void Set(String value, int overrideDelay = -1, bool refresh = true) + public void Set(String value, bool immediate, bool refresh) { if (delayTimer != null) delayTimer.Stop(); @@ -89,13 +89,13 @@ namespace PowerControl.Menu SelectedOption = value; runAfterApply = refresh; - if (ApplyDelay == 0 || overrideDelay == 0) + if (ApplyDelay == 0 || immediate) { FinalizeSet(); return; } - delayTimer.Interval = overrideDelay > 0 ? overrideDelay : ApplyDelay > 0 ? ApplyDelay : 1; + delayTimer.Interval = ApplyDelay > 0 ? ApplyDelay : 1; delayTimer.Enabled = true; } @@ -141,7 +141,7 @@ namespace PowerControl.Menu { var item = new ToolStripMenuItem(option); item.Checked = option == (SelectedOption ?? ActiveOption); - item.Click += delegate { Set(option, 0); }; + item.Click += delegate { Set(option, true, true); }; toolStripItem.DropDownItems.Add(item); } @@ -154,7 +154,7 @@ namespace PowerControl.Menu if (Options.Count == 0) return; - Set(Options[Math.Clamp(index, 0, Options.Count - 1)]); + Set(Options[Math.Clamp(index, 0, Options.Count - 1)], false, true); } public override void SelectNext(int change) diff --git a/PowerControl/ProfilesController.cs b/PowerControl/ProfilesController.cs index fb194c5..eefb751 100644 --- a/PowerControl/ProfilesController.cs +++ b/PowerControl/ProfilesController.cs @@ -14,6 +14,7 @@ namespace PowerControl private Dictionary watchedProcesses = new Dictionary(); private Dictionary? changedSettings; + private CancellationTokenSource? changeTask; private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer() { @@ -202,28 +203,32 @@ namespace PowerControl int delay = CurrentProfileSettings.GetInt("ApplyDelay", ApplyProfileDelayMs); - foreach (var menuItem in PersistableOptions()) + changeTask?.Cancel(); + changeTask = Dispatcher.RunWithDelay(delay, () => { - var persistedValue = CurrentProfileSettings.GetValue(menuItem.PersistentKey ?? ""); - if (persistedValue is null) - continue; - - try + foreach (var menuItem in PersistableOptions()) { - menuItem.Set(persistedValue, delay, false); + var persistedValue = CurrentProfileSettings.GetValue(menuItem.PersistentKey ?? ""); + if (persistedValue is null) + continue; - Log.TraceLine("ProfilesController: Applied from Profile: {0}: {1} = {2}", - CurrentProfileSettings.ProfileName, menuItem.PersistentKey, persistedValue); - } - catch (Exception e) - { - Log.TraceLine("ProfilesController: Exception Profile: {0}: {1} = {2} => {3}", - CurrentProfileSettings.ProfileName, menuItem.PersistentKey, persistedValue, e); + try + { + menuItem.Set(persistedValue, true, false); - CurrentProfileSettings.DeleteKey(menuItem.PersistentKey ?? ""); - menuItem.ProfileOption = null; + Log.TraceLine("ProfilesController: Applied from Profile: {0}: {1} = {2}", + CurrentProfileSettings.ProfileName, menuItem.PersistentKey, persistedValue); + } + catch (Exception e) + { + Log.TraceLine("ProfilesController: Exception Profile: {0}: {1} = {2} => {3}", + CurrentProfileSettings.ProfileName, menuItem.PersistentKey, persistedValue, e); + + CurrentProfileSettings.DeleteKey(menuItem.PersistentKey ?? ""); + menuItem.ProfileOption = null; + } } - } + }); } private void ResetProfile() @@ -238,24 +243,28 @@ namespace PowerControl var appliedSettings = changedSettings; changedSettings = null; - foreach (var menuItem in PersistableOptions()) + changeTask?.Cancel(); + changeTask = Dispatcher.RunWithDelay(ResetProfileDelayMs, () => { - if (!appliedSettings.TryGetValue(menuItem, out var setting)) - continue; - - try + foreach (var menuItem in PersistableOptions()) { - menuItem.Set(setting, ResetProfileDelayMs, true); + if (!appliedSettings.TryGetValue(menuItem, out var setting)) + continue; - Log.TraceLine("ProfilesController: Reset: {0} = {1}", - menuItem.PersistentKey, setting); + try + { + menuItem.Set(setting, true, true); + + Log.TraceLine("ProfilesController: Reset: {0} = {1}", + menuItem.PersistentKey, setting); + } + catch (Exception e) + { + Log.TraceLine("ProfilesController: Reset Exception: {0} = {1} => {2}", + menuItem.PersistentKey, setting, e); + } } - catch (Exception e) - { - Log.TraceLine("ProfilesController: Reset Exception: {0} = {1} => {2}", - menuItem.PersistentKey, setting, e); - } - } + }); } private IEnumerable PersistableOptions() diff --git a/RELEASE.md b/RELEASE.md index 687a34f..bc95bed 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -9,6 +9,7 @@ ## 0.6.x +- PowerControl: Apply profile changes with a delay in bulk - SteamController: Fix detection of the Steam client released around 2023-01-20, version: 1674182294 - All: Improve Anti-Cheat protection to allow to dismiss it - SteamController: Fix `STEAM+DPadUp` not working