Skip to content

Commit 2a7fc00

Browse files
committed
ModernSettings: Remove duplicates
Windows started to add newer version of settings to settings description file. These have the same description as older settings, but use different parameters. Unfortunately old settings are still present. This causes our modern settings folder to contain duplicates. And also we tend to use older setting definitions that no longer work properly. Thus we will de-duplicate parsed settings and try to keep newer ones (that should work better). New settings tend to have numeric suffix, so we will keep those with biggest suffix. Fixes #1031
1 parent 658981a commit 2a7fc00

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

Src/StartMenu/StartMenuHelper/ModernSettings.cpp

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <appmodel.h>
1111
#include <Shlobj.h>
1212
#include <Shlwapi.h>
13+
#include <algorithm>
1314
#include <functional>
1415
#include <iterator>
1516
#include <mutex>
@@ -316,9 +317,9 @@ static std::vector<uint8_t> ParseSetting(CComPtr<IXMLDOMNode>& parent)
316317
return writer.buffer();
317318
}
318319

319-
static std::vector<uint8_t> ParseModernSettings()
320+
static std::vector<std::vector<uint8_t>> ParseModernSettings()
320321
{
321-
AttributeWriter writer;
322+
std::vector<std::vector<uint8_t>> retval;
322323

323324
CComPtr<IXMLDOMDocument> doc;
324325
if (SUCCEEDED(doc.CoCreateInstance(L"Msxml2.FreeThreadedDOMDocument")))
@@ -335,16 +336,13 @@ static std::vector<uint8_t> ParseModernSettings()
335336
CComPtr<IXMLDOMNode> root;
336337
if (doc->selectSingleNode(CComBSTR(L"PCSettings"), &root) == S_OK)
337338
{
338-
FileHdr hdr{};
339-
writer.addBlob(Id::Header, &hdr, sizeof(hdr));
340-
341339
CComPtr<IXMLDOMNode> node;
342340
root->get_firstChild(&node);
343341
while (node)
344342
{
345343
auto buffer = ParseSetting(node);
346344
if (!buffer.empty())
347-
writer.addBlob(Id::Blob, buffer.data(), buffer.size());
345+
retval.push_back(std::move(buffer));
348346

349347
CComPtr<IXMLDOMNode> next;
350348
if (FAILED(node->get_nextSibling(&next)))
@@ -355,6 +353,19 @@ static std::vector<uint8_t> ParseModernSettings()
355353
}
356354
}
357355

356+
return retval;
357+
}
358+
359+
static std::vector<uint8_t> SerializeModernSettings(const std::vector<std::vector<uint8_t>>& settings)
360+
{
361+
AttributeWriter writer;
362+
363+
FileHdr hdr{};
364+
writer.addBlob(Id::Header, &hdr, sizeof(hdr));
365+
366+
for (const auto& setting : settings)
367+
writer.addBlob(Id::Blob, setting.data(), setting.size());
368+
358369
return writer.buffer();
359370
}
360371

@@ -480,11 +491,30 @@ std::shared_ptr<ModernSettings> GetModernSettings()
480491
s_settings.reset();
481492

482493
// re-parse settings
483-
auto buffer = ParseModernSettings();
484-
if (!buffer.empty())
494+
auto settings = ParseModernSettings();
495+
if (!settings.empty())
485496
{
497+
// sort by setting name (in reverse order)
498+
// this way we will have newer settings (like SomeSetting-2) before older ones
499+
std::stable_sort(settings.begin(), settings.end(), [](const auto& a, const auto& b) {
500+
return ModernSettings::Setting(a).fileName > ModernSettings::Setting(b).fileName;
501+
});
502+
503+
// now sort by description (strings presented to the user)
504+
// and keep relative order of items with the same description
505+
std::stable_sort(settings.begin(), settings.end(), [](const auto& a, const auto& b) {
506+
return ModernSettings::Setting(a).description < ModernSettings::Setting(b).description;
507+
});
508+
509+
// remove duplicates
510+
settings.erase(std::unique(settings.begin(), settings.end(), [](const auto& a, const auto& b) {
511+
return ModernSettings::Setting(a).description == ModernSettings::Setting(b).description;
512+
}), settings.end());
513+
486514
// store to file
487515
{
516+
auto buffer = SerializeModernSettings(settings);
517+
488518
File f(path.c_str(), GENERIC_WRITE, 0, CREATE_ALWAYS);
489519
if (f)
490520
{

Src/StartMenu/StartMenuHelper/ModernSettings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class ModernSettings
121121

122122
Setting() = default;
123123
Setting(const Blob& blob);
124+
Setting(const std::vector<uint8_t>& blob) : Setting(Blob{ blob.data(), blob.size() }) {}
124125

125126
explicit operator bool() const
126127
{

0 commit comments

Comments
 (0)