Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6ba8630
Update expect.txt
cgaarden Nov 17, 2024
db394ca
Merge branch 'microsoft:main' into main
cgaarden Nov 22, 2024
65d5fea
Merge branch 'main' of https://github.com/cgaarden/PowerToys
cgaarden Nov 27, 2024
94e1c1e
Merge remote-tracking branch 'upstream/main'
cgaarden Nov 27, 2024
07a9789
Merge branch 'microsoft:main' into main
cgaarden Nov 29, 2024
7e4be3d
Merge branch 'microsoft:main' into main
cgaarden Dec 3, 2024
0db150b
Merge branch 'microsoft:main' into main
cgaarden Dec 21, 2024
90f7d61
Merge branch 'main' of https://github.com/cgaarden/PowerToys
cgaarden Dec 21, 2024
3dffe3d
Merge branch 'microsoft:main' into main
cgaarden Jan 23, 2025
30583f1
Merge branch 'microsoft:main' into main
cgaarden Jan 25, 2025
fc67460
Merge branch 'microsoft:main' into main
cgaarden Feb 26, 2025
0b7760d
Merge branch 'microsoft:main' into main
cgaarden Mar 2, 2025
b64be50
Merge branch 'microsoft:main' into main
cgaarden Mar 15, 2025
be24d00
Merge branch 'microsoft:main' into main
cgaarden Mar 18, 2025
68a7b42
Merge branch 'microsoft:main' into main
cgaarden Apr 6, 2025
ca76278
Merge branch 'microsoft:main' into main
cgaarden Apr 12, 2025
442463e
Merge branch 'microsoft:main' into main
cgaarden May 7, 2025
3af4201
Merge branch 'microsoft:main' into main
cgaarden May 17, 2025
c173a57
Merge branch 'microsoft:main' into main
cgaarden May 23, 2025
f4c5046
Merge branch 'microsoft:main' into main
cgaarden Jun 1, 2025
dd36e9b
Merge branch 'microsoft:main' into main
cgaarden Jun 13, 2025
18061ff
Merge branch 'microsoft:main' into main
cgaarden Jun 20, 2025
66178d1
Merge branch 'microsoft:main' into main
cgaarden Jun 25, 2025
d7a17d6
Merge branch 'microsoft:main' into main
cgaarden Jun 29, 2025
584a52d
Merge branch 'microsoft:main' into main
cgaarden Aug 16, 2025
9df6dcc
Merge branch 'microsoft:main' into main
cgaarden Sep 13, 2025
7b7c344
Merge branch 'microsoft:main' into main
cgaarden Sep 19, 2025
997f846
Merge branch 'microsoft:main' into main
cgaarden Jan 20, 2026
de8abc4
Initial remake of Hiding Built-In New
cgaarden Jan 22, 2026
c44e00b
Merge remote-tracking branch 'upstream/main' into Hide-existing-new-(…
cgaarden Jan 22, 2026
19a24f3
Spelling fixes
cgaarden Jan 23, 2026
f68fa9f
Restore New on uninstall
cgaarden Jan 23, 2026
f4d41d0
Merge remote-tracking branch 'upstream/main' into Hide-existing-new-(…
cgaarden Feb 2, 2026
ec4977e
Merge branch 'microsoft:main' into Hide-existing-new-(remake)
cgaarden Feb 26, 2026
e7cf367
Merge remote-tracking branch 'upstream/main' into Hide-existing-new-(…
cgaarden Feb 28, 2026
00441c7
Updated xaml styling
cgaarden Feb 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/devdocs/modules/newplus.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,10 @@ Note: The DllHost process loads the DLL only when the context menu is triggered
- A signature issue with the MSIX package

- For development and testing, using the Windows 10 handler can be easier since it doesn't require signing.

## Restoring Built-in Windows New context menu
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cgaarden Would you mind opening a PR in the MS Learn docs too with this troubleshooting paragraph?

https://github.com/MicrosoftDocs/windows-dev-docs/blob/docs/hub/powertoys/newplus.md

If the Windows 11 built-in New context menu doesn't reappear on uninstalling PowerToys, some issue with settings etc. here's how to restore the built-in New context menu.

1. Open Registry Editor
1. Go to the key "Computer\HKEY_CURRENT_USER\Software\Classes\Directory\background\ShellEx\ContextMenuHandlers"
1. Delete the "New" subkey (i.e. fullpath "Computer\HKEY_CURRENT_USER\Software\Classes\Directory\background\ShellEx\ContextMenuHandlers\New")
29 changes: 29 additions & 0 deletions installer/PowerToysSetupCustomActionsVNext/CustomAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,35 @@ UINT __stdcall RemoveScheduledTasksCA(MSIHANDLE hInstall)
return WcaFinalize(er);
}

UINT __stdcall RestoreBuiltInNewContextMenuCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
hr = WcaInitialize(hInstall, "RestoreBuiltInNewContextMenuCA");

constexpr wchar_t built_in_new_registry_path[] = LR"(Software\Classes\Directory\Background\ShellEx\ContextMenuHandlers\New)";

HKEY key{};

if (RegOpenKeyExW(HKEY_CURRENT_USER,
built_in_new_registry_path,
0,
KEY_ALL_ACCESS,
&key) != ERROR_SUCCESS)
{
return WcaFinalize(ERROR_SUCCESS);
}

if (RegDeleteValueW(key, nullptr) != ERROR_SUCCESS)
{
RegCloseKey(key);
return WcaFinalize(ERROR_SUCCESS);
}

RegCloseKey(key);

return WcaFinalize(ERROR_SUCCESS);
}

UINT __stdcall TelemetryLogInstallSuccessCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ EXPORTS
ApplyModulesRegistryChangeSetsCA
DetectPrevInstallPathCA
RemoveScheduledTasksCA
RestoreBuiltInNewContextMenuCA
TelemetryLogInstallSuccessCA
TelemetryLogInstallCancelCA
TelemetryLogInstallFailCA
Expand Down
5 changes: 5 additions & 0 deletions installer/PowerToysSetupVNext/Product.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@
<!-- Clean Video Conference Mute registry keys that might be around from previous installations. We've deprecated this utility since then. -->
<Custom Action="CleanVideoConferenceRegistry" Before="InstallFinalize" Condition="NOT Installed" />

<!-- Restore built-in "New" context menu in case user disabled it via New+ -->
<Custom Action="RestoreBuiltInNewContextMenu" Before="RemoveFiles" Condition="Installed AND (REMOVE=&quot;ALL&quot;)" />

</InstallExecuteSequence>

<CustomAction Id="SetLaunchPowerToysParam" Property="LaunchPowerToys" Value="[INSTALLFOLDER]" />
Expand Down Expand Up @@ -262,6 +265,8 @@

<CustomAction Id="SetBundleInstallLocation" Return="ignore" Impersonate="no" Execute="deferred" DllEntry="SetBundleInstallLocationCA" BinaryRef="PTCustomActions" />

<CustomAction Id="RestoreBuiltInNewContextMenu" Return="ignore" Impersonate="yes" Execute="deferred" DllEntry="RestoreBuiltInNewContextMenuCA" BinaryRef="PTCustomActions" />

<!-- Close 'PowerToys.exe' before uninstall-->
<Property Id="MSIRESTARTMANAGERCONTROL" Value="DisableShutdown" />
<Property Id="MSIFASTINSTALL" Value="DisableShutdown" />
Expand Down
4 changes: 4 additions & 0 deletions src/common/GPOWrapper/GPOWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,4 +292,8 @@ namespace winrt::PowerToys::GPOWrapper::implementation
{
return static_cast<GpoRuleConfigured>(powertoys_gpo::getConfiguredRunAtStartupValue());
}
GpoRuleConfigured GPOWrapper::GetConfiguredNewPlusHideBuiltInNewContextMenuValue()
{
return static_cast<GpoRuleConfigured>(powertoys_gpo::getConfiguredNewPlusHideBuiltInNewContextMenuValue());
}
}
1 change: 1 addition & 0 deletions src/common/GPOWrapper/GPOWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ namespace winrt::PowerToys::GPOWrapper::implementation
static GpoRuleConfigured GetAllowDataDiagnosticsValue();
static GpoRuleConfigured GetConfiguredRunAtStartupValue();
static GpoRuleConfigured GetConfiguredNewPlusReplaceVariablesValue();
static GpoRuleConfigured GetConfiguredNewPlusHideBuiltInNewContextMenuValue();
};
}

