2020-08-15 04:35:06 +08:00
|
|
|
|
// Copyright (c) Microsoft Corporation
|
|
|
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
|
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
2020-11-03 01:33:43 +08:00
|
|
|
|
using System.IO.Abstractions;
|
2020-08-15 04:35:06 +08:00
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Windows.Input;
|
2020-10-24 06:05:07 +08:00
|
|
|
|
using ManagedCommon;
|
2021-01-05 22:54:32 +08:00
|
|
|
|
using Microsoft.PowerToys.Common.UI;
|
2020-10-23 00:45:48 +08:00
|
|
|
|
using Microsoft.PowerToys.Settings.UI.Library;
|
2020-09-09 01:04:17 +08:00
|
|
|
|
using PowerLauncher.Helper;
|
2020-11-04 04:45:01 +08:00
|
|
|
|
using PowerLauncher.Plugin;
|
2020-08-15 04:35:06 +08:00
|
|
|
|
using Wox.Infrastructure.Hotkey;
|
|
|
|
|
using Wox.Infrastructure.UserSettings;
|
|
|
|
|
using Wox.Plugin;
|
2020-10-24 04:06:22 +08:00
|
|
|
|
using Wox.Plugin.Logger;
|
2020-09-09 01:04:17 +08:00
|
|
|
|
using JsonException = System.Text.Json.JsonException;
|
2020-08-15 04:35:06 +08:00
|
|
|
|
|
|
|
|
|
namespace PowerLauncher
|
|
|
|
|
{
|
|
|
|
|
// Watch for /Local/Microsoft/PowerToys/Launcher/Settings.json changes
|
|
|
|
|
public class SettingsWatcher : BaseModel
|
|
|
|
|
{
|
2020-09-22 01:14:44 +08:00
|
|
|
|
private readonly ISettingsUtils _settingsUtils;
|
|
|
|
|
|
2020-08-15 04:35:06 +08:00
|
|
|
|
private const int MaxRetries = 10;
|
|
|
|
|
private static readonly object _watcherSyncObject = new object();
|
2020-11-03 01:33:43 +08:00
|
|
|
|
private readonly IFileSystemWatcher _watcher;
|
2020-10-30 08:52:35 +08:00
|
|
|
|
private readonly PowerToysRunSettings _settings;
|
|
|
|
|
|
2020-10-24 06:05:07 +08:00
|
|
|
|
private readonly ThemeManager _themeManager;
|
2020-08-15 04:35:06 +08:00
|
|
|
|
|
2020-10-30 08:52:35 +08:00
|
|
|
|
public SettingsWatcher(PowerToysRunSettings settings, ThemeManager themeManager)
|
2020-08-15 04:35:06 +08:00
|
|
|
|
{
|
2020-11-03 01:33:43 +08:00
|
|
|
|
_settingsUtils = new SettingsUtils();
|
2020-08-15 04:35:06 +08:00
|
|
|
|
_settings = settings;
|
2020-10-24 06:05:07 +08:00
|
|
|
|
_themeManager = themeManager;
|
2020-08-15 04:35:06 +08:00
|
|
|
|
|
|
|
|
|
// Set up watcher
|
2020-10-23 00:45:48 +08:00
|
|
|
|
_watcher = Microsoft.PowerToys.Settings.UI.Library.Utilities.Helper.GetFileWatcher(PowerLauncherSettings.ModuleName, "settings.json", OverloadSettings);
|
2020-08-15 04:35:06 +08:00
|
|
|
|
|
|
|
|
|
// Load initial settings file
|
|
|
|
|
OverloadSettings();
|
2020-11-03 18:30:19 +08:00
|
|
|
|
|
|
|
|
|
// Apply theme at startup
|
|
|
|
|
_themeManager.ChangeTheme(_settings.Theme, _settings.Theme == Theme.System);
|
2020-08-15 04:35:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-09-22 01:14:44 +08:00
|
|
|
|
public void CreateSettingsIfNotExists()
|
2020-09-09 01:04:17 +08:00
|
|
|
|
{
|
2020-09-22 01:14:44 +08:00
|
|
|
|
if (!_settingsUtils.SettingsExists(PowerLauncherSettings.ModuleName))
|
2020-09-09 01:04:17 +08:00
|
|
|
|
{
|
2020-09-24 07:32:06 +08:00
|
|
|
|
Log.Info("PT Run settings.json was missing, creating a new one", GetType());
|
2020-09-22 01:14:44 +08:00
|
|
|
|
|
2020-09-09 01:04:17 +08:00
|
|
|
|
var defaultSettings = new PowerLauncherSettings();
|
2020-09-22 01:14:44 +08:00
|
|
|
|
defaultSettings.Save(_settingsUtils);
|
2020-09-09 01:04:17 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-15 04:35:06 +08:00
|
|
|
|
public void OverloadSettings()
|
|
|
|
|
{
|
|
|
|
|
Monitor.Enter(_watcherSyncObject);
|
|
|
|
|
var retry = true;
|
|
|
|
|
var retryCount = 0;
|
|
|
|
|
while (retry)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
retryCount++;
|
2020-09-09 01:04:17 +08:00
|
|
|
|
CreateSettingsIfNotExists();
|
2020-08-15 04:35:06 +08:00
|
|
|
|
|
2020-09-22 01:14:44 +08:00
|
|
|
|
var overloadSettings = _settingsUtils.GetSettings<PowerLauncherSettings>(PowerLauncherSettings.ModuleName);
|
2020-08-15 04:35:06 +08:00
|
|
|
|
|
|
|
|
|
var openPowerlauncher = ConvertHotkey(overloadSettings.Properties.OpenPowerLauncher);
|
|
|
|
|
if (_settings.Hotkey != openPowerlauncher)
|
|
|
|
|
{
|
|
|
|
|
_settings.Hotkey = openPowerlauncher;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var shell = PluginManager.AllPlugins.Find(pp => pp.Metadata.Name == "Shell");
|
|
|
|
|
if (shell != null)
|
|
|
|
|
{
|
|
|
|
|
var shellSettings = shell.Plugin as ISettingProvider;
|
|
|
|
|
shellSettings.UpdateSettings(overloadSettings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_settings.MaxResultsToShow != overloadSettings.Properties.MaximumNumberOfResults)
|
|
|
|
|
{
|
|
|
|
|
_settings.MaxResultsToShow = overloadSettings.Properties.MaximumNumberOfResults;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_settings.IgnoreHotkeysOnFullscreen != overloadSettings.Properties.IgnoreHotkeysInFullscreen)
|
|
|
|
|
{
|
|
|
|
|
_settings.IgnoreHotkeysOnFullscreen = overloadSettings.Properties.IgnoreHotkeysInFullscreen;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-31 07:43:09 +08:00
|
|
|
|
// Using OrdinalIgnoreCase since this is internal
|
2020-09-12 04:45:32 +08:00
|
|
|
|
var indexer = PluginManager.AllPlugins.Find(p => p.Metadata.Name.Equals("Windows Indexer", StringComparison.OrdinalIgnoreCase));
|
2020-08-15 04:35:06 +08:00
|
|
|
|
if (indexer != null)
|
|
|
|
|
{
|
|
|
|
|
var indexerSettings = indexer.Plugin as ISettingProvider;
|
|
|
|
|
indexerSettings.UpdateSettings(overloadSettings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_settings.ClearInputOnLaunch != overloadSettings.Properties.ClearInputOnLaunch)
|
|
|
|
|
{
|
|
|
|
|
_settings.ClearInputOnLaunch = overloadSettings.Properties.ClearInputOnLaunch;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-24 06:05:07 +08:00
|
|
|
|
if (_settings.Theme != overloadSettings.Properties.Theme)
|
|
|
|
|
{
|
|
|
|
|
_settings.Theme = overloadSettings.Properties.Theme;
|
|
|
|
|
_themeManager.ChangeTheme(_settings.Theme, _settings.Theme == Theme.System);
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-15 04:35:06 +08:00
|
|
|
|
retry = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// the settings application can hold a lock on the settings.json file which will result in a IOException.
|
|
|
|
|
// This should be changed to properly synch with the settings app instead of retrying.
|
|
|
|
|
catch (IOException e)
|
|
|
|
|
{
|
|
|
|
|
if (retryCount > MaxRetries)
|
|
|
|
|
{
|
|
|
|
|
retry = false;
|
2020-09-24 07:32:06 +08:00
|
|
|
|
Log.Exception($"Failed to Deserialize PowerToys settings, Retrying {e.Message}", e, GetType());
|
2020-09-09 01:04:17 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(1000);
|
2020-08-15 04:35:06 +08:00
|
|
|
|
}
|
2020-09-09 01:04:17 +08:00
|
|
|
|
}
|
|
|
|
|
catch (JsonException e)
|
|
|
|
|
{
|
|
|
|
|
if (retryCount > MaxRetries)
|
|
|
|
|
{
|
|
|
|
|
retry = false;
|
2020-09-24 07:32:06 +08:00
|
|
|
|
Log.Exception($"Failed to Deserialize PowerToys settings, Creating new settings as file could be corrupted {e.Message}", e, GetType());
|
2020-08-15 04:35:06 +08:00
|
|
|
|
|
2020-09-09 01:04:17 +08:00
|
|
|
|
// Settings.json could possibly be corrupted. To mitigate this we delete the
|
|
|
|
|
// current file and replace it with a correct json value.
|
2020-09-22 01:14:44 +08:00
|
|
|
|
_settingsUtils.DeleteSettings(PowerLauncherSettings.ModuleName);
|
2020-09-09 01:04:17 +08:00
|
|
|
|
CreateSettingsIfNotExists();
|
|
|
|
|
ErrorReporting.ShowMessageBox(Properties.Resources.deseralization_error_title, Properties.Resources.deseralization_error_message);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
}
|
2020-08-15 04:35:06 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Monitor.Exit(_watcherSyncObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static string ConvertHotkey(HotkeySettings hotkey)
|
|
|
|
|
{
|
|
|
|
|
Key key = KeyInterop.KeyFromVirtualKey(hotkey.Code);
|
|
|
|
|
HotkeyModel model = new HotkeyModel(hotkey.Alt, hotkey.Shift, hotkey.Win, hotkey.Ctrl, key);
|
|
|
|
|
return model.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|