From ec18e31ff15d9a16c62dd8be60d079b62d1ea687 Mon Sep 17 00:00:00 2001 From: yuyoyuppe Date: Tue, 20 Oct 2020 01:27:24 +0300 Subject: [PATCH] settings: use actionable toast notifications for file explorer modules warning --- src/common/common.vcxproj | 4 +- src/common/common.vcxproj.filters | 6 ++ .../notifications/fancyzones_notifications.h | 71 ------------------- src/common/toast_dont_show_again.cpp | 62 ++++++++++++++++ src/common/toast_dont_show_again.h | 15 ++++ .../fancyzones/lib/WindowMoveHandler.cpp | 23 +++--- .../previewpane/powerpreview/Resources.resx | 10 ++- .../previewpane/powerpreview/powerpreview.cpp | 23 ++++-- src/runner/main.cpp | 33 ++++++--- 9 files changed, 146 insertions(+), 101 deletions(-) delete mode 100644 src/common/notifications/fancyzones_notifications.h create mode 100644 src/common/toast_dont_show_again.cpp create mode 100644 src/common/toast_dont_show_again.h diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj index 4a2ed39280..d44af3419e 100644 --- a/src/common/common.vcxproj +++ b/src/common/common.vcxproj @@ -1,4 +1,4 @@ - + @@ -140,6 +140,7 @@ + @@ -185,6 +186,7 @@ + diff --git a/src/common/common.vcxproj.filters b/src/common/common.vcxproj.filters index c9abbe7cb4..da8ff204d2 100644 --- a/src/common/common.vcxproj.filters +++ b/src/common/common.vcxproj.filters @@ -141,6 +141,9 @@ Header Files + + Header Files + @@ -222,6 +225,9 @@ Source Files + + Source Files + diff --git a/src/common/notifications/fancyzones_notifications.h b/src/common/notifications/fancyzones_notifications.h deleted file mode 100644 index 0e79e15427..0000000000 --- a/src/common/notifications/fancyzones_notifications.h +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include - -#include "../timeutil.h" -namespace -{ - const inline wchar_t CANT_DRAG_ELEVATED_DONT_SHOW_AGAIN_REGISTRY_PATH[] = LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain\{e16ea82f-6d94-4f30-bb02-d6d911588afd})"; - const inline int64_t disable_interval_in_days = 30; -} - -inline bool disable_cant_drag_elevated_warning() -{ - HKEY key{}; - if (RegCreateKeyExW(HKEY_CURRENT_USER, - CANT_DRAG_ELEVATED_DONT_SHOW_AGAIN_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(&now), sizeof(now)) != ERROR_SUCCESS) - { - RegCloseKey(key); - return false; - } - RegCloseKey(key); - return true; -} - -inline bool is_cant_drag_elevated_warning_disabled() -{ - HKEY key{}; - if (RegOpenKeyExW(HKEY_CURRENT_USER, - CANT_DRAG_ELEVATED_DONT_SHOW_AGAIN_REGISTRY_PATH, - 0, - KEY_READ, - &key) != ERROR_SUCCESS) - { - return false; - } - std::wstring buffer(std::numeric_limits::digits10 + 2, L'\0'); - time_t last_disabled_time{}; - DWORD time_size = static_cast(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; -} \ No newline at end of file diff --git a/src/common/toast_dont_show_again.cpp b/src/common/toast_dont_show_again.cpp new file mode 100644 index 0000000000..c57ee81866 --- /dev/null +++ b/src/common/toast_dont_show_again.cpp @@ -0,0 +1,62 @@ +#include "pch.h" +#include "toast_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(&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::digits10 + 2, L'\0'); + time_t last_disabled_time{}; + DWORD time_size = static_cast(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; + } +} \ No newline at end of file diff --git a/src/common/toast_dont_show_again.h b/src/common/toast_dont_show_again.h new file mode 100644 index 0000000000..95444b0d5a --- /dev/null +++ b/src/common/toast_dont_show_again.h @@ -0,0 +1,15 @@ +#pragma once + +#include "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); +} diff --git a/src/modules/fancyzones/lib/WindowMoveHandler.cpp b/src/modules/fancyzones/lib/WindowMoveHandler.cpp index d5e3fbfc9e..ee2361ffa7 100644 --- a/src/modules/fancyzones/lib/WindowMoveHandler.cpp +++ b/src/modules/fancyzones/lib/WindowMoveHandler.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include "FancyZonesData.h" @@ -214,7 +214,7 @@ void WindowMoveHandler::MoveSizeEnd(HWND window, POINT const& ptScreen, const st if ((isStandardWindow == false && hasNoVisibleOwner == true && m_moveSizeWindowInfo.isStandardWindow == true && m_moveSizeWindowInfo.hasNoVisibleOwner == true) || - FancyZonesUtils::IsWindowMaximized(window)) + FancyZonesUtils::IsWindowMaximized(window)) { // Abort the zoning, this is a Chromium based tab that is merged back with an existing window // or if the window is maximized by Windows when the cursor hits the screen top border @@ -299,20 +299,23 @@ bool WindowMoveHandler::ExtendWindowByDirectionAndPosition(HWND window, DWORD vk void WindowMoveHandler::WarnIfElevationIsRequired(HWND window) noexcept { + using namespace notifications; + using namespace NonLocalizable; + static bool warning_shown = false; if (!is_process_elevated() && IsProcessOfWindowElevated(window)) { m_dragEnabled = false; - if (!warning_shown && !is_cant_drag_elevated_warning_disabled()) + if (!warning_shown && !is_toast_disabled(CantDragElevatedDontShowAgainRegistryPath, CantDragElevatedDisableIntervalInDays)) { - std::vector actions = { - notifications::link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_LEARN_MORE), NonLocalizable::FancyZonesRunAsAdminInfoPage }, - notifications::link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN), NonLocalizable::ToastNotificationButtonUrl } + std::vector actions = { + link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_LEARN_MORE), FancyZonesRunAsAdminInfoPage }, + link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN), ToastNotificationButtonUrl } }; - notifications::show_toast_with_activations(GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED), - GET_RESOURCE_STRING(IDS_FANCYZONES), - {}, - std::move(actions)); + show_toast_with_activations(GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED), + GET_RESOURCE_STRING(IDS_FANCYZONES), + {}, + std::move(actions)); warning_shown = true; } } diff --git a/src/modules/previewpane/powerpreview/Resources.resx b/src/modules/previewpane/powerpreview/Resources.resx index 070462134c..0b4cbf17bd 100644 --- a/src/modules/previewpane/powerpreview/Resources.resx +++ b/src/modules/previewpane/powerpreview/Resources.resx @@ -157,9 +157,15 @@ Render SVG images - Some of the File Explorer modules could not be registered/unregistered as per your settings. Please restart PowerToys as admin for the changes to take place. + Some of the File Explorer modules could not be turned off/on as per your settings. Please restart PowerToys as admin for the changes to take place. - Failed to modify File Explorer modules + Couldn't modify File Explorer modules + + Open Settings + + + Don't show again + \ No newline at end of file diff --git a/src/modules/previewpane/powerpreview/powerpreview.cpp b/src/modules/previewpane/powerpreview/powerpreview.cpp index 0073f004fc..2a957575af 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.cpp +++ b/src/modules/previewpane/powerpreview/powerpreview.cpp @@ -5,7 +5,9 @@ #include "trace.h" #include "settings.h" #include "Generated Files/resource.h" -#include +#include +#include +#include // Constructor PowerPreviewModule::PowerPreviewModule() : @@ -203,11 +205,20 @@ bool PowerPreviewModule::is_registry_update_required() // Function to warn the user that PowerToys needs to run as administrator for changes to take effect void PowerPreviewModule::show_update_warning_message() { - // Show warning message if update is required - MessageBoxW(NULL, - GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_DESCRIPTION).c_str(), - GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_TITLE).c_str(), - MB_OK | MB_ICONWARNING); + using namespace notifications; + if (!is_toast_disabled(PreviewModulesDontShowAgainRegistryPath, PreviewModulesDisableIntervalInDays)) + { + std::vector actions = { + link_button{ GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_OPEN_SETTINGS), + L"powertoys://open_settings/" }, + link_button{ GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_DONT_SHOW_AGAIN), + L"powertoys://couldnt_toggle_powerpreview_modules_disable/" } + }; + show_toast_with_activations(GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_DESCRIPTION), + GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_TITLE), + {}, + std::move(actions)); + } } // Function that checks if a registry method is required and if so checks if the process is elevated and accordingly executes the method or shows a warning diff --git a/src/runner/main.cpp b/src/runner/main.cpp index 6b6d1fecb3..ec7a56ad0c 100644 --- a/src/runner/main.cpp +++ b/src/runner/main.cpp @@ -9,15 +9,16 @@ #include "restart_elevated.h" #include "Generated files/resource.h" -#include -#include -#include -#include -#include -#include #include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include "update_state.h" #include "update_utils.h" @@ -32,7 +33,6 @@ #if _DEBUG && _WIN64 #include "unhandled_exception_handler.h" #endif -#include extern "C" IMAGE_DOS_HEADER __ImageBase; @@ -210,13 +210,15 @@ enum class toast_notification_handler_result toast_notification_handler_result toast_notification_handler(const std::wstring_view param) { const std::wstring_view cant_drag_elevated_disable = L"cant_drag_elevated_disable/"; - const std::wstring_view update_now = L"update_now/"; - const std::wstring_view schedule_update = L"schedule_update/"; + const std::wstring_view couldnt_toggle_powerpreview_modules_disable = L"couldnt_toggle_powerpreview_modules_disable/"; const std::wstring_view download_and_install_update = L"download_and_install_update/"; + const std::wstring_view open_settings = L"open_settings/"; + const std::wstring_view schedule_update = L"schedule_update/"; + const std::wstring_view update_now = L"update_now/"; if (param == cant_drag_elevated_disable) { - return disable_cant_drag_elevated_warning() ? toast_notification_handler_result::exit_success : toast_notification_handler_result::exit_error; + return notifications::disable_toast(notifications::CantDragElevatedDontShowAgainRegistryPath) ? toast_notification_handler_result::exit_success : toast_notification_handler_result::exit_error; } else if (param.starts_with(update_now)) { @@ -260,6 +262,15 @@ toast_notification_handler_result toast_notification_handler(const std::wstring_ return toast_notification_handler_result::exit_error; } } + else if (param == couldnt_toggle_powerpreview_modules_disable) + { + return notifications::disable_toast(notifications::PreviewModulesDontShowAgainRegistryPath) ? toast_notification_handler_result::exit_success : toast_notification_handler_result::exit_error; + } + else if (param == open_settings) + { + open_menu_from_another_instance(); + return toast_notification_handler_result::exit_success; + } else { return toast_notification_handler_result::exit_error;