fix hot reloading for this file
This commit is contained in:
parent
de9dc32aa0
commit
8635537ebc
|
@ -908,17 +908,15 @@ namespace winrt::TerminalApp::implementation
|
|||
// editors, who will write a temp file, then rename it to be the
|
||||
// actual file you wrote. So listen for that too.
|
||||
wil::FolderChangeEvents::FileName | wil::FolderChangeEvents::LastWriteTime,
|
||||
[this, settingsPath](wil::FolderChangeEvent, PCWSTR fileModified) {
|
||||
// TODO!
|
||||
static const std::filesystem::path statePath{ std::wstring_view{ ApplicationState::SharedInstance().FilePath() } };
|
||||
[this, settingsBasename = settingsPath.filename()](wil::FolderChangeEvent, PCWSTR fileModified) {
|
||||
static const auto appState{ ApplicationState::SharedInstance() };
|
||||
const winrt::hstring modifiedBasename{ std::filesystem::path{ fileModified }.filename().c_str() };
|
||||
|
||||
const auto modifiedBasename = std::filesystem::path{ fileModified }.filename();
|
||||
|
||||
if (modifiedBasename == settingsPath.filename())
|
||||
if (modifiedBasename == settingsBasename)
|
||||
{
|
||||
_reloadSettings->Run();
|
||||
}
|
||||
else if (modifiedBasename == statePath.filename())
|
||||
else if (appState.IsStatePath(modifiedBasename))
|
||||
{
|
||||
_reloadState();
|
||||
}
|
||||
|
|
|
@ -87,14 +87,16 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
_read();
|
||||
}
|
||||
|
||||
// Returns the state.json path on the disk.
|
||||
winrt::hstring ApplicationState::FilePath() const noexcept
|
||||
bool ApplicationState::IsStatePath(const winrt::hstring& filename)
|
||||
{
|
||||
return winrt::hstring{ _sharedPath.wstring() };
|
||||
static const auto sharedPath{ _sharedPath.filename() };
|
||||
static const auto elevatedPath{ _elevatedPath.filename() };
|
||||
static const auto userPath{ _userPath.filename() };
|
||||
return filename == sharedPath || filename == elevatedPath || filename == userPath;
|
||||
}
|
||||
|
||||
// TODO!
|
||||
// Deserializes the state.json at _path into this ApplicationState.
|
||||
// Deserializes the state.json and user-state (or elevated-state if
|
||||
// elevated) into this ApplicationState.
|
||||
// * ANY errors during app state will result in the creation of a new empty state.
|
||||
// * ANY errors during runtime will result in changes being partially ignored.
|
||||
void ApplicationState::_read() const noexcept
|
||||
|
@ -103,6 +105,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
std::string errs;
|
||||
std::unique_ptr<Json::CharReader> reader{ Json::CharReaderBuilder::CharReaderBuilder().newCharReader() };
|
||||
|
||||
// First get shared state out of `state.json` into us
|
||||
const auto sharedData = _readSharedContents().value_or(std::string{});
|
||||
if (!sharedData.empty())
|
||||
{
|
||||
|
@ -114,6 +117,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
|
||||
FromJson(root, FileSource::Shared);
|
||||
}
|
||||
|
||||
// Then, try and get anything in user-state/elevated-state
|
||||
if (const auto localData{ _readLocalContents().value_or(std::string{}) }; !localData.empty())
|
||||
{
|
||||
Json::Value root;
|
||||
|
@ -149,6 +154,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
return *state;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Loads data from the given json blob. Will only read the data that's in
|
||||
// the specified parseSource - so if we're reading the Local state file,
|
||||
// we won't destroy previously parsed Shared data.
|
||||
// - READ: there's no layering for app state.
|
||||
void ApplicationState::FromJson(const Json::Value& root, FileSource parseSource) const noexcept
|
||||
{
|
||||
auto state = _state.lock();
|
||||
|
@ -202,11 +212,22 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
MTSM_APPLICATION_STATE_FIELDS(MTSM_APPLICATION_STATE_GEN)
|
||||
#undef MTSM_APPLICATION_STATE_GEN
|
||||
|
||||
// Method Description:
|
||||
// - Read the contents of our "shared" state - state that should be shared
|
||||
// for elevated and unelevated instances. This is things like the list of
|
||||
// generated profiles, the cmdpal commandlines.
|
||||
std::optional<std::string> ApplicationState::_readSharedContents() const
|
||||
{
|
||||
return ReadUTF8FileIfExists(_sharedPath);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Read the contents of our "local" state - state that should be kept in
|
||||
// separate files for elevated and unelevated instances. This is things
|
||||
// like the persisted window state, and the approved commandlines (though,
|
||||
// those don't matter when unelevated).
|
||||
// - When elevated, this will DELETE `elevated-state.json` if it has bad
|
||||
// permissions, so we don't potentially read malicious data.
|
||||
std::optional<std::string> ApplicationState::_readLocalContents() const
|
||||
{
|
||||
return ::Microsoft::Console::Utils::IsElevated() ?
|
||||
|
@ -214,11 +235,20 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
ReadUTF8FileIfExists(_userPath, false);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Write the contents of our "shared" state - state that should be shared
|
||||
// for elevated and unelevated instances. This will atomically write to
|
||||
// `state.json`
|
||||
void ApplicationState::_writeSharedContents(const std::string_view content) const
|
||||
{
|
||||
WriteUTF8FileAtomic(_sharedPath, content);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Write the contents of our "local" state - state that should be kept in
|
||||
// separate files for elevated and unelevated instances. When elevated,
|
||||
// this will write to `elevated-state.json`, and when unelevated, this
|
||||
// will atomically write to `user-state.json`
|
||||
void ApplicationState::_writeLocalContents(const std::string_view content) const
|
||||
{
|
||||
if (::Microsoft::Console::Utils::IsElevated())
|
||||
|
|
|
@ -18,19 +18,22 @@ Abstract:
|
|||
#include <inc/cppwinrt_utils.h>
|
||||
#include <JsonUtils.h>
|
||||
|
||||
// This macro generates all getters and setters for ApplicationState.
|
||||
// It provides X with the following arguments:
|
||||
// (type, function name, JSON key, ...variadic construction arguments)
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
// If a property is Shared, then it'll be stored in `state.json`, and used
|
||||
// in both elevated and unelevated instances of the Terminal. If a property
|
||||
// is marked Local, then it will have separate values for elevated and
|
||||
// unelevated instances.
|
||||
enum FileSource : int
|
||||
{
|
||||
Shared = 0x1,
|
||||
Local = 0x2,
|
||||
// ElevatedOnly
|
||||
Local = 0x2
|
||||
};
|
||||
DEFINE_ENUM_FLAG_OPERATORS(FileSource);
|
||||
|
||||
// This macro generates all getters and setters for ApplicationState.
|
||||
// It provides X with the following arguments:
|
||||
// (source, type, function name, JSON key, ...variadic construction arguments)
|
||||
#define MTSM_APPLICATION_STATE_FIELDS(X) \
|
||||
X(FileSource::Shared, std::unordered_set<winrt::guid>, GeneratedProfiles, "generatedProfiles") \
|
||||
X(FileSource::Local, Windows::Foundation::Collections::IVector<Model::WindowLayout>, PersistedWindowLayouts, "persistedWindowLayouts") \
|
||||
|
@ -60,7 +63,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
Json::Value ToJson(FileSource parseSource) const noexcept;
|
||||
|
||||
// General getters/setters
|
||||
winrt::hstring FilePath() const noexcept;
|
||||
bool IsStatePath(const winrt::hstring& filename);
|
||||
|
||||
// State getters/setters
|
||||
#define MTSM_APPLICATION_STATE_GEN(source, type, name, key, ...) \
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
|
||||
void Reload();
|
||||
|
||||
String FilePath { get; };
|
||||
Boolean IsStatePath(String filename);
|
||||
|
||||
Windows.Foundation.Collections.IVector<WindowLayout> PersistedWindowLayouts { get; set; };
|
||||
|
||||
|
|
Loading…
Reference in a new issue