Expand Down
1 change: 1 addition & 0 deletions src/common/GPOWrapper/GPOWrapper.idl
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ namespace PowerToys
static GpoRuleConfigured GetAllowDataDiagnosticsValue();
static GpoRuleConfigured GetConfiguredRunAtStartupValue();
static GpoRuleConfigured GetConfiguredNewPlusReplaceVariablesValue();
static GpoRuleConfigured GetConfiguredNewPlusHideBuiltInNewContextMenuValue();
}
}
}
6 changes: 6 additions & 0 deletions src/common/utils/gpo.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ namespace powertoys_gpo
const std::wstring POLICY_MWB_POLICY_DEFINED_IP_MAPPING_RULES = L"MwbPolicyDefinedIpMappingRules";
const std::wstring POLICY_NEW_PLUS_HIDE_TEMPLATE_FILENAME_EXTENSION = L"NewPlusHideTemplateFilenameExtension";
const std::wstring POLICY_NEW_PLUS_REPLACE_VARIABLES = L"NewPlusReplaceVariablesInTemplateFilenames";
const std::wstring POLICY_NEW_PLUS_HIDE_BUILT_IN_NEW_CONTEXT_MENU = L"NewPlusHideBuiltInNewContextMenu";

// Methods used for reading the registry
#pragma region ReadRegistryMethods
Expand Down Expand Up @@ -700,5 +701,10 @@ namespace powertoys_gpo
return getConfiguredValue(POLICY_NEW_PLUS_REPLACE_VARIABLES);
}

inline gpo_rule_configured_t getConfiguredNewPlusHideBuiltInNewContextMenuValue()
{
return getConfiguredValue(POLICY_NEW_PLUS_HIDE_BUILT_IN_NEW_CONTEXT_MENU);
}

#pragma endregion IndividualModuleSettingPolicies
}
15 changes: 13 additions & 2 deletions src/gpo/assets/PowerToys.admx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation.
Licensed under the MIT License. -->
<policyDefinitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.19" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<policyDefinitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.20" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<policyNamespaces>
<target prefix="powertoys" namespace="Microsoft.Policies.PowerToys" />
</policyNamespaces>
<resources minRequiredRevision="1.19"/><!-- Last changed with PowerToys v0.97.0 -->
<resources minRequiredRevision="1.20"/><!-- Last changed with PowerToys v0.98.0 -->
<supportedOn>
<definitions>
<definition name="SUPPORTED_POWERTOYS_0_64_0" displayName="$(string.SUPPORTED_POWERTOYS_0_64_0)"/>
Expand All @@ -28,6 +28,7 @@
<definition name="SUPPORTED_POWERTOYS_0_90_0" displayName="$(string.SUPPORTED_POWERTOYS_0_90_0)"/>
<definition name="SUPPORTED_POWERTOYS_0_96_0" displayName="$(string.SUPPORTED_POWERTOYS_0_96_0)"/>
<definition name="SUPPORTED_POWERTOYS_0_97_0" displayName="$(string.SUPPORTED_POWERTOYS_0_97_0)"/>
<definition name="SUPPORTED_POWERTOYS_0_98_0" displayName="$(string.SUPPORTED_POWERTOYS_0_98_0)"/>
<definition name="SUPPORTED_POWERTOYS_0_64_0_TO_0_87_1" displayName="$(string.SUPPORTED_POWERTOYS_0_64_0_TO_0_87_1)"/>
</definitions>
</supportedOn>
Expand Down Expand Up @@ -826,5 +827,15 @@
<decimal value="0" />
</disabledValue>
</policy>
<policy name="NewPlusHideBuiltInNewContextMenu" class="Both" displayName="$(string.NewPlusHideBuiltInNewContextMenu)" explainText="$(string.NewPlusHideBuiltInNewContextMenuDescription)" key="Software\Policies\PowerToys" valueName="NewPlusHideBuiltInNewContextMenu">
<parentCategory ref="NewPlus" />
<supportedOn ref="SUPPORTED_POWERTOYS_0_98_0" />
<enabledValue>
<decimal value="1" />
</enabledValue>
<disabledValue>
<decimal value="0" />
</disabledValue>
</policy>
</policies>
</policyDefinitions>
13 changes: 11 additions & 2 deletions src/gpo/assets/en-US/PowerToys.adml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<string id="SUPPORTED_POWERTOYS_0_90_0">PowerToys version 0.90.0 or later</string>
<string id="SUPPORTED_POWERTOYS_0_96_0">PowerToys version 0.96.0 or later</string>
<string id="SUPPORTED_POWERTOYS_0_97_0">PowerToys version 0.97.0 or later</string>
<string id="SUPPORTED_POWERTOYS_0_98_0">PowerToys version 0.98.0 or later</string>
<string id="SUPPORTED_POWERTOYS_0_64_0_TO_0_87_1">From PowerToys version 0.64.0 until PowerToys version 0.87.1</string>

