mirror of
https://github.com/ayufan/steam-deck-tools.git
synced 2026-01-24 17:30:27 +01:00
PowerControl: Base Profiles Implementation (#38)
Small refactor of menu with options Fix protection error on menuwithoptions Make profiles controller non static Dynamicall set and load options Use IsOSDForeground when retriveing current game name Better alt-tab functionality Get rid off thread.sleep Merged #38
This commit is contained in:
parent
ef94d24cfc
commit
3252e799cb
|
|
@ -7,11 +7,18 @@ namespace CommonHelpers
|
|||
{
|
||||
public static bool IsOSDForeground()
|
||||
{
|
||||
return IsOSDForeground(out _);
|
||||
return IsOSDForeground(out _, out _);
|
||||
}
|
||||
|
||||
public static bool IsOSDForeground(out int processId)
|
||||
{
|
||||
return IsOSDForeground(out processId, out _);
|
||||
}
|
||||
|
||||
public static bool IsOSDForeground(out int processId, out string? applicationName)
|
||||
{
|
||||
applicationName = null;
|
||||
|
||||
try
|
||||
{
|
||||
var id = GetTopLevelProcessId();
|
||||
|
|
@ -22,7 +29,10 @@ namespace CommonHelpers
|
|||
foreach (var app in OSD.GetAppEntries(AppFlags.MASK))
|
||||
{
|
||||
if (app.ProcessId == processId)
|
||||
{
|
||||
applicationName = ExtractAppName(app.Name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -76,6 +86,13 @@ namespace CommonHelpers
|
|||
}
|
||||
}
|
||||
|
||||
public static List<string> GetCurrentApps()
|
||||
{
|
||||
var apps = OSD.GetAppEntries(AppFlags.MASK).Select(e => ExtractAppName(e.Name)).ToList();
|
||||
|
||||
return apps;
|
||||
}
|
||||
|
||||
public static uint EnableFlag(uint flag, bool status)
|
||||
{
|
||||
var current = SetFlags(~flag, status ? flag : 0);
|
||||
|
|
@ -125,6 +142,18 @@ namespace CommonHelpers
|
|||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetForegroundWindow();
|
||||
|
||||
private static string ExtractAppName(string fullName)
|
||||
{
|
||||
string res = fullName.Split('\\').Last();
|
||||
|
||||
if (res.ToLower().Contains(".exe"))
|
||||
{
|
||||
return res[..^4];
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private static uint? GetTopLevelProcessId()
|
||||
{
|
||||
var hWnd = GetForegroundWindow();
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ namespace PowerControl
|
|||
DateTime? neptuneDeviceNextKey;
|
||||
System.Windows.Forms.Timer neptuneTimer;
|
||||
|
||||
ProfilesController profilesController;
|
||||
|
||||
SharedData<PowerControlSetting> sharedData = SharedData<PowerControlSetting>.CreateNew();
|
||||
|
||||
static Controller()
|
||||
|
|
@ -110,6 +112,9 @@ namespace PowerControl
|
|||
osdTimer.Interval = 250;
|
||||
osdTimer.Enabled = true;
|
||||
|
||||
profilesController = new ProfilesController();
|
||||
profilesController.Initialize();
|
||||
|
||||
GlobalHotKey.RegisterHotKey(Settings.Default.MenuUpKey, () =>
|
||||
{
|
||||
if (!RTSS.IsOSDForeground())
|
||||
|
|
@ -409,6 +414,9 @@ namespace PowerControl
|
|||
System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(
|
||||
new Action(() =>
|
||||
{
|
||||
Options.RefreshRate.Instance?.Reset();
|
||||
Options.FPSLimit.Instance?.Reset();
|
||||
|
||||
rootMenu.Update();
|
||||
})
|
||||
);
|
||||
|
|
|
|||
53
PowerControl/Helpers/ProfileSettings.cs
Normal file
53
PowerControl/Helpers/ProfileSettings.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using CommonHelpers;
|
||||
|
||||
namespace PowerControl.Helper
|
||||
{
|
||||
public class ProfileSettings : BaseSettings
|
||||
{
|
||||
private static string profilesPath = Path.Combine(Directory.GetCurrentDirectory(), "Profiles");
|
||||
|
||||
static ProfileSettings()
|
||||
{
|
||||
Directory.CreateDirectory(profilesPath);
|
||||
}
|
||||
|
||||
public ProfileSettings(string profileName) : base("Profile")
|
||||
{
|
||||
this.TouchSettings = true;
|
||||
this.ConfigFile = Path.Combine(profilesPath, profileName + ".ini");
|
||||
|
||||
this.SettingChanging += delegate { };
|
||||
this.SettingChanged += delegate { };
|
||||
}
|
||||
|
||||
public T Get<T>(string key, T defaultValue)
|
||||
{
|
||||
return base.Get(key, defaultValue);
|
||||
}
|
||||
|
||||
public new bool Set<T>(string key, T value)
|
||||
{
|
||||
return base.Set(key, value);
|
||||
}
|
||||
|
||||
public static bool CheckIfExists(string profileName)
|
||||
{
|
||||
foreach (FileInfo fi in Directory.CreateDirectory(profilesPath).GetFiles())
|
||||
{
|
||||
if (fi.Name[^4..].Equals(".ini") && fi.Name[..^4].Equals(profileName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
137
PowerControl/Helpers/ProfilesController.cs
Normal file
137
PowerControl/Helpers/ProfilesController.cs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
using CommonHelpers;
|
||||
using PowerControl.Helper;
|
||||
using PowerControl.Menu;
|
||||
|
||||
namespace PowerControl.Helpers
|
||||
{
|
||||
public class ProfilesController
|
||||
{
|
||||
private const string IsTroubledKey = "IsTroubled";
|
||||
private const string DefaultName = "Default";
|
||||
|
||||
private string CurrentGame = string.Empty;
|
||||
private ProfileSettings DefaultSettings = new ProfileSettings(DefaultName);
|
||||
private ProfileSettings? CurrentSettings;
|
||||
private static string[] troubledGames = { "dragonageinquisition" };
|
||||
|
||||
private System.Windows.Forms.Timer? timer;
|
||||
|
||||
public ProfilesController()
|
||||
{
|
||||
timer = new System.Windows.Forms.Timer();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
MenuStack.Root.ValueChanged += OnOptionValueChange;
|
||||
|
||||
timer.Interval = 1000;
|
||||
timer.Tick += (_, _) =>
|
||||
{
|
||||
timer.Stop();
|
||||
|
||||
RefreshProfiles();
|
||||
|
||||
timer.Start();
|
||||
};
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
private void RefreshProfiles()
|
||||
{
|
||||
if (!DeviceManager.IsDeckOnlyDisplay())
|
||||
{
|
||||
CurrentGame = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
string? gameName;
|
||||
|
||||
RTSS.IsOSDForeground(out _, out gameName);
|
||||
|
||||
// If there's no foreground games keep current profile if possible
|
||||
if (gameName == null && RTSS.GetCurrentApps().Contains(CurrentGame))
|
||||
{
|
||||
gameName = CurrentGame;
|
||||
}
|
||||
|
||||
if (gameName == null && CurrentGame != DefaultName)
|
||||
{
|
||||
CurrentGame = DefaultName;
|
||||
CurrentSettings = null;
|
||||
|
||||
ApplyProfile();
|
||||
}
|
||||
|
||||
if (gameName != null && CurrentGame != gameName)
|
||||
{
|
||||
CurrentGame = gameName;
|
||||
CurrentSettings = ProfileSettings.CheckIfExists(CurrentGame) ?
|
||||
new ProfileSettings(CurrentGame) : null;
|
||||
|
||||
ApplyProfile();
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyProfile()
|
||||
{
|
||||
int delay = GetBoolValue(IsTroubledKey) ? 5200 : 0;
|
||||
var options = MenuStack.Root.Items.Where(o => o is MenuItemWithOptions).Select(o => (MenuItemWithOptions)o).ToList();
|
||||
|
||||
foreach (var option in options)
|
||||
{
|
||||
string? key = option.PersistentKey;
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
option.Set(GetValue(option), delay, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnOptionValueChange(MenuItemWithOptions options, string? oldValue, string newValue)
|
||||
{
|
||||
string? key = options.PersistentKey;
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
SetValue(key, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetBoolValue(string key, bool value)
|
||||
{
|
||||
var settings = CurrentSettings ?? DefaultSettings;
|
||||
|
||||
settings.Set(key, value);
|
||||
}
|
||||
|
||||
private bool GetBoolValue(string key)
|
||||
{
|
||||
var settings = CurrentSettings ?? DefaultSettings;
|
||||
|
||||
return settings.Get(key, false);
|
||||
}
|
||||
|
||||
private void SetValue(string key, string value)
|
||||
{
|
||||
var settings = CurrentSettings ?? DefaultSettings;
|
||||
settings.Set(key, value);
|
||||
}
|
||||
|
||||
private string GetValue(MenuItemWithOptions option)
|
||||
{
|
||||
if (CurrentSettings == null)
|
||||
{
|
||||
return GetDefaultValue(option);
|
||||
}
|
||||
|
||||
return CurrentSettings.Get(option.PersistentKey, GetDefaultValue(option));
|
||||
}
|
||||
|
||||
private string GetDefaultValue(MenuItemWithOptions option)
|
||||
{
|
||||
return DefaultSettings.Get(option.PersistentKey, option.ResetValue?.Invoke() ?? string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,10 +7,12 @@ namespace PowerControl.Menu
|
|||
public string? ActiveOption { get; set; }
|
||||
public int ApplyDelay { get; set; }
|
||||
public bool CycleOptions { get; set; } = true;
|
||||
public string? PersistentKey;
|
||||
|
||||
public Func<string?>? CurrentValue { get; set; }
|
||||
public Func<string[]?>? OptionsValues { get; set; }
|
||||
public Func<string, string?>? ApplyValue { get; set; }
|
||||
public Action? AfterApply { get; set; }
|
||||
public Func<string?>? ResetValue { get; set; }
|
||||
|
||||
public event Action<MenuItemWithOptions, String?, String> ValueChanged;
|
||||
|
|
@ -29,7 +31,7 @@ namespace PowerControl.Menu
|
|||
if (delayTimer != null)
|
||||
delayTimer.Stop();
|
||||
|
||||
FinalizeSet();
|
||||
FinalizeSet(delayTimer.Interval > ApplyDelay);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +44,7 @@ namespace PowerControl.Menu
|
|||
if (resetOption == null || resetOption == ActiveOption)
|
||||
return;
|
||||
|
||||
Set(resetOption, true);
|
||||
Set(resetOption, 0);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
|
|
@ -74,35 +76,40 @@ namespace PowerControl.Menu
|
|||
ActiveOption = Options.First();
|
||||
}
|
||||
|
||||
public void Set(String value, bool immediately = false)
|
||||
public void Set(String value, int overrideDelay = -1, bool silent = false)
|
||||
{
|
||||
if (delayTimer != null)
|
||||
delayTimer.Stop();
|
||||
|
||||
SelectedOption = value;
|
||||
|
||||
if (ApplyDelay == 0 || immediately)
|
||||
if (ApplyDelay == 0 || overrideDelay == 0)
|
||||
{
|
||||
FinalizeSet();
|
||||
FinalizeSet(silent);
|
||||
return;
|
||||
}
|
||||
|
||||
delayTimer.Interval = ApplyDelay > 0 ? ApplyDelay : 1;
|
||||
delayTimer.Interval = overrideDelay > 0 ? overrideDelay : ApplyDelay > 0 ? ApplyDelay : 1;
|
||||
delayTimer.Enabled = true;
|
||||
}
|
||||
|
||||
private void FinalizeSet()
|
||||
private void FinalizeSet(bool silent = false)
|
||||
{
|
||||
var wasOption = ActiveOption;
|
||||
|
||||
if (ApplyValue != null && SelectedOption != null)
|
||||
{
|
||||
ActiveOption = ApplyValue(SelectedOption);
|
||||
|
||||
if (AfterApply != null && !silent)
|
||||
AfterApply();
|
||||
}
|
||||
else
|
||||
ActiveOption = SelectedOption;
|
||||
|
||||
SelectedOption = null;
|
||||
|
||||
if (wasOption != ActiveOption && ActiveOption != null)
|
||||
if (wasOption != ActiveOption && ActiveOption != null && !silent)
|
||||
ValueChanged(this, wasOption, ActiveOption);
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +127,7 @@ namespace PowerControl.Menu
|
|||
{
|
||||
var item = new ToolStripMenuItem(option);
|
||||
item.Checked = option == (SelectedOption ?? ActiveOption);
|
||||
item.Click += delegate { Set(option, true); };
|
||||
item.Click += delegate { Set(option, 0); };
|
||||
toolStripItem.DropDownItems.Add(item);
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +140,7 @@ namespace PowerControl.Menu
|
|||
if (Options.Count == 0)
|
||||
return;
|
||||
|
||||
Set(Options[Math.Clamp(index, 0, Options.Count - 1)], false);
|
||||
Set(Options[Math.Clamp(index, 0, Options.Count - 1)]);
|
||||
}
|
||||
|
||||
public override void SelectNext(int change)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ namespace PowerControl.Options
|
|||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "FPS Limit",
|
||||
PersistentKey = "FPSLimit",
|
||||
ApplyDelay = 500,
|
||||
ResetValue = () => { return "Off"; },
|
||||
OptionsValues = delegate ()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ namespace PowerControl.Options
|
|||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Refresh Rate",
|
||||
PersistentKey = "RefreshRate",
|
||||
ApplyDelay = 1000,
|
||||
ResetValue = () => { return DisplayResolutionController.GetRefreshRates().Max().ToString(); },
|
||||
OptionsValues = delegate ()
|
||||
|
|
@ -24,10 +25,14 @@ namespace PowerControl.Options
|
|||
ApplyValue = (selected) =>
|
||||
{
|
||||
DisplayResolutionController.SetRefreshRate(int.Parse(selected));
|
||||
|
||||
return DisplayResolutionController.GetRefreshRate().ToString();
|
||||
},
|
||||
AfterApply = () =>
|
||||
{
|
||||
// force reset and refresh of FPS limit
|
||||
FPSLimit.Instance.Reset();
|
||||
FPSLimit.Instance.Update();
|
||||
return DisplayResolutionController.GetRefreshRate().ToString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue