diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 7c72abb8a5..b51781c58e 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -50,6 +50,7 @@ body:
- Always on Top
- Awake
- ColorPicker
+ - Command not found
- Crop and Lock
- Environment Variables
- FancyZones
diff --git a/.github/ISSUE_TEMPLATE/translation_issue.yml b/.github/ISSUE_TEMPLATE/translation_issue.yml
index 5d9d292029..11517c195b 100644
--- a/.github/ISSUE_TEMPLATE/translation_issue.yml
+++ b/.github/ISSUE_TEMPLATE/translation_issue.yml
@@ -24,6 +24,7 @@ body:
- Always on Top
- Awake
- ColorPicker
+ - Command not found
- Crop and Lock
- Environment Variables
- FancyZones
diff --git a/.pipelines/ESRPSigning_core.json b/.pipelines/ESRPSigning_core.json
index a6350ec764..097645b675 100644
--- a/.pipelines/ESRPSigning_core.json
+++ b/.pipelines/ESRPSigning_core.json
@@ -5,7 +5,9 @@
{
"MatchedPath": [
"*.resources.dll",
-
+
+ "WinUI3Apps\\Assets\\Settings\\Scripts\\*.ps1",
+
"PowerToys.ActionRunner.exe",
"PowerToys.Update.exe",
"PowerToys.BackgroundActivatorDLL.dll",
diff --git a/.pipelines/release.yml b/.pipelines/release.yml
index 1993c2b3ce..d28596e0f6 100644
--- a/.pipelines/release.yml
+++ b/.pipelines/release.yml
@@ -8,7 +8,7 @@ resources:
- repository: 1ESPipelineTemplates
type: git
name: 1ESPipelineTemplates/1ESPipelineTemplates
- ref: refs/tags/release-2023-11-13-4
+ ref: refs/tags/release
parameters:
- name: buildConfigurations
diff --git a/.pipelines/versionAndSignCheck.ps1 b/.pipelines/versionAndSignCheck.ps1
index d5960efb64..67c5312f95 100644
--- a/.pipelines/versionAndSignCheck.ps1
+++ b/.pipelines/versionAndSignCheck.ps1
@@ -68,11 +68,6 @@ $items | ForEach-Object {
Write-Host "Version not set: " + $_.FullName
$totalFailure++;
}
- elseif ($_.VersionInfo.ProductName -contains "PowerToys" -and $_.VersionInfo.LegalCopyright -notmatch "Copyright \(C\) $((Get-Date).Year)") {
- # PowerToys assemblies that aren't updated to the current year in the copyright
- Write-Host "Copyright year out of date: " + $_.FullName
- $totalFailure++;
- }
else {
$auth = Get-AuthenticodeSignature $_.FullName
if ($auth.SignerCertificate -eq $null) {
@@ -86,4 +81,4 @@ if ($totalFailure -gt 0) {
exit 1
}
-exit 0
\ No newline at end of file
+exit 0
diff --git a/Directory.Build.props b/Directory.Build.props
index 14a45385d4..f932d0036d 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,9 +1,9 @@
- Copyright (C) 2024 Microsoft Corporation
+ Copyright (C) Microsoft Corporation. All rights reserved.
Microsoft Corp.
- Copyright (C) 2024 Microsoft Corporation
+ Copyright (C) Microsoft Corporation. All rights reserved.
PowerToys
Microsoft Corporation
en-US
@@ -86,4 +86,4 @@
-
\ No newline at end of file
+
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 927f9a2886..221c1ed464 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -44,7 +44,7 @@
-
+
diff --git a/NOTICE.md b/NOTICE.md
index a43a1eb23c..9a7db68301 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -1333,7 +1333,7 @@ EXHIBIT A -Mozilla Public License.
- Microsoft.Windows.CsWinRT 2.0.4
- Microsoft.Windows.SDK.BuildTools 10.0.22621.2428
- Microsoft.Windows.SDK.Contracts 10.0.19041.1
-- Microsoft.WindowsAppSDK 1.4.231115000
+- Microsoft.WindowsAppSDK 1.4.231219000
- Microsoft.Xaml.Behaviors.WinUI.Managed 2.0.9
- Microsoft.Xaml.Behaviors.Wpf 1.1.39
- ModernWpfUI 0.9.4
diff --git a/doc/devdocs/modules/launcher/new-plugin-checklist.md b/doc/devdocs/modules/launcher/new-plugin-checklist.md
index c3fcab39a8..1d76e85b75 100644
--- a/doc/devdocs/modules/launcher/new-plugin-checklist.md
+++ b/doc/devdocs/modules/launcher/new-plugin-checklist.md
@@ -1,12 +1,14 @@
# New plugin checklist
+
- [ ] The plugin is a project under `modules\launcher\Plugins`
- [ ] Microsoft plugin project name pattern: `Microsoft.PowerToys.Run.Plugin.{PluginName}`
- [ ] Community plugin project name pattern: `Community.PowerToys.Run.Plugin.{PluginName}`
+- [ ] The plugin target framework should be `net8.0-windows`
- [ ] The project file should import `Version.props` and specify `$(Version).0`
- [ ] If the plugin uses any 3rd party dependencies the project file should import `DynamicPlugin.props`
-- [ ] Make sure `*.csproj` specify only x64 platform target
-- [ ] The plugin has to contain a `plugin.json` file of the following format in its root folder
-```
+- [ ] The plugin has to contain a `plugin.json` file of the following format in its root folder:
+
+```json
{
"ID": string, // GUID string
"ActionKeyword": string, // Direct activation phrase
@@ -22,20 +24,22 @@
"DynamicLoading": bool // Sets whether the plugin should dynamically load any dependencies isolated from the core application.
}
```
+
- [ ] Make sure your `Main` class contains a public, static string property for the `PluginID`. The plugin id has to be the same as the one in the `plugin.json`file.
+
```csharp
public static string PluginID => "xxxxxxx"; // The part xxxxxxx stands for the plugin ID.
```
+
- [ ] Do not use plugin name or PowerToys as prefixes for entities inside of the plugin project
- [ ] The plugin has to have Unit tests. Use MSTest framework
- [ ] Plugin's output code and assets have to be included in the installer [`Product.wxs`](/installer/PowerToysSetup/Product.wxs)
- [ ] Test the plugin with a local build. Build the installer, install, check that the plugin works as expected
- [ ] All plugin's binaries have to be included in the signed build [`pipeline.user.windows.yml`](/.pipelines/pipeline.user.windows.yml)
-- [ ] The plugin target framework has to be .NET Core 3.1. All dependencies have to have .NET 5 version
+- [ ] The plugin target framework has to be net8.0-windows. All dependencies should be compatible with .NET 8.
Some localization steps can only be done after the first pass by the localization team to provide the localized resources.
In the PR that adds a new plugin, reference a new issue to track the work for fully enabling localization for the new plugin.
- - [ ] Add the resource folder to https://github.com/microsoft/PowerToys/blob/21247c0bb09a1bee3d14d6efa53d0c247f7236af/installer/PowerToysSetup/Product.wxs#L825
- - [ ] Add the resource files under the section https://github.com/microsoft/PowerToys/blob/21247c0bb09a1bee3d14d6efa53d0c247f7236af/installer/PowerToysSetup/Product.wxs#L882
-
+- [ ] Add the resource folder to https://github.com/microsoft/PowerToys/blob/21247c0bb09a1bee3d14d6efa53d0c247f7236af/installer/PowerToysSetup/Product.wxs#L825
+- [ ] Add the resource files under the section https://github.com/microsoft/PowerToys/blob/21247c0bb09a1bee3d14d6efa53d0c247f7236af/installer/PowerToysSetup/Product.wxs#L882
diff --git a/doc/thirdPartyRunPlugins.md b/doc/thirdPartyRunPlugins.md
index 1ac63c7f87..0e9f4a62ab 100644
--- a/doc/thirdPartyRunPlugins.md
+++ b/doc/thirdPartyRunPlugins.md
@@ -34,4 +34,6 @@ Contact the developers of a plugin directly for assistance with a specific plugi
| [Visual Studio](https://github.com/davidegiacometti/PowerToys-Run-VisualStudio) | [davidegiacometti](https://github.com/davidegiacometti) | Open Visual Studio recents |
| [WinGet](https://github.com/bostrot/PowerToysRunPluginWinget) | [bostrot](https://github.com/bostrot) | Search and install packages from WinGet |
| [Scoop](https://github.com/Quriz/PowerToysRunScoop) | [Quriz](https://github.com/Quriz) | Search and install packages from Scoop |
-| [Spotify](https://github.com/waaverecords/PowerToys-Run-Spotify) | [waaverecords](https://github.com/waaverecords) | Search Spotify and control its player |
\ No newline at end of file
+| [Spotify](https://github.com/waaverecords/PowerToys-Run-Spotify) | [waaverecords](https://github.com/waaverecords) | Search Spotify and control its player |
+| [Input Typer](https://github.com/CoreyHayward/PowerToys-Run-InputTyper) | [CoreyHayward](https://github.com/CoreyHayward) | Type the input as if sent from a keyboard |
+| [Clipboard Manager](https://github.com/CoreyHayward/PowerToys-Run-ClipboardManager) | [CoreyHayward](https://github.com/CoreyHayward) | Search and paste text from your clipboard history |
\ No newline at end of file
diff --git a/src/common/GPOWrapper/GPOWrapper.cpp b/src/common/GPOWrapper/GPOWrapper.cpp
index c3177d60db..a8eb3a5513 100644
--- a/src/common/GPOWrapper/GPOWrapper.cpp
+++ b/src/common/GPOWrapper/GPOWrapper.cpp
@@ -140,10 +140,18 @@ namespace winrt::PowerToys::GPOWrapper::implementation
{
return static_cast(powertoys_gpo::getConfiguredPeekEnabledValue());
}
+ GpoRuleConfigured GPOWrapper::GetDisableNewUpdateToastValue()
+ {
+ return static_cast(powertoys_gpo::getDisableNewUpdateToastValue());
+ }
GpoRuleConfigured GPOWrapper::GetDisableAutomaticUpdateDownloadValue()
{
return static_cast(powertoys_gpo::getDisableAutomaticUpdateDownloadValue());
}
+ GpoRuleConfigured GPOWrapper::GetDisableShowWhatsNewAfterUpdatesValue()
+ {
+ return static_cast(powertoys_gpo::getDisableShowWhatsNewAfterUpdatesValue());
+ }
GpoRuleConfigured GPOWrapper::GetAllowExperimentationValue()
{
return static_cast(powertoys_gpo::getAllowExperimentationValue());
diff --git a/src/common/GPOWrapper/GPOWrapper.h b/src/common/GPOWrapper/GPOWrapper.h
index bd153ed258..981c6dc50e 100644
--- a/src/common/GPOWrapper/GPOWrapper.h
+++ b/src/common/GPOWrapper/GPOWrapper.h
@@ -41,7 +41,9 @@ namespace winrt::PowerToys::GPOWrapper::implementation
static GpoRuleConfigured GetConfiguredPastePlainEnabledValue();
static GpoRuleConfigured GetConfiguredVideoConferenceMuteEnabledValue();
static GpoRuleConfigured GetConfiguredPeekEnabledValue();
+ static GpoRuleConfigured GetDisableNewUpdateToastValue();
static GpoRuleConfigured GetDisableAutomaticUpdateDownloadValue();
+ static GpoRuleConfigured GetDisableShowWhatsNewAfterUpdatesValue();
static GpoRuleConfigured GetAllowExperimentationValue();
static GpoRuleConfigured GetRunPluginEnabledValue(winrt::hstring const& pluginID);
static GpoRuleConfigured GetConfiguredEnvironmentVariablesEnabledValue();
diff --git a/src/common/GPOWrapper/GPOWrapper.idl b/src/common/GPOWrapper/GPOWrapper.idl
index 3b4c0eca28..eed2f2f393 100644
--- a/src/common/GPOWrapper/GPOWrapper.idl
+++ b/src/common/GPOWrapper/GPOWrapper.idl
@@ -45,7 +45,9 @@ namespace PowerToys
static GpoRuleConfigured GetConfiguredPastePlainEnabledValue();
static GpoRuleConfigured GetConfiguredVideoConferenceMuteEnabledValue();
static GpoRuleConfigured GetConfiguredPeekEnabledValue();
+ static GpoRuleConfigured GetDisableNewUpdateToastValue();
static GpoRuleConfigured GetDisableAutomaticUpdateDownloadValue();
+ static GpoRuleConfigured GetDisableShowWhatsNewAfterUpdatesValue();
static GpoRuleConfigured GetAllowExperimentationValue();
static GpoRuleConfigured GetRunPluginEnabledValue(String pluginID);
static GpoRuleConfigured GetConfiguredEnvironmentVariablesEnabledValue();
diff --git a/src/common/ManagedCommon/ModuleType.cs b/src/common/ManagedCommon/ModuleType.cs
index 0bbfaeeda3..3a489711b0 100644
--- a/src/common/ManagedCommon/ModuleType.cs
+++ b/src/common/ManagedCommon/ModuleType.cs
@@ -9,7 +9,6 @@ namespace ManagedCommon
AlwaysOnTop,
Awake,
ColorPicker,
- CmdNotFound,
CropAndLock,
EnvironmentVariables,
FancyZones,
diff --git a/src/common/utils/gpo.h b/src/common/utils/gpo.h
index 016bd744cc..66fe34a10a 100644
--- a/src/common/utils/gpo.h
+++ b/src/common/utils/gpo.h
@@ -64,7 +64,9 @@ namespace powertoys_gpo {
const std::wstring POLICY_DISABLE_PER_USER_INSTALLATION = L"PerUserInstallationDisabled";
const std::wstring POLICY_DISABLE_AUTOMATIC_UPDATE_DOWNLOAD = L"AutomaticUpdateDownloadDisabled";
const std::wstring POLICY_SUSPEND_NEW_UPDATE_TOAST = L"SuspendNewUpdateAvailableToast";
+ const std::wstring POLICY_DISABLE_NEW_UPDATE_TOAST = L"DisableNewUpdateAvailableToast";
const std::wstring POLICY_DISABLE_PERIODIC_UPDATE_CHECK = L"PeriodicUpdateCheckDisabled";
+ const std::wstring POLICY_DISABLE_SHOW_WHATS_NEW_AFTER_UPDATES = L"DoNotShowWhatsNewAfterUpdates";
// The registry value names for other PowerToys policies.
const std::wstring POLICY_ALLOW_EXPERIMENTATION = L"AllowExperimentation";
@@ -405,11 +407,21 @@ namespace powertoys_gpo {
return getConfiguredValue(POLICY_SUSPEND_NEW_UPDATE_TOAST);
}
+ inline gpo_rule_configured_t getDisableNewUpdateToastValue()
+ {
+ return getConfiguredValue(POLICY_DISABLE_NEW_UPDATE_TOAST);
+ }
+
inline gpo_rule_configured_t getDisablePeriodicUpdateCheckValue()
{
return getConfiguredValue(POLICY_DISABLE_PERIODIC_UPDATE_CHECK);
}
+ inline gpo_rule_configured_t getDisableShowWhatsNewAfterUpdatesValue()
+ {
+ return getConfiguredValue(POLICY_DISABLE_SHOW_WHATS_NEW_AFTER_UPDATES);
+ }
+
inline gpo_rule_configured_t getAllowExperimentationValue()
{
return getConfiguredValue(POLICY_ALLOW_EXPERIMENTATION);
diff --git a/src/common/version/version.h b/src/common/version/version.h
index b300619565..f1602e10c4 100644
--- a/src/common/version/version.h
+++ b/src/common/version/version.h
@@ -13,7 +13,7 @@
#define PRODUCT_VERSION_STRING FILE_VERSION_STRING
#define COMPANY_NAME "Microsoft Corporation"
-#define COPYRIGHT_NOTE "Copyright (C) 2024 Microsoft Corporation"
+#define COPYRIGHT_NOTE "Copyright (C) Microsoft Corporation. All rights reserved."
#define PRODUCT_NAME "PowerToys"
#include
@@ -43,4 +43,4 @@ inline std::wstring get_std_product_version()
L"." + std::to_wstring(VERSION_REVISION) + L".0";
return version;
-}
\ No newline at end of file
+}
diff --git a/src/gpo/assets/PowerToys.admx b/src/gpo/assets/PowerToys.admx
index 42ebfe3349..06757271a0 100644
--- a/src/gpo/assets/PowerToys.admx
+++ b/src/gpo/assets/PowerToys.admx
@@ -1,11 +1,11 @@
-
+
-
+
@@ -16,6 +16,7 @@
+
@@ -439,6 +440,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/gpo/assets/en-US/PowerToys.adml b/src/gpo/assets/en-US/PowerToys.adml
index 2eb3c700b3..0fb97927af 100644
--- a/src/gpo/assets/en-US/PowerToys.adml
+++ b/src/gpo/assets/en-US/PowerToys.adml
@@ -1,7 +1,7 @@
-
+
PowerToys
PowerToys
@@ -18,6 +18,7 @@
PowerToys version 0.75.0 or later
PowerToys version 0.76.0 or later
PowerToys version 0.77.0 or later
+ PowerToys version 0.78.0 or later
This policy configures the enabled state for all PowerToys utilities.
@@ -71,12 +72,26 @@ If enabled, the notification is suspended.
If disabled or not configured, the notification is shown.
Note: The notification about new major versions is always displayed.
+
+This policy has no effect if the update notification is disabled by the policy "Disable Action Center notification for new updates" or the user setting.
+
+ This policy configures whether the action center notification for new updates is shown or not.
+
+If enabled, the notification is disabled.
+
+If disabled or not configured, the user can control if the notification is shown or not.
This policy allows you to disable automatic update checks running in the background. (The manual check in PT Settings is not affected by this policy.)
If enabled, the automatic update checks are disabled.
If disabled or not configured, the automatic update checks are enabled.
+
+ This policy allows you to configure if the window with the release notes is shown after updates.
+
+If enabled, the window with the release notes is not shown automatically.
+
+If disabled or not configured, the user can control this in the settings of PowerToys.
This policy configures whether PowerToys experimentation is allowed. With experimentation allowed the user sees the new features being experimented if it gets selected as part of the test group. (Experimentation will only happen on Windows Insider builds.)
@@ -147,7 +162,9 @@ Note: Changes require a restart of PowerToys Run.
Video Conference Mute: Configure enabled state
Disable per-user installation
Disable automatic downloads
+ Do not show the release notes after updates
Suspend Action Center notification for new updates
+ Disable Action Center notification for new updates
Disable automatic update checks
Allow Experimentation
Configure enabled state for all plugins
diff --git a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj
index 8e57c6ef6a..840bb868a5 100644
--- a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj
+++ b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj
@@ -1,7 +1,7 @@
-
+
true
@@ -145,7 +145,7 @@
-
+
@@ -155,8 +155,8 @@
-
-
+
+
diff --git a/src/modules/MeasureTool/MeasureToolCore/packages.config b/src/modules/MeasureTool/MeasureToolCore/packages.config
index 285cc434ce..627512b778 100644
--- a/src/modules/MeasureTool/MeasureToolCore/packages.config
+++ b/src/modules/MeasureTool/MeasureToolCore/packages.config
@@ -3,5 +3,5 @@
-
+
\ No newline at end of file
diff --git a/src/modules/MouseUtils/FindMyMouse/FindMyMouse.cpp b/src/modules/MouseUtils/FindMyMouse/FindMyMouse.cpp
index 29ab5419ec..51b93c37a6 100644
--- a/src/modules/MouseUtils/FindMyMouse/FindMyMouse.cpp
+++ b/src/modules/MouseUtils/FindMyMouse/FindMyMouse.cpp
@@ -75,6 +75,11 @@ protected:
static constexpr int FinalAlphaDenominator = 100;
winrt::DispatcherQueueController m_dispatcherQueueController{ nullptr };
+ // Don't consider movements started past these milliseconds to detect shaking.
+ int m_shakeIntervalMs = FIND_MY_MOUSE_DEFAULT_SHAKE_INTERVAL_MS;
+ // By which factor must travelled distance be than the diagonal of the rectangle containing the movements. (value in percent)
+ int m_shakeFactor = FIND_MY_MOUSE_DEFAULT_SHAKE_FACTOR;
+
private:
// Save the mouse movement that occurred in any direction.
@@ -87,10 +92,6 @@ private:
// Raw Input may give relative or absolute values. Need to take each case into account.
bool m_seenAnAbsoluteMousePosition = false;
POINT m_lastAbsolutePosition = { 0, 0 };
- // Don't consider movements started past these milliseconds to detect shaking.
- static constexpr LONG ShakeIntervalMs = 1000;
- // By which factor must travelled distance be than the diagonal of the rectangle containing the movements.
- static constexpr float ShakeFactor = 4.0f;
static inline byte GetSign(LONG const& num)
{
@@ -398,7 +399,7 @@ void SuperSonar::OnSonarKeyboardInput(RAWINPUT const& input)
template
void SuperSonar::DetectShake()
{
- ULONGLONG shakeStartTick = GetTickCount64() - ShakeIntervalMs;
+ ULONGLONG shakeStartTick = GetTickCount64() - m_shakeIntervalMs;
// Prune the story of movements for those movements that started too long ago.
std::erase_if(m_movementHistory, [shakeStartTick](const PointerRecentMovement& movement) { return movement.tick < shakeStartTick; });
@@ -429,7 +430,7 @@ void SuperSonar::DetectShake()
double rectangleHeight = static_cast(maxY) - minY;
double diagonal = sqrt(rectangleWidth * rectangleWidth + rectangleHeight * rectangleHeight);
- if (diagonal > 0 && distanceTravelled / diagonal > ShakeFactor)
+ if (diagonal > 0 && distanceTravelled / diagonal > (m_shakeFactor/100.f))
{
m_movementHistory.clear();
StartSonar();
@@ -767,6 +768,8 @@ public:
m_sonarZoomFactor = settings.spotlightInitialZoom;
m_excludedApps = settings.excludedApps;
m_shakeMinimumDistance = settings.shakeMinimumDistance;
+ m_shakeIntervalMs = settings.shakeIntervalMs;
+ m_shakeFactor = settings.shakeFactor;
}
else
{
@@ -794,6 +797,8 @@ public:
m_sonarZoomFactor = localSettings.spotlightInitialZoom;
m_excludedApps = localSettings.excludedApps;
m_shakeMinimumDistance = localSettings.shakeMinimumDistance;
+ m_shakeIntervalMs = localSettings.shakeIntervalMs;
+ m_shakeFactor = localSettings.shakeFactor;
UpdateMouseSnooping(); // For the shake mouse activation method
// Apply new settings to runtime composition objects.
diff --git a/src/modules/MouseUtils/FindMyMouse/FindMyMouse.h b/src/modules/MouseUtils/FindMyMouse/FindMyMouse.h
index 149e52842b..d55b72a34d 100644
--- a/src/modules/MouseUtils/FindMyMouse/FindMyMouse.h
+++ b/src/modules/MouseUtils/FindMyMouse/FindMyMouse.h
@@ -19,6 +19,8 @@ constexpr int FIND_MY_MOUSE_DEFAULT_ANIMATION_DURATION_MS = 500;
constexpr int FIND_MY_MOUSE_DEFAULT_SPOTLIGHT_INITIAL_ZOOM = 9;
constexpr FindMyMouseActivationMethod FIND_MY_MOUSE_DEFAULT_ACTIVATION_METHOD = FindMyMouseActivationMethod::DoubleLeftControlKey;
constexpr int FIND_MY_MOUSE_DEFAULT_SHAKE_MINIMUM_DISTANCE = 1000;
+constexpr int FIND_MY_MOUSE_DEFAULT_SHAKE_INTERVAL_MS = 1000;
+constexpr int FIND_MY_MOUSE_DEFAULT_SHAKE_FACTOR = 400; // 400 percent
struct FindMyMouseSettings
{
@@ -31,6 +33,8 @@ struct FindMyMouseSettings
int animationDurationMs = FIND_MY_MOUSE_DEFAULT_ANIMATION_DURATION_MS;
int spotlightInitialZoom = FIND_MY_MOUSE_DEFAULT_SPOTLIGHT_INITIAL_ZOOM;
int shakeMinimumDistance = FIND_MY_MOUSE_DEFAULT_SHAKE_MINIMUM_DISTANCE;
+ int shakeIntervalMs = FIND_MY_MOUSE_DEFAULT_SHAKE_INTERVAL_MS;
+ int shakeFactor = FIND_MY_MOUSE_DEFAULT_SHAKE_FACTOR;
std::vector excludedApps;
};
diff --git a/src/modules/MouseUtils/FindMyMouse/dllmain.cpp b/src/modules/MouseUtils/FindMyMouse/dllmain.cpp
index 2d1aa55acc..d0102ba507 100644
--- a/src/modules/MouseUtils/FindMyMouse/dllmain.cpp
+++ b/src/modules/MouseUtils/FindMyMouse/dllmain.cpp
@@ -23,6 +23,8 @@ namespace
const wchar_t JSON_KEY_SPOTLIGHT_INITIAL_ZOOM[] = L"spotlight_initial_zoom";
const wchar_t JSON_KEY_EXCLUDED_APPS[] = L"excluded_apps";
const wchar_t JSON_KEY_SHAKING_MINIMUM_DISTANCE[] = L"shaking_minimum_distance";
+ const wchar_t JSON_KEY_SHAKING_INTERVAL_MS[] = L"shaking_interval_ms";
+ const wchar_t JSON_KEY_SHAKING_FACTOR[] = L"shaking_factor";
const wchar_t JSON_KEY_ACTIVATION_SHORTCUT[] = L"activation_shortcut";
}
@@ -396,6 +398,42 @@ void FindMyMouse::parse_settings(PowerToysSettings::PowerToyValues& settings)
{
Logger::warn("Failed to initialize Shaking Minimum Distance from settings. Will use default value");
}
+ try
+ {
+ // Parse Shaking Interval Milliseconds
+ auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_SHAKING_INTERVAL_MS);
+ int value = static_cast(jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE));
+ if (value >= 0)
+ {
+ findMyMouseSettings.shakeIntervalMs = value;
+ }
+ else
+ {
+ throw std::runtime_error("Invalid Shaking Interval Milliseconds value");
+ }
+ }
+ catch (...)
+ {
+ Logger::warn("Failed to initialize Shaking Interval Milliseconds from settings. Will use default value");
+ }
+ try
+ {
+ // Parse Shaking Factor
+ auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_SHAKING_FACTOR);
+ int value = static_cast(jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE));
+ if (value >= 0)
+ {
+ findMyMouseSettings.shakeFactor = value;
+ }
+ else
+ {
+ throw std::runtime_error("Invalid Shaking Factor value");
+ }
+ }
+ catch (...)
+ {
+ Logger::warn("Failed to initialize Shaking Factor from settings. Will use default value");
+ }
try
{
diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.base.rc b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.base.rc
index 75d478289a..c4e1b7cfc5 100644
--- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.base.rc
+++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.base.rc
@@ -39,3 +39,11 @@ BEGIN
END
END
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON "../../Assets/AlwaysOnTop.ico"
diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj
index 3ca65747da..39233d7ed5 100644
--- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj
+++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj
@@ -185,6 +185,9 @@
+
+
+
diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj.filters b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj.filters
index 878894a704..156373674f 100644
--- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj.filters
+++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj.filters
@@ -125,4 +125,9 @@
+
+
+ Resource Files
+
+
\ No newline at end of file
diff --git a/src/modules/alwaysontop/Assets/AlwaysOnTop.ico b/src/modules/alwaysontop/Assets/AlwaysOnTop.ico
new file mode 100644
index 0000000000..fdfc40a14b
Binary files /dev/null and b/src/modules/alwaysontop/Assets/AlwaysOnTop.ico differ
diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/InputInterpreterTests.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/InputInterpreterTests.cs
index 1da5c1d8da..99a1a265b9 100644
--- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/InputInterpreterTests.cs
+++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/InputInterpreterTests.cs
@@ -19,6 +19,12 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter.UnitTest
[DataRow(new string[] { "1'5\"" }, new string[] { "1", "'", "5", "\"" })]
[DataRow(new string[] { "5\"" }, new string[] { "5", "\"" })]
[DataRow(new string[] { "1'5" }, new string[] { "1", "'", "5" })]
+ [DataRow(new string[] { "-1,5'" }, new string[] { "-1,5", "'" })]
+ [DataRow(new string[] { "-1.5'" }, new string[] { "-1.5", "'" })]
+ [DataRow(new string[] { "-1'" }, new string[] { "-1", "'" })]
+ [DataRow(new string[] { "-1'5\"" }, new string[] { "-1", "'", "5", "\"" })]
+ [DataRow(new string[] { "-5\"" }, new string[] { "-5", "\"" })]
+ [DataRow(new string[] { "-1'5" }, new string[] { "-1", "'", "5" })]
public void RegexSplitsInput(string[] input, string[] expectedResult)
{
string[] shortsplit = InputInterpreter.RegexSplitter(input);
@@ -27,6 +33,7 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter.UnitTest
[DataTestMethod]
[DataRow(new string[] { "1cm", "to", "mm" }, new string[] { "1", "cm", "to", "mm" })]
+ [DataRow(new string[] { "-1cm", "to", "mm" }, new string[] { "-1", "cm", "to", "mm" })]
public void InsertsSpaces(string[] input, string[] expectedResult)
{
InputInterpreter.InputSpaceInserter(ref input);
@@ -38,6 +45,10 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter.UnitTest
[DataRow(new string[] { "1\"", "in", "cm" }, new string[] { "1", "inch", "in", "cm" })]
[DataRow(new string[] { "1'6", "in", "cm" }, new string[] { "1.5", "foot", "in", "cm" })]
[DataRow(new string[] { "1'6\"", "in", "cm" }, new string[] { "1.5", "foot", "in", "cm" })]
+ [DataRow(new string[] { "-1'", "in", "cm" }, new string[] { "-1", "foot", "in", "cm" })]
+ [DataRow(new string[] { "-1\"", "in", "cm" }, new string[] { "-1", "inch", "in", "cm" })]
+ [DataRow(new string[] { "-1'6", "in", "cm" }, new string[] { "-1.5", "foot", "in", "cm" })]
+ [DataRow(new string[] { "-1'6\"", "in", "cm" }, new string[] { "-1.5", "foot", "in", "cm" })]
public void HandlesShorthandFeetInchNotation(string[] input, string[] expectedResult)
{
InputInterpreter.ShorthandFeetInchHandler(ref input, CultureInfo.InvariantCulture);
@@ -69,6 +80,8 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter.UnitTest
[DataTestMethod]
[DataRow("a f in c")]
[DataRow("12 f in")]
+ [DataRow("1-2 f in c")]
+ [DataRow("12- f in c")]
public void ParseInvalidQueries(string queryString)
{
Query query = new Query(queryString);
@@ -79,6 +92,8 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter.UnitTest
[DataTestMethod]
[DataRow("12 f in c", 12)]
[DataRow("10m to cm", 10)]
+ [DataRow("-12 f in c", -12)]
+ [DataRow("-10m to cm", -10)]
public void ParseValidQueries(string queryString, double result)
{
Query query = new Query(queryString);
diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/InputInterpreter.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/InputInterpreter.cs
index f9a784181a..5cdaf9683e 100644
--- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/InputInterpreter.cs
+++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/InputInterpreter.cs
@@ -14,11 +14,11 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter
{
public static class InputInterpreter
{
- private static string pattern = @"(?<=\d)(?![,.])(?=\D)|(?<=\D)(?
@@ -31,7 +31,7 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter
return;
}
- string[] parseInputWithoutSpace = Regex.Split(split[0], pattern);
+ string[] parseInputWithoutSpace = Regex.Split(split[0], Pattern);
if (parseInputWithoutSpace.Length > 1)
{
@@ -80,6 +80,12 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter
// ex: 1'2 and 1'2"
if (shortsplit[1] == "\'")
{
+ bool isNegative = shortsplit[0].StartsWith('-');
+ if (isNegative)
+ {
+ shortsplit[0] = shortsplit[0].Remove(0, 1);
+ }
+
bool isFeet = double.TryParse(shortsplit[0], NumberStyles.AllowDecimalPoint, culture, out double feet);
bool isInches = double.TryParse(shortsplit[2], NumberStyles.AllowDecimalPoint, culture, out double inches);
@@ -89,9 +95,13 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter
break;
}
- string convertedTotalInFeet = Length.FromFeetInches(feet, inches).Feet.ToString(culture);
+ double convertedTotalInFeet = Length.FromFeetInches(feet, inches).Feet;
+ if (isNegative)
+ {
+ convertedTotalInFeet *= -1;
+ }
- string[] newInput = new string[] { convertedTotalInFeet, "foot", split[1], split[2] };
+ string[] newInput = new string[] { convertedTotalInFeet.ToString(culture), "foot", split[1], split[2] };
split = newInput;
}
diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspacesApi.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspacesApi.cs
index bd318f0896..0be408dc49 100644
--- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspacesApi.cs
+++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspacesApi.cs
@@ -46,6 +46,11 @@ namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper
path = path[1..];
}
+ if (!DoesPathExist(path, workspaceEnv.Value, machineName))
+ {
+ return null;
+ }
+
var folderName = Path.GetFileName(path);
// Check we haven't returned '' if we have a path like C:\
@@ -67,6 +72,24 @@ namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper
};
}
+ private bool DoesPathExist(string path, WorkspaceEnvironment workspaceEnv, string machineName)
+ {
+ if (workspaceEnv == WorkspaceEnvironment.Local || workspaceEnv == WorkspaceEnvironment.RemoteWSL)
+ {
+ var resolvedPath = path;
+
+ if (workspaceEnv == WorkspaceEnvironment.RemoteWSL)
+ {
+ resolvedPath = $"\\\\wsl$\\{machineName}{resolvedPath.Replace('/', '\\')}";
+ }
+
+ return Directory.Exists(resolvedPath) || File.Exists(resolvedPath);
+ }
+
+ // If the workspace environment is not Local or WSL, assume the path exists
+ return true;
+ }
+
public List Workspaces
{
get
diff --git a/src/modules/launcher/PowerLauncher/Helper/NativeMethods.cs b/src/modules/launcher/PowerLauncher/Helper/NativeMethods.cs
index c6dd2c33ad..5e6ff90c95 100644
--- a/src/modules/launcher/PowerLauncher/Helper/NativeMethods.cs
+++ b/src/modules/launcher/PowerLauncher/Helper/NativeMethods.cs
@@ -69,6 +69,9 @@ namespace PowerLauncher.Helper
[DllImport("user32.DLL", CharSet = CharSet.Unicode)]
internal static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
+ [DllImport("shell32.dll")]
+ public static extern int SHQueryUserNotificationState(out UserNotificationState state);
+
public static string[] CommandLineToArgvW(string cmdLine)
{
IntPtr argv = IntPtr.Zero;
@@ -242,4 +245,15 @@ namespace PowerLauncher.Helper
TRAYMOUSEMESSAGE = 0x800, // WM_USER + 1024
APP = 0x8000,
}
+
+ internal enum UserNotificationState : int
+ {
+ QUNS_NOT_PRESENT = 1,
+ QUNS_BUSY,
+ QUNS_RUNNING_D3D_FULL_SCREEN,
+ QUNS_PRESENTATION_MODE,
+ QUNS_ACCEPTS_NOTIFICATIONS,
+ QUNS_QUIET_TIME,
+ QUNS_APP,
+ }
}
diff --git a/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs b/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs
index 4c0819f203..612476daff 100644
--- a/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs
+++ b/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs
@@ -112,6 +112,15 @@ namespace PowerLauncher.Helper
public static bool IsWindowFullscreen()
{
+ // First, check to see if a game is fullscreen, if so, we definitely have
+ // a full-screen window
+ UserNotificationState state;
+ if (Marshal.GetExceptionForHR(NativeMethods.SHQueryUserNotificationState(out state)) == null &&
+ state == UserNotificationState.QUNS_RUNNING_D3D_FULL_SCREEN)
+ {
+ return true;
+ }
+
// get current active window
IntPtr hWnd = NativeMethods.GetForegroundWindow();
diff --git a/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs b/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs
index 00278adba9..4e62d9d407 100644
--- a/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs
+++ b/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs
@@ -55,6 +55,10 @@ namespace PowerLauncher
_viewModel = mainVM;
_nativeWaiterCancelToken = nativeWaiterCancelToken;
_settings = settings;
+
+ // Fixes #30850
+ AppContext.SetSwitch("Switch.System.Windows.Controls.Grid.StarDefinitionsCanExceedAvailableSpace", true);
+
InitializeComponent();
if (OSVersionHelper.IsWindows11())
diff --git a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj
index 287570edfc..2f911fcd22 100644
--- a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj
+++ b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj
@@ -1,8 +1,8 @@
+
-
true
true
@@ -202,7 +202,7 @@
-
+
@@ -213,8 +213,8 @@
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
diff --git a/src/modules/powerrename/PowerRenameUILib/packages.config b/src/modules/powerrename/PowerRenameUILib/packages.config
index 8820eb03ad..040eedefa7 100644
--- a/src/modules/powerrename/PowerRenameUILib/packages.config
+++ b/src/modules/powerrename/PowerRenameUILib/packages.config
@@ -5,5 +5,5 @@
-
+
\ No newline at end of file
diff --git a/src/runner/UpdateUtils.cpp b/src/runner/UpdateUtils.cpp
index c5f74e31ef..c2297e630d 100644
--- a/src/runner/UpdateUtils.cpp
+++ b/src/runner/UpdateUtils.cpp
@@ -140,9 +140,16 @@ void ProcessNewVersionInfo(const github_version_info& version_info,
return;
}
- // Check notification GPO.
- // We check only if notifications are allowed. This is the case if we are triggered by the periodic check.
- if (show_notifications && powertoys_gpo::getSuspendNewUpdateToastValue() == powertoys_gpo::gpo_rule_configured_enabled)
+ // Check toast notification GPOs and settings. (We check only if notifications are allowed. This is the case if we are triggered by the periodic check.)
+ // Disable notification GPO or setting
+ bool disable_notification_setting = get_general_settings().showNewUpdatesToastNotification == false;
+ if (show_notifications && (disable_notification_setting || powertoys_gpo::getDisableNewUpdateToastValue() == powertoys_gpo::gpo_rule_configured_enabled))
+ {
+ Logger::info(L"There is a new update available or ready to install. But the toast notification is disabled by setting or GPO.");
+ show_notifications = false;
+ }
+ // Suspend notification GPO
+ else if (show_notifications && powertoys_gpo::getSuspendNewUpdateToastValue() == powertoys_gpo::gpo_rule_configured_enabled)
{
Logger::info(L"GPO to suspend new update toast notification is enabled.");
if (new_version_info.version.major <= VERSION_MAJOR && new_version_info.version.minor - VERSION_MINOR <= UPDATE_NOTIFICATION_TOAST_SUSPEND_MINOR_VERSION_COUNT)
diff --git a/src/runner/general_settings.cpp b/src/runner/general_settings.cpp
index 5c56702ab3..9925308507 100644
--- a/src/runner/general_settings.cpp
+++ b/src/runner/general_settings.cpp
@@ -15,7 +15,9 @@
// TODO: would be nice to get rid of these globals, since they're basically cached json settings
static std::wstring settings_theme = L"system";
static bool run_as_elevated = false;
+static bool show_new_updates_toast_notification = true;
static bool download_updates_automatically = true;
+static bool show_whats_new_after_updates = true;
static bool enable_experimentation = true;
static bool enable_warnings_elevated_apps = true;
@@ -38,7 +40,9 @@ json::JsonObject GeneralSettings::to_json()
result.SetNamedValue(L"is_elevated", json::value(isElevated));
result.SetNamedValue(L"run_elevated", json::value(isRunElevated));
+ result.SetNamedValue(L"show_new_updates_toast_notification", json::value(showNewUpdatesToastNotification));
result.SetNamedValue(L"download_updates_automatically", json::value(downloadUpdatesAutomatically));
+ result.SetNamedValue(L"show_whats_new_after_updates", json::value(showWhatsNewAfterUpdates));
result.SetNamedValue(L"enable_experimentation", json::value(enableExperimentation));
result.SetNamedValue(L"is_admin", json::value(isAdmin));
result.SetNamedValue(L"enable_warnings_elevated_apps", json::value(enableWarningsElevatedApps));
@@ -58,7 +62,9 @@ json::JsonObject load_general_settings()
settings_theme = L"system";
}
run_as_elevated = loaded.GetNamedBoolean(L"run_elevated", false);
+ show_new_updates_toast_notification = loaded.GetNamedBoolean(L"show_new_updates_toast_notification", true);
download_updates_automatically = loaded.GetNamedBoolean(L"download_updates_automatically", true) && check_user_is_admin();
+ show_whats_new_after_updates = loaded.GetNamedBoolean(L"show_whats_new_after_updates", true);
enable_experimentation = loaded.GetNamedBoolean(L"enable_experimentation",true);
enable_warnings_elevated_apps = loaded.GetNamedBoolean(L"enable_warnings_elevated_apps", true);
@@ -73,7 +79,9 @@ GeneralSettings get_general_settings()
.isRunElevated = run_as_elevated,
.isAdmin = is_user_admin,
.enableWarningsElevatedApps = enable_warnings_elevated_apps,
+ .showNewUpdatesToastNotification = show_new_updates_toast_notification,
.downloadUpdatesAutomatically = download_updates_automatically && is_user_admin,
+ .showWhatsNewAfterUpdates = show_whats_new_after_updates,
.enableExperimentation = enable_experimentation,
.theme = settings_theme,
.systemTheme = WindowsColors::is_dark_mode() ? L"dark" : L"light",
@@ -97,7 +105,10 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save)
enable_warnings_elevated_apps = general_configs.GetNamedBoolean(L"enable_warnings_elevated_apps", true);
+ show_new_updates_toast_notification = general_configs.GetNamedBoolean(L"show_new_updates_toast_notification", true);
+
download_updates_automatically = general_configs.GetNamedBoolean(L"download_updates_automatically", true);
+ show_whats_new_after_updates = general_configs.GetNamedBoolean(L"show_whats_new_after_updates", true);
enable_experimentation = general_configs.GetNamedBoolean(L"enable_experimentation", true);
diff --git a/src/runner/general_settings.h b/src/runner/general_settings.h
index c2b9dcc03d..f56271cf07 100644
--- a/src/runner/general_settings.h
+++ b/src/runner/general_settings.h
@@ -11,7 +11,9 @@ struct GeneralSettings
bool isRunElevated;
bool isAdmin;
bool enableWarningsElevatedApps;
+ bool showNewUpdatesToastNotification;
bool downloadUpdatesAutomatically;
+ bool showWhatsNewAfterUpdates;
bool enableExperimentation;
std::wstring theme;
std::wstring systemTheme;
diff --git a/src/runner/main.cpp b/src/runner/main.cpp
index a16197655e..1a8f64e738 100644
--- a/src/runner/main.cpp
+++ b/src/runner/main.cpp
@@ -46,6 +46,7 @@
#include
#include
#include
+#include
// disabling warning 4458 - declaration of 'identifier' hides class member
// to avoid warnings from GDI files - can't add winRT directory to external code
@@ -89,9 +90,9 @@ void open_menu_from_another_instance(std::optional settings_window)
PostMessageW(hwnd_main, WM_COMMAND, ID_SETTINGS_MENU_COMMAND, msg);
}
-int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow, bool openOobe, bool openScoobe)
+int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow, bool openOobe, bool openScoobe, bool showRestartNotificationAfterUpdate)
{
- Logger::info("Runner is starting. Elevated={} openOobe={} openScoobe={}", isProcessElevated, openOobe, openScoobe);
+ Logger::info("Runner is starting. Elevated={} openOobe={} openScoobe={} showRestartNotificationAfterUpdate={}", isProcessElevated, openOobe, openScoobe, showRestartNotificationAfterUpdate);
DPIAware::EnableDPIAwarenessForThisProcess();
#if _DEBUG && _WIN64
@@ -106,7 +107,7 @@ int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow
int result = -1;
try
{
- if (!openOobe && openScoobe)
+ if (!openOobe && showRestartNotificationAfterUpdate)
{
std::thread{
[] {
@@ -386,11 +387,13 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR l
}
bool openScoobe = false;
+ bool showRestartNotificationAfterUpdate = false;
try
{
std::wstring last_version_run = PTSettingsHelper::get_last_version_run();
const auto product_version = get_product_version();
openScoobe = product_version != last_version_run;
+ showRestartNotificationAfterUpdate = openScoobe;
Logger::info(L"Scoobe: product_version={} last_version_run={}", product_version, last_version_run);
}
catch (const std::exception& e)
@@ -422,6 +425,16 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR l
const bool run_elevated_setting = general_settings.GetNamedBoolean(L"run_elevated", false);
const bool with_restartedElevated_arg = cmdLine.find("--restartedElevated") != std::string::npos;
+ // Update scoobe behavior based on setting and gpo
+ bool scoobeSettingDisabled = general_settings.GetNamedBoolean(L"show_whats_new_after_updates", true) == false;
+ bool scoobeDisabledByGpo = powertoys_gpo::getDisableShowWhatsNewAfterUpdatesValue() == powertoys_gpo::gpo_rule_configured_enabled;
+ if (openScoobe && (scoobeSettingDisabled || scoobeDisabledByGpo))
+ {
+ // Scoobe should show after an update, but is disabled by policy or setting
+ Logger::info(L"Scoobe: Showing scoobe after updates is disabled by setting or by GPO.");
+ openScoobe = false;
+ }
+
if (elevated && with_dont_elevate_arg && !run_elevated_setting)
{
Logger::info("Scheduling restart as non elevated");
@@ -436,7 +449,7 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR l
Logger::info("Restart as elevated failed. Running non-elevated.");
}
- result = runner(elevated, open_settings, settings_window, openOobe, openScoobe);
+ result = runner(elevated, open_settings, settings_window, openOobe, openScoobe, showRestartNotificationAfterUpdate);
if (result == 0)
{
diff --git a/src/settings-ui/Settings.UI.Library/FindMyMouseProperties.cs b/src/settings-ui/Settings.UI.Library/FindMyMouseProperties.cs
index ba97a590d7..2256898b45 100644
--- a/src/settings-ui/Settings.UI.Library/FindMyMouseProperties.cs
+++ b/src/settings-ui/Settings.UI.Library/FindMyMouseProperties.cs
@@ -43,6 +43,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("shaking_minimum_distance")]
public IntProperty ShakingMinimumDistance { get; set; }
+ [JsonPropertyName("shaking_interval_ms")]
+ public IntProperty ShakingIntervalMs { get; set; }
+
+ [JsonPropertyName("shaking_factor")]
+ public IntProperty ShakingFactor { get; set; }
+
public FindMyMouseProperties()
{
ActivationMethod = new IntProperty(0);
@@ -56,6 +62,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library
SpotlightInitialZoom = new IntProperty(9);
ExcludedApps = new StringProperty();
ShakingMinimumDistance = new IntProperty(1000);
+ ShakingIntervalMs = new IntProperty(1000);
+ ShakingFactor = new IntProperty(400);
}
}
}
diff --git a/src/settings-ui/Settings.UI.Library/GeneralSettings.cs b/src/settings-ui/Settings.UI.Library/GeneralSettings.cs
index 68648bdfbc..f8d4030d3d 100644
--- a/src/settings-ui/Settings.UI.Library/GeneralSettings.cs
+++ b/src/settings-ui/Settings.UI.Library/GeneralSettings.cs
@@ -51,9 +51,15 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("enabled")]
public EnabledModules Enabled { get; set; }
+ [JsonPropertyName("show_new_updates_toast_notification")]
+ public bool ShowNewUpdatesToastNotification { get; set; }
+
[JsonPropertyName("download_updates_automatically")]
public bool AutoDownloadUpdates { get; set; }
+ [JsonPropertyName("show_whats_new_after_updates")]
+ public bool ShowWhatsNewAfterUpdates { get; set; }
+
[JsonPropertyName("enable_experimentation")]
public bool EnableExperimentation { get; set; }
@@ -63,6 +69,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
IsAdmin = false;
EnableWarningsElevatedApps = true;
IsElevated = false;
+ ShowNewUpdatesToastNotification = true;
AutoDownloadUpdates = false;
EnableExperimentation = true;
Theme = "system";
diff --git a/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs b/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs
index 7daa62ae0d..25d5fb4f59 100644
--- a/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs
+++ b/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs
@@ -44,7 +44,6 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
case ModuleType.AlwaysOnTop: return generalSettingsConfig.Enabled.AlwaysOnTop;
case ModuleType.Awake: return generalSettingsConfig.Enabled.Awake;
case ModuleType.ColorPicker: return generalSettingsConfig.Enabled.ColorPicker;
- case ModuleType.CmdNotFound: return generalSettingsConfig.Enabled.CmdNotFound;
case ModuleType.CropAndLock: return generalSettingsConfig.Enabled.CropAndLock;
case ModuleType.EnvironmentVariables: return generalSettingsConfig.Enabled.EnvironmentVariables;
case ModuleType.FancyZones: return generalSettingsConfig.Enabled.FancyZones;
@@ -77,7 +76,6 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
case ModuleType.AlwaysOnTop: generalSettingsConfig.Enabled.AlwaysOnTop = isEnabled; break;
case ModuleType.Awake: generalSettingsConfig.Enabled.Awake = isEnabled; break;
case ModuleType.ColorPicker: generalSettingsConfig.Enabled.ColorPicker = isEnabled; break;
- case ModuleType.CmdNotFound: generalSettingsConfig.Enabled.CmdNotFound = isEnabled; break;
case ModuleType.CropAndLock: generalSettingsConfig.Enabled.CropAndLock = isEnabled; break;
case ModuleType.EnvironmentVariables: generalSettingsConfig.Enabled.EnvironmentVariables = isEnabled; break;
case ModuleType.FancyZones: generalSettingsConfig.Enabled.FancyZones = isEnabled; break;
@@ -109,7 +107,6 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
case ModuleType.AlwaysOnTop: return GPOWrapper.GetConfiguredAlwaysOnTopEnabledValue();
case ModuleType.Awake: return GPOWrapper.GetConfiguredAwakeEnabledValue();
case ModuleType.ColorPicker: return GPOWrapper.GetConfiguredColorPickerEnabledValue();
- case ModuleType.CmdNotFound: return GPOWrapper.GetConfiguredCmdNotFoundEnabledValue();
case ModuleType.CropAndLock: return GPOWrapper.GetConfiguredCropAndLockEnabledValue();
case ModuleType.EnvironmentVariables: return GPOWrapper.GetConfiguredEnvironmentVariablesEnabledValue();
case ModuleType.FancyZones: return GPOWrapper.GetConfiguredFancyZonesEnabledValue();
@@ -142,7 +139,6 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
ModuleType.AlwaysOnTop => Color.FromArgb(255, 74, 196, 242), // #4ac4f2
ModuleType.Awake => Color.FromArgb(255, 40, 177, 233), // #28b1e9
ModuleType.ColorPicker => Color.FromArgb(255, 7, 129, 211), // #0781d3
- ModuleType.CmdNotFound => Color.FromArgb(255, 31, 164, 227), // #1fa4e3
ModuleType.CropAndLock => Color.FromArgb(255, 32, 166, 228), // #20a6e4
ModuleType.EnvironmentVariables => Color.FromArgb(255, 16, 132, 208), // #1084d0
ModuleType.FancyZones => Color.FromArgb(255, 65, 209, 247), // #41d1f7
@@ -175,7 +171,6 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
ModuleType.AlwaysOnTop => typeof(AlwaysOnTopPage),
ModuleType.Awake => typeof(AwakePage),
ModuleType.ColorPicker => typeof(ColorPickerPage),
- ModuleType.CmdNotFound => typeof(CmdNotFoundPage),
ModuleType.CropAndLock => typeof(CropAndLockPage),
ModuleType.EnvironmentVariables => typeof(EnvironmentVariablesPage),
ModuleType.FancyZones => typeof(FancyZonesPage),
diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/GeneralPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/GeneralPage.xaml
index 2a5fb16385..857b027808 100644
--- a/src/settings-ui/Settings.UI/SettingsXAML/Views/GeneralPage.xaml
+++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/GeneralPage.xaml
@@ -188,6 +188,29 @@
IsOpen="{x:Bind ViewModel.ShowAutoDownloadUpdatesGpoInformation, Mode=OneWay}"
IsTabStop="{x:Bind ViewModel.ShowAutoDownloadUpdatesGpoInformation, Mode=OneWay}"
Severity="Informational" />
+
+
+
+
+
+
+
+
+
+
diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml
index 0228c9f2d4..39aa3e6e95 100644
--- a/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml
+++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml
@@ -56,6 +56,26 @@
SpinButtonPlacementMode="Compact"
Value="{x:Bind ViewModel.FindMyMouseShakingMinimumDistance, Mode=TwoWay}" />
+
+
+
+
+
+
The minimum distance for mouse shaking activation, for adjusting sensitivity
+
+ Shake Interval (ms)
+ ms = milliseconds
+
+
+ The span of time during which we track mouse movement to detect shaking, for adjusting sensitivity
+
+
+ Shake factor (percent)
+
+
+ Mouse shaking is detected by checking how much the mouse pointer has travelled when compared to the diagonal of the movement area. Reducing this factor increases sensitivity.
+
Mouse Highlighter
Refers to the utility name
@@ -3998,7 +4011,16 @@ Activate by holding the key for the character you want to add an accent to, then
Text size of result titles
+
+ Show the release notes after updates
+
Command Not Found is not supported on the ARM64 architecture currently. We are actively working on a solution.
-
+
+ Notifications in the settings and the tray flyout are always shown
+
+
+ Show notifications for new updates
+
+
\ No newline at end of file
diff --git a/src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs
index 17b6e2b142..e449356beb 100644
--- a/src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs
+++ b/src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs
@@ -121,7 +121,9 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
_startup = GeneralSettingsConfig.Startup;
+ _showNewUpdatesToastNotification = GeneralSettingsConfig.ShowNewUpdatesToastNotification;
_autoDownloadUpdates = GeneralSettingsConfig.AutoDownloadUpdates;
+ _showWhatsNewAfterUpdates = GeneralSettingsConfig.ShowWhatsNewAfterUpdates;
_enableExperimentation = GeneralSettingsConfig.EnableExperimentation;
_isElevated = isElevated;
@@ -138,8 +140,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
_newAvailableVersionLink = UpdatingSettingsConfig.ReleasePageLink;
_updateCheckedDate = UpdatingSettingsConfig.LastCheckedDateLocalized;
- _experimentationIsGpoDisallowed = GPOWrapper.GetAllowExperimentationValue() == GpoRuleConfigured.Disabled;
+ _newUpdatesToastIsGpoDisabled = GPOWrapper.GetDisableNewUpdateToastValue() == GpoRuleConfigured.Enabled;
_autoDownloadUpdatesIsGpoDisabled = GPOWrapper.GetDisableAutomaticUpdateDownloadValue() == GpoRuleConfigured.Enabled;
+ _experimentationIsGpoDisallowed = GPOWrapper.GetAllowExperimentationValue() == GpoRuleConfigured.Disabled;
+ _showWhatsNewAfterUpdatesIsGpoDisabled = GPOWrapper.GetDisableShowWhatsNewAfterUpdatesValue() == GpoRuleConfigured.Enabled;
if (dispatcherAction != null)
{
@@ -154,8 +158,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private bool _enableWarningsElevatedApps;
private int _themeIndex;
+ private bool _showNewUpdatesToastNotification;
+ private bool _newUpdatesToastIsGpoDisabled;
private bool _autoDownloadUpdates;
private bool _autoDownloadUpdatesIsGpoDisabled;
+ private bool _showWhatsNewAfterUpdates;
+ private bool _showWhatsNewAfterUpdatesIsGpoDisabled;
private bool _enableExperimentation;
private bool _experimentationIsGpoDisallowed;
@@ -299,6 +307,29 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
}
+ public bool ShowNewUpdatesToastNotification
+ {
+ get
+ {
+ return _showNewUpdatesToastNotification && !_newUpdatesToastIsGpoDisabled;
+ }
+
+ set
+ {
+ if (_showNewUpdatesToastNotification != value)
+ {
+ _showNewUpdatesToastNotification = value;
+ GeneralSettingsConfig.ShowNewUpdatesToastNotification = value;
+ NotifyPropertyChanged();
+ }
+ }
+ }
+
+ public bool IsNewUpdatesToastDisabledGpoConfigured
+ {
+ get => _newUpdatesToastIsGpoDisabled;
+ }
+
public bool AutoDownloadUpdates
{
get
@@ -329,6 +360,29 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
get => _isAdmin && _autoDownloadUpdatesIsGpoDisabled;
}
+ public bool ShowWhatsNewAfterUpdates
+ {
+ get
+ {
+ return _showWhatsNewAfterUpdates && !_showWhatsNewAfterUpdatesIsGpoDisabled;
+ }
+
+ set
+ {
+ if (_showWhatsNewAfterUpdates != value)
+ {
+ _showWhatsNewAfterUpdates = value;
+ GeneralSettingsConfig.ShowWhatsNewAfterUpdates = value;
+ NotifyPropertyChanged();
+ }
+ }
+ }
+
+ public bool ShowWhatsNewAfterUpdatesIsGpoDisabled
+ {
+ get => _showWhatsNewAfterUpdatesIsGpoDisabled;
+ }
+
public bool EnableExperimentation
{
get
diff --git a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs
index f7b9934e58..05d8184a46 100644
--- a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs
+++ b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs
@@ -58,6 +58,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
_findMyMouseSpotlightInitialZoom = FindMyMouseSettingsConfig.Properties.SpotlightInitialZoom.Value;
_findMyMouseExcludedApps = FindMyMouseSettingsConfig.Properties.ExcludedApps.Value;
_findMyMouseShakingMinimumDistance = FindMyMouseSettingsConfig.Properties.ShakingMinimumDistance.Value;
+ _findMyMouseShakingIntervalMs = FindMyMouseSettingsConfig.Properties.ShakingIntervalMs.Value;
+ _findMyMouseShakingFactor = FindMyMouseSettingsConfig.Properties.ShakingFactor.Value;
ArgumentNullException.ThrowIfNull(mouseHighlighterSettingsRepository);
@@ -402,6 +404,42 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
}
+ public int FindMyMouseShakingIntervalMs
+ {
+ get
+ {
+ return _findMyMouseShakingIntervalMs;
+ }
+
+ set
+ {
+ if (value != _findMyMouseShakingIntervalMs)
+ {
+ _findMyMouseShakingIntervalMs = value;
+ FindMyMouseSettingsConfig.Properties.ShakingIntervalMs.Value = value;
+ NotifyFindMyMousePropertyChanged();
+ }
+ }
+ }
+
+ public int FindMyMouseShakingFactor
+ {
+ get
+ {
+ return _findMyMouseShakingFactor;
+ }
+
+ set
+ {
+ if (value != _findMyMouseShakingFactor)
+ {
+ _findMyMouseShakingFactor = value;
+ FindMyMouseSettingsConfig.Properties.ShakingFactor.Value = value;
+ NotifyFindMyMousePropertyChanged();
+ }
+ }
+ }
+
public void NotifyFindMyMousePropertyChanged([CallerMemberName] string propertyName = null)
{
OnPropertyChanged(propertyName);
@@ -944,6 +982,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private int _findMyMouseSpotlightInitialZoom;
private string _findMyMouseExcludedApps;
private int _findMyMouseShakingMinimumDistance;
+ private int _findMyMouseShakingIntervalMs;
+ private int _findMyMouseShakingFactor;
private GpoRuleConfigured _highlighterEnabledGpoRuleConfiguration;
private bool _highlighterEnabledStateIsGPOConfigured;