<string id="ConfigureAllUtilityGlobalEnabledStateDescription">This policy configures the enabled state for all PowerToys utilities.
Expand Down Expand Up @@ -238,7 +239,7 @@ If you disable this policy, the setting is disabled and variables in filenames w

If you don't configure this policy, the user will be able to control the setting and can enable or disable it.
</string>

<string id="ConfigureAllUtilityGlobalEnabledState">Configure global utility enabled state</string>
<string id="ConfigureEnabledUtilityAdvancedPaste">Advanced Paste: Configure enabled state</string>
<string id="ConfigureEnabledUtilityAlwaysOnTop">Always On Top: Configure enabled state</string>
Expand Down Expand Up @@ -356,6 +357,15 @@ If you disable this policy, users will not be able to select or use Foundry Loca
<string id="AllowDiagnosticData">Allow sending diagnostic data</string>
<string id="ConfigureRunAtStartup">Configure the run at startup setting</string>
<string id="NewPlusReplaceVariablesInTemplateFilenames">Replace variables in template filenames</string>
<string id="NewPlusHideBuiltInNewContextMenu">Hide the built-in "New" context menu</string>
<string id="NewPlusHideBuiltInNewContextMenuDescription">This policy configures if Windows' built-in New context menu should be hidden on the context menu.

If you enable this policy, then the built-in New context menu will be hidden, and user can only create new files and folders using New+ and the explorer toolbar New button.

If you disable this policy, then the build-in New context menu will be displayed as normal in Windows.
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in comment: "build-in" should be "built-in".

Suggested change
If you disable this policy, then the build-in New context menu will be displayed as normal in Windows.
If you disable this policy, then the built-in New context menu will be displayed as normal in Windows.

Copilot uses AI. Check for mistakes.

If you don't configure this policy, the user will be able to control the setting and can enable or disable it.
</string>
</stringTable>

<presentationTable>
Expand All @@ -369,4 +379,3 @@ If you disable this policy, users will not be able to select or use Foundry Loca

</resources>
</policyDefinitionResources>

2 changes: 2 additions & 0 deletions src/modules/NewPlus/NewShellExtensionContextMenu/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ namespace newplus::constants::non_localizable

constexpr WCHAR settings_json_key_template_location[] = L"TemplateLocation";

constexpr WCHAR settings_json_key_hide_built_in_new[] = L"BuiltInNewHidePreference";

constexpr WCHAR context_menu_package_name[] = L"NewPlusContextMenu";

constexpr WCHAR msix_package_name[] = L"NewPlusPackage.msix";
Expand Down
65 changes: 65 additions & 0 deletions src/modules/NewPlus/NewShellExtensionContextMenu/new_utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,4 +446,69 @@ namespace newplus::utilities

return hr;
}

constexpr wchar_t built_in_new_registry_path[] = LR"(Software\Classes\Directory\Background\ShellEx\ContextMenuHandlers\New)";
constexpr wchar_t built_in_new_registry_disabled_value_prefix[] = L"disabled_";

