Skip to content

Commit

Permalink
add creation of SDR color profile, add NVIDIA HDR10+ support, fix Min…
Browse files Browse the repository at this point in the history
…TML/MaxTML, add LG TPC/GSR actions, add LG/Samsung trigger events
  • Loading branch information
Maassoft committed Feb 11, 2024
1 parent c958e6c commit b1120c8
Show file tree
Hide file tree
Showing 39 changed files with 1,308 additions and 334 deletions.
4 changes: 2 additions & 2 deletions ColorControl/ColorControl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
<PublisherName>Maassoft</PublisherName>
<Company>Maassoft</Company>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>9.8.0.1</ApplicationVersion>
<Version>9.8.0.1</Version>
<ApplicationVersion>9.8.1.0</ApplicationVersion>
<Version>9.8.1.0</Version>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>false</BootstrapperEnabled>
Expand Down
14 changes: 11 additions & 3 deletions ColorControl/MainForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 32 additions & 13 deletions ColorControl/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,14 @@ public MainForm(AppContextProvider appContextProvider, PowerEventDispatcher powe

_initialized = true;

AfterInitialized();
Task.Run(AfterInitialized);

if (_config.UseDarkMode)
{
SetTheme(_config.UseDarkMode);
}
}

private void MainForm_Load(object sender, EventArgs e)
{
}

private void LoadModules()
{
_modules.Add("NVIDIA controller", InitNvService);
Expand Down Expand Up @@ -236,6 +232,8 @@ private void InitModules()
}

tcMain.SelectedIndex = 0;

_serviceManager.NvService?.InstallEventHandlers();
}

private void UpdateServiceInfo()
Expand Down Expand Up @@ -352,7 +350,7 @@ private UserControl InitLgService()
{
_serviceManager.LgService = _serviceProvider.GetRequiredService<LgService>();

_lgPanel = new LgPanel(_serviceManager.LgService, _serviceManager.NvService, _serviceManager.AmdService, _trayIcon, Handle);
_lgPanel = new LgPanel(_serviceManager.LgService, _serviceManager.NvService, _serviceManager.AmdService, _trayIcon, Handle, _powerEventDispatcher);
_lgPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;

_lgPanel.Init();
Expand All @@ -378,7 +376,7 @@ private UserControl InitSamsungService()

//_serviceManager.SamsungService.Init();

_samsungPanel = new SamsungPanel(_serviceManager.SamsungService, _serviceManager.NvService, _serviceManager.AmdService, Handle);
_samsungPanel = new SamsungPanel(_serviceManager.SamsungService, _serviceManager.NvService, _serviceManager.AmdService, Handle, _powerEventDispatcher);
_samsungPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;

_samsungPanel.Init();
Expand Down Expand Up @@ -958,13 +956,21 @@ private void MainForm_Activated(object sender, EventArgs e)
}
}

private void AfterInitialized()
private async Task AfterInitialized()
{
_nvPanel?.AfterInitialized();
_amdPanel?.AfterInitialized();
await _powerEventDispatcher.SendEventAsync(PowerEventDispatcher.Event_Startup);

if (_nvPanel != null)
{
await _nvPanel.AfterInitialized();
}
if (_amdPanel != null)
{
await _amdPanel.AfterInitialized();
}
if (_trayIcon.Visible)
{
var _ = CheckForUpdates();
await CheckForUpdates();
}
}

Expand Down Expand Up @@ -1289,7 +1295,7 @@ private async void MainForm_Click(object sender, EventArgs e)
//InstallUpdate("");
//await Test();

//_serviceManager.NvService.TestResolution();
_serviceManager.NvService?.TestResolution();
}

private async Task Test()
Expand Down Expand Up @@ -1395,8 +1401,15 @@ private void btnOptionsAdvanced_Click(object sender, EventArgs e)
SubLabel = "This enables shortcuts to work during applications/games that block certain keys (like WinKey or Control). NOTE: if the application in the foreground runs with higher privileges than ColorControl, Raw Input does not work and normal hot keys are used",
Value = _config.UseRawInput
};
var setMinTmlAndMaxTmlField = new FieldDefinition
{
FieldType = FieldType.CheckBox,
Label = "Set MinTML and MaxTML when applying color profiles",
SubLabel = "When this is enabled MinTML and MaxTML will be automatically be set to respectively the minimum luminance and the maximum luminance of the color profile",
Value = _config.SetMinTmlAndMaxTml
};

var values = MessageForms.ShowDialog("Advanced settings", new[] { processPollingIntervalField, useRawInputField });
var values = MessageForms.ShowDialog("Advanced settings", new[] { processPollingIntervalField, useRawInputField, setMinTmlAndMaxTmlField });

