diff --git a/.pipelines/ESRPSigning_core.json b/.pipelines/ESRPSigning_core.json index fcd5e5c03c..237e48b409 100644 --- a/.pipelines/ESRPSigning_core.json +++ b/.pipelines/ESRPSigning_core.json @@ -21,6 +21,8 @@ "PowerToys.ManagedCommon.dll", "PowerToys.Common.UI.dll", "PowerToys.Settings.UI.Lib.dll", + "PowerToys.GPOWrapper.dll", + "PowerToys.GPOWrapperProjection.dll", "modules\\AlwaysOnTop\\PowerToys.AlwaysOnTop.exe", "modules\\AlwaysOnTop\\PowerToys.AlwaysOnTopModuleInterface.dll", diff --git a/.pipelines/release.yml b/.pipelines/release.yml index 16e79aaf19..f630815610 100644 --- a/.pipelines/release.yml +++ b/.pipelines/release.yml @@ -528,5 +528,11 @@ jobs: PathtoPublish: $(System.ArtifactsDirectory) ArtifactName: setup-$(BuildPlatform) + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: GPO Files' + inputs: + PathtoPublish: doc\gpo\assets + ArtifactName: GroupPolicyObjectsFiles + ... diff --git a/PowerToys.sln b/PowerToys.sln index 437de874b2..867ba3a6db 100644 --- a/PowerToys.sln +++ b/PowerToys.sln @@ -272,6 +272,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "utils", "utils", "{B39DC643 src\common\utils\excluded_apps.h = src\common\utils\excluded_apps.h src\common\utils\exec.h = src\common\utils\exec.h src\common\utils\game_mode.h = src\common\utils\game_mode.h + src\common\utils\gpo.h = src\common\utils\gpo.h src\common\utils\HDropIterator.h = src\common\utils\HDropIterator.h src\common\utils\HttpClient.h = src\common\utils\HttpClient.h src\common\utils\json.h = src\common\utils\json.h @@ -457,6 +458,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hosts.Tests", "src\modules\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HostsModuleInterface", "src\modules\Hosts\HostsModuleInterface\HostsModuleInterface.vcxproj", "{B41B888C-7DB8-4747-B262-4062E05A230D}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPOWrapper", "src\common\GPOWrapper\GPOWrapper.vcxproj", "{E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GPOWrapperProjection", "src\common\GPOWrapperProjection\GPOWrapperProjection.csproj", "{00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM64 = Debug|ARM64 @@ -1848,6 +1853,30 @@ Global {B41B888C-7DB8-4747-B262-4062E05A230D}.Release|x64.Build.0 = Release|x64 {B41B888C-7DB8-4747-B262-4062E05A230D}.Release|x86.ActiveCfg = Release|x64 {B41B888C-7DB8-4747-B262-4062E05A230D}.Release|x86.Build.0 = Release|x64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Debug|ARM64.Build.0 = Debug|ARM64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Debug|x64.ActiveCfg = Debug|x64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Debug|x64.Build.0 = Debug|x64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Debug|x86.ActiveCfg = Debug|x64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Debug|x86.Build.0 = Debug|x64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Release|ARM64.ActiveCfg = Release|ARM64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Release|ARM64.Build.0 = Release|ARM64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Release|x64.ActiveCfg = Release|x64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Release|x64.Build.0 = Release|x64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Release|x86.ActiveCfg = Release|x64 + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}.Release|x86.Build.0 = Release|x64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Debug|ARM64.Build.0 = Debug|ARM64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Debug|x64.ActiveCfg = Debug|x64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Debug|x64.Build.0 = Debug|x64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Debug|x86.ActiveCfg = Debug|x64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Debug|x86.Build.0 = Debug|x64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|ARM64.ActiveCfg = Release|ARM64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|ARM64.Build.0 = Release|ARM64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|x64.ActiveCfg = Release|x64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|x64.Build.0 = Release|x64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|x86.ActiveCfg = Release|x64 + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|x86.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2004,6 +2033,8 @@ Global {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC} {E2D03E0F-7A75-4813-9F4B-D8763D43FD3A} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA} {B41B888C-7DB8-4747-B262-4062E05A230D} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA} + {E599C30B-9DC8-4E5A-BF27-93D4CCEDE788} = {1AFB6476-670D-4E80-A464-657E01DFF482} + {00EE9BA6-4E8F-43CA-960D-D4882F0FBB97} = {1AFB6476-670D-4E80-A464-657E01DFF482} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0} diff --git a/doc/gpo/README.md b/doc/gpo/README.md new file mode 100644 index 0000000000..482c3f6271 --- /dev/null +++ b/doc/gpo/README.md @@ -0,0 +1,33 @@ +# Group Policy Objects + +Since version 0.64, PowerToys is released on GitHub with GroupPolicyObject files. You can check these releases on https://github.com/microsoft/PowerToys/releases . + +## How to install + +### Add the administrative template to an individual computer + +1. Copy the "PowerToys.admx" file to your Policy Definition template folder. (Example: C:\Windows\PolicyDefinitions) +2. Copy the "PowerToys.adml" file to the matching language folder in your Policy Definition folder. (Example: C:\Windows\PolicyDefinitions\en-US) + +### Add the administrative template to Active Directory + +1. On a domain controller or workstation with RSAT, go to the **PolicyDefinition** folder (also known as the *Central Store*) on any domain controller for your domain. For older versions of Windows Server, you might need to create the **PolicyDefinition** folder. For more information, see [How to create and manage the Central Store for Group Policy Administrative Templates in Windows](https://support.microsoft.com/help/3087759/how-to-create-and-manage-the-central-store-for-group-policy-administra). +2. Copy the "PowerToys.admx" file to the PolicyDefinition folder. (Example: %systemroot%\sysvol\domain\policies\PolicyDefinitions) +3. Copy the "PowerToys.adml" file to the matching language folder in the PolicyDefinition folder. Create the folder if it doesn't already exist. (Example: %systemroot%\sysvol\domain\policies\PolicyDefinitions\EN-US) +4. If your domain has more than one domain controller, the new ADMX files will be replicated to them at the next domain replication interval. + +### Scope + +You will find the policies under "Administrative Templates/Microsoft PowerToys" in both the Computer Configuration and User Configuration folders. If both settings are configured, the setting in Computer Configuration takes precedence over the setting in User Configuration. + +## Policies + +### Configure enabled state + +For each utility shipped with PowerToys, there's a "Configure enabled state" policy, which forces and Enabled state for the utility. + +If you enable this setting, the utility will be always enabled and the user won't be able to disable it. + +If you disable this setting, the utility will be always disabled and the user won't be able to enable it. + +If you don't configure this setting, users are able to disable or enable the utility. diff --git a/doc/gpo/assets/PowerToys.admx b/doc/gpo/assets/PowerToys.admx new file mode 100644 index 0000000000..1ae32fcb79 --- /dev/null +++ b/doc/gpo/assets/PowerToys.admx @@ -0,0 +1,281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/gpo/assets/en-US/PowerToys.adml b/doc/gpo/assets/en-US/PowerToys.adml new file mode 100644 index 0000000000..d53ee7c8e6 --- /dev/null +++ b/doc/gpo/assets/en-US/PowerToys.adml @@ -0,0 +1,60 @@ + + + + PowerToys + PowerToys + + + Microsoft PowerToys + + PowerToys version 0.64.0 or later + + This policy configures the enabled state for a PowerToys utility. + +If you enable this setting, the utility will be always enabled and the user won't be able to disable it. + +If you disable this setting, the utility will be always disabled and the user won't be able to enable it. + +If you don't configure this setting, users are able to disable or enable the utility. + + (Note: There have been reports of incompatibility between the PDF Preview Handler and Outlook) + +This policy configures the enabled state for a PowerToys utility. + +If you enable this setting, the utility will be always enabled and the user won't be able to disable it. + +If you disable this setting, the utility will be always disabled and the user won't be able to enable it. + +If you don't configure this setting, users are able to disable or enable the utility. + + Always On Top: Configure enabled state + Awake: Configure enabled state + Color Picker: Configure enabled state + FancyZones: Configure enabled state + SVG file preview: Configure enabled state + Markdown file preview: Configure enabled state + Source code file preview: Configure enabled state + PDF file preview: Configure enabled state + Gcode file preview: Configure enabled state + SVG file thumbnail: Configure enabled state + PDF file thumbnail: Configure enabled state + Gcode file thumbnail: Configure enabled state + STL file thumbnail: Configure enabled state + Hosts file editor: Configure enabled state + Image Resizer: Configure enabled state + Keyboard Manager: Configure enabled state + Find My Mouse: Configure enabled state + Mouse Highlighter: Configure enabled state + Mouse Pointer Crosshairs: Configure enabled state + Power Rename: Configure enabled state + PowerToys Run: Configure enabled state + Quick Accent: Configure enabled state + Screen Ruler: Configure enabled state + Shortcut Guide: Configure enabled state + Text Extractor: Configure enabled state + Video Conference Mute: Configure enabled state + + + + diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index 80ebeb4a2a..d2caac5336 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -44,13 +44,13 @@ --> - + - + - + - + @@ -120,9 +120,9 @@ - + - + @@ -134,7 +134,7 @@ - + - - + + @@ -1022,8 +1022,8 @@ - - + + @@ -1032,8 +1032,8 @@ - - + + @@ -1991,9 +1991,9 @@ - + - + diff --git a/src/common/GPOWrapper/GPOWrapper.cpp b/src/common/GPOWrapper/GPOWrapper.cpp new file mode 100644 index 0000000000..b3cd0be71e --- /dev/null +++ b/src/common/GPOWrapper/GPOWrapper.cpp @@ -0,0 +1,111 @@ +#include "pch.h" +#include "GPOWrapper.h" +#include "GPOWrapper.g.cpp" + +namespace winrt::PowerToys::GPOWrapper::implementation +{ + GpoRuleConfigured GPOWrapper::GetConfiguredAlwaysOnTopEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredAlwaysOnTopEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredAwakeEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredAwakeEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredColorPickerEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredColorPickerEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredFancyZonesEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredFancyZonesEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredSvgPreviewEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredSvgPreviewEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredMarkdownPreviewEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredMarkdownPreviewEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredMonacoPreviewEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredMonacoPreviewEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredPdfPreviewEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredPdfPreviewEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredGcodePreviewEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredGcodePreviewEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredSvgThumbnailsEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredSvgThumbnailsEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredPdfThumbnailsEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredPdfThumbnailsEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredGcodeThumbnailsEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredGcodeThumbnailsEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredStlThumbnailsEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredStlThumbnailsEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredHostsFileEditorEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredHostsFileEditorEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredImageResizerEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredImageResizerEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredKeyboardManagerEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredKeyboardManagerEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredFindMyMouseEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredFindMyMouseEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredMouseHighlighterEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredMouseHightlighterEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredMousePointerCrosshairsEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredMousePointerCrosshairsEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredPowerRenameEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredPowerRenameEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredPowerLauncherEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredPowerLauncherEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredQuickAccentEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredQuickAccentEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredScreenRulerEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredScreenRulerEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredShortcutGuideEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredShortcutGuideEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredTextExtractorEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredTextExtractorEnabledValue(); + } + GpoRuleConfigured GPOWrapper::GetConfiguredVideoConferenceMuteEnabledValue() + { + return (GpoRuleConfigured)powertoys_gpo::getConfiguredVideoConferenceMuteEnabledValue(); + } +} diff --git a/src/common/GPOWrapper/GPOWrapper.def b/src/common/GPOWrapper/GPOWrapper.def new file mode 100644 index 0000000000..24e7c1235c --- /dev/null +++ b/src/common/GPOWrapper/GPOWrapper.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/src/common/GPOWrapper/GPOWrapper.h b/src/common/GPOWrapper/GPOWrapper.h new file mode 100644 index 0000000000..47079ee781 --- /dev/null +++ b/src/common/GPOWrapper/GPOWrapper.h @@ -0,0 +1,44 @@ +#pragma once +#include "GPOWrapper.g.h" +#include + +namespace winrt::PowerToys::GPOWrapper::implementation +{ + struct GPOWrapper : GPOWrapperT + { + GPOWrapper() = default; + static GpoRuleConfigured GetConfiguredAlwaysOnTopEnabledValue(); + static GpoRuleConfigured GetConfiguredAwakeEnabledValue(); + static GpoRuleConfigured GetConfiguredColorPickerEnabledValue(); + static GpoRuleConfigured GetConfiguredFancyZonesEnabledValue(); + static GpoRuleConfigured GetConfiguredSvgPreviewEnabledValue(); + static GpoRuleConfigured GetConfiguredMarkdownPreviewEnabledValue(); + static GpoRuleConfigured GetConfiguredMonacoPreviewEnabledValue(); + static GpoRuleConfigured GetConfiguredPdfPreviewEnabledValue(); + static GpoRuleConfigured GetConfiguredGcodePreviewEnabledValue(); + static GpoRuleConfigured GetConfiguredSvgThumbnailsEnabledValue(); + static GpoRuleConfigured GetConfiguredPdfThumbnailsEnabledValue(); + static GpoRuleConfigured GetConfiguredGcodeThumbnailsEnabledValue(); + static GpoRuleConfigured GetConfiguredStlThumbnailsEnabledValue(); + static GpoRuleConfigured GetConfiguredHostsFileEditorEnabledValue(); + static GpoRuleConfigured GetConfiguredImageResizerEnabledValue(); + static GpoRuleConfigured GetConfiguredKeyboardManagerEnabledValue(); + static GpoRuleConfigured GetConfiguredFindMyMouseEnabledValue(); + static GpoRuleConfigured GetConfiguredMouseHighlighterEnabledValue(); + static GpoRuleConfigured GetConfiguredMousePointerCrosshairsEnabledValue(); + static GpoRuleConfigured GetConfiguredPowerRenameEnabledValue(); + static GpoRuleConfigured GetConfiguredPowerLauncherEnabledValue(); + static GpoRuleConfigured GetConfiguredQuickAccentEnabledValue(); + static GpoRuleConfigured GetConfiguredScreenRulerEnabledValue(); + static GpoRuleConfigured GetConfiguredShortcutGuideEnabledValue(); + static GpoRuleConfigured GetConfiguredTextExtractorEnabledValue(); + static GpoRuleConfigured GetConfiguredVideoConferenceMuteEnabledValue(); + }; +} + +namespace winrt::PowerToys::GPOWrapper::factory_implementation +{ + struct GPOWrapper : GPOWrapperT + { + }; +} diff --git a/src/common/GPOWrapper/GPOWrapper.idl b/src/common/GPOWrapper/GPOWrapper.idl new file mode 100644 index 0000000000..2b25ba772f --- /dev/null +++ b/src/common/GPOWrapper/GPOWrapper.idl @@ -0,0 +1,42 @@ +namespace PowerToys +{ + namespace GPOWrapper + { + enum GpoRuleConfigured + { + WrongValue = -3, + Unavailable = -2, + NotConfigured = -1, + Disabled = 0, + Enabled = 1 + }; + [default_interface] static runtimeclass GPOWrapper { + static GpoRuleConfigured GetConfiguredAlwaysOnTopEnabledValue(); + static GpoRuleConfigured GetConfiguredAwakeEnabledValue(); + static GpoRuleConfigured GetConfiguredColorPickerEnabledValue(); + static GpoRuleConfigured GetConfiguredFancyZonesEnabledValue(); + static GpoRuleConfigured GetConfiguredSvgPreviewEnabledValue(); + static GpoRuleConfigured GetConfiguredMarkdownPreviewEnabledValue(); + static GpoRuleConfigured GetConfiguredMonacoPreviewEnabledValue(); + static GpoRuleConfigured GetConfiguredPdfPreviewEnabledValue(); + static GpoRuleConfigured GetConfiguredGcodePreviewEnabledValue(); + static GpoRuleConfigured GetConfiguredSvgThumbnailsEnabledValue(); + static GpoRuleConfigured GetConfiguredPdfThumbnailsEnabledValue(); + static GpoRuleConfigured GetConfiguredGcodeThumbnailsEnabledValue(); + static GpoRuleConfigured GetConfiguredStlThumbnailsEnabledValue(); + static GpoRuleConfigured GetConfiguredHostsFileEditorEnabledValue(); + static GpoRuleConfigured GetConfiguredImageResizerEnabledValue(); + static GpoRuleConfigured GetConfiguredKeyboardManagerEnabledValue(); + static GpoRuleConfigured GetConfiguredFindMyMouseEnabledValue(); + static GpoRuleConfigured GetConfiguredMouseHighlighterEnabledValue(); + static GpoRuleConfigured GetConfiguredMousePointerCrosshairsEnabledValue(); + static GpoRuleConfigured GetConfiguredPowerRenameEnabledValue(); + static GpoRuleConfigured GetConfiguredPowerLauncherEnabledValue(); + static GpoRuleConfigured GetConfiguredQuickAccentEnabledValue(); + static GpoRuleConfigured GetConfiguredScreenRulerEnabledValue(); + static GpoRuleConfigured GetConfiguredShortcutGuideEnabledValue(); + static GpoRuleConfigured GetConfiguredTextExtractorEnabledValue(); + static GpoRuleConfigured GetConfiguredVideoConferenceMuteEnabledValue(); + } + } +} diff --git a/src/common/GPOWrapper/GPOWrapper.rc b/src/common/GPOWrapper/GPOWrapper.rc new file mode 100644 index 0000000000..5fa3c8b90d --- /dev/null +++ b/src/common/GPOWrapper/GPOWrapper.rc @@ -0,0 +1,40 @@ +#include +#include "resource.h" +#include "../../../common/version/version.h" + +#define APSTUDIO_READONLY_SYMBOLS +#include "winres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +1 VERSIONINFO +FILEVERSION FILE_VERSION +PRODUCTVERSION PRODUCT_VERSION +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG +FILEFLAGS VS_FF_DEBUG +#else +FILEFLAGS 0x0L +#endif +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_DLL +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset + BEGIN + VALUE "CompanyName", COMPANY_NAME + VALUE "FileDescription", FILE_DESCRIPTION + VALUE "FileVersion", FILE_VERSION_STRING + VALUE "InternalName", INTERNAL_NAME + VALUE "LegalCopyright", COPYRIGHT_NOTE + VALUE "OriginalFilename", ORIGINAL_FILENAME + VALUE "ProductName", PRODUCT_NAME + VALUE "ProductVersion", PRODUCT_VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset + END +END diff --git a/src/common/GPOWrapper/GPOWrapper.vcxproj b/src/common/GPOWrapper/GPOWrapper.vcxproj new file mode 100644 index 0000000000..9ae857ded1 --- /dev/null +++ b/src/common/GPOWrapper/GPOWrapper.vcxproj @@ -0,0 +1,127 @@ + + + + + true + true + true + true + {e599c30b-9dc8-4e5a-bf27-93d4ccede788} + GPOWrapper + PowerToys.GPOWrapper + en-US + 14.0 + false + false + Windows Store + 10.0 + 10.0.20348.0 + 10.0.17134.0 + + + + DynamicLibrary + v143 + Unicode + false + true + + + true + true + + + false + true + false + + + + + + + + + + + + + + + PowerToys.GPOWrapper + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) + ../..;%(AdditionalIncludeDirectories) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + + + Console + false + GPOWrapper.def + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + GPOWrapper.idl + + + + + + Create + + + GPOWrapper.idl + + + + + + + + + + + + + + false + + + + + + + + + + + + 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}. + + + + + \ No newline at end of file diff --git a/src/common/GPOWrapper/GPOWrapper.vcxproj.filters b/src/common/GPOWrapper/GPOWrapper.vcxproj.filters new file mode 100644 index 0000000000..4377e536ea --- /dev/null +++ b/src/common/GPOWrapper/GPOWrapper.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + accd3aa8-1ba0-4223-9bbe-0c431709210b + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {926ab91d-31b4-48c3-b9a4-e681349f27f0} + + + + + + + + + + + + + + + + + + + + + + + + + + + Resources + + + \ No newline at end of file diff --git a/src/common/GPOWrapper/PropertySheet.props b/src/common/GPOWrapper/PropertySheet.props new file mode 100644 index 0000000000..e34141b019 --- /dev/null +++ b/src/common/GPOWrapper/PropertySheet.props @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/src/common/GPOWrapper/packages.config b/src/common/GPOWrapper/packages.config new file mode 100644 index 0000000000..48319b8c95 --- /dev/null +++ b/src/common/GPOWrapper/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/common/GPOWrapper/pch.cpp b/src/common/GPOWrapper/pch.cpp new file mode 100644 index 0000000000..bcb5590be1 --- /dev/null +++ b/src/common/GPOWrapper/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/src/common/GPOWrapper/pch.h b/src/common/GPOWrapper/pch.h new file mode 100644 index 0000000000..21199686d5 --- /dev/null +++ b/src/common/GPOWrapper/pch.h @@ -0,0 +1,4 @@ +#pragma once +#include +#include +#include diff --git a/src/common/GPOWrapper/resource.h b/src/common/GPOWrapper/resource.h new file mode 100644 index 0000000000..d1a3bc654c --- /dev/null +++ b/src/common/GPOWrapper/resource.h @@ -0,0 +1,13 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by PowerToys.MeasureToolCore.rc + +////////////////////////////// +// Non-localizable + +#define FILE_DESCRIPTION "PowerToys GPOWrapper" +#define INTERNAL_NAME "PowerToys.GPOWrapper" +#define ORIGINAL_FILENAME "PowerToys.GPOWrapper.dll" + +// Non-localizable +////////////////////////////// diff --git a/src/common/GPOWrapperProjection/GPOWrapper.cs b/src/common/GPOWrapperProjection/GPOWrapper.cs new file mode 100644 index 0000000000..7017a42084 --- /dev/null +++ b/src/common/GPOWrapperProjection/GPOWrapper.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace PowerToys.GPOWrapperProjection +{ + public enum GpoRuleConfigured : int + { + WrongValue = PowerToys.GPOWrapper.GpoRuleConfigured.WrongValue, + Unavailable = PowerToys.GPOWrapper.GpoRuleConfigured.Unavailable, + NotConfigured = PowerToys.GPOWrapper.GpoRuleConfigured.NotConfigured, + Disabled = PowerToys.GPOWrapper.GpoRuleConfigured.Disabled, + Enabled = PowerToys.GPOWrapper.GpoRuleConfigured.Enabled, + } + + // Some WPF applications have trouble consuming WinRT/C++ projections, because WPF makes an intermediary _wpftmp.csproj which doesn't build projections correctly on MSBUILD. + // This is a workaround to give access to GPOWrapper for WPF applications. + public static class GPOWrapper + { + public static GpoRuleConfigured GetConfiguredPowerLauncherEnabledValue() + { + return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetConfiguredPowerLauncherEnabledValue(); + } + + public static GpoRuleConfigured GetConfiguredFancyZonesEnabledValue() + { + return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetConfiguredFancyZonesEnabledValue(); + } + + public static GpoRuleConfigured GetConfiguredColorPickerEnabledValue() + { + return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetConfiguredColorPickerEnabledValue(); + } + + public static GpoRuleConfigured GetConfiguredImageResizerEnabledValue() + { + return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetConfiguredImageResizerEnabledValue(); + } + + public static GpoRuleConfigured GetConfiguredTextExtractorEnabledValue() + { + return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetConfiguredTextExtractorEnabledValue(); + } + } +} diff --git a/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj b/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj new file mode 100644 index 0000000000..62a2b6d115 --- /dev/null +++ b/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj @@ -0,0 +1,28 @@ + + + + net6.0-windows10.0.19041.0 + enable + enable + PowerToys.GPOWrapperProjection + PowerToys.GPOWrapperProjection + PowerToys.GPOWrapperProjection + + + + + PowerToys.GPOWrapper + $(OutDir) + false + + + + + + + + + + + + diff --git a/src/common/utils/gpo.h b/src/common/utils/gpo.h new file mode 100644 index 0000000000..3bac6bb856 --- /dev/null +++ b/src/common/utils/gpo.h @@ -0,0 +1,232 @@ +#pragma once + +#include + +namespace powertoys_gpo { + enum gpo_rule_configured_t { + gpo_rule_configured_wrong_value = -3, // The policy is set to an unrecognized value + gpo_rule_configured_unavailable = -2, // Couldn't access registry + gpo_rule_configured_not_configured = -1, // Policy is not configured + gpo_rule_configured_disabled = 0, // Policy is disabled + gpo_rule_configured_enabled = 1, // Policy is enabled + }; + + // Registry path where gpo policy values are stored. + const std::wstring POLICIES_PATH = L"SOFTWARE\\Policies\\PowerToys"; + + // Registry scope where gpo policy values are stored. + const HKEY POLICIES_SCOPE_MACHINE = HKEY_LOCAL_MACHINE; + const HKEY POLICIES_SCOPE_USER = HKEY_CURRENT_USER; + + // The registry value names for PowerToys utilities enabled and disabled policies. + const std::wstring POLICY_CONFIGURE_ENABLED_ALWAYS_ON_TOP = L"ConfigureEnabledUtilityAlwaysOnTop"; + const std::wstring POLICY_CONFIGURE_ENABLED_AWAKE = L"ConfigureEnabledUtilityAwake"; + const std::wstring POLICY_CONFIGURE_ENABLED_COLOR_PICKER = L"ConfigureEnabledUtilityColorPicker"; + const std::wstring POLICY_CONFIGURE_ENABLED_FANCYZONES = L"ConfigureEnabledUtilityFancyZones"; + const std::wstring POLICY_CONFIGURE_ENABLED_SVG_PREVIEW = L"ConfigureEnabledUtilityFileExplorerSVGPreview"; + const std::wstring POLICY_CONFIGURE_ENABLED_MARKDOWN_PREVIEW = L"ConfigureEnabledUtilityFileExplorerMarkdownPreview"; + const std::wstring POLICY_CONFIGURE_ENABLED_MONACO_PREVIEW = L"ConfigureEnabledUtilityFileExplorerMonacoPreview"; + const std::wstring POLICY_CONFIGURE_ENABLED_PDF_PREVIEW = L"ConfigureEnabledUtilityFileExplorerPDFPreview"; + const std::wstring POLICY_CONFIGURE_ENABLED_GCODE_PREVIEW = L"ConfigureEnabledUtilityFileExplorerGcodePreview"; + const std::wstring POLICY_CONFIGURE_ENABLED_SVG_THUMBNAILS = L"ConfigureEnabledUtilityFileExplorerSVGThumbnails"; + const std::wstring POLICY_CONFIGURE_ENABLED_PDF_THUMBNAILS = L"ConfigureEnabledUtilityFileExplorerPDFThumbnails"; + const std::wstring POLICY_CONFIGURE_ENABLED_GCODE_THUMBNAILS = L"ConfigureEnabledUtilityFileExplorerGcodeThumbnails"; + const std::wstring POLICY_CONFIGURE_ENABLED_STL_THUMBNAILS = L"ConfigureEnabledUtilityFileExplorerSTLThumbnails"; + const std::wstring POLICY_CONFIGURE_ENABLED_HOSTS_FILE_EDITOR = L"ConfigureEnabledUtilityHostsFileEditor"; + const std::wstring POLICY_CONFIGURE_ENABLED_IMAGE_RESIZER = L"ConfigureEnabledUtilityImageResizer"; + const std::wstring POLICY_CONFIGURE_ENABLED_KEYBOARD_MANAGER = L"ConfigureEnabledUtilityKeyboardManager"; + const std::wstring POLICY_CONFIGURE_ENABLED_FIND_MY_MOUSE = L"ConfigureEnabledUtilityFindMyMouse"; + const std::wstring POLICY_CONFIGURE_ENABLED_MOUSE_HIGHLIGHTER = L"ConfigureEnabledUtilityMouseHighlighter"; + const std::wstring POLICY_CONFIGURE_ENABLED_MOUSE_POINTER_CROSSHAIRS = L"ConfigureEnabledUtilityMousePointerCrosshairs"; + const std::wstring POLICY_CONFIGURE_ENABLED_POWER_RENAME = L"ConfigureEnabledUtilityPowerRename"; + const std::wstring POLICY_CONFIGURE_ENABLED_POWER_LAUNCHER = L"ConfigureEnabledUtilityPowerLauncher"; + const std::wstring POLICY_CONFIGURE_ENABLED_QUICK_ACCENT = L"ConfigureEnabledUtilityQuickAccent"; + const std::wstring POLICY_CONFIGURE_ENABLED_SCREEN_RULER = L"ConfigureEnabledUtilityScreenRuler"; + const std::wstring POLICY_CONFIGURE_ENABLED_SHORTCUT_GUIDE = L"ConfigureEnabledUtilityShortcutGuide"; + const std::wstring POLICY_CONFIGURE_ENABLED_TEXT_EXTRACTOR = L"ConfigureEnabledUtilityTextExtractor"; + const std::wstring POLICY_CONFIGURE_ENABLED_VIDEO_CONFERENCE_MUTE = L"ConfigureEnabledUtilityVideoConferenceMute"; + + inline gpo_rule_configured_t getConfiguredValue(const std::wstring& registry_value_name) + { + HKEY key{}; + DWORD value = (DWORD) -2; + DWORD valueSize = sizeof(value); + + bool machine_key_found = true; + if (auto res = RegOpenKeyExW(POLICIES_SCOPE_MACHINE, POLICIES_PATH.c_str(), 0, KEY_READ, &key); res != ERROR_SUCCESS) + { + machine_key_found = false; + } + + if(machine_key_found) + { + // If the path was found in the machine, we need to check if the value for the policy exists. + auto res = RegQueryValueExW(key, registry_value_name.c_str(), nullptr, nullptr, (LPBYTE)&value, &valueSize); + + RegCloseKey(key); + + if (res != ERROR_SUCCESS) { + // Value not found on the path. + machine_key_found=false; + } + } + + if (!machine_key_found) + { + // If there's no value found on the machine scope, try to get it from the user scope. + if (auto res = RegOpenKeyExW(POLICIES_SCOPE_USER, POLICIES_PATH.c_str(), 0, KEY_READ, &key); res != ERROR_SUCCESS) + { + if (res == ERROR_FILE_NOT_FOUND) { + return gpo_rule_configured_not_configured; + } + return gpo_rule_configured_unavailable; + } + auto res = RegQueryValueExW(key, registry_value_name.c_str(), nullptr, nullptr, (LPBYTE)&value, &valueSize); + RegCloseKey(key); + + if (res != ERROR_SUCCESS) { + return gpo_rule_configured_not_configured; + } + } + + switch (value) + { + case 0: + return gpo_rule_configured_disabled; + case 1: + return gpo_rule_configured_enabled; + default: + return gpo_rule_configured_wrong_value; + } + } + + inline gpo_rule_configured_t getConfiguredAlwaysOnTopEnabledValue() { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_ALWAYS_ON_TOP); + } + + inline gpo_rule_configured_t getConfiguredAwakeEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_AWAKE); + } + + inline gpo_rule_configured_t getConfiguredColorPickerEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_COLOR_PICKER); + } + + inline gpo_rule_configured_t getConfiguredFancyZonesEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_FANCYZONES); + } + + inline gpo_rule_configured_t getConfiguredSvgPreviewEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_SVG_PREVIEW); + } + + inline gpo_rule_configured_t getConfiguredMarkdownPreviewEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_MARKDOWN_PREVIEW); + } + + inline gpo_rule_configured_t getConfiguredMonacoPreviewEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_MONACO_PREVIEW); + } + + inline gpo_rule_configured_t getConfiguredPdfPreviewEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_PDF_PREVIEW); + } + + inline gpo_rule_configured_t getConfiguredGcodePreviewEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_GCODE_PREVIEW); + } + + inline gpo_rule_configured_t getConfiguredSvgThumbnailsEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_SVG_THUMBNAILS); + } + + inline gpo_rule_configured_t getConfiguredPdfThumbnailsEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_PDF_THUMBNAILS); + } + + inline gpo_rule_configured_t getConfiguredGcodeThumbnailsEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_GCODE_THUMBNAILS); + } + + inline gpo_rule_configured_t getConfiguredStlThumbnailsEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_STL_THUMBNAILS); + } + + inline gpo_rule_configured_t getConfiguredHostsFileEditorEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_HOSTS_FILE_EDITOR); + } + + inline gpo_rule_configured_t getConfiguredImageResizerEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_IMAGE_RESIZER); + } + + inline gpo_rule_configured_t getConfiguredKeyboardManagerEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_KEYBOARD_MANAGER); + } + + inline gpo_rule_configured_t getConfiguredFindMyMouseEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_FIND_MY_MOUSE); + } + + inline gpo_rule_configured_t getConfiguredMouseHightlighterEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_MOUSE_HIGHLIGHTER); + } + + inline gpo_rule_configured_t getConfiguredMousePointerCrosshairsEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_MOUSE_POINTER_CROSSHAIRS); + } + + inline gpo_rule_configured_t getConfiguredPowerRenameEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_POWER_RENAME); + } + + inline gpo_rule_configured_t getConfiguredPowerLauncherEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_POWER_LAUNCHER); + } + + inline gpo_rule_configured_t getConfiguredQuickAccentEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_QUICK_ACCENT); + } + + inline gpo_rule_configured_t getConfiguredScreenRulerEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_SCREEN_RULER); + } + + inline gpo_rule_configured_t getConfiguredShortcutGuideEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_SHORTCUT_GUIDE); + } + + inline gpo_rule_configured_t getConfiguredTextExtractorEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_TEXT_EXTRACTOR); + } + + inline gpo_rule_configured_t getConfiguredVideoConferenceMuteEnabledValue() + { + return getConfiguredValue(POLICY_CONFIGURE_ENABLED_VIDEO_CONFERENCE_MUTE); + } + +} diff --git a/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj b/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj index bf30015f00..70c144ba6f 100644 --- a/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj +++ b/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj @@ -14,6 +14,7 @@ + diff --git a/src/modules/Hosts/Hosts/Hosts.csproj b/src/modules/Hosts/Hosts/Hosts.csproj index e87eecde66..374483bce5 100644 --- a/src/modules/Hosts/Hosts/Hosts.csproj +++ b/src/modules/Hosts/Hosts/Hosts.csproj @@ -21,7 +21,13 @@ DISABLE_XAML_GENERATED_MAIN,TRACE Assets/Hosts.ico - + + + + PowerToys.GPOWrapper + $(OutDir) + false + @@ -31,6 +37,7 @@ + @@ -47,6 +54,7 @@ + diff --git a/src/modules/Hosts/Hosts/Program.cs b/src/modules/Hosts/Hosts/Program.cs index 1754261d51..32b46a7a44 100644 --- a/src/modules/Hosts/Hosts/Program.cs +++ b/src/modules/Hosts/Hosts/Program.cs @@ -16,6 +16,13 @@ namespace Hosts public static void Main(string[] args) { WinRT.ComWrappersSupport.InitializeComWrappers(); + + if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredHostsFileEditorEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + Logger.LogWarning("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + return; + } + var instanceKey = AppInstance.FindOrRegisterForKey("PowerToys_Hosts_Instance"); if (instanceKey.IsCurrent) diff --git a/src/modules/Hosts/HostsModuleInterface/dllmain.cpp b/src/modules/Hosts/HostsModuleInterface/dllmain.cpp index 13cade9b38..528cdade66 100644 --- a/src/modules/Hosts/HostsModuleInterface/dllmain.cpp +++ b/src/modules/Hosts/HostsModuleInterface/dllmain.cpp @@ -135,6 +135,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredHostsFileEditorEnabledValue(); + } + virtual bool get_config(wchar_t* buffer, int* buffer_size) override { return false; diff --git a/src/modules/MeasureTool/MeasureToolModuleInterface/dllmain.cpp b/src/modules/MeasureTool/MeasureToolModuleInterface/dllmain.cpp index cd773921c8..2ac948b763 100644 --- a/src/modules/MeasureTool/MeasureToolModuleInterface/dllmain.cpp +++ b/src/modules/MeasureTool/MeasureToolModuleInterface/dllmain.cpp @@ -174,6 +174,12 @@ public: return MODULE_NAME; } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredScreenRulerEnabledValue(); + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { diff --git a/src/modules/MeasureTool/MeasureToolUI/App.xaml.cs b/src/modules/MeasureTool/MeasureToolUI/App.xaml.cs index c7afbc5065..f81bc2047f 100644 --- a/src/modules/MeasureTool/MeasureToolUI/App.xaml.cs +++ b/src/modules/MeasureTool/MeasureToolUI/App.xaml.cs @@ -32,6 +32,13 @@ namespace MeasureToolUI /// Details about the launch request and process. protected override void OnLaunched(LaunchActivatedEventArgs args) { + if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredScreenRulerEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + Logger.LogWarning("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + Environment.Exit(0); // Current.Exit won't work until there's a window opened. + return; + } + var cmdArgs = Environment.GetCommandLineArgs(); if (cmdArgs?.Length > 1) { diff --git a/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj b/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj index ed88e51917..ce77037fb9 100644 --- a/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj +++ b/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj @@ -26,7 +26,7 @@ - PowerToys.MeasureToolCore + PowerToys.MeasureToolCore;PowerToys.GPOWrapper $(OutDir) false @@ -79,6 +79,7 @@ + diff --git a/src/modules/MouseUtils/FindMyMouse/dllmain.cpp b/src/modules/MouseUtils/FindMyMouse/dllmain.cpp index 39bd14e2ee..27d809d07d 100644 --- a/src/modules/MouseUtils/FindMyMouse/dllmain.cpp +++ b/src/modules/MouseUtils/FindMyMouse/dllmain.cpp @@ -93,6 +93,12 @@ public: return MODULE_NAME; } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredFindMyMouseEnabledValue(); + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { diff --git a/src/modules/MouseUtils/MouseHighlighter/dllmain.cpp b/src/modules/MouseUtils/MouseHighlighter/dllmain.cpp index c3aa1380a6..88ec7cffb6 100644 --- a/src/modules/MouseUtils/MouseHighlighter/dllmain.cpp +++ b/src/modules/MouseUtils/MouseHighlighter/dllmain.cpp @@ -84,6 +84,12 @@ public: return MODULE_NAME; } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredMouseHightlighterEnabledValue(); + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { diff --git a/src/modules/MouseUtils/MousePointerCrosshairs/dllmain.cpp b/src/modules/MouseUtils/MousePointerCrosshairs/dllmain.cpp index 12877956cc..81c79c57b6 100644 --- a/src/modules/MouseUtils/MousePointerCrosshairs/dllmain.cpp +++ b/src/modules/MouseUtils/MousePointerCrosshairs/dllmain.cpp @@ -85,6 +85,12 @@ public: return MODULE_NAME; } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredMousePointerCrosshairsEnabledValue(); + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { diff --git a/src/modules/PowerOCR/PowerOCR/App.xaml.cs b/src/modules/PowerOCR/PowerOCR/App.xaml.cs index ebfad3a553..7a83b93897 100644 --- a/src/modules/PowerOCR/PowerOCR/App.xaml.cs +++ b/src/modules/PowerOCR/PowerOCR/App.xaml.cs @@ -37,6 +37,13 @@ public partial class App : Application, IDisposable private void Application_Startup(object sender, StartupEventArgs e) { + if (PowerToys.GPOWrapperProjection.GPOWrapper.GetConfiguredTextExtractorEnabledValue() == PowerToys.GPOWrapperProjection.GpoRuleConfigured.Disabled) + { + Logger.LogWarning("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + Shutdown(); + return; + } + // allow only one instance of PowerOCR _instanceMutex = new Mutex(true, @"Local\PowerToys_PowerOCR_InstanceMutex", out bool createdNew); if (!createdNew) diff --git a/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj b/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj index 7185c7b1d1..ea63044f55 100644 --- a/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj +++ b/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj @@ -39,11 +39,13 @@ + + diff --git a/src/modules/PowerOCR/PowerOCRModuleInterface/dllmain.cpp b/src/modules/PowerOCR/PowerOCRModuleInterface/dllmain.cpp index 6b03c3d91e..d25285a608 100644 --- a/src/modules/PowerOCR/PowerOCRModuleInterface/dllmain.cpp +++ b/src/modules/PowerOCR/PowerOCRModuleInterface/dllmain.cpp @@ -188,6 +188,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredTextExtractorEnabledValue(); + } + virtual bool get_config(wchar_t* buffer, int* buffer_size) override { HINSTANCE hinstance = reinterpret_cast(&__ImageBase); diff --git a/src/modules/ShortcutGuide/ShortcutGuide/main.cpp b/src/modules/ShortcutGuide/ShortcutGuide/main.cpp index bd91c6d6b0..d1029dd180 100644 --- a/src/modules/ShortcutGuide/ShortcutGuide/main.cpp +++ b/src/modules/ShortcutGuide/ShortcutGuide/main.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "shortcut_guide.h" #include "target_state.h" @@ -46,6 +47,13 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, { winrt::init_apartment(); LoggerHelpers::init_logger(ShortcutGuideConstants::ModuleKey, L"ShortcutGuide", LogSettings::shortcutGuideLoggerName); + + if (powertoys_gpo::getConfiguredShortcutGuideEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) + { + Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + return 0; + } + InitUnhandledExceptionHandler(); Logger::trace("Starting Shortcut Guide"); diff --git a/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/dllmain.cpp b/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/dllmain.cpp index 9e31abce44..de47094de0 100644 --- a/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/dllmain.cpp +++ b/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/dllmain.cpp @@ -48,6 +48,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredShortcutGuideEnabledValue(); + } + virtual bool get_config(wchar_t* buffer, int* buffer_size) override { HINSTANCE hinstance = reinterpret_cast(&__ImageBase); diff --git a/src/modules/alwaysontop/AlwaysOnTop/main.cpp b/src/modules/alwaysontop/AlwaysOnTop/main.cpp index 4b7909079a..8b7d901c7d 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/main.cpp +++ b/src/modules/alwaysontop/AlwaysOnTop/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -18,7 +19,14 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, { winrt::init_apartment(); LoggerHelpers::init_logger(moduleName, internalPath, LogSettings::alwaysOnTopLoggerName); - InitUnhandledExceptionHandler(); + + if (powertoys_gpo::getConfiguredAlwaysOnTopEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) + { + Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + return 0; + } + + InitUnhandledExceptionHandler(); auto mutex = CreateMutex(nullptr, true, instanceMutexName.c_str()); if (mutex == nullptr) diff --git a/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp b/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp index 9b1fcbf7cb..17b93986fc 100644 --- a/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp +++ b/src/modules/alwaysontop/AlwaysOnTopModuleInterface/dllmain.cpp @@ -64,6 +64,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredAlwaysOnTopEnabledValue(); + } + // Return JSON with the configuration options. // These are the settings shown on the settings page along with their current values. virtual bool get_config(wchar_t* buffer, int* buffer_size) override diff --git a/src/modules/awake/Awake/Awake.csproj b/src/modules/awake/Awake/Awake.csproj index f0bf791b51..f117633fb5 100644 --- a/src/modules/awake/Awake/Awake.csproj +++ b/src/modules/awake/Awake/Awake.csproj @@ -21,6 +21,13 @@ Recommended + + + PowerToys.GPOWrapper + $(OutDir) + false + + DEBUG;TRACE full @@ -42,6 +49,7 @@ + all @@ -53,6 +61,7 @@ + diff --git a/src/modules/awake/Awake/Program.cs b/src/modules/awake/Awake/Program.cs index 712cf7dd00..a53b54684a 100644 --- a/src/modules/awake/Awake/Program.cs +++ b/src/modules/awake/Awake/Program.cs @@ -61,6 +61,12 @@ namespace Awake // only one instance of Awake is running. _log = LogManager.GetCurrentClassLogger(); + if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredAwakeEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + Exit("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.", 1, _exitSignal, true); + return 0; + } + LockMutex = new Mutex(true, InternalConstants.AppName, out bool instantiated); if (!instantiated) diff --git a/src/modules/awake/AwakeModuleInterface/dllmain.cpp b/src/modules/awake/AwakeModuleInterface/dllmain.cpp index 4b5859e3b2..313a920ec1 100644 --- a/src/modules/awake/AwakeModuleInterface/dllmain.cpp +++ b/src/modules/awake/AwakeModuleInterface/dllmain.cpp @@ -85,6 +85,12 @@ public: Logger::info("Launcher object is constructing"); }; + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredAwakeEnabledValue(); + } + virtual void destroy() override { delete this; diff --git a/src/modules/colorPicker/ColorPicker/dllmain.cpp b/src/modules/colorPicker/ColorPicker/dllmain.cpp index 6e3a44ba7f..6c126b0ecd 100644 --- a/src/modules/colorPicker/ColorPicker/dllmain.cpp +++ b/src/modules/colorPicker/ColorPicker/dllmain.cpp @@ -189,6 +189,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredColorPickerEnabledValue(); + } + virtual bool get_config(wchar_t* buffer, int* buffer_size) override { HINSTANCE hinstance = reinterpret_cast(&__ImageBase); diff --git a/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj b/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj index c0c29cd184..9e77f96cd5 100644 --- a/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj +++ b/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj @@ -39,6 +39,7 @@ + @@ -60,6 +61,7 @@ + diff --git a/src/modules/colorPicker/ColorPickerUI/Program.cs b/src/modules/colorPicker/ColorPickerUI/Program.cs index 65808b1544..9c97e8308b 100644 --- a/src/modules/colorPicker/ColorPickerUI/Program.cs +++ b/src/modules/colorPicker/ColorPickerUI/Program.cs @@ -18,6 +18,13 @@ namespace ColorPicker { _args = args; Logger.LogInfo($"Color Picker started with pid={Environment.ProcessId}"); + + if (PowerToys.GPOWrapperProjection.GPOWrapper.GetConfiguredColorPickerEnabledValue() == PowerToys.GPOWrapperProjection.GpoRuleConfigured.Disabled) + { + Logger.LogWarning("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + return; + } + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; try { diff --git a/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj b/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj index dcba090974..3148f8de2f 100644 --- a/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj +++ b/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj @@ -16,6 +16,7 @@ + diff --git a/src/modules/fancyzones/FancyZones/main.cpp b/src/modules/fancyzones/FancyZones/main.cpp index 3c123fdce1..265c474496 100644 --- a/src/modules/fancyzones/FancyZones/main.cpp +++ b/src/modules/fancyzones/FancyZones/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -26,6 +27,13 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, { winrt::init_apartment(); LoggerHelpers::init_logger(moduleName, internalPath, LogSettings::fancyZonesLoggerName); + + if (powertoys_gpo::getConfiguredFancyZonesEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) + { + Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + return 0; + } + InitUnhandledExceptionHandler(); auto mutex = CreateMutex(nullptr, true, instanceMutexName.c_str()); diff --git a/src/modules/fancyzones/FancyZonesModuleInterface/dllmain.cpp b/src/modules/fancyzones/FancyZonesModuleInterface/dllmain.cpp index 92d11c242a..26e36d4696 100644 --- a/src/modules/fancyzones/FancyZonesModuleInterface/dllmain.cpp +++ b/src/modules/fancyzones/FancyZonesModuleInterface/dllmain.cpp @@ -51,6 +51,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredFancyZonesEnabledValue(); + } + // Return JSON with the configuration options. // These are the settings shown on the settings page along with their current values. virtual bool get_config(_Out_ PWSTR buffer, _Out_ int* buffer_size) override diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs index da5ec58385..4658681866 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs @@ -66,6 +66,13 @@ namespace FancyZonesEditor private void OnStartup(object sender, StartupEventArgs e) { + if (PowerToys.GPOWrapperProjection.GPOWrapper.GetConfiguredFancyZonesEnabledValue() == PowerToys.GPOWrapperProjection.GpoRuleConfigured.Disabled) + { + Logger.LogWarning("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + Shutdown(0); + return; + } + AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; _themeManager = new ThemeManager(this); diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj index 8bb4c15cb7..c8f69a191f 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj +++ b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj @@ -19,7 +19,6 @@ net6.0-windows10.0.19041.0 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} true - $(SolutionDir)$(Platform)\$(Configuration)\obj\$(AssemblyName)\ @@ -29,7 +28,7 @@ false - + images\FancyZonesEditor.ico @@ -47,6 +46,7 @@ + @@ -55,6 +55,7 @@ + diff --git a/src/modules/imageresizer/ImageResizerLib/Settings.h b/src/modules/imageresizer/ImageResizerLib/Settings.h index aaff4793b7..fa1e15a50f 100644 --- a/src/modules/imageresizer/ImageResizerLib/Settings.h +++ b/src/modules/imageresizer/ImageResizerLib/Settings.h @@ -1,5 +1,7 @@ #pragma once +#include + class CSettings { public: @@ -7,6 +9,11 @@ public: inline bool GetEnabled() { + auto gpoSetting = powertoys_gpo::getConfiguredImageResizerEnabledValue(); + if (gpoSetting == powertoys_gpo::gpo_rule_configured_enabled) + return true; + if (gpoSetting == powertoys_gpo::gpo_rule_configured_disabled) + return false; Reload(); return settings.enabled; } diff --git a/src/modules/imageresizer/dll/dllmain.cpp b/src/modules/imageresizer/dll/dllmain.cpp index a2d3789496..90d85f88df 100644 --- a/src/modules/imageresizer/dll/dllmain.cpp +++ b/src/modules/imageresizer/dll/dllmain.cpp @@ -70,6 +70,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredImageResizerEnabledValue(); + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { diff --git a/src/modules/imageresizer/tests/ImageResizerUITest.csproj b/src/modules/imageresizer/tests/ImageResizerUITest.csproj index ecce5e00ef..7406ee187f 100644 --- a/src/modules/imageresizer/tests/ImageResizerUITest.csproj +++ b/src/modules/imageresizer/tests/ImageResizerUITest.csproj @@ -49,6 +49,7 @@ + diff --git a/src/modules/imageresizer/ui/App.xaml.cs b/src/modules/imageresizer/ui/App.xaml.cs index 2f99e73e17..3d96cfb770 100644 --- a/src/modules/imageresizer/ui/App.xaml.cs +++ b/src/modules/imageresizer/ui/App.xaml.cs @@ -28,6 +28,16 @@ namespace ImageResizer { // Fix for .net 3.1.19 making Image Resizer not adapt to DPI changes. NativeMethods.SetProcessDPIAware(); + + if (PowerToys.GPOWrapperProjection.GPOWrapper.GetConfiguredImageResizerEnabledValue() == PowerToys.GPOWrapperProjection.GpoRuleConfigured.Disabled) + { + /* TODO: Add logs to ImageResizer. + * Logger.LogWarning("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + */ + Environment.Exit(0); // Current.Exit won't work until there's a window opened. + return; + } + var batch = ResizeBatch.FromCommandLine(Console.In, e?.Args); // TODO: Add command-line parameters that can be used in lieu of the input page (issue #14) diff --git a/src/modules/imageresizer/ui/ImageResizerUI.csproj b/src/modules/imageresizer/ui/ImageResizerUI.csproj index 16dc6effa4..dd5337aac4 100644 --- a/src/modules/imageresizer/ui/ImageResizerUI.csproj +++ b/src/modules/imageresizer/ui/ImageResizerUI.csproj @@ -30,7 +30,6 @@ false - PublicResXFileCodeGenerator @@ -45,6 +44,7 @@ + @@ -53,6 +53,7 @@ + diff --git a/src/modules/interface/powertoy_module_interface.h b/src/modules/interface/powertoy_module_interface.h index 4bc44e4967..c3f03010bf 100644 --- a/src/modules/interface/powertoy_module_interface.h +++ b/src/modules/interface/powertoy_module_interface.h @@ -1,6 +1,7 @@ #pragma once #include +#include /* DLL Interface for PowerToys. The powertoy_create() (see below) must return @@ -112,6 +113,11 @@ public: virtual bool is_enabled_by_default() const { return true; } + /* Provides the GPO configuration value for the module. This should be overriden by the module interface to get the proper gpo policy setting. */ + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() { + return powertoys_gpo::gpo_rule_configured_not_configured; + } + protected: HANDLE CreateDefaultEvent(const wchar_t* eventName) { diff --git a/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.cpp b/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.cpp index 5683bb7f8f..1edc585f5e 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.cpp +++ b/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -28,6 +29,13 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, UNREFERENCED_PARAMETER(hPrevInstance); LoggerHelpers::init_logger(KeyboardManagerConstants::ModuleName, L"Editor", LogSettings::keyboardManagerLoggerName); + + if (powertoys_gpo::getConfiguredKeyboardManagerEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) + { + Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + return 0; + } + InitUnhandledExceptionHandler(); Trace::RegisterProvider(); diff --git a/src/modules/keyboardmanager/KeyboardManagerEngine/main.cpp b/src/modules/keyboardmanager/KeyboardManagerEngine/main.cpp index 3551fc81e8..7084bc6dcd 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngine/main.cpp +++ b/src/modules/keyboardmanager/KeyboardManagerEngine/main.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -14,7 +15,13 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, { winrt::init_apartment(); LoggerHelpers::init_logger(KeyboardManagerConstants::ModuleName, L"Engine", LogSettings::keyboardManagerLoggerName); - + + if (powertoys_gpo::getConfiguredKeyboardManagerEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) + { + Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + return 0; + } + InitUnhandledExceptionHandler(); auto mutex = CreateMutex(nullptr, true, instanceMutexName.c_str()); diff --git a/src/modules/keyboardmanager/dll/dllmain.cpp b/src/modules/keyboardmanager/dll/dllmain.cpp index d07952ab44..675755d6ad 100644 --- a/src/modules/keyboardmanager/dll/dllmain.cpp +++ b/src/modules/keyboardmanager/dll/dllmain.cpp @@ -69,6 +69,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredKeyboardManagerEnabledValue(); + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { diff --git a/src/modules/launcher/Microsoft.Launcher/dllmain.cpp b/src/modules/launcher/Microsoft.Launcher/dllmain.cpp index 79a6a4eca6..6824a137e0 100644 --- a/src/modules/launcher/Microsoft.Launcher/dllmain.cpp +++ b/src/modules/launcher/Microsoft.Launcher/dllmain.cpp @@ -152,6 +152,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredPowerLauncherEnabledValue(); + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.History/Microsoft.PowerToys.Run.Plugin.History.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.History/Microsoft.PowerToys.Run.Plugin.History.csproj index e977bac282..e6cc69b497 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.History/Microsoft.PowerToys.Run.Plugin.History.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.History/Microsoft.PowerToys.Run.Plugin.History.csproj @@ -48,6 +48,7 @@ + diff --git a/src/modules/launcher/PowerLauncher/App.xaml.cs b/src/modules/launcher/PowerLauncher/App.xaml.cs index 551cb1bfad..8f147b9ca7 100644 --- a/src/modules/launcher/PowerLauncher/App.xaml.cs +++ b/src/modules/launcher/PowerLauncher/App.xaml.cs @@ -52,6 +52,12 @@ namespace PowerLauncher NativeThreadCTS = new CancellationTokenSource(); Log.Info($"Starting PowerToys Run with PID={Environment.ProcessId}", typeof(App)); + if (PowerToys.GPOWrapperProjection.GPOWrapper.GetConfiguredPowerLauncherEnabledValue() == PowerToys.GPOWrapperProjection.GpoRuleConfigured.Disabled) + { + Log.Warn("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.", typeof(App)); + return; + } + int powerToysPid = GetPowerToysPId(); if (powerToysPid != 0) { diff --git a/src/modules/launcher/PowerLauncher/PowerLauncher.csproj b/src/modules/launcher/PowerLauncher/PowerLauncher.csproj index 8b394196e9..db9c4434fa 100644 --- a/src/modules/launcher/PowerLauncher/PowerLauncher.csproj +++ b/src/modules/launcher/PowerLauncher/PowerLauncher.csproj @@ -76,6 +76,7 @@ + @@ -94,6 +95,7 @@ + diff --git a/src/modules/launcher/Wox.Test/Wox.Test.csproj b/src/modules/launcher/Wox.Test/Wox.Test.csproj index 53b4652e6d..e1290dbcd5 100644 --- a/src/modules/launcher/Wox.Test/Wox.Test.csproj +++ b/src/modules/launcher/Wox.Test/Wox.Test.csproj @@ -47,6 +47,7 @@ + diff --git a/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj b/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj index a9c75c05d0..f124fec3d2 100644 --- a/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj +++ b/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj @@ -10,7 +10,7 @@ true - PowerToys.PowerAccentKeyboardService + PowerToys.GPOWrapper;PowerToys.PowerAccentKeyboardService $(OutDir) false @@ -23,6 +23,7 @@ + diff --git a/src/modules/poweraccent/PowerAccent/Program.cs b/src/modules/poweraccent/PowerAccent/Program.cs index 0b31fabc59..28f2712146 100644 --- a/src/modules/poweraccent/PowerAccent/Program.cs +++ b/src/modules/poweraccent/PowerAccent/Program.cs @@ -28,6 +28,12 @@ internal static class Program { _ = new Mutex(true, PROGRAM_APP_NAME, out bool instantiated); + if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredQuickAccentEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + Logger.LogWarning("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + return; + } + if (instantiated) { Arguments(args); diff --git a/src/modules/poweraccent/PowerAccentModuleInterface/dllmain.cpp b/src/modules/poweraccent/PowerAccentModuleInterface/dllmain.cpp index a1ae35f6e0..a69ad22d23 100644 --- a/src/modules/poweraccent/PowerAccentModuleInterface/dllmain.cpp +++ b/src/modules/poweraccent/PowerAccentModuleInterface/dllmain.cpp @@ -108,6 +108,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredQuickAccentEnabledValue(); + } + virtual void set_config(const wchar_t* config) override { try diff --git a/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp b/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp index 4cdf8669d0..4d78b31a73 100644 --- a/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp +++ b/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp @@ -9,6 +9,7 @@ #include #include #include +#include using namespace winrt; using namespace winrt::Microsoft::UI::Xaml; @@ -53,6 +54,12 @@ void App::OnLaunched(LaunchActivatedEventArgs const&) { LoggerHelpers::init_logger(moduleName, L"", LogSettings::powerRenameLoggerName); + if (powertoys_gpo::getConfiguredPowerRenameEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled) + { + Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); + ExitProcess(0); + } + auto args = std::wstring{ GetCommandLine() }; size_t pos{ args.rfind(L"\\\\.\\pipe\\") }; diff --git a/src/modules/powerrename/dll/dllmain.cpp b/src/modules/powerrename/dll/dllmain.cpp index a092823842..fb7a457a7c 100644 --- a/src/modules/powerrename/dll/dllmain.cpp +++ b/src/modules/powerrename/dll/dllmain.cpp @@ -182,6 +182,12 @@ public: return app_key.c_str(); } + // Return the configured status for the gpo policy for the module + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override + { + return powertoys_gpo::getConfiguredPowerRenameEnabledValue(); + } + // Enable the powertoy virtual void enable() { diff --git a/src/modules/powerrename/lib/Settings.h b/src/modules/powerrename/lib/Settings.h index 787a1ebbe1..f74201c31b 100644 --- a/src/modules/powerrename/lib/Settings.h +++ b/src/modules/powerrename/lib/Settings.h @@ -1,6 +1,7 @@ #pragma once #include +#include class CSettings { @@ -9,6 +10,11 @@ public: inline bool GetEnabled() { + auto gpoSetting = powertoys_gpo::getConfiguredPowerRenameEnabledValue(); + if (gpoSetting == powertoys_gpo::gpo_rule_configured_enabled) + return true; + if (gpoSetting == powertoys_gpo::gpo_rule_configured_disabled) + return false; Reload(); return settings.enabled; } diff --git a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj index 95c9eb312a..9304419e9e 100644 --- a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj +++ b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj @@ -31,12 +31,25 @@ + + + PowerToys.GPOWrapper + $(OutDir) + false + + + + $(NoWarn);1591 + + + + diff --git a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs index a614345d15..63e83480e9 100644 --- a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs +++ b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandlerControl.cs @@ -43,6 +43,20 @@ namespace Microsoft.PowerToys.PreviewHandler.Gcode /// Stream reference to access source file. public override void DoPreview(T dataSource) { + if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredGcodePreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + // GPO is disabling this utility. Show an error message instead. + InvokeOnControlThread(() => + { + _infoBarAdded = true; + AddTextBoxControl(Properties.Resource.GpoDisabledErrorText); + Resize += FormResized; + base.DoPreview(dataSource); + }); + + return; + } + InvokeOnControlThread(() => { try diff --git a/src/modules/previewpane/GcodePreviewHandler/Properties/Resource.Designer.cs b/src/modules/previewpane/GcodePreviewHandler/Properties/Resource.Designer.cs index 6b5a367acf..893dc623a2 100644 --- a/src/modules/previewpane/GcodePreviewHandler/Properties/Resource.Designer.cs +++ b/src/modules/previewpane/GcodePreviewHandler/Properties/Resource.Designer.cs @@ -77,5 +77,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Gcode.Properties { return ResourceManager.GetString("GcodeWithoutEmbeddedThumbnails", resourceCulture); } } + + /// + /// Looks up a localized string for an error when Gpo has the utility disabled. + /// + internal static string GpoDisabledErrorText { + get { + return ResourceManager.GetString("GpoDisabledErrorText", resourceCulture); + } + } } } diff --git a/src/modules/previewpane/GcodePreviewHandler/Properties/Resource.resx b/src/modules/previewpane/GcodePreviewHandler/Properties/Resource.resx index 22d7fc6278..3aa2d635ec 100644 --- a/src/modules/previewpane/GcodePreviewHandler/Properties/Resource.resx +++ b/src/modules/previewpane/GcodePreviewHandler/Properties/Resource.resx @@ -124,4 +124,8 @@ This G-code does not contain any embedded thumbnails. + + Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator. + GPO stands for the Windows Group Policy Object feature. + \ No newline at end of file diff --git a/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.cs b/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.cs index 5738ba1ff4..2a52a53dbe 100644 --- a/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.cs +++ b/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.cs @@ -158,6 +158,12 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Gcode return; } + if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredGcodeThumbnailsEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + // GPO is disabling this utility. + return; + } + using (var stream = new ReadonlyStream(this.Stream as IStream)) { using (var reader = new StreamReader(stream)) diff --git a/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.csproj b/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.csproj index 5d3bf9bc6f..1ccf566290 100644 --- a/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.csproj +++ b/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.csproj @@ -6,7 +6,7 @@ PowerToys.GcodeThumbnailProvider PowerToys.GcodeThumbnailProvider PowerToys GcodePreviewHandler - net6.0-windows + net6.0-windows10.0.19041.0 true true PowerToys GcodePreviewHandler @@ -18,7 +18,23 @@ + + + PowerToys.GPOWrapper + $(OutDir) + false + + + + $(NoWarn);1591 + + + + + + + diff --git a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj index c55662d754..ae2c55378f 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj +++ b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj @@ -37,7 +37,19 @@ + + + PowerToys.GPOWrapper + $(OutDir) + false + + + + $(NoWarn);1591 + + + @@ -45,6 +57,7 @@ + diff --git a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs index afbdb4846d..cc0a1b9420 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs +++ b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs @@ -130,6 +130,21 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown /// Path to the file. public override void DoPreview(T dataSource) { + if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMarkdownPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + // GPO is disabling this utility. Show an error message instead. + InvokeOnControlThread(() => + { + _infoBarDisplayed = true; + _infoBar = GetTextBoxControl(Resources.GpoDisabledErrorText); + Resize += FormResized; + Controls.Add(_infoBar); + base.DoPreview(dataSource); + }); + + return; + } + CleanupWebView2UserDataFolder(); _infoBarDisplayed = false; diff --git a/src/modules/previewpane/MarkdownPreviewHandler/Properties/Resources.Designer.cs b/src/modules/previewpane/MarkdownPreviewHandler/Properties/Resources.Designer.cs index b0f5e9f6e8..c15e32ce06 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/Properties/Resources.Designer.cs +++ b/src/modules/previewpane/MarkdownPreviewHandler/Properties/Resources.Designer.cs @@ -77,5 +77,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown.Properties { return ResourceManager.GetString("MarkdownNotPreviewedError", resourceCulture); } } + + /// + /// Looks up a localized string for an error when Gpo has the utility disabled. + /// + internal static string GpoDisabledErrorText { + get { + return ResourceManager.GetString("GpoDisabledErrorText", resourceCulture); + } + } } } diff --git a/src/modules/previewpane/MarkdownPreviewHandler/Properties/Resources.resx b/src/modules/previewpane/MarkdownPreviewHandler/Properties/Resources.resx index e97ed33cad..7c4d1b6065 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/Properties/Resources.resx +++ b/src/modules/previewpane/MarkdownPreviewHandler/Properties/Resources.resx @@ -125,4 +125,8 @@ The markdown could not be preview due to an internal error. This text is displayed if markdown fails to preview + + Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator. + GPO stands for the Windows Group Policy Object feature. + \ No newline at end of file diff --git a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj index a0b69f9b09..420869d009 100644 --- a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj +++ b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj @@ -26,7 +26,19 @@ 1701;1702 + + + PowerToys.GPOWrapper + $(OutDir) + false + + + + $(NoWarn);1591 + + + @@ -41,6 +53,7 @@ + diff --git a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs index c900e7b6ea..81e962aeed 100644 --- a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs +++ b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs @@ -37,6 +37,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco new XmlFormatter(), }.AsReadOnly(); + /// + /// Text box to display the information about blocked elements from Svg. + /// + private RichTextBox _textBox; + + /// + /// Represent if an text box info bar is added for showing message. + /// + private bool _infoBarAdded; + /// /// Saves if the user already navigated to the index page /// @@ -94,6 +104,20 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco { Logger.LogTrace(); + if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMonacoPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + // GPO is disabling this utility. Show an error message instead. + InvokeOnControlThread(() => + { + _infoBarAdded = true; + AddTextBoxControl(Properties.Resources.GpoDisabledErrorText); + Resize += FormResized; + base.DoPreview(dataSource); + }); + + return; + } + base.DoPreview(dataSource); // Sets background color @@ -421,5 +445,47 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco await Launcher.LaunchUriAsync(new Uri("https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section")); Logger.LogTrace(); } + + /// + /// Occurs when RichtextBox is resized. + /// + /// Reference to resized control. + /// Provides data for the ContentsResized event. + private void RTBContentsResized(object sender, ContentsResizedEventArgs e) + { + var richTextBox = sender as RichTextBox; + richTextBox.Height = e.NewRectangle.Height + 5; + } + + /// + /// Occurs when form is resized. + /// + /// Reference to resized control. + /// Provides data for the resize event. + private void FormResized(object sender, EventArgs e) + { + if (_infoBarAdded) + { + _textBox.Width = Width; + } + } + + /// + /// Adds a Text Box in Controls for showing information about blocked elements. + /// + /// Message to be displayed in textbox. + private void AddTextBoxControl(string message) + { + _textBox = new RichTextBox(); + _textBox.Text = message; + _textBox.BackColor = Color.LightYellow; + _textBox.Multiline = true; + _textBox.Dock = DockStyle.Top; + _textBox.ReadOnly = true; + _textBox.ContentsResized += RTBContentsResized; + _textBox.ScrollBars = RichTextBoxScrollBars.None; + _textBox.BorderStyle = BorderStyle.None; + Controls.Add(_textBox); + } } } diff --git a/src/modules/previewpane/MonacoPreviewHandler/Properties/Resources.Designer.cs b/src/modules/previewpane/MonacoPreviewHandler/Properties/Resources.Designer.cs index 6772c075c8..cb056ae013 100644 --- a/src/modules/previewpane/MonacoPreviewHandler/Properties/Resources.Designer.cs +++ b/src/modules/previewpane/MonacoPreviewHandler/Properties/Resources.Designer.cs @@ -106,5 +106,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco.Properties { return ResourceManager.GetString("WebView2_Not_Installed_Message", resourceCulture); } } + + /// + /// Looks up a localized string for an error when Gpo has the utility disabled. + /// + internal static string GpoDisabledErrorText { + get { + return ResourceManager.GetString("GpoDisabledErrorText", resourceCulture); + } + } } } diff --git a/src/modules/previewpane/MonacoPreviewHandler/Properties/Resources.resx b/src/modules/previewpane/MonacoPreviewHandler/Properties/Resources.resx index be4a29da68..d0d97c0d42 100644 --- a/src/modules/previewpane/MonacoPreviewHandler/Properties/Resources.resx +++ b/src/modules/previewpane/MonacoPreviewHandler/Properties/Resources.resx @@ -136,4 +136,8 @@ Max file size: %1KB Download WebView2 to display this file. + + Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator. + GPO stands for the Windows Group Policy Object feature. + \ No newline at end of file diff --git a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj index 18f18add35..90cd137c00 100644 --- a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj +++ b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj @@ -31,11 +31,24 @@ + + + PowerToys.GPOWrapper + $(OutDir) + false + + + + $(NoWarn);1591 + + + + diff --git a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandlerControl.cs b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandlerControl.cs index 80d3ddf202..e59a976793 100644 --- a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandlerControl.cs +++ b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandlerControl.cs @@ -52,6 +52,19 @@ namespace Microsoft.PowerToys.PreviewHandler.Pdf /// Stream reference to access source file. public override void DoPreview(T dataSource) { + if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredPdfPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + // GPO is disabling this utility. Show an error message instead. + InvokeOnControlThread(() => + { + _infoBar = GetTextBoxControl(Resources.GpoDisabledErrorText); + Controls.Add(_infoBar); + base.DoPreview(dataSource); + }); + + return; + } + this.SuspendLayout(); try diff --git a/src/modules/previewpane/PdfPreviewHandler/Properties/Resources.Designer.cs b/src/modules/previewpane/PdfPreviewHandler/Properties/Resources.Designer.cs index f8531f334e..4bcb7e5866 100644 --- a/src/modules/previewpane/PdfPreviewHandler/Properties/Resources.Designer.cs +++ b/src/modules/previewpane/PdfPreviewHandler/Properties/Resources.Designer.cs @@ -100,5 +100,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Pdf.Properties return ResourceManager.GetString("PdfMorePagesMessage", resourceCulture); } } + + /// + /// Looks up a localized string for an error when Gpo has the utility disabled. + /// + internal static string GpoDisabledErrorText { + get { + return ResourceManager.GetString("GpoDisabledErrorText", resourceCulture); + } + } } } diff --git a/src/modules/previewpane/PdfPreviewHandler/Properties/Resources.resx b/src/modules/previewpane/PdfPreviewHandler/Properties/Resources.resx index 809efc52b8..c134e0f6b2 100644 --- a/src/modules/previewpane/PdfPreviewHandler/Properties/Resources.resx +++ b/src/modules/previewpane/PdfPreviewHandler/Properties/Resources.resx @@ -129,4 +129,8 @@ Can't preview file. This PDF is password protected. This text is displayed if PDF is password protected. + + Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator. + GPO stands for the Windows Group Policy Object feature. + diff --git a/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.cs b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.cs index c12152e673..a38d6813b5 100644 --- a/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.cs +++ b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.cs @@ -49,6 +49,12 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Pdf return; } + if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredPdfThumbnailsEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + // GPO is disabling this utility. + return; + } + using var dataStream = new ReadonlyStream(this.Stream as IStream); using var memStream = new MemoryStream(); diff --git a/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj index aebf5c447e..d89816e909 100644 --- a/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj +++ b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj @@ -17,7 +17,23 @@ + + + PowerToys.GPOWrapper + $(OutDir) + false + + + + $(NoWarn);1591 + + + + + + + diff --git a/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.cs b/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.cs index f79812bb9a..c944d7936b 100644 --- a/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.cs +++ b/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.cs @@ -123,6 +123,12 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Stl return; } + if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredStlThumbnailsEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + // GPO is disabling this utility. + return; + } + using (var stream = new ReadonlyStream(this.Stream as IStream)) { using (var memStream = new MemoryStream()) diff --git a/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.csproj b/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.csproj index 2e22e631be..32b8de4efe 100644 --- a/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.csproj +++ b/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.csproj @@ -6,7 +6,7 @@ PowerToys.StlThumbnailProvider PowerToys.StlThumbnailProvider PowerToys StlPreviewHandler - net6.0-windows + net6.0-windows10.0.19041.0 true true PowerToys StlPreviewHandler @@ -18,12 +18,25 @@ + + + PowerToys.GPOWrapper + $(OutDir) + false + + + + $(NoWarn);1591 + + + + diff --git a/src/modules/previewpane/SvgPreviewHandler/Properties/Resource.Designer.cs b/src/modules/previewpane/SvgPreviewHandler/Properties/Resource.Designer.cs index 9477c8517b..648105802a 100644 --- a/src/modules/previewpane/SvgPreviewHandler/Properties/Resource.Designer.cs +++ b/src/modules/previewpane/SvgPreviewHandler/Properties/Resource.Designer.cs @@ -77,5 +77,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg.Properties { return ResourceManager.GetString("SvgNotPreviewedError", resourceCulture); } } + + /// + /// Looks up a localized string for an error when Gpo has the utility disabled. + /// + internal static string GpoDisabledErrorText { + get { + return ResourceManager.GetString("GpoDisabledErrorText", resourceCulture); + } + } } } diff --git a/src/modules/previewpane/SvgPreviewHandler/Properties/Resource.resx b/src/modules/previewpane/SvgPreviewHandler/Properties/Resource.resx index e8d5827f1b..1a7cb79427 100644 --- a/src/modules/previewpane/SvgPreviewHandler/Properties/Resource.resx +++ b/src/modules/previewpane/SvgPreviewHandler/Properties/Resource.resx @@ -123,4 +123,8 @@ The Svg could not be preview due to an internal error in Svg Preview Handler. + + Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator. + GPO stands for the Windows Group Policy Object feature. + \ No newline at end of file diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs index 06dd8a6969..cb0152f170 100644 --- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs +++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs @@ -11,6 +11,7 @@ using System.Runtime.InteropServices.ComTypes; using System.Windows.Forms; using Common; using Common.Utilities; +using Microsoft.PowerToys.PreviewHandler.Svg.Properties; using Microsoft.PowerToys.PreviewHandler.Svg.Telemetry.Events; using Microsoft.PowerToys.Telemetry; using Microsoft.Web.WebView2.Core; @@ -82,6 +83,20 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg /// Stream reference to access source file. public override void DoPreview(T dataSource) { + if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredSvgPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + // GPO is disabling this utility. Show an error message instead. + InvokeOnControlThread(() => + { + _infoBarAdded = true; + AddTextBoxControl(Properties.Resource.GpoDisabledErrorText); + Resize += FormResized; + base.DoPreview(dataSource); + }); + + return; + } + CleanupWebView2UserDataFolder(); string svgData = null; diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj index ddd8659e7f..c187c0916e 100644 --- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj +++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj @@ -32,12 +32,25 @@ + + + PowerToys.GPOWrapper + $(OutDir) + false + + + + $(NoWarn);1591 + + + + diff --git a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs index 41c1c2ce83..64a13d93fd 100644 --- a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs +++ b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs @@ -272,6 +272,12 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg return; } + if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredSvgThumbnailsEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + // GPO is disabling this utility. + return; + } + string svgData = null; using (var stream = new ReadonlyStream(this.Stream as IStream)) { diff --git a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj index 18d3201e54..f66e6159df 100644 --- a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj +++ b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj @@ -20,10 +20,24 @@ + + + PowerToys.GPOWrapper + $(OutDir) + false + + + + $(NoWarn);1591 + + + + + diff --git a/src/modules/previewpane/UnitTests-GcodePreviewHandler/UnitTests-GcodePreviewHandler.csproj b/src/modules/previewpane/UnitTests-GcodePreviewHandler/UnitTests-GcodePreviewHandler.csproj index a1fabeab24..3fa1bff142 100644 --- a/src/modules/previewpane/UnitTests-GcodePreviewHandler/UnitTests-GcodePreviewHandler.csproj +++ b/src/modules/previewpane/UnitTests-GcodePreviewHandler/UnitTests-GcodePreviewHandler.csproj @@ -23,6 +23,7 @@ + diff --git a/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/UnitTests-GcodeThumbnailProvider.csproj b/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/UnitTests-GcodeThumbnailProvider.csproj index 10aa82a5c0..9800e65526 100644 --- a/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/UnitTests-GcodeThumbnailProvider.csproj +++ b/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/UnitTests-GcodeThumbnailProvider.csproj @@ -24,6 +24,7 @@ + diff --git a/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/UnitTests-MarkdownPreviewHandler.csproj b/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/UnitTests-MarkdownPreviewHandler.csproj index 7fe4efbc6d..26f7b53fcf 100644 --- a/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/UnitTests-MarkdownPreviewHandler.csproj +++ b/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/UnitTests-MarkdownPreviewHandler.csproj @@ -23,7 +23,7 @@ - + diff --git a/src/modules/previewpane/UnitTests-PdfPreviewHandler/UnitTests-PdfPreviewHandler.csproj b/src/modules/previewpane/UnitTests-PdfPreviewHandler/UnitTests-PdfPreviewHandler.csproj index 4749815527..30f5294afe 100644 --- a/src/modules/previewpane/UnitTests-PdfPreviewHandler/UnitTests-PdfPreviewHandler.csproj +++ b/src/modules/previewpane/UnitTests-PdfPreviewHandler/UnitTests-PdfPreviewHandler.csproj @@ -29,6 +29,7 @@ + diff --git a/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj index 3499eded00..e0a28750e9 100644 --- a/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj +++ b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj @@ -24,6 +24,7 @@ + diff --git a/src/modules/previewpane/UnitTests-StlThumbnailProvider/UnitTests-StlThumbnailProvider.csproj b/src/modules/previewpane/UnitTests-StlThumbnailProvider/UnitTests-StlThumbnailProvider.csproj index 3028a57272..ec70eb4bca 100644 --- a/src/modules/previewpane/UnitTests-StlThumbnailProvider/UnitTests-StlThumbnailProvider.csproj +++ b/src/modules/previewpane/UnitTests-StlThumbnailProvider/UnitTests-StlThumbnailProvider.csproj @@ -24,6 +24,7 @@ + diff --git a/src/modules/previewpane/UnitTests-SvgPreviewHandler/UnitTests-SvgPreviewHandler.csproj b/src/modules/previewpane/UnitTests-SvgPreviewHandler/UnitTests-SvgPreviewHandler.csproj index f07b96bc23..4d9015a824 100644 --- a/src/modules/previewpane/UnitTests-SvgPreviewHandler/UnitTests-SvgPreviewHandler.csproj +++ b/src/modules/previewpane/UnitTests-SvgPreviewHandler/UnitTests-SvgPreviewHandler.csproj @@ -28,6 +28,7 @@ + diff --git a/src/modules/previewpane/UnitTests-SvgThumbnailProvider/UnitTests-SvgThumbnailProvider.csproj b/src/modules/previewpane/UnitTests-SvgThumbnailProvider/UnitTests-SvgThumbnailProvider.csproj index 0f9fa187a4..71f3511ea6 100644 --- a/src/modules/previewpane/UnitTests-SvgThumbnailProvider/UnitTests-SvgThumbnailProvider.csproj +++ b/src/modules/previewpane/UnitTests-SvgThumbnailProvider/UnitTests-SvgThumbnailProvider.csproj @@ -20,6 +20,7 @@ + diff --git a/src/modules/previewpane/powerpreview/powerpreview.cpp b/src/modules/previewpane/powerpreview/powerpreview.cpp index f95e381628..eade6a3a43 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.cpp +++ b/src/modules/previewpane/powerpreview/powerpreview.cpp @@ -28,38 +28,47 @@ PowerPreviewModule::PowerPreviewModule() : const bool installPerUser = true; m_fileExplorerModules.push_back({ .settingName = L"svg-previewer-toggle-setting", .settingDescription = GET_RESOURCE_STRING(IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION), + .checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredSvgPreviewEnabledValue, .registryChanges = getSvgPreviewHandlerChangeSet(installationDir, installPerUser) }); m_fileExplorerModules.push_back({ .settingName = L"md-previewer-toggle-setting", .settingDescription = GET_RESOURCE_STRING(IDS_PREVPANE_MD_SETTINGS_DESCRIPTION), + .checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredMarkdownPreviewEnabledValue, .registryChanges = getMdPreviewHandlerChangeSet(installationDir, installPerUser) }); m_fileExplorerModules.push_back({ .settingName = L"monaco-previewer-toggle-setting", .settingDescription = GET_RESOURCE_STRING(IDS_PREVPANE_MONACO_SETTINGS_DESCRIPTION), + .checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredMonacoPreviewEnabledValue, .registryChanges = getMonacoPreviewHandlerChangeSet(installationDir, installPerUser) }); m_fileExplorerModules.push_back({ .settingName = L"pdf-previewer-toggle-setting", .settingDescription = GET_RESOURCE_STRING(IDS_PREVPANE_PDF_SETTINGS_DESCRIPTION), + .checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredPdfPreviewEnabledValue, .registryChanges = getPdfPreviewHandlerChangeSet(installationDir, installPerUser) }); m_fileExplorerModules.push_back({ .settingName = L"gcode-previewer-toggle-setting", .settingDescription = GET_RESOURCE_STRING(IDS_PREVPANE_GCODE_SETTINGS_DESCRIPTION), + .checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredGcodePreviewEnabledValue, .registryChanges = getGcodePreviewHandlerChangeSet(installationDir, installPerUser) }); m_fileExplorerModules.push_back({ .settingName = L"svg-thumbnail-toggle-setting", .settingDescription = GET_RESOURCE_STRING(IDS_SVG_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION), + .checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredSvgThumbnailsEnabledValue, .registryChanges = getSvgThumbnailHandlerChangeSet(installationDir, installPerUser) }); m_fileExplorerModules.push_back({ .settingName = L"pdf-thumbnail-toggle-setting", .settingDescription = GET_RESOURCE_STRING(IDS_PDF_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION), + .checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredPdfThumbnailsEnabledValue, .registryChanges = getPdfThumbnailHandlerChangeSet(installationDir, installPerUser) }); m_fileExplorerModules.push_back({ .settingName = L"gcode-thumbnail-toggle-setting", .settingDescription = GET_RESOURCE_STRING(IDS_GCODE_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION), + .checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredGcodeThumbnailsEnabledValue, .registryChanges = getGcodeThumbnailHandlerChangeSet(installationDir, installPerUser) }); m_fileExplorerModules.push_back({ .settingName = L"stl-thumbnail-toggle-setting", .settingDescription = GET_RESOURCE_STRING(IDS_STL_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION), + .checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredStlThumbnailsEnabledValue, .registryChanges = getStlThumbnailHandlerChangeSet(installationDir, installPerUser) }); try @@ -202,15 +211,43 @@ void PowerPreviewModule::apply_settings(const PowerToysSettings::PowerToyValues& for (auto& fileExplorerModule : m_fileExplorerModules) { const auto toggle = settings.get_bool_value(fileExplorerModule.settingName); + const auto gpo_rule = fileExplorerModule.checkModuleGPOEnabledRuleFunction(); + const auto gpo_is_configured = gpo_rule == powertoys_gpo::gpo_rule_configured_enabled || gpo_rule == powertoys_gpo::gpo_rule_configured_disabled; + + if (gpo_rule == powertoys_gpo::gpo_rule_configured_unavailable) + { + Logger::warn(L"Couldn't read the gpo rule for Power Preview module {}", fileExplorerModule.settingName); + } + if (gpo_rule == powertoys_gpo::gpo_rule_configured_wrong_value) + { + Logger::warn(L"gpo rule for Power Preview module {} is set to an unknown value", fileExplorerModule.settingName); + } // Skip if no need to update - if (!toggle.has_value() || *toggle == fileExplorerModule.registryChanges.isApplied()) + if (!toggle.has_value() && !gpo_is_configured) + { + continue; + } + + bool module_new_state = false; + if (toggle.has_value()) + { + module_new_state = *toggle; + } + if (gpo_is_configured) + { + // gpo rule overrides settings state + module_new_state = gpo_rule == powertoys_gpo::gpo_rule_configured_enabled; + } + + // Skip if no need to update + if (module_new_state == fileExplorerModule.registryChanges.isApplied()) { continue; } // (Un)Apply registry changes depending on the new setting value - const bool updated = *toggle ? fileExplorerModule.registryChanges.apply() : fileExplorerModule.registryChanges.unApply(); + const bool updated = module_new_state ? fileExplorerModule.registryChanges.apply() : fileExplorerModule.registryChanges.unApply(); if (updated) { diff --git a/src/modules/previewpane/powerpreview/powerpreview.h b/src/modules/previewpane/powerpreview/powerpreview.h index 1819c45ca8..aae629027d 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.h +++ b/src/modules/previewpane/powerpreview/powerpreview.h @@ -7,11 +7,13 @@ #include #include +#include struct FileExplorerModule { std::wstring settingName; std::wstring settingDescription; + powertoys_gpo::gpo_rule_configured_t (*checkModuleGPOEnabledRuleFunction)(); registry::ChangeSet registryChanges; }; diff --git a/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.cpp b/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.cpp index 7756ea70d8..7cee1e96da 100644 --- a/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.cpp +++ b/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.cpp @@ -345,6 +345,12 @@ const wchar_t* VideoConferenceModule::get_key() return L"Video Conference"; } +// Return the configured status for the gpo policy for the module +powertoys_gpo::gpo_rule_configured_t VideoConferenceModule::gpo_policy_enabled_configuration() +{ + return powertoys_gpo::getConfiguredVideoConferenceMuteEnabledValue(); +} + bool VideoConferenceModule::get_config(wchar_t* buffer, int* buffer_size) { return true; diff --git a/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.h b/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.h index 883e12f40f..063f17adc9 100644 --- a/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.h +++ b/src/modules/videoconference/VideoConferenceModule/VideoConferenceModule.h @@ -37,6 +37,8 @@ public: ~VideoConferenceModule(); virtual const wchar_t* get_name() override; + virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override; + virtual bool get_config(wchar_t* buffer, int* buffer_size) override; virtual void set_config(const wchar_t* config) override; diff --git a/src/runner/general_settings.cpp b/src/runner/general_settings.cpp index 02a1aaad20..60f69eccdf 100644 --- a/src/runner/general_settings.cpp +++ b/src/runner/general_settings.cpp @@ -138,7 +138,15 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save) } PowertoyModule& powertoy = modules().at(name); const bool module_inst_enabled = powertoy->is_enabled(); - const bool target_enabled = value.GetBoolean(); + bool target_enabled = value.GetBoolean(); + + auto gpo_rule = powertoy->gpo_policy_enabled_configuration(); + if (gpo_rule == powertoys_gpo::gpo_rule_configured_enabled || gpo_rule == powertoys_gpo::gpo_rule_configured_disabled) + { + // Apply the GPO Rule. + target_enabled = gpo_rule == powertoys_gpo::gpo_rule_configured_enabled; + } + if (module_inst_enabled == target_enabled) { continue; @@ -174,9 +182,21 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save) void start_enabled_powertoys() { std::unordered_set powertoys_to_disable; - // Take into account default values supplied by modules themselves + std::unordered_map powertoys_gpo_configuration; + // Take into account default values supplied by modules themselves and gpo configurations for (auto& [name, powertoy] : modules()) { + auto gpo_rule = powertoy->gpo_policy_enabled_configuration(); + powertoys_gpo_configuration[name] = gpo_rule; + if (gpo_rule == powertoys_gpo::gpo_rule_configured_unavailable) + { + Logger::warn(L"start_enabled_powertoys: couldn't read the gpo rule for Powertoy {}", name); + } + if (gpo_rule == powertoys_gpo::gpo_rule_configured_wrong_value) + { + Logger::warn(L"start_enabled_powertoys: gpo rule for Powertoy {} is set to an unknown value", name); + } + if (!powertoy->is_enabled_by_default()) powertoys_to_disable.emplace(name); } @@ -191,6 +211,14 @@ void start_enabled_powertoys() for (const auto& disabled_element : enabled) { std::wstring disable_module_name{ static_cast(disabled_element.Key()) }; + + if (powertoys_gpo_configuration.find(disable_module_name)!=powertoys_gpo_configuration.end() + && (powertoys_gpo_configuration[disable_module_name]==powertoys_gpo::gpo_rule_configured_enabled || powertoys_gpo_configuration[disable_module_name]==powertoys_gpo::gpo_rule_configured_disabled)) + { + // If gpo forces the enabled setting, no need to check the setting for this PowerToy. It will be applied later on this function. + continue; + } + // Disable explicitly disabled modules if (!disabled_element.Value().GetBoolean()) { @@ -212,7 +240,23 @@ void start_enabled_powertoys() for (auto& [name, powertoy] : modules()) { - if (!powertoys_to_disable.contains(name)) + bool should_powertoy_be_enabled = true; + + auto gpo_rule = powertoys_gpo_configuration.find(name) != powertoys_gpo_configuration.end() ? powertoys_gpo_configuration[name] : powertoys_gpo::gpo_rule_configured_not_configured; + + if (gpo_rule == powertoys_gpo::gpo_rule_configured_enabled || gpo_rule == powertoys_gpo::gpo_rule_configured_disabled) + { + // Apply the GPO Rule. + should_powertoy_be_enabled = gpo_rule == powertoys_gpo::gpo_rule_configured_enabled; + Logger::info(L"start_enabled_powertoys: GPO sets the enabled state for {} powertoy as {}", name, should_powertoy_be_enabled); + } + else if (powertoys_to_disable.contains(name)) + { + // Apply the settings or default information provided by the PowerToy on first run. + should_powertoy_be_enabled = false; + } + + if (should_powertoy_be_enabled) { Logger::info(L"start_enabled_powertoys: Enabling powertoy {}", name); powertoy->enable(); diff --git a/src/runner/pch.h b/src/runner/pch.h index 06d67b3c8f..a01e93cc17 100644 --- a/src/runner/pch.h +++ b/src/runner/pch.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/PowerPreviewViewModel.cs b/src/settings-ui/Settings.UI.Library/ViewModels/PowerPreviewViewModel.cs deleted file mode 100644 index e1d3b3fe1f..0000000000 --- a/src/settings-ui/Settings.UI.Library/ViewModels/PowerPreviewViewModel.cs +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Runtime.CompilerServices; -using Microsoft.PowerToys.Settings.UI.Library.Helpers; -using Microsoft.PowerToys.Settings.UI.Library.Interfaces; - -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels -{ - public class PowerPreviewViewModel : Observable - { - private const string ModuleName = PowerPreviewSettings.ModuleName; - - private PowerPreviewSettings Settings { get; set; } - - private Func SendConfigMSG { get; } - - private string _settingsConfigFileFolder = string.Empty; - - private GeneralSettings GeneralSettingsConfig { get; set; } - - public PowerPreviewViewModel(ISettingsRepository moduleSettingsRepository, ISettingsRepository generalSettingsRepository, Func ipcMSGCallBackFunc, string configFileSubfolder = "") - { - // Update Settings file folder: - _settingsConfigFileFolder = configFileSubfolder; - - // To obtain the general Settings configurations of PowerToys - if (generalSettingsRepository == null) - { - throw new ArgumentNullException(nameof(generalSettingsRepository)); - } - - GeneralSettingsConfig = generalSettingsRepository.SettingsConfig; - - // To obtain the PowerPreview settings if it exists. - // If the file does not exist, to create a new one and return the default settings configurations. - if (moduleSettingsRepository == null) - { - throw new ArgumentNullException(nameof(moduleSettingsRepository)); - } - - Settings = moduleSettingsRepository.SettingsConfig; - - // set the callback functions value to hangle outgoing IPC message. - SendConfigMSG = ipcMSGCallBackFunc; - - _svgRenderIsEnabled = Settings.Properties.EnableSvgPreview; - _svgThumbnailIsEnabled = Settings.Properties.EnableSvgThumbnail; - _mdRenderIsEnabled = Settings.Properties.EnableMdPreview; - _monacoRenderIsEnabled = Settings.Properties.EnableMonacoPreview; - _monacoWrapText = Settings.Properties.EnableMonacoPreviewWordWrap; - _monacoPreviewTryFormat = Settings.Properties.MonacoPreviewTryFormat; - _pdfRenderIsEnabled = Settings.Properties.EnablePdfPreview; - _gcodeRenderIsEnabled = Settings.Properties.EnableGcodePreview; - _pdfThumbnailIsEnabled = Settings.Properties.EnablePdfThumbnail; - _gcodeThumbnailIsEnabled = Settings.Properties.EnableGcodeThumbnail; - _stlThumbnailIsEnabled = Settings.Properties.EnableStlThumbnail; - _stlThumbnailColor = Settings.Properties.StlThumbnailColor.Value; - } - - private bool _svgRenderIsEnabled; - private bool _mdRenderIsEnabled; - private bool _monacoRenderIsEnabled; - private bool _monacoWrapText; - private bool _monacoPreviewTryFormat; - private bool _pdfRenderIsEnabled; - private bool _gcodeRenderIsEnabled; - private bool _svgThumbnailIsEnabled; - private bool _pdfThumbnailIsEnabled; - private bool _gcodeThumbnailIsEnabled; - private bool _stlThumbnailIsEnabled; - private string _stlThumbnailColor; - - public bool SVGRenderIsEnabled - { - get - { - return _svgRenderIsEnabled; - } - - set - { - if (value != _svgRenderIsEnabled) - { - _svgRenderIsEnabled = value; - Settings.Properties.EnableSvgPreview = value; - RaisePropertyChanged(); - } - } - } - - public bool SVGThumbnailIsEnabled - { - get - { - return _svgThumbnailIsEnabled; - } - - set - { - if (value != _svgThumbnailIsEnabled) - { - _svgThumbnailIsEnabled = value; - Settings.Properties.EnableSvgThumbnail = value; - RaisePropertyChanged(); - } - } - } - - public bool MDRenderIsEnabled - { - get - { - return _mdRenderIsEnabled; - } - - set - { - if (value != _mdRenderIsEnabled) - { - _mdRenderIsEnabled = value; - Settings.Properties.EnableMdPreview = value; - RaisePropertyChanged(); - } - } - } - - public bool MonacoRenderIsEnabled - { - get - { - return _monacoRenderIsEnabled; - } - - set - { - if (value != _monacoRenderIsEnabled) - { - _monacoRenderIsEnabled = value; - Settings.Properties.EnableMonacoPreview = value; - RaisePropertyChanged(); - } - } - } - - public bool MonacoWrapText - { - get - { - return _monacoWrapText; - } - - set - { - if (_monacoWrapText != value) - { - _monacoWrapText = value; - Settings.Properties.EnableMonacoPreviewWordWrap = value; - RaisePropertyChanged(); - } - } - } - - public bool MonacoPreviewTryFormat - { - get - { - return _monacoPreviewTryFormat; - } - - set - { - if (_monacoPreviewTryFormat != value) - { - _monacoPreviewTryFormat = value; - Settings.Properties.MonacoPreviewTryFormat = value; - RaisePropertyChanged(); - } - } - } - - public bool PDFRenderIsEnabled - { - get - { - return _pdfRenderIsEnabled; - } - - set - { - if (value != _pdfRenderIsEnabled) - { - _pdfRenderIsEnabled = value; - Settings.Properties.EnablePdfPreview = value; - RaisePropertyChanged(); - } - } - } - - public bool PDFThumbnailIsEnabled - { - get - { - return _pdfThumbnailIsEnabled; - } - - set - { - if (value != _pdfThumbnailIsEnabled) - { - _pdfThumbnailIsEnabled = value; - Settings.Properties.EnablePdfThumbnail = value; - RaisePropertyChanged(); - } - } - } - - public bool GCODERenderIsEnabled - { - get - { - return _gcodeRenderIsEnabled; - } - - set - { - if (value != _gcodeRenderIsEnabled) - { - _gcodeRenderIsEnabled = value; - Settings.Properties.EnableGcodePreview = value; - RaisePropertyChanged(); - } - } - } - - public bool GCODEThumbnailIsEnabled - { - get - { - return _gcodeThumbnailIsEnabled; - } - - set - { - if (value != _gcodeThumbnailIsEnabled) - { - _gcodeThumbnailIsEnabled = value; - Settings.Properties.EnableGcodeThumbnail = value; - RaisePropertyChanged(); - } - } - } - - public bool STLThumbnailIsEnabled - { - get - { - return _stlThumbnailIsEnabled; - } - - set - { - if (value != _stlThumbnailIsEnabled) - { - _stlThumbnailIsEnabled = value; - Settings.Properties.EnableStlThumbnail = value; - RaisePropertyChanged(); - } - } - } - - public string STLThumbnailColor - { - get - { - return _stlThumbnailColor; - } - - set - { - if (value != _stlThumbnailColor) - { - _stlThumbnailColor = value; - Settings.Properties.StlThumbnailColor.Value = value; - RaisePropertyChanged(); - } - } - } - - public string GetSettingsSubPath() - { - return _settingsConfigFileFolder + "\\" + ModuleName; - } - - public bool IsElevated - { - get - { - return GeneralSettingsConfig.IsElevated; - } - } - - private void RaisePropertyChanged([CallerMemberName] string propertyName = null) - { - // Notify UI of property change - OnPropertyChanged(propertyName); - - if (SendConfigMSG != null) - { - SndPowerPreviewSettings snd = new SndPowerPreviewSettings(Settings); - SndModuleSettings ipcMessage = new SndModuleSettings(snd); - SendConfigMSG(ipcMessage.ToJsonString()); - } - } - } -} diff --git a/src/settings-ui/Settings.UI.UnitTests/Settings.UI.UnitTests.csproj b/src/settings-ui/Settings.UI.UnitTests/Settings.UI.UnitTests.csproj index 7021b458f4..47484c60d3 100644 --- a/src/settings-ui/Settings.UI.UnitTests/Settings.UI.UnitTests.csproj +++ b/src/settings-ui/Settings.UI.UnitTests/Settings.UI.UnitTests.csproj @@ -1,7 +1,7 @@  - net6.0-windows + net6.0-windows10.0.19041.0 false $(Version).0 @@ -19,6 +19,7 @@ + @@ -33,6 +34,7 @@ + diff --git a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ColorPicker.cs b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ColorPicker.cs index 0594b6b30e..5fe20f3cda 100644 --- a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ColorPicker.cs +++ b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ColorPicker.cs @@ -4,9 +4,9 @@ using System.Text.Json; using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility; using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; diff --git a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/FancyZones.cs b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/FancyZones.cs index 2c0b61314f..dc21d4cb0c 100644 --- a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/FancyZones.cs +++ b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/FancyZones.cs @@ -5,9 +5,9 @@ using System; using System.Text.Json; using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility; using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; diff --git a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/General.cs b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/General.cs index ce0a01be21..bec4597b6a 100644 --- a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/General.cs +++ b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/General.cs @@ -4,9 +4,9 @@ using System; using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility; using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using JsonSerializer = System.Text.Json.JsonSerializer; diff --git a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ImageResizer.cs b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ImageResizer.cs index af570c47f7..530fd59d25 100644 --- a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ImageResizer.cs +++ b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ImageResizer.cs @@ -7,9 +7,9 @@ using System.IO.Abstractions.TestingHelpers; using System.Linq; using System.Text.Json; using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility; using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; diff --git a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/KeyboardManager.cs b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/KeyboardManager.cs index 442c2e32e8..2234540f4f 100644 --- a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/KeyboardManager.cs +++ b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/KeyboardManager.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace ViewModelTests diff --git a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs index 8a80f0cbf6..1f3b0ea9fd 100644 --- a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs +++ b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs @@ -4,8 +4,8 @@ using System; using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; diff --git a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerPreview.cs b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerPreview.cs index f8e942a525..07869ede8e 100644 --- a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerPreview.cs +++ b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerPreview.cs @@ -5,9 +5,9 @@ using System; using System.Text.Json; using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility; using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; diff --git a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerRename.cs b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerRename.cs index 16f00d8329..441fd906e7 100644 --- a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerRename.cs +++ b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerRename.cs @@ -5,9 +5,9 @@ using System; using System.Text.Json; using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility; using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; diff --git a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ShortcutGuide.cs b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ShortcutGuide.cs index 64d0f627b7..b162ecc713 100644 --- a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ShortcutGuide.cs +++ b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/ShortcutGuide.cs @@ -5,9 +5,9 @@ using System; using System.Text.Json; using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility; using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; diff --git a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj index e5f4b505cd..882c8945ee 100644 --- a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj +++ b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj @@ -35,6 +35,13 @@ true + + + PowerToys.GPOWrapper + $(OutDir) + false + + @@ -50,6 +57,7 @@ + @@ -64,6 +72,7 @@ + diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index 38bba46da8..e06168ceda 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -2640,4 +2640,7 @@ Activate by holding the key for the character you want to add an accent to, then Launch as administrator + + The systems administrator is forcing this setting. + \ No newline at end of file diff --git a/src/settings-ui/Settings.UI/Utilities/NativeMethods.cs b/src/settings-ui/Settings.UI/Utilities/NativeMethods.cs new file mode 100644 index 0000000000..270a60451f --- /dev/null +++ b/src/settings-ui/Settings.UI/Utilities/NativeMethods.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.PowerToys.Settings.Utilities +{ + internal static class NativeMethods + { + [DllImport("user32.dll")] + public static extern bool AllowSetForegroundWindow(int dwProcessId); + + public const int SWRESTORE = 9; + + [System.Runtime.InteropServices.DllImport("User32.dll")] + public static extern bool SetForegroundWindow(IntPtr handle); + + [System.Runtime.InteropServices.DllImport("User32.dll")] + public static extern bool ShowWindow(IntPtr handle, int nCmdShow); + + [System.Runtime.InteropServices.DllImport("User32.dll")] + public static extern bool IsIconic(IntPtr handle); + } +} diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/AlwaysOnTopViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/AlwaysOnTopViewModel.cs similarity index 87% rename from src/settings-ui/Settings.UI.Library/ViewModels/AlwaysOnTopViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/AlwaysOnTopViewModel.cs index 9cdd21092a..120a93cd12 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/AlwaysOnTopViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/AlwaysOnTopViewModel.cs @@ -6,11 +6,13 @@ using System; using System.Globalization; using System.Runtime.CompilerServices; using System.Text.Json; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.UI.Library.Utilities; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class AlwaysOnTopViewModel : Observable { @@ -47,7 +49,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels Settings = moduleSettingsRepository.SettingsConfig; - _isEnabled = GeneralSettingsConfig.Enabled.AlwaysOnTop; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredAlwaysOnTopEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.AlwaysOnTop; + } + _hotkey = Settings.Properties.Hotkey.Value; _frameEnabled = Settings.Properties.FrameEnabled.Value; _frameThickness = Settings.Properties.FrameThickness.Value; @@ -69,6 +82,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels set { + if (_enabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (value != _isEnabled) { _isEnabled = value; @@ -83,6 +102,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public HotkeySettings Hotkey { get => _hotkey; @@ -250,6 +274,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels SettingsUtils.SaveSettings(Settings.ToJsonString(), AlwaysOnTopSettings.ModuleName); } + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; private bool _isEnabled; private HotkeySettings _hotkey; private bool _frameEnabled; diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/AwakeViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/AwakeViewModel.cs similarity index 81% rename from src/settings-ui/Settings.UI.Library/ViewModels/AwakeViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/AwakeViewModel.cs index e283f1190e..2eb4cf140c 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/AwakeViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/AwakeViewModel.cs @@ -4,10 +4,12 @@ using System; using System.Runtime.CompilerServices; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class AwakeViewModel : Observable { @@ -35,7 +37,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels Settings = moduleSettingsRepository.SettingsConfig; - _isEnabled = GeneralSettingsConfig.Enabled.Awake; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredAwakeEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.Awake; + } + _keepDisplayOn = Settings.Properties.KeepDisplayOn; _mode = Settings.Properties.Mode; _hours = Settings.Properties.Hours; @@ -52,6 +65,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels { if (_isEnabled != value) { + if (_enabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + _isEnabled = value; GeneralSettingsConfig.Enabled.Awake = value; @@ -65,6 +84,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public bool IsTimeConfigurationEnabled { get => _mode == AwakeMode.TIMED && _isEnabled; @@ -148,6 +172,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; private bool _isEnabled; private uint _hours; private uint _minutes; diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/ColorPickerViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/ColorPickerViewModel.cs similarity index 92% rename from src/settings-ui/Settings.UI.Library/ViewModels/ColorPickerViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/ColorPickerViewModel.cs index f44349fbc1..22c0b3ee78 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/ColorPickerViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/ColorPickerViewModel.cs @@ -9,11 +9,13 @@ using System.Globalization; using System.Linq; using System.Text.Json; using System.Timers; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Enumerations; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class ColorPickerViewModel : Observable, IDisposable { @@ -30,6 +32,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels private readonly ColorPickerSettings _colorPickerSettings; private Timer _delayedTimer; + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; private bool _isEnabled; private Func SendConfigMSG { get; } @@ -73,8 +77,17 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } _colorPickerSettings = colorPickerSettingsRepository.SettingsConfig; - - _isEnabled = GeneralSettingsConfig.Enabled.ColorPicker; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredColorPickerEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.ColorPicker; + } // set the callback functions value to hangle outgoing IPC message. SendConfigMSG = ipcMSGCallBackFunc; @@ -97,6 +110,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels get => _isEnabled; set { + if (_enabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (_isEnabled != value) { _isEnabled = value; @@ -111,6 +130,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public bool ChangeCursor { get => _colorPickerSettings.Properties.ChangeCursor; diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/FancyZonesViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/FancyZonesViewModel.cs similarity index 96% rename from src/settings-ui/Settings.UI.Library/ViewModels/FancyZonesViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/FancyZonesViewModel.cs index d07643dce4..ee9330e0c2 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/FancyZonesViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/FancyZonesViewModel.cs @@ -4,12 +4,14 @@ using System; using System.Runtime.CompilerServices; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.UI.Library.Utilities; using Microsoft.PowerToys.Settings.UI.Library.ViewModels.Commands; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class FancyZonesViewModel : Observable { @@ -114,7 +116,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels string numberColor = Settings.Properties.FancyzonesNumberColor.Value; _zoneNumberColor = !string.IsNullOrEmpty(numberColor) ? numberColor : ConfigDefaults.DefaultFancyzonesNumberColor; - _isEnabled = GeneralSettingsConfig.Enabled.FancyZones; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredFancyZonesEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.FancyZones; + } + _windows11 = Helper.Windows11(); // Disable setting on windows 10 @@ -124,6 +137,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; private bool _isEnabled; private bool _shiftDrag; private bool _mouseSwitch; @@ -168,6 +183,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels set { + if (_enabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (value != _isEnabled) { _isEnabled = value; @@ -185,6 +206,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public bool SnapHotkeysCategoryEnabled { get diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/GeneralViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs similarity index 99% rename from src/settings-ui/Settings.UI.Library/ViewModels/GeneralViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs index a1eac0be9a..02ee2793bf 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/GeneralViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs @@ -11,12 +11,13 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Text.Json; using System.Threading.Tasks; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.UI.Library.Utilities; using Microsoft.PowerToys.Settings.UI.Library.ViewModels.Commands; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class GeneralViewModel : Observable { diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/HostsViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs similarity index 75% rename from src/settings-ui/Settings.UI.Library/ViewModels/HostsViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs index 3317bc1320..16b5e00054 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/HostsViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs @@ -4,17 +4,21 @@ using System; using System.Runtime.CompilerServices; +using global::PowerToys.GPOWrapper; using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.UI.Library.ViewModels.Commands; using Settings.UI.Library.Enumerations; -namespace Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class HostsViewModel : Observable { private bool _isElevated; + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; + private bool _isEnabled; private ISettingsUtils SettingsUtils { get; set; } @@ -28,12 +32,20 @@ namespace Settings.UI.Library.ViewModels public bool IsEnabled { - get => GeneralSettingsConfig.Enabled.Hosts; + get => _isEnabled; set { - if (value != GeneralSettingsConfig.Enabled.Hosts) + if (_enabledStateIsGPOConfigured) { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (value != _isEnabled) + { + _isEnabled = value; + // Set the status in the general settings configuration GeneralSettingsConfig.Enabled.Hosts = value; OutGoingGeneralSettings snd = new OutGoingGeneralSettings(GeneralSettingsConfig); @@ -44,6 +56,11 @@ namespace Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public bool LaunchAdministratorEnabled => IsEnabled && !_isElevated; public bool ShowStartupWarning @@ -92,6 +109,17 @@ namespace Settings.UI.Library.ViewModels Settings = moduleSettingsRepository.SettingsConfig; SendConfigMSG = ipcMSGCallBackFunc; _isElevated = isElevated; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredHostsFileEditorEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.Hosts; + } } public void Launch() diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/ImageResizerViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/ImageResizerViewModel.cs similarity index 92% rename from src/settings-ui/Settings.UI.Library/ViewModels/ImageResizerViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/ImageResizerViewModel.cs index 4e7c0d6ec4..9e4a764e53 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/ImageResizerViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/ImageResizerViewModel.cs @@ -7,11 +7,13 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Linq; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.UI.Library.Utilities; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class ImageResizerViewModel : Observable { @@ -57,7 +59,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels // set the callback functions value to hangle outgoing IPC message. SendConfigMSG = ipcMSGCallBackFunc; - _isEnabled = GeneralSettingsConfig.Enabled.ImageResizer; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredImageResizerEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.ImageResizer; + } + _advancedSizes = Settings.Properties.ImageresizerSizes.Value; _jpegQualityLevel = Settings.Properties.ImageresizerJpegQualityLevel.Value; _pngInterlaceOption = Settings.Properties.ImageresizerPngInterlaceOption.Value; @@ -75,6 +88,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; private bool _isEnabled; private ObservableCollection _advancedSizes = new ObservableCollection(); private int _jpegQualityLevel; @@ -95,6 +110,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels set { + if (_enabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (value != _isEnabled) { // To set the status of ImageResizer in the General PowerToys settings. @@ -108,6 +129,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public ObservableCollection Sizes { get diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/KeyboardManagerViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/KeyboardManagerViewModel.cs similarity index 89% rename from src/settings-ui/Settings.UI.Library/ViewModels/KeyboardManagerViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/KeyboardManagerViewModel.cs index cbf03f2b06..48c9cb70cb 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/KeyboardManagerViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/KeyboardManagerViewModel.cs @@ -11,12 +11,15 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Input; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.UI.Library.Utilities; using Microsoft.PowerToys.Settings.UI.Library.ViewModels.Commands; +using Microsoft.PowerToys.Settings.Utilities; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class KeyboardManagerViewModel : Observable { @@ -36,6 +39,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels ShortcutEditor, } + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; + private bool _isEnabled; + public KeyboardManagerSettings Settings { get; set; } private ICommand _remapKeyboardCommand; @@ -55,6 +62,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels GeneralSettingsConfig = settingsRepository.SettingsConfig; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredKeyboardManagerEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.KeyboardManager; + } + // set the callback functions value to hangle outgoing IPC message. SendConfigMSG = ipcMSGCallBackFunc; FilterRemapKeysList = filterRemapKeysList; @@ -95,13 +114,21 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels { get { - return GeneralSettingsConfig.Enabled.KeyboardManager; + return _isEnabled; } set { - if (GeneralSettingsConfig.Enabled.KeyboardManager != value) + if (_enabledStateIsGPOConfigured) { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (_isEnabled != value) + { + _isEnabled = value; + GeneralSettingsConfig.Enabled.KeyboardManager = value; OnPropertyChanged(nameof(Enabled)); @@ -117,6 +144,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + // store remappings public List RemapKeys { diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/MeasureToolViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/MeasureToolViewModel.cs similarity index 83% rename from src/settings-ui/Settings.UI.Library/ViewModels/MeasureToolViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/MeasureToolViewModel.cs index f286bd9966..cd18565128 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/MeasureToolViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/MeasureToolViewModel.cs @@ -6,10 +6,12 @@ using System; using System.Globalization; using System.Runtime.CompilerServices; using System.Text.Json; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class MeasureToolViewModel : Observable { @@ -17,6 +19,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels private GeneralSettings GeneralSettingsConfig { get; set; } + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; + private bool _isEnabled; + private MeasureToolSettings Settings { get; set; } public MeasureToolViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, ISettingsRepository measureToolSettingsRepository, Func ipcMSGCallBackFunc) @@ -30,6 +36,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels GeneralSettingsConfig = settingsRepository.SettingsConfig; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredScreenRulerEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.MeasureTool; + } + if (measureToolSettingsRepository == null) { throw new ArgumentNullException(nameof(measureToolSettingsRepository)); @@ -42,11 +60,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels public bool IsEnabled { - get => GeneralSettingsConfig.Enabled.MeasureTool; + get => _isEnabled; set { - if (GeneralSettingsConfig.Enabled.MeasureTool != value) + if (_enabledStateIsGPOConfigured) { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (_isEnabled != value) + { + _isEnabled = value; GeneralSettingsConfig.Enabled.MeasureTool = value; OnPropertyChanged(nameof(IsEnabled)); @@ -59,6 +84,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public bool ContinuousCapture { get diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/MouseUtilsViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs similarity index 86% rename from src/settings-ui/Settings.UI.Library/ViewModels/MouseUtilsViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs index 51e53e6f49..88556b3384 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/MouseUtilsViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs @@ -4,10 +4,12 @@ using System; using System.Runtime.CompilerServices; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class MouseUtilsViewModel : Observable { @@ -33,11 +35,41 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels GeneralSettingsConfig = settingsRepository.SettingsConfig; - _isFindMyMouseEnabled = GeneralSettingsConfig.Enabled.FindMyMouse; + _findMyMouseEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredFindMyMouseEnabledValue(); + if (_findMyMouseEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _findMyMouseEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _findMyMouseEnabledStateIsGPOConfigured = true; + _isFindMyMouseEnabled = _findMyMouseEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isFindMyMouseEnabled = GeneralSettingsConfig.Enabled.FindMyMouse; + } - _isMouseHighlighterEnabled = GeneralSettingsConfig.Enabled.MouseHighlighter; + _highlighterEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredMouseHighlighterEnabledValue(); + if (_highlighterEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _highlighterEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _highlighterEnabledStateIsGPOConfigured = true; + _isMouseHighlighterEnabled = _highlighterEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isMouseHighlighterEnabled = GeneralSettingsConfig.Enabled.MouseHighlighter; + } - _isMousePointerCrosshairsEnabled = GeneralSettingsConfig.Enabled.MousePointerCrosshairs; + _mousePointerCrosshairsEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredMousePointerCrosshairsEnabledValue(); + if (_mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _mousePointerCrosshairsEnabledStateIsGPOConfigured = true; + _isMousePointerCrosshairsEnabled = _mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isMousePointerCrosshairsEnabled = GeneralSettingsConfig.Enabled.MousePointerCrosshairs; + } // To obtain the find my mouse settings, if the file exists. // If not, to create a file with the default settings and to return the default configurations. @@ -107,6 +139,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels get => _isFindMyMouseEnabled; set { + if (_findMyMouseEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (_isFindMyMouseEnabled != value) { _isFindMyMouseEnabled = value; @@ -122,6 +160,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsFindMyMouseEnabledGpoConfigured + { + get => _findMyMouseEnabledStateIsGPOConfigured; + } + public int FindMyMouseActivationMethod { get @@ -319,6 +362,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels get => _isMouseHighlighterEnabled; set { + if (_highlighterEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (_isMouseHighlighterEnabled != value) { _isMouseHighlighterEnabled = value; @@ -334,6 +383,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsHighlighterEnabledGpoConfigured + { + get => _highlighterEnabledStateIsGPOConfigured; + } + public HotkeySettings MouseHighlighterActivationShortcut { get @@ -476,6 +530,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels get => _isMousePointerCrosshairsEnabled; set { + if (_mousePointerCrosshairsEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (_isMousePointerCrosshairsEnabled != value) { _isMousePointerCrosshairsEnabled = value; @@ -491,6 +551,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsMousePointerCrosshairsEnabledGpoConfigured + { + get => _mousePointerCrosshairsEnabledStateIsGPOConfigured; + } + public HotkeySettings MousePointerCrosshairsActivationShortcut { get @@ -630,6 +695,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels private Func SendConfigMSG { get; } + private GpoRuleConfigured _findMyMouseEnabledGpoRuleConfiguration; + private bool _findMyMouseEnabledStateIsGPOConfigured; private bool _isFindMyMouseEnabled; private int _findMyMouseActivationMethod; private bool _findMyMouseDoNotActivateOnGameMode; @@ -642,6 +709,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels private string _findMyMouseExcludedApps; private int _findMyMouseShakingMinimumDistance; + private GpoRuleConfigured _highlighterEnabledGpoRuleConfiguration; + private bool _highlighterEnabledStateIsGPOConfigured; private bool _isMouseHighlighterEnabled; private string _highlighterLeftButtonClickColor; private string _highlighterRightButtonClickColor; @@ -650,6 +719,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels private int _highlightFadeDelayMs; private int _highlightFadeDurationMs; + private GpoRuleConfigured _mousePointerCrosshairsEnabledGpoRuleConfiguration; + private bool _mousePointerCrosshairsEnabledStateIsGPOConfigured; private bool _isMousePointerCrosshairsEnabled; private string _mousePointerCrosshairsColor; private int _mousePointerCrosshairsOpacity; diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/PluginAdditionalOptionViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PluginAdditionalOptionViewModel.cs similarity index 92% rename from src/settings-ui/Settings.UI.Library/ViewModels/PluginAdditionalOptionViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/PluginAdditionalOptionViewModel.cs index da55645a9d..39c6536baf 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/PluginAdditionalOptionViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/PluginAdditionalOptionViewModel.cs @@ -4,8 +4,9 @@ using System.ComponentModel; using System.Runtime.CompilerServices; +using Microsoft.PowerToys.Settings.UI.Library; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class PluginAdditionalOptionViewModel : INotifyPropertyChanged { diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/PowerAccentViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PowerAccentViewModel.cs similarity index 84% rename from src/settings-ui/Settings.UI.Library/ViewModels/PowerAccentViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/PowerAccentViewModel.cs index 24357d39ec..8dfaeba9b1 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/PowerAccentViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/PowerAccentViewModel.cs @@ -4,11 +4,13 @@ using System; using System.Runtime.CompilerServices; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Enumerations; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class PowerAccentViewModel : Observable { @@ -65,7 +67,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels _settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils)); GeneralSettingsConfig = settingsRepository.SettingsConfig; - _isEnabled = GeneralSettingsConfig.Enabled.PowerAccent; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredQuickAccentEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.PowerAccent; + } + if (_settingsUtils.SettingsExists(PowerAccentSettings.ModuleName)) { _powerAccentSettings = _settingsUtils.GetSettingsOrDefault(PowerAccentSettings.ModuleName); @@ -90,6 +103,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels get => _isEnabled; set { + if (_enabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (_isEnabled != value) { _isEnabled = value; @@ -102,6 +121,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public int ActivationKey { get @@ -194,6 +218,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; private bool _isEnabled; } } diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/PowerLauncherPluginViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PowerLauncherPluginViewModel.cs similarity index 98% rename from src/settings-ui/Settings.UI.Library/ViewModels/PowerLauncherPluginViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/PowerLauncherPluginViewModel.cs index 184bf1fbd6..5fca11a873 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/PowerLauncherPluginViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/PowerLauncherPluginViewModel.cs @@ -8,8 +8,9 @@ using System.ComponentModel; using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using Microsoft.PowerToys.Settings.UI.Library; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class PowerLauncherPluginViewModel : INotifyPropertyChanged { diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/PowerLauncherViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PowerLauncherViewModel.cs similarity index 92% rename from src/settings-ui/Settings.UI.Library/ViewModels/PowerLauncherViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/PowerLauncherViewModel.cs index 4583852d4a..5290156daa 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/PowerLauncherViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/PowerLauncherViewModel.cs @@ -10,18 +10,23 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Text.Json; using System.Windows.Input; +using global::PowerToys.GPOWrapper; using ManagedCommon; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.UI.Library.ViewModels.Commands; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class PowerLauncherViewModel : Observable { private int _themeIndex; private int _monitorPositionIndex; + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; + private bool _isEnabled; private string _searchText; private GeneralSettings GeneralSettingsConfig { get; set; } @@ -58,6 +63,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels GeneralSettingsConfig = settingsRepository.SettingsConfig; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredPowerLauncherEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.PowerLauncher; + } + // set the callback functions value to hangle outgoing IPC message. SendConfigMSG = ipcMSGCallBackFunc; callback = (PowerLauncherSettings s) => @@ -134,13 +151,20 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels { get { - return GeneralSettingsConfig.Enabled.PowerLauncher; + return _isEnabled; } set { - if (GeneralSettingsConfig.Enabled.PowerLauncher != value) + if (_enabledStateIsGPOConfigured) { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (_isEnabled != value) + { + _isEnabled = value; GeneralSettingsConfig.Enabled.PowerLauncher = value; OnPropertyChanged(nameof(EnablePowerLauncher)); OnPropertyChanged(nameof(ShowAllPluginsDisabledWarning)); @@ -151,6 +175,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public string SearchResultPreference { get diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/PowerOcrViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PowerOcrViewModel.cs similarity index 82% rename from src/settings-ui/Settings.UI.Library/ViewModels/PowerOcrViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/PowerOcrViewModel.cs index 935b53521e..21a7bcae00 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/PowerOcrViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/PowerOcrViewModel.cs @@ -6,10 +6,12 @@ using System; using System.Globalization; using System.Text.Json; using System.Timers; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class PowerOcrViewModel : Observable, IDisposable { @@ -26,6 +28,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels private readonly PowerOcrSettings _powerOcrSettings; private Timer _delayedTimer; + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; private bool _isEnabled; private Func SendConfigMSG { get; } @@ -59,7 +63,17 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels _powerOcrSettings = powerOcrsettingsRepository.SettingsConfig; - _isEnabled = GeneralSettingsConfig.Enabled.PowerOCR; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredTextExtractorEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.PowerOCR; + } // set the callback functions value to hangle outgoing IPC message. SendConfigMSG = ipcMSGCallBackFunc; @@ -75,6 +89,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels get => _isEnabled; set { + if (_enabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (_isEnabled != value) { _isEnabled = value; @@ -89,6 +109,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public HotkeySettings ActivationShortcut { get => _powerOcrSettings.Properties.ActivationShortcut; diff --git a/src/settings-ui/Settings.UI/ViewModels/PowerPreviewViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PowerPreviewViewModel.cs new file mode 100644 index 0000000000..a6b5fcdab2 --- /dev/null +++ b/src/settings-ui/Settings.UI/ViewModels/PowerPreviewViewModel.cs @@ -0,0 +1,545 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.CompilerServices; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; +using Microsoft.PowerToys.Settings.UI.Library.Helpers; +using Microsoft.PowerToys.Settings.UI.Library.Interfaces; + +namespace Microsoft.PowerToys.Settings.UI.ViewModels +{ + public class PowerPreviewViewModel : Observable + { + private const string ModuleName = PowerPreviewSettings.ModuleName; + + private PowerPreviewSettings Settings { get; set; } + + private Func SendConfigMSG { get; } + + private string _settingsConfigFileFolder = string.Empty; + + private GeneralSettings GeneralSettingsConfig { get; set; } + + public PowerPreviewViewModel(ISettingsRepository moduleSettingsRepository, ISettingsRepository generalSettingsRepository, Func ipcMSGCallBackFunc, string configFileSubfolder = "") + { + // Update Settings file folder: + _settingsConfigFileFolder = configFileSubfolder; + + // To obtain the general Settings configurations of PowerToys + if (generalSettingsRepository == null) + { + throw new ArgumentNullException(nameof(generalSettingsRepository)); + } + + GeneralSettingsConfig = generalSettingsRepository.SettingsConfig; + + // To obtain the PowerPreview settings if it exists. + // If the file does not exist, to create a new one and return the default settings configurations. + if (moduleSettingsRepository == null) + { + throw new ArgumentNullException(nameof(moduleSettingsRepository)); + } + + Settings = moduleSettingsRepository.SettingsConfig; + + // set the callback functions value to hangle outgoing IPC message. + SendConfigMSG = ipcMSGCallBackFunc; + + _svgRenderEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredSvgPreviewEnabledValue(); + if (_svgRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _svgRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _svgRenderEnabledStateIsGPOConfigured = true; + _svgRenderIsEnabled = _svgRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _svgRenderIsEnabled = Settings.Properties.EnableSvgPreview; + } + + _svgThumbnailEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredSvgThumbnailsEnabledValue(); + if (_svgThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _svgThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _svgThumbnailEnabledStateIsGPOConfigured = true; + _svgThumbnailIsEnabled = _svgThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _svgThumbnailIsEnabled = Settings.Properties.EnableSvgThumbnail; + } + + _mdRenderEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredMarkdownPreviewEnabledValue(); + if (_mdRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _mdRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _mdRenderEnabledStateIsGPOConfigured = true; + _mdRenderIsEnabled = _mdRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _mdRenderIsEnabled = Settings.Properties.EnableMdPreview; + } + + _monacoRenderEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredMonacoPreviewEnabledValue(); + if (_monacoRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _monacoRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _monacoRenderEnabledStateIsGPOConfigured = true; + _monacoRenderIsEnabled = _monacoRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _monacoRenderIsEnabled = Settings.Properties.EnableMonacoPreview; + } + + _monacoWrapText = Settings.Properties.EnableMonacoPreviewWordWrap; + _monacoPreviewTryFormat = Settings.Properties.MonacoPreviewTryFormat; + + _pdfRenderEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredPdfPreviewEnabledValue(); + if (_pdfRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _pdfRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _pdfRenderEnabledStateIsGPOConfigured = true; + _pdfRenderIsEnabled = _pdfRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _pdfRenderIsEnabled = Settings.Properties.EnablePdfPreview; + } + + _gcodeRenderEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredGcodePreviewEnabledValue(); + if (_gcodeRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _gcodeRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _gcodeRenderEnabledStateIsGPOConfigured = true; + _gcodeRenderIsEnabled = _gcodeRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _gcodeRenderIsEnabled = Settings.Properties.EnableGcodePreview; + } + + _pdfThumbnailEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredPdfThumbnailsEnabledValue(); + if (_pdfThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _pdfThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _pdfThumbnailEnabledStateIsGPOConfigured = true; + _pdfThumbnailIsEnabled = _pdfThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _pdfThumbnailIsEnabled = Settings.Properties.EnablePdfThumbnail; + } + + _gcodeThumbnailEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredGcodeThumbnailsEnabledValue(); + if (_gcodeThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _gcodeThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _gcodeThumbnailEnabledStateIsGPOConfigured = true; + _gcodeThumbnailIsEnabled = _gcodeThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _gcodeThumbnailIsEnabled = Settings.Properties.EnableGcodeThumbnail; + } + + _stlThumbnailEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredStlThumbnailsEnabledValue(); + if (_stlThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _stlThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _stlThumbnailEnabledStateIsGPOConfigured = true; + _stlThumbnailIsEnabled = _stlThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _stlThumbnailIsEnabled = Settings.Properties.EnableStlThumbnail; + } + + _stlThumbnailColor = Settings.Properties.StlThumbnailColor.Value; + } + + private GpoRuleConfigured _svgRenderEnabledGpoRuleConfiguration; + private bool _svgRenderEnabledStateIsGPOConfigured; + private bool _svgRenderIsEnabled; + + private GpoRuleConfigured _mdRenderEnabledGpoRuleConfiguration; + private bool _mdRenderEnabledStateIsGPOConfigured; + private bool _mdRenderIsEnabled; + + private GpoRuleConfigured _monacoRenderEnabledGpoRuleConfiguration; + private bool _monacoRenderEnabledStateIsGPOConfigured; + private bool _monacoRenderIsEnabled; + private bool _monacoWrapText; + private bool _monacoPreviewTryFormat; + + private GpoRuleConfigured _pdfRenderEnabledGpoRuleConfiguration; + private bool _pdfRenderEnabledStateIsGPOConfigured; + private bool _pdfRenderIsEnabled; + + private GpoRuleConfigured _gcodeRenderEnabledGpoRuleConfiguration; + private bool _gcodeRenderEnabledStateIsGPOConfigured; + private bool _gcodeRenderIsEnabled; + + private GpoRuleConfigured _svgThumbnailEnabledGpoRuleConfiguration; + private bool _svgThumbnailEnabledStateIsGPOConfigured; + private bool _svgThumbnailIsEnabled; + + private GpoRuleConfigured _pdfThumbnailEnabledGpoRuleConfiguration; + private bool _pdfThumbnailEnabledStateIsGPOConfigured; + private bool _pdfThumbnailIsEnabled; + + private GpoRuleConfigured _gcodeThumbnailEnabledGpoRuleConfiguration; + private bool _gcodeThumbnailEnabledStateIsGPOConfigured; + private bool _gcodeThumbnailIsEnabled; + + private GpoRuleConfigured _stlThumbnailEnabledGpoRuleConfiguration; + private bool _stlThumbnailEnabledStateIsGPOConfigured; + private bool _stlThumbnailIsEnabled; + private string _stlThumbnailColor; + + public bool SVGRenderIsEnabled + { + get + { + return _svgRenderIsEnabled; + } + + set + { + if (_svgRenderEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (value != _svgRenderIsEnabled) + { + _svgRenderIsEnabled = value; + Settings.Properties.EnableSvgPreview = value; + RaisePropertyChanged(); + } + } + } + + public bool IsSVGRenderEnabledGpoConfigured + { + get => _svgRenderEnabledStateIsGPOConfigured; + } + + public bool SVGThumbnailIsEnabled + { + get + { + return _svgThumbnailIsEnabled; + } + + set + { + if (_svgThumbnailEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (value != _svgThumbnailIsEnabled) + { + _svgThumbnailIsEnabled = value; + Settings.Properties.EnableSvgThumbnail = value; + RaisePropertyChanged(); + } + } + } + + public bool IsSVGThumbnailEnabledGpoConfigured + { + get => _svgThumbnailEnabledStateIsGPOConfigured; + } + + public bool MDRenderIsEnabled + { + get + { + return _mdRenderIsEnabled; + } + + set + { + if (_mdRenderEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (value != _mdRenderIsEnabled) + { + _mdRenderIsEnabled = value; + Settings.Properties.EnableMdPreview = value; + RaisePropertyChanged(); + } + } + } + + public bool IsMDRenderEnabledGpoConfigured + { + get => _mdRenderEnabledStateIsGPOConfigured; + } + + public bool MonacoRenderIsEnabled + { + get + { + return _monacoRenderIsEnabled; + } + + set + { + if (_monacoRenderEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (value != _monacoRenderIsEnabled) + { + _monacoRenderIsEnabled = value; + Settings.Properties.EnableMonacoPreview = value; + RaisePropertyChanged(); + } + } + } + + public bool IsMonacoRenderEnabledGpoConfigured + { + get => _monacoRenderEnabledStateIsGPOConfigured; + } + + public bool MonacoWrapText + { + get + { + return _monacoWrapText; + } + + set + { + if (_monacoWrapText != value) + { + _monacoWrapText = value; + Settings.Properties.EnableMonacoPreviewWordWrap = value; + RaisePropertyChanged(); + } + } + } + + public bool MonacoPreviewTryFormat + { + get + { + return _monacoPreviewTryFormat; + } + + set + { + if (_monacoPreviewTryFormat != value) + { + _monacoPreviewTryFormat = value; + Settings.Properties.MonacoPreviewTryFormat = value; + RaisePropertyChanged(); + } + } + } + + public bool PDFRenderIsEnabled + { + get + { + return _pdfRenderIsEnabled; + } + + set + { + if (_pdfRenderEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (value != _pdfRenderIsEnabled) + { + _pdfRenderIsEnabled = value; + Settings.Properties.EnablePdfPreview = value; + RaisePropertyChanged(); + } + } + } + + public bool IsPDFRenderEnabledGpoConfigured + { + get => _pdfRenderEnabledStateIsGPOConfigured; + } + + public bool PDFThumbnailIsEnabled + { + get + { + return _pdfThumbnailIsEnabled; + } + + set + { + if (_pdfThumbnailEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (value != _pdfThumbnailIsEnabled) + { + _pdfThumbnailIsEnabled = value; + Settings.Properties.EnablePdfThumbnail = value; + RaisePropertyChanged(); + } + } + } + + public bool IsPDFThumbnailEnabledGpoConfigured + { + get => _pdfThumbnailEnabledStateIsGPOConfigured; + } + + public bool GCODERenderIsEnabled + { + get + { + return _gcodeRenderIsEnabled; + } + + set + { + if (_gcodeRenderEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (value != _gcodeRenderIsEnabled) + { + _gcodeRenderIsEnabled = value; + Settings.Properties.EnableGcodePreview = value; + RaisePropertyChanged(); + } + } + } + + public bool IsGCODERenderEnabledGpoConfigured + { + get => _gcodeRenderEnabledStateIsGPOConfigured; + } + + public bool GCODEThumbnailIsEnabled + { + get + { + return _gcodeThumbnailIsEnabled; + } + + set + { + if (_gcodeThumbnailEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (value != _gcodeThumbnailIsEnabled) + { + _gcodeThumbnailIsEnabled = value; + Settings.Properties.EnableGcodeThumbnail = value; + RaisePropertyChanged(); + } + } + } + + public bool IsGCODEThumbnailEnabledGpoConfigured + { + get => _gcodeThumbnailEnabledStateIsGPOConfigured; + } + + public bool STLThumbnailIsEnabled + { + get + { + return _stlThumbnailIsEnabled; + } + + set + { + if (_stlThumbnailEnabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + + if (value != _stlThumbnailIsEnabled) + { + _stlThumbnailIsEnabled = value; + Settings.Properties.EnableStlThumbnail = value; + RaisePropertyChanged(); + } + } + } + + public bool IsSTLThumbnailEnabledGpoConfigured + { + get => _stlThumbnailEnabledStateIsGPOConfigured; + } + + public string STLThumbnailColor + { + get + { + return _stlThumbnailColor; + } + + set + { + if (value != _stlThumbnailColor) + { + _stlThumbnailColor = value; + Settings.Properties.StlThumbnailColor.Value = value; + RaisePropertyChanged(); + } + } + } + + public string GetSettingsSubPath() + { + return _settingsConfigFileFolder + "\\" + ModuleName; + } + + public bool IsElevated + { + get + { + return GeneralSettingsConfig.IsElevated; + } + } + + private void RaisePropertyChanged([CallerMemberName] string propertyName = null) + { + // Notify UI of property change + OnPropertyChanged(propertyName); + + if (SendConfigMSG != null) + { + SndPowerPreviewSettings snd = new SndPowerPreviewSettings(Settings); + SndModuleSettings ipcMessage = new SndModuleSettings(snd); + SendConfigMSG(ipcMessage.ToJsonString()); + } + } + } +} diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/PowerRenameViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PowerRenameViewModel.cs similarity index 87% rename from src/settings-ui/Settings.UI.Library/ViewModels/PowerRenameViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/PowerRenameViewModel.cs index 78918c24bf..04252afbd6 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/PowerRenameViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/PowerRenameViewModel.cs @@ -5,11 +5,13 @@ using System; using System.IO; using System.Runtime.CompilerServices; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.UI.Library.Utilities; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class PowerRenameViewModel : Observable { @@ -66,9 +68,22 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels _powerRenameMaxDispListNumValue = Settings.Properties.MaxMRUSize.Value; _autoComplete = Settings.Properties.MRUEnabled.Value; _powerRenameUseBoostLib = Settings.Properties.UseBoostLib.Value; - _powerRenameEnabled = GeneralSettingsConfig.Enabled.PowerRename; + + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredPowerRenameEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _powerRenameEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _powerRenameEnabled = GeneralSettingsConfig.Enabled.PowerRename; + } } + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; private bool _powerRenameEnabled; private bool _powerRenameEnabledOnContextMenu; private bool _powerRenameEnabledOnContextExtendedMenu; @@ -86,6 +101,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels set { + if (_enabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (value != _powerRenameEnabled) { GeneralSettingsConfig.Enabled.PowerRename = value; @@ -100,6 +121,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public bool MRUEnabled { get diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/ShortcutGuideViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/ShortcutGuideViewModel.cs similarity index 85% rename from src/settings-ui/Settings.UI.Library/ViewModels/ShortcutGuideViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/ShortcutGuideViewModel.cs index d16004c872..2f1715830b 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/ShortcutGuideViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/ShortcutGuideViewModel.cs @@ -4,10 +4,12 @@ using System; using System.Runtime.CompilerServices; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; -namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +namespace Microsoft.PowerToys.Settings.UI.ViewModels { public class ShortcutGuideViewModel : Observable { @@ -51,7 +53,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels // set the callback functions value to hangle outgoing IPC message. SendConfigMSG = ipcMSGCallBackFunc; - _isEnabled = GeneralSettingsConfig.Enabled.ShortcutGuide; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredShortcutGuideEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.ShortcutGuide; + } + _useLegacyPressWinKeyBehavior = Settings.Properties.UseLegacyPressWinKeyBehavior.Value; _pressTime = Settings.Properties.PressTime.Value; _opacity = Settings.Properties.OverlayOpacity.Value; @@ -65,6 +78,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; private bool _isEnabled; private int _themeIndex; private bool _useLegacyPressWinKeyBehavior; @@ -80,6 +95,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels set { + if (_enabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (value != _isEnabled) { _isEnabled = value; @@ -94,6 +115,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + public HotkeySettings OpenShortcutGuide { get diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/VideoConferenceViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/VideoConferenceViewModel.cs similarity index 92% rename from src/settings-ui/Settings.UI.Library/ViewModels/VideoConferenceViewModel.cs rename to src/settings-ui/Settings.UI/ViewModels/VideoConferenceViewModel.cs index c5e7dba5f4..acc33ea579 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/VideoConferenceViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/VideoConferenceViewModel.cs @@ -9,6 +9,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text.Json; using System.Threading.Tasks; +using global::PowerToys.GPOWrapper; using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; @@ -91,7 +92,18 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels _selectedMicrophoneIndex = MicrophoneNames.FindIndex(name => name == Settings.Properties.SelectedMicrophone.Value); } - _isEnabled = GeneralSettingsConfig.Enabled.VideoConference; + _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredVideoConferenceMuteEnabledValue(); + if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) + { + // Get the enabled state from GPO. + _enabledStateIsGPOConfigured = true; + _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; + } + else + { + _isEnabled = GeneralSettingsConfig.Enabled.VideoConference; + } + _cameraAndMicrophoneMuteHotkey = Settings.Properties.MuteCameraAndMicrophoneHotkey.Value; _microphoneMuteHotkey = Settings.Properties.MuteMicrophoneHotkey.Value; _cameraMuteHotkey = Settings.Properties.MuteCameraHotkey.Value; @@ -151,6 +163,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + private GpoRuleConfigured _enabledGpoRuleConfiguration; + private bool _enabledStateIsGPOConfigured; private bool _isEnabled; private int _toolbarPositionIndex; private int _toolbarMonitorIndex; @@ -246,6 +260,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels set { + if (_enabledStateIsGPOConfigured) + { + // If it's GPO configured, shouldn't be able to change this state. + return; + } + if (value != _isEnabled) { _isEnabled = value; @@ -258,6 +278,19 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + public bool IsEnabledGpoConfigured + { + get => _enabledStateIsGPOConfigured; + } + + public bool CanUserChangeEnabledState + { + get + { + return IsElevated && !IsEnabledGpoConfigured; + } + } + public bool IsElevated { get diff --git a/src/settings-ui/Settings.UI/Views/AlwaysOnTopPage.xaml b/src/settings-ui/Settings.UI/Views/AlwaysOnTopPage.xaml index 9d75979fab..908d0a305b 100644 --- a/src/settings-ui/Settings.UI/Views/AlwaysOnTopPage.xaml +++ b/src/settings-ui/Settings.UI/Views/AlwaysOnTopPage.xaml @@ -5,11 +5,12 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls" - xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters" + xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters" mc:Ignorable="d" AutomationProperties.LandmarkType="Main"> + @@ -19,8 +20,7 @@ ModuleImageSource="ms-appx:///Assets/Modules/AlwaysOnTop.png"> - - + @@ -28,6 +28,11 @@ + diff --git a/src/settings-ui/Settings.UI/Views/AlwaysOnTopPage.xaml.cs b/src/settings-ui/Settings.UI/Views/AlwaysOnTopPage.xaml.cs index 80913e134b..36d1cb9e25 100644 --- a/src/settings-ui/Settings.UI/Views/AlwaysOnTopPage.xaml.cs +++ b/src/settings-ui/Settings.UI/Views/AlwaysOnTopPage.xaml.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.UI.Xaml.Controls; namespace Microsoft.PowerToys.Settings.UI.Views diff --git a/src/settings-ui/Settings.UI/Views/AwakePage.xaml b/src/settings-ui/Settings.UI/Views/AwakePage.xaml index 79367e6b9e..a9f4954920 100644 --- a/src/settings-ui/Settings.UI/Views/AwakePage.xaml +++ b/src/settings-ui/Settings.UI/Views/AwakePage.xaml @@ -5,11 +5,13 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters" + xmlns:toolkitConverters="using:CommunityToolkit.WinUI.UI.Converters" xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls" mc:Ignorable="d" AutomationProperties.LandmarkType="Main"> + @@ -18,7 +20,7 @@ - + @@ -26,6 +28,11 @@ + diff --git a/src/settings-ui/Settings.UI/Views/AwakePage.xaml.cs b/src/settings-ui/Settings.UI/Views/AwakePage.xaml.cs index 9c7817f182..cbcdb40d15 100644 --- a/src/settings-ui/Settings.UI/Views/AwakePage.xaml.cs +++ b/src/settings-ui/Settings.UI/Views/AwakePage.xaml.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.UI.Xaml.Controls; namespace Microsoft.PowerToys.Settings.UI.Views diff --git a/src/settings-ui/Settings.UI/Views/ColorPickerPage.xaml b/src/settings-ui/Settings.UI/Views/ColorPickerPage.xaml index 81f36a3600..54ba68ef83 100644 --- a/src/settings-ui/Settings.UI/Views/ColorPickerPage.xaml +++ b/src/settings-ui/Settings.UI/Views/ColorPickerPage.xaml @@ -5,11 +5,16 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls" + xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters" xmlns:models="using:Microsoft.PowerToys.Settings.UI.Library" mc:Ignorable="d" x:Name="RootPage" AutomationProperties.LandmarkType="Main"> + + + + @@ -17,7 +22,7 @@ - + @@ -25,6 +30,11 @@ + diff --git a/src/settings-ui/Settings.UI/Views/ColorPickerPage.xaml.cs b/src/settings-ui/Settings.UI/Views/ColorPickerPage.xaml.cs index dbf5240dbc..2bc4088d01 100644 --- a/src/settings-ui/Settings.UI/Views/ColorPickerPage.xaml.cs +++ b/src/settings-ui/Settings.UI/Views/ColorPickerPage.xaml.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.PowerToys.Settings.UI.Library; -using Microsoft.PowerToys.Settings.UI.Library.ViewModels; +using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.UI.Xaml.Controls; namespace Microsoft.PowerToys.Settings.UI.Views diff --git a/src/settings-ui/Settings.UI/Views/FancyZonesPage.xaml b/src/settings-ui/Settings.UI/Views/FancyZonesPage.xaml index a05541ceda..a69064e2d5 100644 --- a/src/settings-ui/Settings.UI/Views/FancyZonesPage.xaml +++ b/src/settings-ui/Settings.UI/Views/FancyZonesPage.xaml @@ -5,11 +5,12 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls" - xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters" + xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters" mc:Ignorable="d" AutomationProperties.LandmarkType="Main"> + @@ -21,7 +22,7 @@ - + @@ -29,7 +30,11 @@ - +