inline bool disable_built_in_new_via_registry()
{
// This is implemented to support where New+ GPO is configured to
// hide the built-in New context menu but Settings UI hasn't been launched
// Mirrors the logic in DisableBuiltInNewViaRegistry in .cs

HKEY key{};

if (RegCreateKeyExW(HKEY_CURRENT_USER,
built_in_new_registry_path,
0,
nullptr,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
nullptr,
&key,
nullptr) != ERROR_SUCCESS)
{
return false;
}

const auto built_in_new_registry_disabled_value_prefix_len = lstrlenW(built_in_new_registry_disabled_value_prefix);

if (RegSetValueExW(key, nullptr, 0, REG_SZ, reinterpret_cast<const BYTE*>(&built_in_new_registry_disabled_value_prefix), built_in_new_registry_disabled_value_prefix_len) != ERROR_SUCCESS)
Comment on lines +475 to +476
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The size parameter passed to RegSetValueExW is incorrect. The function expects the size in bytes including the null terminator for REG_SZ types. Currently, lstrlenW returns the character count (excluding null terminator), but you need to multiply by sizeof(wchar_t) and add space for the null terminator.

For REG_SZ strings, the correct size should be: (lstrlenW(str) + 1) * sizeof(wchar_t)

This bug means only part of the string "disabled_" will be written to the registry, potentially writing only "d" or "di" depending on how the registry handles it. Compare with the pattern used in shell_ext_registration.h line 150 and TestHelpers.h line 153.

Suggested change
if (RegSetValueExW(key, nullptr, 0, REG_SZ, reinterpret_cast<const BYTE*>(&built_in_new_registry_disabled_value_prefix), built_in_new_registry_disabled_value_prefix_len) != ERROR_SUCCESS)
const DWORD built_in_new_registry_disabled_value_prefix_size =
static_cast<DWORD>((built_in_new_registry_disabled_value_prefix_len + 1) * sizeof(wchar_t));
if (RegSetValueExW(key,
nullptr,
0,
REG_SZ,
reinterpret_cast<const BYTE*>(built_in_new_registry_disabled_value_prefix),
built_in_new_registry_disabled_value_prefix_size) != ERROR_SUCCESS)

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reinterpret_cast is taking the address of a pointer (&built_in_new_registry_disabled_value_prefix) instead of using the pointer directly. Since built_in_new_registry_disabled_value_prefix is already a const wchar_t*, you should cast it directly without the address-of operator.

Change to: reinterpret_cast<const BYTE*>(built_in_new_registry_disabled_value_prefix)

See the correct pattern in shell_ext_registration.h line 123 and line 150.

Suggested change
if (RegSetValueExW(key, nullptr, 0, REG_SZ, reinterpret_cast<const BYTE*>(&built_in_new_registry_disabled_value_prefix), built_in_new_registry_disabled_value_prefix_len) != ERROR_SUCCESS)
if (RegSetValueExW(key, nullptr, 0, REG_SZ, reinterpret_cast<const BYTE*>(built_in_new_registry_disabled_value_prefix), built_in_new_registry_disabled_value_prefix_len) != ERROR_SUCCESS)

Copilot uses AI. Check for mistakes.
{
RegCloseKey(key);
return true;
}

RegCloseKey(key);
return false;

}
Comment on lines +453 to +485
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value logic is inverted. The function returns true on RegSetValueExW failure (line 479) and false on success (line 483). This contradicts the boolean return type semantics where true typically indicates success. This should return false on RegSetValueExW failure and true on success to be consistent with standard C++ conventions and the enable_built_in_new_via_registry function which also has inverted return logic.

Copilot uses AI. Check for mistakes.

inline bool enable_built_in_new_via_registry()
{
// This is implemented to support where New+ GPO is configured to
// display the built-in New context menu but Settings UI hasn't been launched
// Mirrors the logic in EnableBuiltInNewViaRegistry in .cs

HKEY key{};

if (RegOpenKeyExW(HKEY_CURRENT_USER,
built_in_new_registry_path,
0,
KEY_ALL_ACCESS,
&key) != ERROR_SUCCESS)
{
return true;
}

if (RegDeleteValueW(key, nullptr) != ERROR_SUCCESS)
{
RegCloseKey(key);
return true;
}

RegCloseKey(key);
return false;

}
Comment on lines +487 to +513
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value logic appears inverted. The function returns true when registry operations fail (lines 501, 507) and false when they succeed (line 511). This contradicts typical boolean semantics where true indicates success. Consider whether the return values should be swapped to match standard conventions, or if the function is intentionally designed this way, document it clearly with comments.

Copilot uses AI. Check for mistakes.
}
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,22 @@ class NewModule : public PowertoyModuleIface
void init_settings()
{
powertoy_new_enabled = NewSettingsInstance().GetEnabled();

UpdateRegistration(powertoy_new_enabled);

if (powertoy_new_enabled)
{
// NOTE: This requires that the runner is running and have loaded the new plus module.
// It's not enough for user to just invoke the context menu.
if (NewSettingsInstance().GetHideBuiltInNew())
{
newplus::utilities::disable_built_in_new_via_registry();
}
else
{
newplus::utilities::enable_built_in_new_via_registry();
}
}
}
Comment on lines 172 to 191
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When New+ is enabled (enable() method at line 111-124), the built-in New context menu state is not updated according to user preference. The enable() method registers New+ but doesn't call the logic to hide/show the built-in New based on settings. This means if a user previously set HideBuiltInNew=true, then disabled New+, then re-enabled New+, the built-in New won't be hidden until init_settings() is called again. Consider checking NewSettingsInstance().GetHideBuiltInNew() and calling the appropriate registry function in the enable() method.