if (values?.Any() != true)
{
Expand All @@ -1405,6 +1418,7 @@ private void btnOptionsAdvanced_Click(object sender, EventArgs e)

_config.ProcessMonitorPollingInterval = processPollingIntervalField.ValueAsInt;
_config.UseRawInput = useRawInputField.ValueAsBool;
_config.SetMinTmlAndMaxTml = setMinTmlAndMaxTmlField.ValueAsBool;

KeyboardShortcutManager.SetUseRawInput(_config.UseRawInput);
}
Expand Down Expand Up @@ -1441,5 +1455,10 @@ private void btnOptionsColorProfiles_Click(object sender, EventArgs e)
{
mnuColorProfiles.ShowCustom(btnOptionsColorProfiles);
}

private void miCreateSDRColorProfile_Click(object sender, EventArgs e)
{
ColorProfileWindow.CreateAndShow(isHDR: false);
}
}
}
1 change: 1 addition & 0 deletions ColorControl/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ private static async Task RunService(string[] args)
.ConfigureServices(services =>
{
services.RegisterSharedServices();
services.AddSingleton<PowerEventDispatcher>();
services.AddHostedService<ColorControlBackgroundService>();
})
.Build();
Expand Down
4 changes: 2 additions & 2 deletions ColorControl/Services/AMD/AmdPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ private void AddOrUpdateItemAmd(AmdPreset preset = null)
ServiceFormUtils.AddOrUpdateListItem(lvAmdPresets, _amdService.GetPresets(), _config, preset);
}

public void AfterInitialized()
public async Task AfterInitialized()
{
var _ = ApplyAmdPresetOnStartup();
await ApplyAmdPresetOnStartup();
}

private async Task ApplyAmdPresetOnStartup(int attempts = 5)
Expand Down
28 changes: 23 additions & 5 deletions ColorControl/Services/Common/PresetBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ColorControl.Shared.Common;
using ColorControl.Services.EventDispatcher;
using ColorControl.Shared.Common;
using ColorControl.Shared.Contracts;
using NStandard;
using System;
Expand Down Expand Up @@ -68,10 +69,10 @@ public bool TriggerActive(PresetTriggerContext context)
var active = Conditions == PresetConditionType.None ||
(Conditions.HasFlag(PresetConditionType.SDR) ? !context.IsHDRActive : true) && (Conditions.HasFlag(PresetConditionType.HDR) ? context.IsHDRActive : true) &&
(Conditions.HasFlag(PresetConditionType.GsyncDisabled) ? !context.IsGsyncActive : true) && (Conditions.HasFlag(PresetConditionType.GsyncEnabled) ? context.IsGsyncActive : true);
var allProcesses = IncludedProcesses.Contains("*");

if (Trigger == PresetTriggerType.ProcessSwitch)
if (Trigger == PresetTriggerType.ProcessSwitch && context.Triggers.Contains(Trigger))
{
var allProcesses = IncludedProcesses.Contains("*");
active = active && (allProcesses || (context.ChangedProcesses?.Any() ?? false));

if (active)
Expand All @@ -88,6 +89,15 @@ public bool TriggerActive(PresetTriggerContext context)
active = included && !excluded && screenSizeCheck && notificationsDisabledCheck;
}
}
else if ((Trigger == PresetTriggerType.ScreensaverStart || Trigger == PresetTriggerType.ScreensaverStop) && context.Triggers.Contains(Trigger))
{
active = active && (Trigger == PresetTriggerType.ScreensaverStart && context.ScreenSaverTransitionState == ScreenSaverTransitionState.Started ||
Trigger == PresetTriggerType.ScreensaverStop && context.ScreenSaverTransitionState == ScreenSaverTransitionState.Stopped);
}
else
{
active = context.Triggers.Contains(Trigger);
}

return active;
}
Expand All @@ -99,7 +109,13 @@ public override string ToString()
return string.Empty;
}

return $"On {Trigger.GetDescription()} of {DisplayProcesses(IncludedProcesses)}{(ExcludedProcesses.Any() ? ", excluding " + DisplayProcesses(ExcludedProcesses) : string.Empty)}{(Conditions > 0 ? ", only in " + string.Join(", ", Utils.GetDescriptions<PresetConditionType>((int)Conditions)) : string.Empty)}";
var text = $"On {Trigger.GetDescription()}";

if (Trigger == PresetTriggerType.ProcessSwitch)
{
text += $"of {DisplayProcesses(IncludedProcesses)}{(ExcludedProcesses.Any() ? ", excluding " + DisplayProcesses(ExcludedProcesses) : string.Empty)}";
}
return text += $"{(Conditions > 0 ? ", only in " + string.Join(", ", Utils.GetDescriptions<PresetConditionType>((int)Conditions)) : string.Empty)}";
}

public static string DisplayProcesses(IEnumerable<string> processes)
Expand All @@ -110,12 +126,14 @@ public static string DisplayProcesses(IEnumerable<string> processes)

