mirror of
https://github.com/Maassoft/ColorControl.git
synced 2026-10-21 16:12:18 -05:00
fixed corrupt json file issues, retrieving apps and added HDMI port selection and new power setting
This commit is contained in:
1 parent
0de3deebf7
commit
66e682ba3d
8 files changed
+452
-268
No files matched your search
@@ -18,8 +18,8 @@
|
||||
<PublisherName>Maassoft</PublisherName>
|
||||
<Company>Maassoft</Company>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>5.6.0.0</ApplicationVersion>
|
||||
<Version>5.6.0.0</Version>
|
||||
<ApplicationVersion>5.7.0.0</ApplicationVersion>
|
||||
<Version>5.7.0.0</Version>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>false</BootstrapperEnabled>
|
||||
|
||||
+40
-13
@@ -53,7 +53,7 @@ namespace ColorControl
|
||||
public static Func<string, string[], bool> ExternalServiceHandler;
|
||||
public static List<string> DefaultActionsOnGameBar = new() { "backlight", "contrast", "brightness", "color" };
|
||||
|
||||
public string Name { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public string IpAddress { get; private set; }
|
||||
public string MacAddress { get; private set; }
|
||||
public bool IsCustom { get; private set; }
|
||||
@@ -66,7 +66,9 @@ namespace ColorControl
|
||||
public bool PowerOffOnStandby { get; set; }
|
||||
public bool PowerSwitchOnScreenSaver { get; set; }
|
||||
public bool PowerOnAfterManualPowerOff { get; set; }
|
||||
public bool PowerByWindows { get; set; }
|
||||
public bool TriggersEnabled { get; set; }
|
||||
public int HDMIPortNumber { get; set; }
|
||||
|
||||
private List<string> _actionsForGameBar;
|
||||
|
||||
@@ -113,6 +115,9 @@ namespace ColorControl
|
||||
[JsonIgnore]
|
||||
public LgDevicePictureSettings PictureSettings { get; private set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string CurrentAppId { get; private set; }
|
||||
|
||||
public event EventHandler PictureSettingsChangedEvent;
|
||||
public event EventHandler PowerStateChangedEvent;
|
||||
|
||||
@@ -284,6 +289,7 @@ namespace ColorControl
|
||||
//await _lgTvApi.SubscribeVolume(VolumeChanged);
|
||||
await _lgTvApi.SubscribePowerState(PowerStateChanged);
|
||||
await _lgTvApi.SubscribePictureSettings(PictureSettingsChanged);
|
||||
await _lgTvApi.SubscribeForegroundApp(ForegroundAppChanged);
|
||||
|
||||
//await _lgTvApi.Reboot();
|
||||
|
||||
@@ -323,7 +329,7 @@ namespace ColorControl
|
||||
{
|
||||
var settings = payload.settings;
|
||||
|
||||
Logger.Debug($"PictureSettingsChanged: {JsonConvert.SerializeObject(settings)}");
|
||||
Logger.Debug($"[{Name}] PictureSettingsChanged: {JsonConvert.SerializeObject(settings)}");
|
||||
|
||||
if (settings.backlight != null)
|
||||
{
|
||||
@@ -385,6 +391,18 @@ namespace ColorControl
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ForegroundAppChanged(dynamic payload)
|
||||
{
|
||||
Logger.Debug($"[{Name}] ForegroundAppChanged: {JsonConvert.SerializeObject(payload)}");
|
||||
|
||||
if (payload.appId != null)
|
||||
{
|
||||
CurrentAppId = payload.appId;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsConnected()
|
||||
{
|
||||
return !_lgTvApi?.ConnectionClosed ?? false;
|
||||
@@ -586,6 +604,11 @@ namespace ColorControl
|
||||
|
||||
public async Task<IEnumerable<LgApp>> GetApps(bool force = false)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
|
||||
if (!await Connected(force))
|
||||
{
|
||||
Logger.Debug("Cannot refresh apps: no connection could be made");
|
||||
@@ -595,17 +618,30 @@ namespace ColorControl
|
||||
return await _lgTvApi.GetApps(force);
|
||||
}
|
||||
|
||||
internal async Task<bool> PowerOff()
|
||||
internal async Task<bool> PowerOff(bool checkHdmi = false)
|
||||
{
|
||||
if (!await Connected(true) || CurrentState != PowerState.Active)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (checkHdmi && CurrentAppId != null && HDMIPortNumber != 0 && !CurrentAppId.EndsWith($".hdmi{HDMIPortNumber}", StringComparison.InvariantCulture))
|
||||
{
|
||||
Logger.Debug($"[{Name}] PowerOff is ignored because current app {CurrentAppId} does not match configured HDMI port {HDMIPortNumber}");
|
||||
return true;
|
||||
}
|
||||
|
||||
PoweredOffViaApp = true;
|
||||
_poweredOffViaAppDateTime = DateTimeOffset.Now;
|
||||
|
||||
await _lgTvApi.TurnOff();
|
||||
try
|
||||
{
|
||||
await _lgTvApi.TurnOff().WaitAsync(TimeSpan.FromSeconds(2));
|
||||
}
|
||||
catch (TimeoutException ex)
|
||||
{
|
||||
Logger.Debug($"Timeout when turning off tv: {ex.Message}");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -702,15 +738,6 @@ namespace ColorControl
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
var resumeScript = Path.Combine(Program.DataDir, "ResumeScript.bat");
|
||||
if (File.Exists(resumeScript))
|
||||
{
|
||||
Utils.StartProcess(resumeScript, hidden: true);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+223
-140
@@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
@@ -23,6 +24,13 @@ namespace ColorControl
|
||||
StandBy = 5
|
||||
}
|
||||
|
||||
internal enum WindowsPowerSetting
|
||||
{
|
||||
Off = 0,
|
||||
On = 1,
|
||||
Dimmed = 2
|
||||
}
|
||||
|
||||
internal class ProcessMonitorContext
|
||||
{
|
||||
public List<LgDevice> Devices { get; set; }
|
||||
@@ -66,6 +74,7 @@ namespace ColorControl
|
||||
private Task _monitorTask;
|
||||
private int _monitorTaskCounter;
|
||||
private LgPreset _lastTriggeredPreset;
|
||||
private RestartDetector _restartDetector;
|
||||
|
||||
public LgService(string dataPath, bool allowPowerOn) : base(dataPath, "LgPresets.json")
|
||||
{
|
||||
@@ -73,6 +82,8 @@ namespace ColorControl
|
||||
|
||||
LgPreset.LgApps = _lgApps;
|
||||
|
||||
_restartDetector = new RestartDetector();
|
||||
|
||||
LoadConfig();
|
||||
LoadPresets();
|
||||
LoadRemoteControlButtons();
|
||||
@@ -140,21 +151,25 @@ namespace ColorControl
|
||||
|
||||
presets = JsonConvert.DeserializeObject<List<LgPreset>>(json);
|
||||
}
|
||||
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
private void LoadConfig()
|
||||
{
|
||||
_configFilename = Path.Combine(_dataPath, "LgConfig.json");
|
||||
if (File.Exists(_configFilename))
|
||||
try
|
||||
{
|
||||
Config = JsonConvert.DeserializeObject<LgServiceConfig>(File.ReadAllText(_configFilename));
|
||||
if (File.Exists(_configFilename))
|
||||
{
|
||||
Config = JsonConvert.DeserializeObject<LgServiceConfig>(File.ReadAllText(_configFilename));
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
Config = new LgServiceConfig();
|
||||
Logger.Error($"LoadConfig: {ex.Message}");
|
||||
}
|
||||
Config ??= new LgServiceConfig();
|
||||
|
||||
LgPreset.LgDevices = Config.Devices;
|
||||
}
|
||||
@@ -289,7 +304,7 @@ namespace ColorControl
|
||||
|
||||
Devices.RemoveAll(d => !d.IsCustom && !autoIpAddresses.Contains(d.IpAddress));
|
||||
|
||||
var newAutoDevices = autoDevices.Where(ad => !Devices.Any(d => d.IpAddress.Equals(ad.IpAddress)));
|
||||
var newAutoDevices = autoDevices.Where(ad => ad.IpAddress != null && !Devices.Any(d => d.IpAddress != null && d.IpAddress.Equals(ad.IpAddress)));
|
||||
Devices.AddRange(newAutoDevices);
|
||||
|
||||
if (Devices.Any())
|
||||
@@ -404,22 +419,6 @@ namespace ColorControl
|
||||
return await SelectedDevice?.PowerOff();
|
||||
}
|
||||
|
||||
internal Task PowerOffOnShutdownOrResume(PowerOnOffState state = PowerOnOffState.ShutDown)
|
||||
{
|
||||
var devices = Devices.Where(d => state == PowerOnOffState.ShutDown && d.PowerOffOnShutdown ||
|
||||
state == PowerOnOffState.StandBy && d.PowerOffOnStandby);
|
||||
|
||||
var tasks = new List<Task>();
|
||||
foreach (var device in devices)
|
||||
{
|
||||
var task = device.PowerOff();
|
||||
|
||||
tasks.Add(task);
|
||||
}
|
||||
|
||||
return Task.WhenAll(tasks.ToArray());
|
||||
}
|
||||
|
||||
internal bool WakeSelectedDevice()
|
||||
{
|
||||
return SelectedDevice?.Wake() ?? false;
|
||||
@@ -427,26 +426,11 @@ namespace ColorControl
|
||||
|
||||
internal void WakeAfterStartupOrResume(PowerOnOffState state = PowerOnOffState.StartUp, bool checkUserSession = true)
|
||||
{
|
||||
if (checkUserSession && !UserSessionInfo.UserLocalSession)
|
||||
{
|
||||
Logger.Debug($"WakeAfterStartupOrResume: not waking because session info indicates no local session");
|
||||
return;
|
||||
}
|
||||
|
||||
var wakeDevices = Devices.Where(d => state == PowerOnOffState.StartUp && d.PowerOnAfterStartup ||
|
||||
state == PowerOnOffState.Resume && d.PowerOnAfterResume ||
|
||||
var wakeDevices = Devices.Where(d => state == PowerOnOffState.StartUp && d.PowerOnAfterStartup ||
|
||||
state == PowerOnOffState.Resume && d.PowerOnAfterResume ||
|
||||
state == PowerOnOffState.ScreenSaver && d.PowerSwitchOnScreenSaver);
|
||||
foreach (var device in wakeDevices)
|
||||
{
|
||||
if (!device.PowerOnAfterManualPowerOff && device.PoweredOffBy == LgDevice.PowerOffSource.Manually)
|
||||
{
|
||||
Logger.Debug($"[{device.Name}]: device was manually powered off by user, not powering on");
|
||||
continue;
|
||||
}
|
||||
|
||||
device.DisposeConnection();
|
||||
var _ = device.WakeAndConnectWithRetries(Config.PowerOnRetries);
|
||||
}
|
||||
PowerOnDevices(wakeDevices, state, checkUserSession);
|
||||
}
|
||||
|
||||
public void InstallEventHandlers()
|
||||
@@ -492,27 +476,8 @@ namespace ColorControl
|
||||
return;
|
||||
}
|
||||
|
||||
if (Devices.Any(d => d.PowerOffOnStandby))
|
||||
{
|
||||
NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS | NativeConstants.ES_SYSTEM_REQUIRED | NativeConstants.ES_AWAYMODE_REQUIRED);
|
||||
try
|
||||
{
|
||||
var standByScript = Path.Combine(Program.DataDir, "StandByScript.bat");
|
||||
if (File.Exists(standByScript))
|
||||
{
|
||||
Utils.StartProcess(standByScript, hidden: true);
|
||||
}
|
||||
|
||||
Logger.Debug("Powering off tv...");
|
||||
var task = PowerOffOnShutdownOrResume(PowerOnOffState.StandBy);
|
||||
Utils.WaitForTask(task);
|
||||
Logger.Debug("Done powering off tv");
|
||||
}
|
||||
finally
|
||||
{
|
||||
NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS);
|
||||
}
|
||||
}
|
||||
var devices = Devices.Where(d => d.PowerOffOnStandby);
|
||||
PowerOffDevices(devices, PowerOnOffState.StandBy);
|
||||
}
|
||||
|
||||
private void SessionEnded(object sender, SessionEndedEventArgs e)
|
||||
@@ -644,84 +609,15 @@ namespace ColorControl
|
||||
wasConnected = true;
|
||||
}
|
||||
|
||||
if (connectedDevices.Any(d => d.PowerSwitchOnScreenSaver))
|
||||
{
|
||||
lastProcessId = await HandleScreenSaverProcessAsync(lastProcessId, processes, connectedDevices);
|
||||
}
|
||||
|
||||
MonitorContext.Devices = connectedDevices.Where(d => d.TriggersEnabled).ToList();
|
||||
MonitorContext.RunningProcesses = processes;
|
||||
//if (lastProcesses != null)
|
||||
//{
|
||||
// monitorContext.StartedProcesses = processes.Where(p => !lastProcesses.Any(lp => lp.Id == p.Id)).ToArray();
|
||||
// monitorContext.StoppedProcesses = lastProcesses.Where(lp => !processes.Any(p => p.Id == lp.Id)).ToArray();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// monitorContext.StartedProcesses = null;
|
||||
// monitorContext.StoppedProcesses = null;
|
||||
//}
|
||||
|
||||
//if (monitorContext.StartedProcesses?.Any() ?? false)
|
||||
//{
|
||||
// Logger.Debug("Started processes: " + string.Join(", ", monitorContext.StartedProcesses.Select(p => p.ProcessName)));
|
||||
//}
|
||||
//lastProcesses = processes;
|
||||
|
||||
var process = processes.FirstOrDefault(p => p.ProcessName.ToLowerInvariant().EndsWith(".scr"));
|
||||
|
||||
if (process != null)
|
||||
{
|
||||
var parent = process.Parent(processes);
|
||||
|
||||
if (parent?.ProcessName.Contains("winlogon") ?? false)
|
||||
{
|
||||
Logger.Debug($"Screensaver started: {process.ProcessName}, parent: {parent.ProcessName}");
|
||||
try
|
||||
{
|
||||
foreach (var device in connectedDevices)
|
||||
{
|
||||
Logger.Debug($"Screensaver check: test connection with {device.Name}...");
|
||||
var test = await device.TestConnection();
|
||||
Logger.Debug("Screensaver check: test connection result: " + test);
|
||||
if (!test)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.Debug($"Screensaver check: powering off tv {device.Name} because of screensaver");
|
||||
try
|
||||
{
|
||||
_poweredOffByScreenSaver = await device.PowerOff().WaitAsync(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
catch (TimeoutException)
|
||||
{
|
||||
// Assume powering off was successful
|
||||
_poweredOffByScreenSaver = true;
|
||||
Logger.Error($"Screensaver check: timeout exception while powering off (probably connection closed)");
|
||||
}
|
||||
catch (Exception pex)
|
||||
{
|
||||
// Assume powering off was successful
|
||||
_poweredOffByScreenSaver = true;
|
||||
Logger.Error($"Screensaver check: exception while powering off (probably connection closed): " + pex.Message);
|
||||
}
|
||||
Logger.Debug($"Screensaver check: powered off tv {device.Name}");
|
||||
}
|
||||
|
||||
_poweredOffByScreenSaverProcessId = process.Id;
|
||||
lastProcessId = 0;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Screensaver check: can't power off: " + e.ToLogString());
|
||||
}
|
||||
}
|
||||
else if (process.Id != lastProcessId)
|
||||
{
|
||||
Logger.Debug($"Screensaver started: {process.ProcessName}, but invalid parent: {parent?.ProcessName ?? "no parent"}");
|
||||
lastProcessId = process.Id;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await ExecuteProcessPresets(MonitorContext);
|
||||
}
|
||||
await ExecuteProcessPresets(MonitorContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -730,12 +626,75 @@ namespace ColorControl
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<int> HandleScreenSaverProcessAsync(int lastProcessId, Process[] processes, List<LgDevice> connectedDevices)
|
||||
{
|
||||
var process = processes.FirstOrDefault(p => p.ProcessName.ToLowerInvariant().EndsWith(".scr"));
|
||||
|
||||
if (process == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var parent = process.Parent(processes);
|
||||
|
||||
if (parent?.ProcessName.Contains("winlogon") ?? false)
|
||||
{
|
||||
Logger.Debug($"Screensaver started: {process.ProcessName}, parent: {parent.ProcessName}");
|
||||
try
|
||||
{
|
||||
foreach (var device in connectedDevices)
|
||||
{
|
||||
Logger.Debug($"Screensaver check: test connection with {device.Name}...");
|
||||
var test = await device.TestConnection();
|
||||
Logger.Debug("Screensaver check: test connection result: " + test);
|
||||
if (!test)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.Debug($"Screensaver check: powering off tv {device.Name} because of screensaver");
|
||||
try
|
||||
{
|
||||
_poweredOffByScreenSaver = await device.PowerOff().WaitAsync(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
catch (TimeoutException)
|
||||
{
|
||||
// Assume powering off was successful
|
||||
_poweredOffByScreenSaver = true;
|
||||
Logger.Error($"Screensaver check: timeout exception while powering off (probably connection closed)");
|
||||
}
|
||||
catch (Exception pex)
|
||||
{
|
||||
// Assume powering off was successful
|
||||
_poweredOffByScreenSaver = true;
|
||||
Logger.Error($"Screensaver check: exception while powering off (probably connection closed): " + pex.Message);
|
||||
}
|
||||
Logger.Debug($"Screensaver check: powered off tv {device.Name}");
|
||||
}
|
||||
|
||||
_poweredOffByScreenSaverProcessId = process.Id;
|
||||
lastProcessId = 0;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Screensaver check: can't power off: " + e.ToLogString());
|
||||
}
|
||||
}
|
||||
else if (process.Id != lastProcessId)
|
||||
{
|
||||
Logger.Debug($"Screensaver started: {process.ProcessName}, but invalid parent: {parent?.ProcessName ?? "no parent"}");
|
||||
lastProcessId = process.Id;
|
||||
}
|
||||
|
||||
return lastProcessId;
|
||||
}
|
||||
|
||||
private async Task ExecuteProcessPresets(ProcessMonitorContext context)
|
||||
{
|
||||
var selectedDevice = SelectedDevice;
|
||||
|
||||
var presets = _presets.Where(p => p.Triggers.Any(t => t.Trigger == PresetTriggerType.ProcessSwitch) &&
|
||||
((string.IsNullOrEmpty(p.DeviceMacAddress) && selectedDevice?.TriggersEnabled == true)
|
||||
var presets = _presets.Where(p => p.Triggers.Any(t => t.Trigger == PresetTriggerType.ProcessSwitch) &&
|
||||
((string.IsNullOrEmpty(p.DeviceMacAddress) && selectedDevice?.TriggersEnabled == true)
|
||||
|| Devices.Any(d => d.TriggersEnabled && p.DeviceMacAddress.Equals(d.MacAddress, StringComparison.OrdinalIgnoreCase))));
|
||||
if (!presets.Any())
|
||||
{
|
||||
@@ -753,7 +712,14 @@ namespace ColorControl
|
||||
|
||||
if (processId > 0)
|
||||
{
|
||||
context.ForegroundProcess = context.RunningProcesses.FirstOrDefault(p => p.Id == processId);
|
||||
var process = context.RunningProcesses.FirstOrDefault(p => p.Id == processId);
|
||||
|
||||
if (process?.ProcessName?.Contains(".scr") ?? false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
context.ForegroundProcess = process;
|
||||
context.ForegroundProcessIsFullScreen = isFullScreen;
|
||||
}
|
||||
else
|
||||
@@ -851,5 +817,122 @@ namespace ColorControl
|
||||
SelectedDevice = Devices.Any() ? Devices.First() : null;
|
||||
}
|
||||
}
|
||||
|
||||
public void PowerSettingChanged(WindowsPowerSetting setting)
|
||||
{
|
||||
var devices = Devices.Where(d => d.PowerByWindows).ToList();
|
||||
|
||||
if (setting == WindowsPowerSetting.Off)
|
||||
{
|
||||
PowerOffDevices(devices, PowerOnOffState.StandBy);
|
||||
}
|
||||
else if (setting == WindowsPowerSetting.On)
|
||||
{
|
||||
PowerOnDevices(devices);
|
||||
}
|
||||
}
|
||||
|
||||
public void PowerOffDevices(IEnumerable<LgDevice> devices, PowerOnOffState state = PowerOnOffState.ShutDown)
|
||||
{
|
||||
if (!devices.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (NativeMethods.GetAsyncKeyState(NativeConstants.VK_CONTROL) < 0 || NativeMethods.GetAsyncKeyState(NativeConstants.VK_RCONTROL) < 0)
|
||||
{
|
||||
Logger.Debug("Not powering off because CONTROL-key is down");
|
||||
return;
|
||||
}
|
||||
|
||||
NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS | NativeConstants.ES_SYSTEM_REQUIRED | NativeConstants.ES_AWAYMODE_REQUIRED);
|
||||
try
|
||||
{
|
||||
if (state == PowerOnOffState.ShutDown)
|
||||
{
|
||||
var sleep = Config.ShutdownDelay;
|
||||
|
||||
Logger.Debug($"PowerOffDevices: Waiting for {sleep} milliseconds...");
|
||||
|
||||
while (sleep > 0 && _restartDetector?.PowerOffDetected == false)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
|
||||
if (_restartDetector != null && (_restartDetector.RestartDetected || _restartDetector.IsRebootInProgress()))
|
||||
{
|
||||
Logger.Debug("Not powering off because of a restart");
|
||||
return;
|
||||
}
|
||||
|
||||
sleep -= 100;
|
||||
}
|
||||
}
|
||||
else if (state == PowerOnOffState.StandBy)
|
||||
{
|
||||
var standByScript = Path.Combine(Program.DataDir, "StandByScript.bat");
|
||||
if (File.Exists(standByScript))
|
||||
{
|
||||
Utils.StartProcess(standByScript, hidden: true);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Debug("Powering off tv(s)...");
|
||||
var tasks = new List<Task>();
|
||||
foreach (var device in devices)
|
||||
{
|
||||
var task = device.PowerOff(true);
|
||||
|
||||
tasks.Add(task);
|
||||
}
|
||||
|
||||
var waitTask = Task.WhenAll(tasks.ToArray());
|
||||
Utils.WaitForTask(waitTask);
|
||||
Logger.Debug("Done powering off tv(s)");
|
||||
}
|
||||
finally
|
||||
{
|
||||
NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS);
|
||||
}
|
||||
}
|
||||
|
||||
public void PowerOnDevices(IEnumerable<LgDevice> devices, PowerOnOffState state = PowerOnOffState.StartUp, bool checkUserSession = true)
|
||||
{
|
||||
if (!devices.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkUserSession && !UserSessionInfo.UserLocalSession)
|
||||
{
|
||||
Logger.Debug($"WakeAfterStartupOrResume: not waking because session info indicates no local session");
|
||||
return;
|
||||
}
|
||||
|
||||
var resumeScript = Path.Combine(Program.DataDir, "ResumeScript.bat");
|
||||
|
||||
var tasks = new List<Task>();
|
||||
|
||||
foreach (var device in devices)
|
||||
{
|
||||
if (!device.PowerOnAfterManualPowerOff && device.PoweredOffBy == LgDevice.PowerOffSource.Manually)
|
||||
{
|
||||
Logger.Debug($"[{device.Name}]: device was manually powered off by user, not powering on");
|
||||
continue;
|
||||
}
|
||||
|
||||
device.DisposeConnection();
|
||||
|
||||
var task = device.WakeAndConnectWithRetries(Config.PowerOnRetries);
|
||||
tasks.Add(task);
|
||||
}
|
||||
|
||||
if (File.Exists(resumeScript))
|
||||
{
|
||||
var waitTask = Task.WhenAll(tasks.ToArray());
|
||||
Utils.WaitForTask(waitTask);
|
||||
|
||||
Utils.StartProcess(resumeScript, hidden: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+88
-54
@@ -104,9 +104,11 @@
|
||||
this.lvAmdPresets = new System.Windows.Forms.ListView();
|
||||
this.tabLG = new System.Windows.Forms.TabPage();
|
||||
this.scLgController = new System.Windows.Forms.SplitContainer();
|
||||
this.cbxLgPcHdmiPort = new System.Windows.Forms.ComboBox();
|
||||
this.lblLgPcHdmiPort = new System.Windows.Forms.Label();
|
||||
this.edtLgPresetDescription = new System.Windows.Forms.TextBox();
|
||||
this.lblLgPresetDescription = new System.Windows.Forms.Label();
|
||||
this.btnLgDeviceOptionsHelp = new System.Windows.Forms.Button();
|
||||
this.lblGameBarShortcut = new System.Windows.Forms.Label();
|
||||
this.edtLgGameBarShortcut = new System.Windows.Forms.TextBox();
|
||||
this.btnLgGameBar = new System.Windows.Forms.Button();
|
||||
this.btnLgPresetEditTriggerConditions = new System.Windows.Forms.Button();
|
||||
this.edtLgPresetTriggerConditions = new System.Windows.Forms.TextBox();
|
||||
@@ -172,6 +174,8 @@
|
||||
this.lblFixChromeFontsDescription = new System.Windows.Forms.Label();
|
||||
this.chkFixChromeFonts = new System.Windows.Forms.CheckBox();
|
||||
this.grpLGOptions = new System.Windows.Forms.GroupBox();
|
||||
this.lblGameBarShortcut = new System.Windows.Forms.Label();
|
||||
this.edtLgGameBarShortcut = new System.Windows.Forms.TextBox();
|
||||
this.lblLgOptionShutdownDelayHelp = new System.Windows.Forms.Label();
|
||||
this.edtLgOptionShutdownDelay = new System.Windows.Forms.NumericUpDown();
|
||||
this.lblLgOptionShutdownDelay = new System.Windows.Forms.Label();
|
||||
@@ -201,8 +205,6 @@
|
||||
this.lbPlugins = new System.Windows.Forms.ListBox();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.lblInfo = new System.Windows.Forms.Label();
|
||||
this.edtLgPresetDescription = new System.Windows.Forms.TextBox();
|
||||
this.lblLgPresetDescription = new System.Windows.Forms.Label();
|
||||
this.tcMain.SuspendLayout();
|
||||
this.tabNVIDIA.SuspendLayout();
|
||||
this.mnuNvPresets.SuspendLayout();
|
||||
@@ -988,11 +990,11 @@
|
||||
//
|
||||
// scLgController.Panel1
|
||||
//
|
||||
this.scLgController.Panel1.Controls.Add(this.cbxLgPcHdmiPort);
|
||||
this.scLgController.Panel1.Controls.Add(this.lblLgPcHdmiPort);
|
||||
this.scLgController.Panel1.Controls.Add(this.edtLgPresetDescription);
|
||||
this.scLgController.Panel1.Controls.Add(this.lblLgPresetDescription);
|
||||
this.scLgController.Panel1.Controls.Add(this.btnLgDeviceOptionsHelp);
|
||||
this.scLgController.Panel1.Controls.Add(this.lblGameBarShortcut);
|
||||
this.scLgController.Panel1.Controls.Add(this.edtLgGameBarShortcut);
|
||||
this.scLgController.Panel1.Controls.Add(this.btnLgGameBar);
|
||||
this.scLgController.Panel1.Controls.Add(this.btnLgPresetEditTriggerConditions);
|
||||
this.scLgController.Panel1.Controls.Add(this.edtLgPresetTriggerConditions);
|
||||
@@ -1040,6 +1042,56 @@
|
||||
this.scLgController.SplitterWidth = 5;
|
||||
this.scLgController.TabIndex = 43;
|
||||
//
|
||||
// cbxLgPcHdmiPort
|
||||
//
|
||||
this.cbxLgPcHdmiPort.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cbxLgPcHdmiPort.FormattingEnabled = true;
|
||||
this.cbxLgPcHdmiPort.Items.AddRange(new object[] {
|
||||
"None",
|
||||
"HDMI1",
|
||||
"HDMI2",
|
||||
"HDMI3",
|
||||
"HDMI4"});
|
||||
this.cbxLgPcHdmiPort.Location = new System.Drawing.Point(667, 42);
|
||||
this.cbxLgPcHdmiPort.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.cbxLgPcHdmiPort.Name = "cbxLgPcHdmiPort";
|
||||
this.cbxLgPcHdmiPort.Size = new System.Drawing.Size(86, 23);
|
||||
this.cbxLgPcHdmiPort.TabIndex = 62;
|
||||
this.cbxLgPcHdmiPort.SelectedIndexChanged += new System.EventHandler(this.cbxLgPcHdmiPort_SelectedIndexChanged);
|
||||
//
|
||||
// lblLgPcHdmiPort
|
||||
//
|
||||
this.lblLgPcHdmiPort.AutoSize = true;
|
||||
this.lblLgPcHdmiPort.Location = new System.Drawing.Point(577, 45);
|
||||
this.lblLgPcHdmiPort.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblLgPcHdmiPort.Name = "lblLgPcHdmiPort";
|
||||
this.lblLgPcHdmiPort.Size = new System.Drawing.Size(84, 15);
|
||||
this.lblLgPcHdmiPort.TabIndex = 61;
|
||||
this.lblLgPcHdmiPort.Text = "PC HDMI port:";
|
||||
//
|
||||
// edtLgPresetDescription
|
||||
//
|
||||
this.edtLgPresetDescription.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.edtLgPresetDescription.Enabled = false;
|
||||
this.edtLgPresetDescription.Location = new System.Drawing.Point(100, 469);
|
||||
this.edtLgPresetDescription.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.edtLgPresetDescription.Multiline = true;
|
||||
this.edtLgPresetDescription.Name = "edtLgPresetDescription";
|
||||
this.edtLgPresetDescription.Size = new System.Drawing.Size(694, 43);
|
||||
this.edtLgPresetDescription.TabIndex = 60;
|
||||
//
|
||||
// lblLgPresetDescription
|
||||
//
|
||||
this.lblLgPresetDescription.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.lblLgPresetDescription.AutoSize = true;
|
||||
this.lblLgPresetDescription.Location = new System.Drawing.Point(6, 474);
|
||||
this.lblLgPresetDescription.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblLgPresetDescription.Name = "lblLgPresetDescription";
|
||||
this.lblLgPresetDescription.Size = new System.Drawing.Size(70, 15);
|
||||
this.lblLgPresetDescription.TabIndex = 59;
|
||||
this.lblLgPresetDescription.Text = "Description:";
|
||||
//
|
||||
// btnLgDeviceOptionsHelp
|
||||
//
|
||||
this.btnLgDeviceOptionsHelp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
@@ -1052,28 +1104,6 @@
|
||||
this.btnLgDeviceOptionsHelp.UseVisualStyleBackColor = true;
|
||||
this.btnLgDeviceOptionsHelp.Click += new System.EventHandler(this.btnLgDeviceOptionsHelp_Click);
|
||||
//
|
||||
// lblGameBarShortcut
|
||||
//
|
||||
this.lblGameBarShortcut.AutoSize = true;
|
||||
this.lblGameBarShortcut.Location = new System.Drawing.Point(597, 45);
|
||||
this.lblGameBarShortcut.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblGameBarShortcut.Name = "lblGameBarShortcut";
|
||||
this.lblGameBarShortcut.Size = new System.Drawing.Size(55, 15);
|
||||
this.lblGameBarShortcut.TabIndex = 57;
|
||||
this.lblGameBarShortcut.Text = "Shortcut:";
|
||||
//
|
||||
// edtLgGameBarShortcut
|
||||
//
|
||||
this.edtLgGameBarShortcut.Location = new System.Drawing.Point(667, 42);
|
||||
this.edtLgGameBarShortcut.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.edtLgGameBarShortcut.Name = "edtLgGameBarShortcut";
|
||||
this.edtLgGameBarShortcut.ReadOnly = true;
|
||||
this.edtLgGameBarShortcut.Size = new System.Drawing.Size(128, 23);
|
||||
this.edtLgGameBarShortcut.TabIndex = 56;
|
||||
this.edtLgGameBarShortcut.TextChanged += new System.EventHandler(this.edtLgGameBarShortcut_TextChanged);
|
||||
this.edtLgGameBarShortcut.KeyDown += new System.Windows.Forms.KeyEventHandler(this.edtLgGameBarShortcut_KeyDown);
|
||||
this.edtLgGameBarShortcut.KeyUp += new System.Windows.Forms.KeyEventHandler(this.edtLgGameBarShortcut_KeyUp);
|
||||
//
|
||||
// btnLgGameBar
|
||||
//
|
||||
this.btnLgGameBar.Location = new System.Drawing.Point(478, 40);
|
||||
@@ -1606,7 +1636,8 @@
|
||||
"Automatically power off on standby",
|
||||
"Automatically power off/on when screensaver activates/deactivates",
|
||||
"Power on even after manual power off",
|
||||
"Allow triggers to be fired for this device"});
|
||||
"Allow triggers to be fired for this device",
|
||||
"Use Windows power settings"});
|
||||
this.clbLgPower.Location = new System.Drawing.Point(6, 70);
|
||||
this.clbLgPower.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.clbLgPower.MultiColumn = true;
|
||||
@@ -1805,6 +1836,8 @@
|
||||
//
|
||||
// grpLGOptions
|
||||
//
|
||||
this.grpLGOptions.Controls.Add(this.lblGameBarShortcut);
|
||||
this.grpLGOptions.Controls.Add(this.edtLgGameBarShortcut);
|
||||
this.grpLGOptions.Controls.Add(this.lblLgOptionShutdownDelayHelp);
|
||||
this.grpLGOptions.Controls.Add(this.edtLgOptionShutdownDelay);
|
||||
this.grpLGOptions.Controls.Add(this.lblLgOptionShutdownDelay);
|
||||
@@ -1822,6 +1855,28 @@
|
||||
this.grpLGOptions.TabStop = false;
|
||||
this.grpLGOptions.Text = "LG controller";
|
||||
//
|
||||
// lblGameBarShortcut
|
||||
//
|
||||
this.lblGameBarShortcut.AutoSize = true;
|
||||
this.lblGameBarShortcut.Location = new System.Drawing.Point(201, 127);
|
||||
this.lblGameBarShortcut.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblGameBarShortcut.Name = "lblGameBarShortcut";
|
||||
this.lblGameBarShortcut.Size = new System.Drawing.Size(108, 15);
|
||||
this.lblGameBarShortcut.TabIndex = 59;
|
||||
this.lblGameBarShortcut.Text = "Game Bar shortcut:";
|
||||
//
|
||||
// edtLgGameBarShortcut
|
||||
//
|
||||
this.edtLgGameBarShortcut.Location = new System.Drawing.Point(307, 121);
|
||||
this.edtLgGameBarShortcut.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.edtLgGameBarShortcut.Name = "edtLgGameBarShortcut";
|
||||
this.edtLgGameBarShortcut.ReadOnly = true;
|
||||
this.edtLgGameBarShortcut.Size = new System.Drawing.Size(128, 23);
|
||||
this.edtLgGameBarShortcut.TabIndex = 58;
|
||||
this.edtLgGameBarShortcut.TextChanged += new System.EventHandler(this.edtLgGameBarShortcut_TextChanged);
|
||||
this.edtLgGameBarShortcut.KeyDown += new System.Windows.Forms.KeyEventHandler(this.edtLgGameBarShortcut_KeyDown);
|
||||
this.edtLgGameBarShortcut.KeyUp += new System.Windows.Forms.KeyEventHandler(this.edtLgGameBarShortcut_KeyUp);
|
||||
//
|
||||
// lblLgOptionShutdownDelayHelp
|
||||
//
|
||||
this.lblLgOptionShutdownDelayHelp.AutoSize = true;
|
||||
@@ -2192,29 +2247,6 @@
|
||||
this.lblInfo.TabIndex = 1;
|
||||
this.lblInfo.Text = "Info";
|
||||
//
|
||||
// edtLgPresetDescription
|
||||
//
|
||||
this.edtLgPresetDescription.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.edtLgPresetDescription.Enabled = false;
|
||||
this.edtLgPresetDescription.Location = new System.Drawing.Point(100, 469);
|
||||
this.edtLgPresetDescription.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.edtLgPresetDescription.Multiline = true;
|
||||
this.edtLgPresetDescription.Name = "edtLgPresetDescription";
|
||||
this.edtLgPresetDescription.Size = new System.Drawing.Size(694, 43);
|
||||
this.edtLgPresetDescription.TabIndex = 60;
|
||||
//
|
||||
// lblLgPresetDescription
|
||||
//
|
||||
this.lblLgPresetDescription.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.lblLgPresetDescription.AutoSize = true;
|
||||
this.lblLgPresetDescription.Location = new System.Drawing.Point(6, 474);
|
||||
this.lblLgPresetDescription.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblLgPresetDescription.Name = "lblLgPresetDescription";
|
||||
this.lblLgPresetDescription.Size = new System.Drawing.Size(70, 15);
|
||||
this.lblLgPresetDescription.TabIndex = 59;
|
||||
this.lblLgPresetDescription.Text = "Description:";
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
@@ -2440,8 +2472,6 @@
|
||||
private System.Windows.Forms.CheckBox chkCheckForUpdates;
|
||||
private System.Windows.Forms.CheckBox chkLgShowAdvancedActions;
|
||||
private System.Windows.Forms.Button btnLgGameBar;
|
||||
private System.Windows.Forms.Label lblGameBarShortcut;
|
||||
private System.Windows.Forms.TextBox edtLgGameBarShortcut;
|
||||
private System.Windows.Forms.CheckBox chkGdiScaling;
|
||||
private System.Windows.Forms.Button btnLgDeviceOptionsHelp;
|
||||
private System.Windows.Forms.Label lblLgOptionShutdownDelayHelp;
|
||||
@@ -2449,6 +2479,10 @@
|
||||
private System.Windows.Forms.Label lblLgOptionShutdownDelay;
|
||||
private System.Windows.Forms.TextBox edtLgPresetDescription;
|
||||
private System.Windows.Forms.Label lblLgPresetDescription;
|
||||
private System.Windows.Forms.Label lblGameBarShortcut;
|
||||
private System.Windows.Forms.TextBox edtLgGameBarShortcut;
|
||||
private System.Windows.Forms.ComboBox cbxLgPcHdmiPort;
|
||||
private System.Windows.Forms.Label lblLgPcHdmiPort;
|
||||
}
|
||||
}
|
||||
|
||||
+67
-54
@@ -15,8 +15,8 @@ using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace ColorControl
|
||||
private bool _disableEvents = false;
|
||||
private Config _config;
|
||||
private bool _setVisibleCalled = false;
|
||||
private RestartDetector _restartDetector;
|
||||
|
||||
private LgService _lgService;
|
||||
|
||||
@@ -63,6 +62,7 @@ namespace ColorControl
|
||||
private LgGameBar _gameBarForm;
|
||||
|
||||
private KeyboardHookManager _keyboardHookManager;
|
||||
private IntPtr _screenStateNotify;
|
||||
|
||||
public MainForm(AppContext appContext)
|
||||
{
|
||||
@@ -121,8 +121,7 @@ namespace ColorControl
|
||||
InitInfo();
|
||||
|
||||
UserSessionInfo.Install();
|
||||
|
||||
_restartDetector = new RestartDetector();
|
||||
_screenStateNotify = Utils.RegisterPowerSettingNotification(Handle, ref Utils.GUID_CONSOLE_DISPLAY_STATE, 0);
|
||||
|
||||
//Scale(new SizeF(1.25F, 1.25F));
|
||||
|
||||
@@ -183,7 +182,7 @@ namespace ColorControl
|
||||
try
|
||||
{
|
||||
_lgService = new LgService(_dataDir, StartUpParams.RunningFromScheduledTask);
|
||||
_lgService.RefreshDevices(afterStartUp: true).ContinueWith((_) => BeginInvoke(new Action(AfterLgServiceRefreshDevices)));
|
||||
_lgService.RefreshDevices(afterStartUp: true).ContinueWith((_) => BeginInvoke(() => AfterLgServiceRefreshDevices()));
|
||||
|
||||
FillLgPresets();
|
||||
|
||||
@@ -232,7 +231,7 @@ namespace ColorControl
|
||||
|
||||
private void Invoke()
|
||||
{
|
||||
BeginInvoke(new Action(ToggleGameBar));
|
||||
BeginInvoke(() => ToggleGameBar());
|
||||
}
|
||||
|
||||
private void AfterLgServiceRefreshDevices()
|
||||
@@ -479,46 +478,13 @@ namespace ColorControl
|
||||
|
||||
GlobalSave();
|
||||
|
||||
if (SystemShutdown && _lgService.Devices.Any(d => d.PowerOffOnShutdown))
|
||||
if (SystemShutdown && _lgService != null)
|
||||
{
|
||||
Logger.Debug($"MainForm_FormClosing: SystemShutdown");
|
||||
|
||||
if (NativeMethods.GetAsyncKeyState(NativeConstants.VK_CONTROL) < 0 || NativeMethods.GetAsyncKeyState(NativeConstants.VK_RCONTROL) < 0)
|
||||
{
|
||||
Logger.Debug("Not powering off because CONTROL-key is down");
|
||||
return;
|
||||
}
|
||||
var devices = _lgService.Devices.Where(d => d.PowerOffOnShutdown);
|
||||
|
||||
var sleep = _lgService.Config.ShutdownDelay;
|
||||
|
||||
Logger.Debug($"MainForm_FormClosing: Waiting for {sleep} milliseconds...");
|
||||
|
||||
NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS | NativeConstants.ES_SYSTEM_REQUIRED | NativeConstants.ES_AWAYMODE_REQUIRED);
|
||||
try
|
||||
{
|
||||
while (sleep > 0 && _restartDetector?.PowerOffDetected == false)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
|
||||
if (_restartDetector != null && (_restartDetector.RestartDetected || _restartDetector.IsRebootInProgress()))
|
||||
{
|
||||
Logger.Debug("Not powering off because of a restart");
|
||||
return;
|
||||
}
|
||||
|
||||
sleep -= 100;
|
||||
}
|
||||
|
||||
Logger.Debug("Powering off tv...");
|
||||
var task = _lgService.PowerOffOnShutdownOrResume();
|
||||
Utils.WaitForTask(task);
|
||||
Logger.Debug("Done powering off tv");
|
||||
//ExecPowerOffPreset(true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS);
|
||||
}
|
||||
_lgService.PowerOffDevices(devices);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,6 +592,26 @@ namespace ColorControl
|
||||
Logger.Debug("WM_BRINGTOFRONT message received, opening form");
|
||||
OpenForm(this, EventArgs.Empty);
|
||||
}
|
||||
else if (m.Msg == NativeConstants.WM_SYSCOMMAND)
|
||||
{
|
||||
//Logger.Debug($"WM_SYSCOMMAND: {m.WParam.ToInt32()}");
|
||||
|
||||
if (m.WParam.ToInt32() == NativeConstants.SC_MONITORPOWER)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
else if (m.Msg == NativeConstants.WM_POWERBROADCAST)
|
||||
{
|
||||
if (m.WParam.ToInt32() == Utils.PBT_POWERSETTINGCHANGE)
|
||||
{
|
||||
var ps = Marshal.PtrToStructure<Utils.POWERBROADCAST_SETTING>(m.LParam);
|
||||
|
||||
Logger.Debug($"PBT_POWERSETTINGCHANGE: {ps.Data}");
|
||||
|
||||
_lgService?.PowerSettingChanged((LgService.WindowsPowerSetting)ps.Data);
|
||||
}
|
||||
}
|
||||
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
@@ -668,6 +654,12 @@ namespace ColorControl
|
||||
{
|
||||
// Hide tray icon, otherwise it will remain shown until user mouses over it
|
||||
_trayIcon.Visible = false;
|
||||
|
||||
if (_screenStateNotify != IntPtr.Zero)
|
||||
{
|
||||
Utils.UnregisterPowerSettingNotification(_screenStateNotify);
|
||||
_screenStateNotify = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private void MainForm_Resize(object sender, EventArgs e)
|
||||
@@ -781,7 +773,7 @@ namespace ColorControl
|
||||
if (_lgService == null)
|
||||
{
|
||||
ShowControls(tabLG, false, lblLgError);
|
||||
lblLgError.Text = "Error while initializing the LG-controller. You either don't have a LG TV or it is disabled.";
|
||||
lblLgError.Text = "Error while initializing the LG-controller. You either don't have a LG TV, it is disabled or a configuration file is corrupt.";
|
||||
lblLgError.Visible = true;
|
||||
}
|
||||
|
||||
@@ -1404,6 +1396,11 @@ namespace ColorControl
|
||||
|
||||
private void InitLgTab()
|
||||
{
|
||||
if (_lgService == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (scLgController.Panel2.Controls.Count == 0)
|
||||
{
|
||||
var rcPanel = new RemoteControlPanel(_lgService, _lgService.GetRemoteControlButtons());
|
||||
@@ -1501,7 +1498,7 @@ namespace ColorControl
|
||||
|
||||
if (cbxLgApps.Items.Count == 0 && device != null)
|
||||
{
|
||||
_lgService.RefreshApps().ContinueWith((task) => BeginInvoke(new Action(FillLgApps)));
|
||||
_lgService.RefreshApps().ContinueWith((task) => BeginInvoke(() => FillLgApps(false)));
|
||||
}
|
||||
|
||||
btnLgDeviceConvertToCustom.Enabled = devices.Any();
|
||||
@@ -1526,6 +1523,7 @@ namespace ColorControl
|
||||
clbLgPower.SetItemChecked(4, device?.PowerSwitchOnScreenSaver ?? false);
|
||||
clbLgPower.SetItemChecked(5, device?.PowerOnAfterManualPowerOff ?? false);
|
||||
clbLgPower.SetItemChecked(6, device?.TriggersEnabled ?? true);
|
||||
clbLgPower.SetItemChecked(7, device?.PowerByWindows ?? false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -1533,10 +1531,10 @@ namespace ColorControl
|
||||
}
|
||||
}
|
||||
|
||||
private void FillLgApps()
|
||||
private void FillLgApps(bool forced)
|
||||
{
|
||||
var lgApps = _lgService?.GetApps();
|
||||
if (lgApps == null || !lgApps.Any())
|
||||
if (forced && (lgApps == null || !lgApps.Any()))
|
||||
{
|
||||
MessageForms.WarningOk("Could not refresh the apps. Check the log for details.");
|
||||
return;
|
||||
@@ -1769,7 +1767,7 @@ namespace ColorControl
|
||||
return;
|
||||
}
|
||||
|
||||
var applyTask = _lgService.ApplyPreset(preset, reconnect).ContinueWith((task) => BeginInvoke(new Action<Task<bool>>(LgPresetApplied), new[] { task }));
|
||||
var applyTask = _lgService.ApplyPreset(preset, reconnect).ContinueWith((task) => BeginInvoke(() => LgPresetApplied(task)));
|
||||
if (wait)
|
||||
{
|
||||
Utils.WaitForTask(applyTask);
|
||||
@@ -1807,18 +1805,21 @@ namespace ColorControl
|
||||
|
||||
private void btnLgRefreshApps_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lgService.RefreshApps(true).ContinueWith((task) => BeginInvoke(new Action(FillLgApps)));
|
||||
_lgService.RefreshApps(true).ContinueWith((task) => BeginInvoke(() => FillLgApps(true)));
|
||||
}
|
||||
|
||||
private void cbxLgDevices_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
cbxLgPcHdmiPort.Enabled = cbxLgDevices.SelectedIndex > -1;
|
||||
if (cbxLgDevices.SelectedIndex == -1)
|
||||
{
|
||||
_lgService.SelectedDevice = null;
|
||||
cbxLgPcHdmiPort.SelectedIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lgService.SelectedDevice = (LgDevice)cbxLgDevices.SelectedItem;
|
||||
cbxLgPcHdmiPort.SelectedIndex = _lgService.SelectedDevice.HDMIPortNumber;
|
||||
}
|
||||
chkLgRemoteControlShow.Enabled = _lgService.SelectedDevice != null;
|
||||
btnLgRemoveDevice.Enabled = _lgService.SelectedDevice != null && _lgService.SelectedDevice.IsCustom;
|
||||
@@ -2006,7 +2007,7 @@ You can also activate this option by using the Expert-button and selecting Wake-
|
||||
);
|
||||
}
|
||||
|
||||
BeginInvoke(new Action(() =>
|
||||
BeginInvoke(() =>
|
||||
{
|
||||
device.PowerOnAfterStartup = clbLgPower.GetItemChecked(0);
|
||||
device.PowerOnAfterResume = clbLgPower.GetItemChecked(1);
|
||||
@@ -2015,9 +2016,10 @@ You can also activate this option by using the Expert-button and selecting Wake-
|
||||
device.PowerSwitchOnScreenSaver = clbLgPower.GetItemChecked(4);
|
||||
device.PowerOnAfterManualPowerOff = clbLgPower.GetItemChecked(5);
|
||||
device.TriggersEnabled = clbLgPower.GetItemChecked(6);
|
||||
device.PowerByWindows = clbLgPower.GetItemChecked(7);
|
||||
|
||||
_lgService.InstallEventHandlers();
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private void edtLgPowerOnAfterResumeDelay_ValueChanged(object sender, EventArgs e)
|
||||
@@ -2123,7 +2125,7 @@ Do you want to continue?";
|
||||
|
||||
private void RefreshLgDevices()
|
||||
{
|
||||
_lgService.RefreshDevices(false).ContinueWith((task) => BeginInvoke(new Action(FillLgDevices)));
|
||||
_lgService.RefreshDevices(false).ContinueWith((task) => BeginInvoke(() => FillLgDevices()));
|
||||
}
|
||||
|
||||
private void FillGradient()
|
||||
@@ -2211,7 +2213,7 @@ Do you want to continue?";
|
||||
|
||||
private void InitHandleCheckForUpdates(dynamic latest)
|
||||
{
|
||||
BeginInvoke(new Action<dynamic>(HandleCheckForUpdates), new[] { latest });
|
||||
BeginInvoke(() => HandleCheckForUpdates(latest));
|
||||
}
|
||||
|
||||
private void HandleCheckForUpdates(dynamic latest)
|
||||
@@ -2267,7 +2269,7 @@ Do you want to continue?";
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
BeginInvoke(new Action(() => ApplyNvPresetOnStartup(attempts)));
|
||||
BeginInvoke(() => ApplyNvPresetOnStartup(attempts));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2303,7 +2305,7 @@ Do you want to continue?";
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
BeginInvoke(new Action(() => ApplyAmdPresetOnStartup(attempts)));
|
||||
BeginInvoke(() => ApplyAmdPresetOnStartup(attempts));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3131,6 +3133,7 @@ The InStart and Software Update items are now visible under the Expert-button."
|
||||
- power on after startup requires ""Automatically start after login"" - see Options
|
||||
- power on after resume from standby may need some retries for waking TV - see Options
|
||||
- power off on shutdown: because this app cannot detect a restart, restarting could also trigger this. Hold down Ctrl on restart to prevent power off.
|
||||
- Use Windows power settings: powering on/off of TV will follow Windows settings. If activated, it's better to disable all other power options except power off on shutdown.
|
||||
");
|
||||
}
|
||||
|
||||
@@ -3138,5 +3141,15 @@ The InStart and Software Update items are now visible under the Expert-button."
|
||||
{
|
||||
_lgService.Config.ShutdownDelay = (int)edtLgOptionShutdownDelay.Value;
|
||||
}
|
||||
|
||||
private void cbxLgPcHdmiPort_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (_lgService?.SelectedDevice == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_lgService.SelectedDevice.HDMIPortNumber = cbxLgPcHdmiPort.SelectedIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,15 +118,19 @@ namespace ColorControl
|
||||
{
|
||||
ConfigFilename = Path.Combine(DataDir, "Settings.json");
|
||||
|
||||
if (File.Exists(ConfigFilename))
|
||||
try
|
||||
{
|
||||
var data = File.ReadAllText(ConfigFilename);
|
||||
Config = JsonConvert.DeserializeObject<Config>(data);
|
||||
if (File.Exists(ConfigFilename))
|
||||
{
|
||||
var data = File.ReadAllText(ConfigFilename);
|
||||
Config = JsonConvert.DeserializeObject<Config>(data);
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
Config = new Config();
|
||||
Logger.Error($"LoadConfig: {ex.Message}");
|
||||
}
|
||||
Config ??= new Config();
|
||||
}
|
||||
|
||||
private static bool HandleStartupParams(StartUpParams startUpParams, Process existingProcess)
|
||||
|
||||
@@ -53,6 +53,14 @@ namespace ColorControl
|
||||
UserNotificationState.QUNS_PRESENTATION_MODE,
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
internal struct POWERBROADCAST_SETTING
|
||||
{
|
||||
public Guid PowerSetting;
|
||||
public uint DataLength;
|
||||
public byte Data;
|
||||
}
|
||||
|
||||
public const int WM_BRINGTOFRONT = NativeConstants.WM_USER + 1;
|
||||
|
||||
public const int ENUM_CURRENT_SETTINGS = -1;
|
||||
@@ -60,6 +68,8 @@ namespace ColorControl
|
||||
|
||||
public static string PKEY_PNPX_IpAddress = "{656a3bb3-ecc0-43fd-8477-4ae0404a96cd} 12297";
|
||||
public static string PKEY_PNPX_PhysicalAddress = "{656a3bb3-ecc0-43fd-8477-4ae0404a96cd} 12294";
|
||||
public static Guid GUID_CONSOLE_DISPLAY_STATE = Guid.Parse("6FE69556-704A-47A0-8F24-C28D936FDA47");
|
||||
public static int PBT_POWERSETTINGCHANGE = 32787;
|
||||
|
||||
public delegate void PCREATE_PROCESS_NOTIFY_ROUTINE(IntPtr ParentId, IntPtr ProcessId, bool Create);
|
||||
|
||||
@@ -96,6 +106,12 @@ namespace ColorControl
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
|
||||
|
||||
[DllImport(@"User32", SetLastError = true)]
|
||||
public static extern IntPtr RegisterPowerSettingNotification(IntPtr hRecipient, ref Guid PowerSettingGuid, Int32 Flags);
|
||||
|
||||
[DllImport("User32.dll", SetLastError = true)]
|
||||
public static extern bool UnregisterPowerSettingNotification(IntPtr hWnd);
|
||||
|
||||
//[DllImport("Wtsapi32.dll")]
|
||||
//public extern static bool WTSRegisterSessionNotification(IntPtr hWnd, uint dwFlags);
|
||||
|
||||
|
||||
@@ -491,6 +491,13 @@ namespace LgTv
|
||||
await _connection.SubscribeAsync(requestMessage, callback);
|
||||
}
|
||||
|
||||
public async Task SubscribeForegroundApp(Func<dynamic, bool> callback, dynamic payload = null)
|
||||
{
|
||||
var requestMessage = new RequestMessage("ssap://com.webos.applicationManager/getForegroundAppInfo", null, "subscribe");
|
||||
|
||||
await _connection.SubscribeAsync(requestMessage, callback);
|
||||
}
|
||||
|
||||
public async Task SubscribePictureSettings(Func<dynamic, bool> callback, dynamic payload = null)
|
||||
{
|
||||
if (payload == null)
|
||||
|
||||
Reference in new issue
Block a user