Copilot uses AI. Check for mistakes.
};

Expand Down
30 changes: 30 additions & 0 deletions src/modules/NewPlus/NewShellExtensionContextMenu/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void NewSettings::Save()
values.add_property(newplus::constants::non_localizable::settings_json_key_hide_starting_digits, new_settings.hide_starting_digits);
values.add_property(newplus::constants::non_localizable::settings_json_key_replace_variables, new_settings.replace_variables);
values.add_property(newplus::constants::non_localizable::settings_json_key_template_location, new_settings.template_location);
values.add_property(newplus::constants::non_localizable::settings_json_key_hide_built_in_new, new_settings.hide_built_in_new_preference);

values.save_to_settings_file();

Expand Down Expand Up @@ -75,6 +76,9 @@ void NewSettings::InitializeWithDefaultSettings()
SetReplaceVariables(false);

SetTemplateLocation(GetTemplateLocationDefaultPath());

// By default we show the built-in New context menu
SetHideBuiltInNew(false);
}

void NewSettings::RefreshEnabledState()
Expand Down Expand Up @@ -149,6 +153,12 @@ void NewSettings::ParseJson()
new_settings.replace_variables = resolveVariables.value();
}

const auto hideBuiltInNewValue = settings.get_bool_value(newplus::constants::non_localizable::settings_json_key_hide_built_in_new);
if (hideBuiltInNewValue.has_value())
{
new_settings.hide_built_in_new_preference = hideBuiltInNewValue.value();
}

GetSystemTimeAsFileTime(&new_settings_last_loaded_timestamp);
}

Expand Down Expand Up @@ -239,6 +249,26 @@ std::wstring NewSettings::GetTemplateLocationDefaultPath() const
return full_path;
}

bool NewSettings::GetHideBuiltInNew()
{
const auto gpoSetting = powertoys_gpo::getConfiguredNewPlusHideBuiltInNewContextMenuValue();
if (gpoSetting == powertoys_gpo::gpo_rule_configured_enabled)
{
return true;
}
else if (gpoSetting == powertoys_gpo::gpo_rule_configured_disabled)
{
return false;
}

return new_settings.hide_built_in_new_preference;
}

void NewSettings::SetHideBuiltInNew(const bool hide_built_in_new)
{
new_settings.hide_built_in_new_preference = hide_built_in_new;
}

NewSettings& NewSettingsInstance()
{
static NewSettings instance;
Expand Down
3 changes: 3 additions & 0 deletions src/modules/NewPlus/NewShellExtensionContextMenu/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class NewSettings
void SetReplaceVariables(const bool resolve_variables);
std::wstring GetTemplateLocation() const;
void SetTemplateLocation(const std::wstring template_location);
bool GetHideBuiltInNew();
void SetHideBuiltInNew(const bool hide_built_in_new);

void Save();
void Load();
Expand All @@ -29,6 +31,7 @@ class NewSettings
bool hide_starting_digits{ true };
bool replace_variables{ true };
std::wstring template_location;
bool hide_built_in_new_preference{ false };
};

void RefreshEnabledState();
Expand Down
4 changes: 4 additions & 0 deletions src/settings-ui/Settings.UI.Library/NewPlusProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public NewPlusProperties()
HideStartingDigits = new BoolProperty(true);
TemplateLocation = new StringProperty(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "PowerToys", "NewPlus", "Templates"));
ReplaceVariables = new BoolProperty(false);
BuiltInNewHidePreference = new BoolProperty(false);
}

[JsonPropertyName("HideFileExtension")]
Expand All @@ -33,6 +34,9 @@ public NewPlusProperties()
[JsonPropertyName("ReplaceVariables")]
public BoolProperty ReplaceVariables { get; set; }

[JsonPropertyName("BuiltInNewHidePreference")]
public BoolProperty BuiltInNewHidePreference { get; set; }

public override string ToString() => JsonSerializer.Serialize(this, SettingsSerializationContext.Default.NewPlusProperties);
}
}
Loading