class PresetTriggerContext
{
public IEnumerable<PresetTriggerType> Triggers { get; set; } = new[] { PresetTriggerType.ProcessSwitch };
public bool IsHDRActive { get; set; }
public bool IsGsyncActive { get; set; }
public Process ForegroundProcess { get; set; }
public bool ForegroundProcessIsFullScreen { get; set; }
public List<Process> ChangedProcesses { get; set; }
public bool IsNotificationDisabled { get; set; }
public ScreenSaverTransitionState ScreenSaverTransitionState { get; set; }
}

internal abstract class PresetBase
Expand Down Expand Up @@ -177,7 +195,7 @@ public virtual string GetTextForMenuItem()
return name;
}

public void UpdateTrigger(PresetTriggerType triggerType, PresetConditionType conditions, string includedProcesses, string excludedProcesses)
public void UpdateTrigger(PresetTriggerType triggerType, PresetConditionType conditions, string includedProcesses = null, string excludedProcesses = null)
{
if (!Triggers.Any())
{
Expand Down
59 changes: 58 additions & 1 deletion ColorControl/Services/Common/ServiceBase.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using ColorControl.Shared.Services;
using ColorControl.Services.EventDispatcher;
using ColorControl.Shared.Native;
using ColorControl.Shared.Services;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
Expand All @@ -27,6 +30,7 @@ public abstract string ServiceName
protected List<T> _presets;
protected T _lastAppliedPreset;
protected string _loadPresetsError;
protected T _lastTriggeredPreset;

protected AppContextProvider _appContextProvider;

Expand Down Expand Up @@ -176,5 +180,58 @@ public void ToggleQuickAccessForm()
QuickAccessForm<T>.ToggleQuickAccessForm(this);
}

protected async Task<PresetTriggerContext> CreateTriggerContext(ServiceManager serviceManager, ProcessChangedEventArgs context = null, bool? isHDRActive = null, IList<PresetTriggerType> triggerTypes = null)
{
triggerTypes ??= new[] { PresetTriggerType.ProcessSwitch };

var changedProcesses = new List<Process>();
if (context?.ForegroundProcess != null)
{
changedProcesses.Add(context.ForegroundProcess);
}

var isGsyncActive = await serviceManager.HandleExternalServiceAsync("GsyncEnabled", new[] { "" });

var triggerContext = new PresetTriggerContext
{
Triggers = triggerTypes,
IsHDRActive = isHDRActive ?? CCD.IsHDREnabled(),
IsGsyncActive = isGsyncActive,
ForegroundProcess = context?.ForegroundProcess,
ForegroundProcessIsFullScreen = context?.ForegroundProcessIsFullScreen ?? false,
IsNotificationDisabled = context?.IsNotificationDisabled ?? false,
ChangedProcesses = changedProcesses,
ScreenSaverTransitionState = context?.ScreenSaverTransitionState ?? ScreenSaverTransitionState.None
};

return triggerContext;
}

protected async Task ExecuteScreenSaverPresets(ServiceManager serviceManager, ProcessChangedEventArgs context, bool? isHDRActive = null)
{
await ExecuteEventPresets(serviceManager, new[] { PresetTriggerType.ScreensaverStart, PresetTriggerType.ScreensaverStop }, context, isHDRActive);
}

public async Task ExecuteEventPresets(ServiceManager serviceManager, IList<PresetTriggerType> triggerTypes, ProcessChangedEventArgs context = null, bool? isHDRActive = null)
{
var triggerContext = await CreateTriggerContext(serviceManager, context, isHDRActive, triggerTypes);

var triggerPresets = _presets.Where(p => p.Triggers.Any(t => t.TriggerActive(triggerContext))).ToList();

if (!triggerPresets.Any())
{
return;
}

Logger.Debug($"Executing event presets count: {triggerPresets.Count}");

foreach (var preset in triggerPresets)
{
Logger.Debug($"Executing event preset: {preset.name}");

await ApplyPreset(preset);
}
}

}
}
3 changes: 1 addition & 2 deletions ColorControl/Services/Common/ServiceFormUtils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using ColorControl.Services.Common;
using ColorControl.Shared.Contracts;
using ColorControl.Shared.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -101,7 +100,7 @@ public static void ListViewItemChecked<T>(ListView listView, ItemCheckedEventArg
{
menu.DropDownItems.Clear();

foreach (var nvPreset in service?.GetPresets() ?? new List<T>())
foreach (var nvPreset in service?.GetPresets()?.OrderBy(p => p.name).ToList() ?? new List<T>())
{
var text = nvPreset.name;

Expand Down
2 changes: 2 additions & 0 deletions ColorControl/Services/EventDispatcher/EventDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public async Task DispatchEventAsync(string eventName, T eventArgs)
{
await asyncEventHandlers[eventName]?.InvokeAsync(this, eventArgs);
}

DispatchEvent(eventName, eventArgs);
}

protected bool HasHandlers(string eventName)
Expand Down
Loading

0 comments on commit b1120c8

Please sign in to comment.