mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 18:26:39 +02:00
common: refactor common library pt2 (#8588)
- remove common lib - split settings, remove common-md - move ipc interop/kb_layout to interop - rename core -> settings, settings -> old_settings - os-detect header-only; interop -> PowerToysInterop - split notifications, move single-use headers where they're used - winstore lib - rename com utils - rename Updating and Telemetry projects - rename core -> settings-ui and remove examples folder - rename settings-ui folder + consisent common/version include
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<CppWinRTOptimized>true</CppWinRTOptimized>
|
||||
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
|
||||
<CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata>
|
||||
<MinimalCoreWin>true</MinimalCoreWin>
|
||||
<ProjectGuid>{0b593a6c-4143-4337-860e-db5710fb87db}</ProjectGuid>
|
||||
<ProjectName>BackgroundActivator</ProjectName>
|
||||
<RootNamespace>BackgroundActivator</RootNamespace>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
<AppContainerApplication>true</AppContainerApplication>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<SpectreMitigation>Spectre</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<SpectreMitigation>Spectre</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetName>notifications</TargetName>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetName>notifications</TargetName>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
|
||||
<!--Temporarily disable cppwinrt heap enforcement to work around xaml compiler generated std::shared_ptr use -->
|
||||
<AdditionalOptions Condition="'$(CppWinRTHeapEnforcement)'==''">/DWINRT_NO_MAKE_DETECTION /await %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>
|
||||
</DisableSpecificWarnings>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
<ModuleDefinitionFile>notifications.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</TreatWarningAsError>
|
||||
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">stdcpplatest</LanguageStandard>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</TreatWarningAsError>
|
||||
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|x64'">stdcpplatest</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(CIBuild)'!='true'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(CIBuild)'=='true'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="handler_functions.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="BackgroundHandler.h">
|
||||
<DependentUpon>BackgroundHandler.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="handler_functions.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BackgroundHandler.cpp">
|
||||
<DependentUpon>BackgroundHandler.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="BackgroundHandler.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="PropertySheet.props" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>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}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\.\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Resources">
|
||||
<UniqueIdentifier>accd3aa8-1ba0-4223-9bbe-0c431709210b</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{926ab91d-31b4-48c3-b9a4-e681349f27f0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="handler_functions.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="handler_functions.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="BackgroundHandler.idl" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "pch.h"
|
||||
#include "BackgroundHandler.h"
|
||||
#include "BackgroundHandler.g.cpp"
|
||||
|
||||
#include "handler_functions.h"
|
||||
|
||||
namespace winrt::BackgroundActivator::implementation
|
||||
{
|
||||
using Windows::ApplicationModel::Background::IBackgroundTaskInstance;
|
||||
using Windows::UI::Notifications::ToastNotificationActionTriggerDetail;
|
||||
|
||||
void BackgroundHandler::Run(IBackgroundTaskInstance bti)
|
||||
{
|
||||
const auto details = bti.TriggerDetails().try_as<ToastNotificationActionTriggerDetail>();
|
||||
if (!details)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch_to_background_handler(details.Argument());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "BackgroundHandler.g.h"
|
||||
|
||||
namespace winrt::BackgroundActivator::implementation
|
||||
{
|
||||
struct BackgroundHandler : BackgroundHandlerT<BackgroundHandler>
|
||||
{
|
||||
BackgroundHandler() = default;
|
||||
|
||||
void Run(winrt::Windows::ApplicationModel::Background::IBackgroundTaskInstance);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::BackgroundActivator::factory_implementation
|
||||
{
|
||||
struct BackgroundHandler : BackgroundHandlerT<BackgroundHandler, implementation::BackgroundHandler>
|
||||
{
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace BackgroundActivator
|
||||
{
|
||||
[version(1)]
|
||||
runtimeclass BackgroundHandler
|
||||
{
|
||||
BackgroundHandler();
|
||||
|
||||
void Run(Windows.ApplicationModel.Background.IBackgroundTaskInstance taskInstance);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "handler_functions.h"
|
||||
|
||||
#include <winrt/Windows.System.h>
|
||||
|
||||
using handler_function_t = void (*)(const size_t button_id);
|
||||
|
||||
namespace
|
||||
{
|
||||
const std::unordered_map<std::wstring_view, handler_function_t> handlers_map;
|
||||
}
|
||||
|
||||
void dispatch_to_background_handler(std::wstring_view argument)
|
||||
{
|
||||
winrt::Windows::Foundation::WwwFormUrlDecoder decoder{ argument };
|
||||
|
||||
const size_t button_id = std::stoi(decoder.GetFirstValueByName(L"button_id").c_str());
|
||||
auto handler = decoder.GetFirstValueByName(L"handler");
|
||||
|
||||
const auto found_handler = handlers_map.find(handler);
|
||||
if (found_handler == end(handlers_map))
|
||||
{
|
||||
return;
|
||||
}
|
||||
found_handler->second(button_id);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
void dispatch_to_background_handler(std::wstring_view argument);
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
|
||||
</packages>
|
||||
1
src/common/notifications/BackgroundActivator/pch.cpp
Normal file
1
src/common/notifications/BackgroundActivator/pch.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "pch.h"
|
||||
7
src/common/notifications/BackgroundActivator/pch.h
Normal file
7
src/common/notifications/BackgroundActivator/pch.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include <unknwn.h>
|
||||
#include <winrt/Windows.ApplicationModel.Background.h>
|
||||
#include <winrt/Windows.Data.Xml.Dom.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.UI.Notifications.h>
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "../version.h"
|
||||
#include "../../version/version.h"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION FILE_VERSION
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>notificationsdll</RootNamespace>
|
||||
<RootNamespace>BackgroundActivatorDLL</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
@@ -32,7 +32,7 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<TargetName>Notifications</TargetName>
|
||||
<TargetName>BackgroundActivatorDLL</TargetName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||
@@ -54,7 +54,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>notifications.def</ModuleDefinitionFile>
|
||||
<ModuleDefinitionFile>BackgroundActivator.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions> /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
@@ -77,21 +77,21 @@
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\notifications_winrt\notifications.vcxproj">
|
||||
<ProjectReference Include="..\BackgroundActivator\BackgroundActivator.vcxproj">
|
||||
<Project>{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="notifications_dll.rc" />
|
||||
<ResourceCompile Include="BackgroundActivator.rc" />
|
||||
</ItemGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>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}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
|
||||
</packages>
|
||||
5
src/common/notifications/BackgroundActivatorDLL/pch.cpp
Normal file
5
src/common/notifications/BackgroundActivatorDLL/pch.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
// pch.cpp: source file corresponding to the pre-compiled header
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
||||
8
src/common/notifications/BackgroundActivatorDLL/pch.h
Normal file
8
src/common/notifications/BackgroundActivatorDLL/pch.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
#include "framework.h"
|
||||
|
||||
#endif //PCH_H
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#define FILE_DESCRIPTION "PowerToys Notifications"
|
||||
#define INTERNAL_NAME "Notifications"
|
||||
#define ORIGINAL_FILENAME "Notifications.dll"
|
||||
#define ORIGINAL_FILENAME "BackgroundActivatorDLL.dll"
|
||||
|
||||
// Non-localizable
|
||||
//////////////////////////////
|
||||
62
src/common/notifications/dont_show_again.cpp
Normal file
62
src/common/notifications/dont_show_again.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "pch.h"
|
||||
#include "dont_show_again.h"
|
||||
|
||||
namespace notifications
|
||||
{
|
||||
bool disable_toast(const wchar_t* registry_path)
|
||||
{
|
||||
HKEY key{};
|
||||
if (RegCreateKeyExW(HKEY_CURRENT_USER,
|
||||
registry_path,
|
||||
0,
|
||||
nullptr,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_ALL_ACCESS,
|
||||
nullptr,
|
||||
&key,
|
||||
nullptr) != ERROR_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const auto now = timeutil::now();
|
||||
const size_t buf_size = sizeof(now);
|
||||
if (RegSetValueExW(key, nullptr, 0, REG_QWORD, reinterpret_cast<const BYTE*>(&now), sizeof(now)) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(key);
|
||||
return false;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_toast_disabled(const wchar_t* registry_path, const int64_t disable_interval_in_days)
|
||||
{
|
||||
HKEY key{};
|
||||
if (RegOpenKeyExW(HKEY_CURRENT_USER,
|
||||
registry_path,
|
||||
0,
|
||||
KEY_READ,
|
||||
&key) != ERROR_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::wstring buffer(std::numeric_limits<time_t>::digits10 + 2, L'\0');
|
||||
time_t last_disabled_time{};
|
||||
DWORD time_size = static_cast<DWORD>(sizeof(last_disabled_time));
|
||||
if (RegGetValueW(
|
||||
key,
|
||||
nullptr,
|
||||
nullptr,
|
||||
RRF_RT_REG_QWORD,
|
||||
nullptr,
|
||||
&last_disabled_time,
|
||||
&time_size) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(key);
|
||||
return false;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
return timeutil::diff::in_days(timeutil::now(), last_disabled_time) < disable_interval_in_days;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
15
src/common/notifications/dont_show_again.h
Normal file
15
src/common/notifications/dont_show_again.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "../utils/timeutil.h"
|
||||
|
||||
namespace notifications
|
||||
{
|
||||
const inline wchar_t CantDragElevatedDontShowAgainRegistryPath[] = LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain\{e16ea82f-6d94-4f30-bb02-d6d911588afd})";
|
||||
const inline int64_t CantDragElevatedDisableIntervalInDays = 30;
|
||||
|
||||
const inline wchar_t PreviewModulesDontShowAgainRegistryPath[] = LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain\{7e29e2b2-b31c-4dcd-b7b0-79c078b02430})";
|
||||
const inline int64_t PreviewModulesDisableIntervalInDays = 30;
|
||||
|
||||
bool disable_toast(const wchar_t* registry_path);
|
||||
bool is_toast_disabled(const wchar_t* registry_path, const int64_t disable_interval_in_days);
|
||||
}
|
||||
474
src/common/notifications/notifications.cpp
Normal file
474
src/common/notifications/notifications.cpp
Normal file
@@ -0,0 +1,474 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "notifications.h"
|
||||
#include "utils/com_object_factory.h"
|
||||
#include "utils/window.h"
|
||||
#include "winstore/winstore.h"
|
||||
|
||||
#include <unknwn.h>
|
||||
#include <winrt/base.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Data.Xml.Dom.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.UI.Notifications.h>
|
||||
#include <winrt/Windows.UI.Notifications.Management.h>
|
||||
#include <winrt/Windows.ApplicationModel.Background.h>
|
||||
#include <winrt/Windows.System.h>
|
||||
#include <winrt/Windows.System.UserProfile.h>
|
||||
#include <wil/com.h>
|
||||
#include <propvarutil.h>
|
||||
#include <propkey.h>
|
||||
#include <Shobjidl.h>
|
||||
#include <filesystem>
|
||||
|
||||
#include <winerror.h>
|
||||
#include <NotificationActivationCallback.h>
|
||||
|
||||
#include "BackgroundActivator/handler_functions.h"
|
||||
|
||||
using namespace winrt::Windows::ApplicationModel::Background;
|
||||
using winrt::Windows::Data::Xml::Dom::XmlDocument;
|
||||
using winrt::Windows::UI::Notifications::ToastNotification;
|
||||
using winrt::Windows::UI::Notifications::ToastNotificationManager;
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
template<class... Ts>
|
||||
struct overloaded : Ts...
|
||||
{
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
template<class... Ts>
|
||||
overloaded(Ts...) -> overloaded<Ts...>;
|
||||
|
||||
namespace // Strings in this namespace should not be localized
|
||||
{
|
||||
constexpr std::wstring_view TASK_NAME = L"PowerToysBackgroundNotificationsHandler";
|
||||
constexpr std::wstring_view TASK_ENTRYPOINT = L"BackgroundActivator.BackgroundHandler";
|
||||
constexpr std::wstring_view PACKAGED_APPLICATION_ID = L"PowerToys";
|
||||
constexpr std::wstring_view APPIDS_REGISTRY = LR"(Software\Classes\AppUserModelId\)";
|
||||
|
||||
std::wstring APPLICATION_ID = L"Microsoft.PowerToysWin32";
|
||||
constexpr std::wstring_view DEFAULT_TOAST_GROUP = L"PowerToysToastTag";
|
||||
}
|
||||
|
||||
static DWORD loop_thread_id()
|
||||
{
|
||||
static const DWORD thread_id = GetCurrentThreadId();
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
class DECLSPEC_UUID("DD5CACDA-7C2E-4997-A62A-04A597B58F76") NotificationActivator : public INotificationActivationCallback
|
||||
{
|
||||
public:
|
||||
HRESULT __stdcall QueryInterface(_In_ REFIID iid, _Outptr_ void** resultInterface) override
|
||||
{
|
||||
static const QITAB qit[] = {
|
||||
QITABENT(NotificationActivator, INotificationActivationCallback),
|
||||
{ 0 }
|
||||
};
|
||||
return QISearch(this, qit, iid, resultInterface);
|
||||
}
|
||||
|
||||
ULONG __stdcall AddRef() override
|
||||
{
|
||||
return ++_refCount;
|
||||
}
|
||||
|
||||
ULONG __stdcall Release() override
|
||||
{
|
||||
LONG refCount = --_refCount;
|
||||
if (refCount == 0)
|
||||
{
|
||||
PostThreadMessage(loop_thread_id(), WM_QUIT, 0, 0);
|
||||
delete this;
|
||||
}
|
||||
return refCount;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Activate(
|
||||
LPCWSTR appUserModelId,
|
||||
LPCWSTR invokedArgs,
|
||||
const NOTIFICATION_USER_INPUT_DATA*,
|
||||
ULONG) override
|
||||
{
|
||||
auto lib = LoadLibraryW(L"BackgroundActivatorDLL.dll");
|
||||
if (!lib)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
auto dispatcher = reinterpret_cast<decltype(dispatch_to_background_handler)*>(GetProcAddress(lib, "dispatch_to_background_handler"));
|
||||
if (!dispatcher)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
dispatcher(invokedArgs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<long> _refCount;
|
||||
};
|
||||
|
||||
void notifications::run_desktop_app_activator_loop()
|
||||
{
|
||||
com_object_factory<NotificationActivator> factory;
|
||||
|
||||
(void)loop_thread_id();
|
||||
|
||||
DWORD token;
|
||||
auto res = CoRegisterClassObject(__uuidof(NotificationActivator), &factory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &token);
|
||||
if (!SUCCEEDED(res))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
run_message_loop();
|
||||
CoRevokeClassObject(token);
|
||||
}
|
||||
|
||||
bool notifications::register_application_id(const std::wstring_view appName, const std::wstring_view iconPath)
|
||||
{
|
||||
std::wstring aumidPath{ APPIDS_REGISTRY };
|
||||
aumidPath += APPLICATION_ID;
|
||||
wil::unique_hkey aumidKey;
|
||||
if (FAILED(RegCreateKeyW(HKEY_CURRENT_USER, aumidPath.c_str(), &aumidKey)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (FAILED(RegSetKeyValueW(aumidKey.get(),
|
||||
nullptr,
|
||||
L"DisplayName",
|
||||
REG_SZ,
|
||||
appName.data(),
|
||||
static_cast<DWORD>((size(appName) + 1) * sizeof(wchar_t)))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(RegSetKeyValueW(aumidKey.get(),
|
||||
nullptr,
|
||||
L"IconUri",
|
||||
REG_SZ,
|
||||
iconPath.data(),
|
||||
static_cast<DWORD>((size(iconPath) + 1) * sizeof(wchar_t)))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::wstring_view iconColor = L"FFDDDDDD";
|
||||
if (FAILED(RegSetKeyValueW(aumidKey.get(),
|
||||
nullptr,
|
||||
L"IconBackgroundColor",
|
||||
REG_SZ,
|
||||
iconColor.data(),
|
||||
static_cast<DWORD>((size(iconColor) + 1) * sizeof(wchar_t)))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void notifications::unregister_application_id()
|
||||
{
|
||||
std::wstring aumidPath{ APPIDS_REGISTRY };
|
||||
aumidPath += APPLICATION_ID;
|
||||
wil::unique_hkey registryRoot;
|
||||
RegOpenKeyW(HKEY_CURRENT_USER, aumidPath.c_str(), ®istryRoot);
|
||||
if (!registryRoot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
RegDeleteTreeW(registryRoot.get(), nullptr);
|
||||
registryRoot.reset();
|
||||
RegOpenKeyW(HKEY_CURRENT_USER, APPIDS_REGISTRY.data(), ®istryRoot);
|
||||
if (!registryRoot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
RegDeleteKeyW(registryRoot.get(), APPLICATION_ID.data());
|
||||
}
|
||||
|
||||
void notifications::override_application_id(const std::wstring_view appID)
|
||||
{
|
||||
APPLICATION_ID = appID;
|
||||
SetCurrentProcessExplicitAppUserModelID(APPLICATION_ID.c_str());
|
||||
}
|
||||
|
||||
void notifications::register_background_toast_handler()
|
||||
{
|
||||
if (!winstore::running_as_packaged())
|
||||
{
|
||||
// The WIX installer will have us registered via the registry
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
// Re-request access to clean up from previous PowerToys installations
|
||||
BackgroundExecutionManager::RemoveAccess();
|
||||
BackgroundExecutionManager::RequestAccessAsync().get();
|
||||
|
||||
BackgroundTaskBuilder builder;
|
||||
ToastNotificationActionTrigger trigger{ PACKAGED_APPLICATION_ID };
|
||||
builder.SetTrigger(trigger);
|
||||
builder.TaskEntryPoint(TASK_ENTRYPOINT);
|
||||
builder.Name(TASK_NAME);
|
||||
|
||||
const auto tasks = BackgroundTaskRegistration::AllTasks();
|
||||
const bool already_registered = std::any_of(begin(tasks), end(tasks), [=](const auto& task) {
|
||||
return task.Value().Name() == TASK_NAME;
|
||||
});
|
||||
if (already_registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
(void)builder.Register();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Couldn't register the background task, nothing we can do
|
||||
}
|
||||
}
|
||||
|
||||
void notifications::show_toast(std::wstring message, std::wstring title, toast_params params)
|
||||
{
|
||||
// The toast won't be actually activated in the background, since it doesn't have any buttons
|
||||
show_toast_with_activations(std::move(message), std::move(title), {}, {}, std::move(params));
|
||||
}
|
||||
|
||||
inline void xml_escape(std::wstring data)
|
||||
{
|
||||
std::wstring buffer;
|
||||
buffer.reserve(data.size());
|
||||
for (size_t pos = 0; pos != data.size(); ++pos)
|
||||
{
|
||||
switch (data[pos])
|
||||
{
|
||||
case L'&':
|
||||
buffer.append(L"&");
|
||||
break;
|
||||
case L'\"':
|
||||
buffer.append(L""");
|
||||
break;
|
||||
case L'\'':
|
||||
buffer.append(L"'");
|
||||
break;
|
||||
case L'<':
|
||||
buffer.append(L"<");
|
||||
break;
|
||||
case L'>':
|
||||
buffer.append(L">");
|
||||
break;
|
||||
default:
|
||||
buffer.append(&data[pos], 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
data.swap(buffer);
|
||||
}
|
||||
|
||||
void notifications::show_toast_with_activations(std::wstring message,
|
||||
std::wstring title,
|
||||
std::wstring_view background_handler_id,
|
||||
std::vector<action_t> actions,
|
||||
toast_params params)
|
||||
{
|
||||
// DO NOT LOCALIZE any string in this function, because they're XML tags and a subject to
|
||||
// https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/toast-xml-schema
|
||||
|
||||
std::wstring toast_xml;
|
||||
toast_xml.reserve(2048);
|
||||
|
||||
toast_xml += LR"(<?xml version="1.0"?><toast><visual><binding template="ToastGeneric">)";
|
||||
toast_xml += LR"(<text id="1">{title}</text>)";
|
||||
toast_xml += LR"(<text id="2">{message}</text>)";
|
||||
|
||||
if (params.progress_bar.has_value())
|
||||
{
|
||||
toast_xml += LR"(<progress title="{progressTitle}" value="{progressValue}" valueStringOverride="{progressValueString}" status="" />)";
|
||||
}
|
||||
toast_xml += L"</binding></visual><actions>";
|
||||
for (size_t i = 0; i < size(actions); ++i)
|
||||
{
|
||||
std::visit(overloaded{
|
||||
[&](const snooze_button& b) {
|
||||
const bool has_durations = !b.durations.empty() && size(b.durations) <= 5;
|
||||
std::wstring selection_id = L"snoozeTime";
|
||||
selection_id += static_cast<wchar_t>(L'0' + i);
|
||||
if (has_durations)
|
||||
{
|
||||
toast_xml += LR"(<input id=")";
|
||||
toast_xml += selection_id;
|
||||
toast_xml += LR"(" type="selection" defaultInput=")";
|
||||
toast_xml += std::to_wstring(b.durations[0].minutes);
|
||||
toast_xml += L'"';
|
||||
if (!b.snooze_title.empty())
|
||||
{
|
||||
toast_xml += LR"( title=")";
|
||||
toast_xml += b.snooze_title;
|
||||
toast_xml += L'"';
|
||||
}
|
||||
toast_xml += L'>';
|
||||
for (const auto& duration : b.durations)
|
||||
{
|
||||
toast_xml += LR"(<selection id=")";
|
||||
toast_xml += std::to_wstring(duration.minutes);
|
||||
toast_xml += LR"(" content=")";
|
||||
toast_xml += duration.label;
|
||||
toast_xml += LR"("/>)";
|
||||
}
|
||||
toast_xml += LR"(</input>)";
|
||||
}
|
||||
},
|
||||
[](const auto&) {} },
|
||||
actions[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size(actions); ++i)
|
||||
{
|
||||
std::visit(overloaded{
|
||||
[&](const link_button& b) {
|
||||
toast_xml += LR"(<action activationType="protocol" )";
|
||||
if (b.context_menu)
|
||||
{
|
||||
toast_xml += LR"(placement="contextMenu" )";
|
||||
}
|
||||
toast_xml += LR"(arguments=")";
|
||||
toast_xml += b.url;
|
||||
toast_xml += LR"(" content=")";
|
||||
toast_xml += b.label;
|
||||
toast_xml += LR"(" />)";
|
||||
},
|
||||
[&](const background_activated_button& b) {
|
||||
toast_xml += LR"(<action activationType="background" )";
|
||||
if (b.context_menu)
|
||||
{
|
||||
toast_xml += LR"(placement="contextMenu" )";
|
||||
}
|
||||
toast_xml += LR"(arguments=")";
|
||||
toast_xml += L"button_id=" + std::to_wstring(i); // pass the button ID
|
||||
toast_xml += L"&handler=";
|
||||
toast_xml += background_handler_id;
|
||||
toast_xml += LR"(" content=")";
|
||||
toast_xml += b.label;
|
||||
toast_xml += LR"(" />)";
|
||||
},
|
||||
[&](const snooze_button& b) {
|
||||
const bool has_durations = !b.durations.empty() && size(b.durations) <= 5;
|
||||
std::wstring selection_id = L"snoozeTime";
|
||||
selection_id += static_cast<wchar_t>(L'0' + i);
|
||||
toast_xml += LR"(<action activationType="system" arguments="snooze" )";
|
||||
if (has_durations)
|
||||
{
|
||||
toast_xml += LR"(hint-inputId=")";
|
||||
toast_xml += selection_id;
|
||||
toast_xml += '"';
|
||||
}
|
||||
toast_xml += LR"( content=")";
|
||||
toast_xml += b.snooze_button_title;
|
||||
toast_xml += LR"(" />)";
|
||||
} },
|
||||
actions[i]);
|
||||
}
|
||||
toast_xml += L"</actions></toast>";
|
||||
|
||||
XmlDocument toast_xml_doc;
|
||||
xml_escape(toast_xml);
|
||||
toast_xml_doc.LoadXml(toast_xml);
|
||||
ToastNotification notification{ toast_xml_doc };
|
||||
notification.Group(DEFAULT_TOAST_GROUP);
|
||||
|
||||
winrt::Windows::Foundation::Collections::StringMap map;
|
||||
map.Insert(L"message", std::move(message));
|
||||
map.Insert(L"title", std::move(title));
|
||||
if (params.progress_bar.has_value())
|
||||
{
|
||||
float progress = std::clamp(params.progress_bar->progress, 0.0f, 1.0f);
|
||||
map.Insert(L"progressValue", std::to_wstring(progress));
|
||||
map.Insert(L"progressValueString", std::to_wstring(static_cast<int>(progress * 100)) + std::wstring(L"%"));
|
||||
map.Insert(L"progressTitle", params.progress_bar->progress_title);
|
||||
}
|
||||
winrt::Windows::UI::Notifications::NotificationData data{ map };
|
||||
notification.Data(std::move(data));
|
||||
|
||||
const auto notifier = winstore::running_as_packaged() ? ToastNotificationManager::ToastNotificationManager::CreateToastNotifier() :
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||
|
||||
// Set a tag-related params if it has a valid length
|
||||
if (params.tag.has_value() && params.tag->length() < 64)
|
||||
{
|
||||
notification.Tag(*params.tag);
|
||||
if (!params.resend_if_scheduled)
|
||||
{
|
||||
for (const auto& scheduled_toast : notifier.GetScheduledToastNotifications())
|
||||
{
|
||||
if (scheduled_toast.Tag() == *params.tag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
notifier.Show(notification);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void notifications::update_toast_progress_bar(std::wstring_view tag, progress_bar_params params)
|
||||
{
|
||||
const auto notifier = winstore::running_as_packaged() ?
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier() :
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||
|
||||
float progress = std::clamp(params.progress, 0.0f, 1.0f);
|
||||
winrt::Windows::Foundation::Collections::StringMap map;
|
||||
map.Insert(L"progressValue", std::to_wstring(progress));
|
||||
map.Insert(L"progressValueString", std::to_wstring(static_cast<int>(progress * 100)) + std::wstring(L"%"));
|
||||
map.Insert(L"progressTitle", params.progress_title);
|
||||
|
||||
winrt::Windows::UI::Notifications::NotificationData data(map);
|
||||
winrt::Windows::UI::Notifications::NotificationUpdateResult res = notifier.Update(data, tag, DEFAULT_TOAST_GROUP);
|
||||
}
|
||||
|
||||
void notifications::update_toast_contents(std::wstring_view tag, std::wstring plaintext_message, std::wstring title)
|
||||
{
|
||||
const auto notifier = winstore::running_as_packaged() ?
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier() :
|
||||
ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);
|
||||
|
||||
winrt::Windows::Foundation::Collections::StringMap map;
|
||||
|
||||
map.Insert(L"title", std::move(title));
|
||||
map.Insert(L"message", std::move(plaintext_message));
|
||||
|
||||
winrt::Windows::UI::Notifications::NotificationData data(map);
|
||||
winrt::Windows::UI::Notifications::NotificationUpdateResult res = notifier.Update(data, tag, DEFAULT_TOAST_GROUP);
|
||||
}
|
||||
|
||||
void notifications::remove_toasts(std::wstring_view tag)
|
||||
{
|
||||
using namespace winrt::Windows::System;
|
||||
|
||||
try
|
||||
{
|
||||
User currentUser{ *User::FindAllAsync(UserType::LocalUser, UserAuthenticationStatus::LocallyAuthenticated).get().First() };
|
||||
if (!currentUser)
|
||||
{
|
||||
return;
|
||||
}
|
||||
currentUser.GetPropertyAsync(KnownUserProperties::AccountName());
|
||||
auto toastHistory = ToastNotificationManager::GetForUser(currentUser).History();
|
||||
toastHistory.Remove(tag, DEFAULT_TOAST_GROUP, APPLICATION_ID);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Couldn't get the current user or problem removing the toast => nothing we can do
|
||||
}
|
||||
}
|
||||
67
src/common/notifications/notifications.h
Normal file
67
src/common/notifications/notifications.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <optional>
|
||||
|
||||
namespace notifications
|
||||
{
|
||||
constexpr inline const wchar_t TOAST_ACTIVATED_LAUNCH_ARG[] = L"-ToastActivated";
|
||||
constexpr inline const wchar_t UPDATING_PROCESS_TOAST_TAG[] = L"PTUpdateNotifyTag";
|
||||
|
||||
void override_application_id(const std::wstring_view appID);
|
||||
void register_background_toast_handler();
|
||||
void run_desktop_app_activator_loop();
|
||||
|
||||
bool register_application_id(const std::wstring_view appName, const std::wstring_view iconPath);
|
||||
void unregister_application_id();
|
||||
|
||||
struct snooze_duration
|
||||
{
|
||||
std::wstring label;
|
||||
int minutes;
|
||||
};
|
||||
|
||||
struct snooze_button
|
||||
{
|
||||
std::wstring snooze_title;
|
||||
std::vector<snooze_duration> durations;
|
||||
std::wstring snooze_button_title;
|
||||
};
|
||||
|
||||
struct link_button
|
||||
{
|
||||
std::wstring label;
|
||||
std::wstring url;
|
||||
bool context_menu = false;
|
||||
};
|
||||
|
||||
struct background_activated_button
|
||||
{
|
||||
std::wstring label;
|
||||
bool context_menu = false;
|
||||
};
|
||||
|
||||
struct progress_bar_params
|
||||
{
|
||||
std::wstring progress_title;
|
||||
float progress = 0.f;
|
||||
};
|
||||
|
||||
struct toast_params
|
||||
{
|
||||
std::optional<std::wstring_view> tag;
|
||||
bool resend_if_scheduled = true;
|
||||
std::optional<progress_bar_params> progress_bar;
|
||||
};
|
||||
|
||||
using action_t = std::variant<link_button, background_activated_button, snooze_button>;
|
||||
|
||||
void show_toast(std::wstring plaintext_message, std::wstring title, toast_params params = {});
|
||||
void show_toast_with_activations(std::wstring plaintext_message, std::wstring title, std::wstring_view background_handler_id, std::vector<action_t> actions, toast_params params = {});
|
||||
void update_toast_progress_bar(std::wstring_view tag, progress_bar_params params);
|
||||
void update_toast_contents(std::wstring_view tag, std::wstring plaintext_message, std::wstring title);
|
||||
void remove_toasts(std::wstring_view tag);
|
||||
}
|
||||
61
src/common/notifications/notifications.vcxproj
Normal file
61
src/common/notifications/notifications.vcxproj
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{1D5BE09D-78C0-4FD7-AF00-AE7C1AF7C525}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>notifications</RootNamespace>
|
||||
<ProjectName>Notifications</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\;..\..\;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="notifications.h" />
|
||||
<ClInclude Include="dont_show_again.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dont_show_again.cpp" />
|
||||
<ClCompile Include="notifications.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WinStore\Winstore.vcxproj">
|
||||
<Project>{c502a854-53ac-4ebb-8dc0-e4af2191e4f6}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>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}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200902.2" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -1,5 +1 @@
|
||||
// pch.cpp: source file corresponding to the pre-compiled header
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
||||
#include "pch.h"
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include "framework.h"
|
||||
|
||||
#endif //PCH_H
|
||||
#include <winrt/base.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <Windows.h>
|
||||
Reference in New Issue
Block a user