diff --git a/.pipelines/ESRPSigning_core.json b/.pipelines/ESRPSigning_core.json index 7a07abd3eac0..f1af7d7688d3 100644 --- a/.pipelines/ESRPSigning_core.json +++ b/.pipelines/ESRPSigning_core.json @@ -99,7 +99,7 @@ "modules\\MouseUtils\\PowerToys.FindMyMouse.dll", "modules\\MouseUtils\\PowerToys.MouseHighlighter.dll", - "modules\\MouseUtils\\PowerToys.MousePointerCrosshair.dll", + "modules\\MouseUtils\\PowerToys.MousePointerCrosshairs.dll", "modules\\PowerRename\\PowerToys.PowerRenameExt.dll", "modules\\PowerRename\\PowerToys.PowerRenameUILib.dll", diff --git a/PowerToys.sln b/PowerToys.sln index 9ad0b0b4fc00..14dd3a356aef 100644 --- a/PowerToys.sln +++ b/PowerToys.sln @@ -388,7 +388,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AlwaysOnTopModuleInterface" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Community.PowerToys.Run.Plugin.WebSearch", "src\modules\launcher\Plugins\Community.PowerToys.Run.Plugin.WebSearch\Community.PowerToys.Run.Plugin.WebSearch.csproj", "{9F94B303-5E21-4364-9362-64426F8DB932}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MousePointerCrosshair", "src\modules\MouseUtils\MousePointerCrosshair\MousePointerCrosshair.vcxproj", "{EAE14C0E-7A6B-45DA-9080-A7D8C077BA6E}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MousePointerCrosshairs", "src\modules\MouseUtils\MousePointerCrosshairs\MousePointerCrosshairs.vcxproj", "{EAE14C0E-7A6B-45DA-9080-A7D8C077BA6E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StlThumbnailProvider", "src\modules\previewpane\StlThumbnailProvider\StlThumbnailProvider.csproj", "{F7C8C0F1-5431-4347-89D0-8E5354F93CF2}" EndProject diff --git a/doc/images/icons/Mouse Crosshair.png b/doc/images/icons/Mouse Crosshairs.png similarity index 100% rename from doc/images/icons/Mouse Crosshair.png rename to doc/images/icons/Mouse Crosshairs.png diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index c315725efb4b..d3fdde365ef0 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -715,8 +715,8 @@ - - + + @@ -983,7 +983,7 @@ - + @@ -1083,7 +1083,7 @@ - + diff --git a/src/common/logger/logger_settings.h b/src/common/logger/logger_settings.h index a5be14ced572..87e05ccf2e29 100644 --- a/src/common/logger/logger_settings.h +++ b/src/common/logger/logger_settings.h @@ -27,7 +27,7 @@ struct LogSettings inline const static std::wstring keyboardManagerLogPath = L"Logs\\keyboard-manager-log.txt"; inline const static std::string findMyMouseLoggerName = "find-my-mouse"; inline const static std::string mouseHighlighterLoggerName = "mouse-highlighter"; - inline const static std::string mousePointerCrosshairLoggerName = "mouse-pointer-crosshair"; + inline const static std::string mousePointerCrosshairsLoggerName = "mouse-pointer-crosshairs"; inline const static std::string powerRenameLoggerName = "powerrename"; inline const static std::string alwaysOnTopLoggerName = "always-on-top"; inline const static std::wstring alwaysOnTopLogPath = L"always-on-top-log.txt"; diff --git a/src/modules/MouseUtils/MousePointerCrosshair/InclusiveCrosshair.cpp b/src/modules/MouseUtils/MousePointerCrosshair/InclusiveCrosshair.cpp deleted file mode 100644 index 0c67e4e77d98..000000000000 --- a/src/modules/MouseUtils/MousePointerCrosshair/InclusiveCrosshair.cpp +++ /dev/null @@ -1,452 +0,0 @@ -// InclusiveCrosshair.cpp : Defines the entry point for the application. -// - -#include "pch.h" -#include "InclusiveCrosshair.h" -#include "trace.h" - -#ifdef COMPOSITION -namespace winrt -{ - using namespace winrt::Windows::System; - using namespace winrt::Windows::UI::Composition; -} - -namespace ABI -{ - using namespace ABI::Windows::System; - using namespace ABI::Windows::UI::Composition::Desktop; -} -#endif - -struct InclusiveCrosshair -{ - bool MyRegisterClass(HINSTANCE hInstance); - static InclusiveCrosshair* instance; - void Terminate(); - void SwitchActivationMode(); - void ApplySettings(InclusiveCrosshairSettings& settings, bool applyToRuntimeObjects); - -private: - enum class MouseButton - { - Left, - Right - }; - - void DestroyInclusiveCrosshair(); - static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) noexcept; - void StartDrawing(); - void StopDrawing(); - bool CreateInclusiveCrosshair(); - void UpdateCrosshairPosition(); - HHOOK m_mouseHook = NULL; - static LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) noexcept; - - static constexpr auto m_className = L"MousePointerCrosshair"; - static constexpr auto m_windowTitle = L"PowerToys Mouse Pointer Crosshair"; - HWND m_hwndOwner = NULL; - HWND m_hwnd = NULL; - HINSTANCE m_hinstance = NULL; - static constexpr DWORD WM_SWITCH_ACTIVATION_MODE = WM_APP; - - winrt::DispatcherQueueController m_dispatcherQueueController{ nullptr }; - winrt::Compositor m_compositor{ nullptr }; - winrt::Desktop::DesktopWindowTarget m_target{ nullptr }; - winrt::ContainerVisual m_root{ nullptr }; - winrt::LayerVisual m_crosshair_border_layer{ nullptr }; - winrt::LayerVisual m_crosshair_layer{ nullptr }; - winrt::SpriteVisual m_left_crosshair_border{ nullptr }; - winrt::SpriteVisual m_left_crosshair{ nullptr }; - winrt::SpriteVisual m_right_crosshair_border{ nullptr }; - winrt::SpriteVisual m_right_crosshair{ nullptr }; - winrt::SpriteVisual m_top_crosshair_border{ nullptr }; - winrt::SpriteVisual m_top_crosshair{ nullptr }; - winrt::SpriteVisual m_bottom_crosshair_border{ nullptr }; - winrt::SpriteVisual m_bottom_crosshair{ nullptr }; - - bool m_visible = false; - bool m_destroyed = false; - - // Configurable Settings - winrt::Windows::UI::Color m_crosshair_border_color = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_BORDER_COLOR; - winrt::Windows::UI::Color m_crosshair_color = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_COLOR; - float m_crosshair_radius = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_RADIUS; - float m_crosshair_thickness = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_THICKNESS; - float m_crosshair_border_size = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_BORDER_SIZE; - float m_crosshair_opacity = max(0.f, min(1.f, (float)INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_OPACITY / 100.0f)); -}; - -InclusiveCrosshair* InclusiveCrosshair::instance = nullptr; - -bool InclusiveCrosshair::CreateInclusiveCrosshair() -{ - try - { - // We need a dispatcher queue. - DispatcherQueueOptions options = { - sizeof(options), - DQTYPE_THREAD_CURRENT, - DQTAT_COM_ASTA, - }; - ABI::IDispatcherQueueController* controller; - winrt::check_hresult(CreateDispatcherQueueController(options, &controller)); - *winrt::put_abi(m_dispatcherQueueController) = controller; - - // Create the compositor for our window. - m_compositor = winrt::Compositor(); - ABI::IDesktopWindowTarget* target; - winrt::check_hresult(m_compositor.as()->CreateDesktopWindowTarget(m_hwnd, false, &target)); - *winrt::put_abi(m_target) = target; - - // Our composition tree: - // - // [root] ContainerVisual - // \ [crosshair border layer] LayerVisual - // \ [crosshair border sprites] - // [crosshair layer] LayerVisual - // \ [crosshair sprites] - - m_root = m_compositor.CreateContainerVisual(); - m_root.RelativeSizeAdjustment({ 1.0f, 1.0f }); - m_target.Root(m_root); - - m_root.Opacity(m_crosshair_opacity); - - m_crosshair_border_layer = m_compositor.CreateLayerVisual(); - m_crosshair_border_layer.RelativeSizeAdjustment({ 1.0f, 1.0f }); - m_root.Children().InsertAtTop(m_crosshair_border_layer); - m_crosshair_border_layer.Opacity(1.0f); - - m_crosshair_layer = m_compositor.CreateLayerVisual(); - m_crosshair_layer.RelativeSizeAdjustment({ 1.0f, 1.0f }); - - // Create the crosshair sprites. - m_left_crosshair_border = m_compositor.CreateSpriteVisual(); - m_left_crosshair_border.AnchorPoint({ 1.0f, 0.5f }); - m_left_crosshair_border.Brush(m_compositor.CreateColorBrush(m_crosshair_border_color)); - m_crosshair_border_layer.Children().InsertAtTop(m_left_crosshair_border); - m_left_crosshair = m_compositor.CreateSpriteVisual(); - m_left_crosshair.AnchorPoint({ 1.0f, 0.5f }); - m_left_crosshair.Brush(m_compositor.CreateColorBrush(m_crosshair_color)); - m_crosshair_layer.Children().InsertAtTop(m_left_crosshair); - - m_right_crosshair_border = m_compositor.CreateSpriteVisual(); - m_right_crosshair_border.AnchorPoint({ 0.0f, 0.5f }); - m_right_crosshair_border.Brush(m_compositor.CreateColorBrush(m_crosshair_border_color)); - m_crosshair_border_layer.Children().InsertAtTop(m_right_crosshair_border); - m_right_crosshair = m_compositor.CreateSpriteVisual(); - m_right_crosshair.AnchorPoint({ 0.0f, 0.5f }); - m_right_crosshair.Brush(m_compositor.CreateColorBrush(m_crosshair_color)); - m_crosshair_layer.Children().InsertAtTop(m_right_crosshair); - - m_top_crosshair_border = m_compositor.CreateSpriteVisual(); - m_top_crosshair_border.AnchorPoint({ 0.5f, 1.0f }); - m_top_crosshair_border.Brush(m_compositor.CreateColorBrush(m_crosshair_border_color)); - m_crosshair_border_layer.Children().InsertAtTop(m_top_crosshair_border); - m_top_crosshair = m_compositor.CreateSpriteVisual(); - m_top_crosshair.AnchorPoint({ 0.5f, 1.0f }); - m_top_crosshair.Brush(m_compositor.CreateColorBrush(m_crosshair_color)); - m_crosshair_layer.Children().InsertAtTop(m_top_crosshair); - - m_bottom_crosshair_border = m_compositor.CreateSpriteVisual(); - m_bottom_crosshair_border.AnchorPoint({ 0.5f, 0.0f }); - m_bottom_crosshair_border.Brush(m_compositor.CreateColorBrush(m_crosshair_border_color)); - m_crosshair_border_layer.Children().InsertAtTop(m_bottom_crosshair_border); - m_bottom_crosshair = m_compositor.CreateSpriteVisual(); - m_bottom_crosshair.AnchorPoint({ 0.5f, 0.0f }); - m_bottom_crosshair.Brush(m_compositor.CreateColorBrush(m_crosshair_color)); - m_crosshair_layer.Children().InsertAtTop(m_bottom_crosshair); - - m_crosshair_border_layer.Children().InsertAtTop(m_crosshair_layer); - m_crosshair_layer.Opacity(1.0f); - - UpdateCrosshairPosition(); - - return true; - } - catch (...) - { - return false; - } -} - -void InclusiveCrosshair::UpdateCrosshairPosition() -{ - POINT ptCursor; - - GetCursorPos(&ptCursor); - - HMONITOR cursorMonitor = MonitorFromPoint(ptCursor, MONITOR_DEFAULTTONEAREST); - - if (cursorMonitor == NULL) - { - return; - } - - MONITORINFO monitorInfo; - monitorInfo.cbSize = sizeof(monitorInfo); - - if (!GetMonitorInfo(cursorMonitor, &monitorInfo)) - { - return; - } - - POINT ptMonitorUpperLeft; - ptMonitorUpperLeft.x = monitorInfo.rcMonitor.left; - ptMonitorUpperLeft.y = monitorInfo.rcMonitor.top; - - POINT ptMonitorBottomRight; - ptMonitorBottomRight.x = monitorInfo.rcMonitor.right; - ptMonitorBottomRight.y = monitorInfo.rcMonitor.bottom; - - // Convert everything to client coordinates. - ScreenToClient(m_hwnd, &ptCursor); - ScreenToClient(m_hwnd, &ptMonitorUpperLeft); - ScreenToClient(m_hwnd, &ptMonitorBottomRight); - - // Position crosshair components around the mouse pointer. - m_left_crosshair_border.Offset({ (float)ptCursor.x - m_crosshair_radius + m_crosshair_border_size, (float)ptCursor.y, .0f }); - m_left_crosshair_border.Size({ (float)ptCursor.x - (float)ptMonitorUpperLeft.x - m_crosshair_radius + m_crosshair_border_size, m_crosshair_thickness + m_crosshair_border_size * 2 }); - m_left_crosshair.Offset({ (float)ptCursor.x - m_crosshair_radius, (float)ptCursor.y, .0f }); - m_left_crosshair.Size({ (float)ptCursor.x - (float)ptMonitorUpperLeft.x - m_crosshair_radius, m_crosshair_thickness }); - - m_right_crosshair_border.Offset({ (float)ptCursor.x + m_crosshair_radius - m_crosshair_border_size, (float)ptCursor.y, .0f }); - m_right_crosshair_border.Size({ (float)ptMonitorBottomRight.x - (float)ptCursor.x - m_crosshair_radius + m_crosshair_border_size, m_crosshair_thickness + m_crosshair_border_size * 2 }); - m_right_crosshair.Offset({ (float)ptCursor.x + m_crosshair_radius, (float)ptCursor.y, .0f }); - m_right_crosshair.Size({ (float)ptMonitorBottomRight.x - (float)ptCursor.x - m_crosshair_radius, m_crosshair_thickness }); - - m_top_crosshair_border.Offset({ (float)ptCursor.x, (float)ptCursor.y - m_crosshair_radius + m_crosshair_border_size, .0f }); - m_top_crosshair_border.Size({ m_crosshair_thickness + m_crosshair_border_size * 2, (float)ptCursor.y - (float)ptMonitorUpperLeft.y - m_crosshair_radius + m_crosshair_border_size }); - m_top_crosshair.Offset({ (float)ptCursor.x, (float)ptCursor.y - m_crosshair_radius, .0f }); - m_top_crosshair.Size({ m_crosshair_thickness, (float)ptCursor.y - (float)ptMonitorUpperLeft.y - m_crosshair_radius }); - - m_bottom_crosshair_border.Offset({ (float)ptCursor.x, (float)ptCursor.y + m_crosshair_radius - m_crosshair_border_size, .0f }); - m_bottom_crosshair_border.Size({ m_crosshair_thickness + m_crosshair_border_size * 2, (float)ptMonitorBottomRight.y - (float)ptCursor.y - m_crosshair_radius + m_crosshair_border_size }); - m_bottom_crosshair.Offset({ (float)ptCursor.x, (float)ptCursor.y + m_crosshair_radius, .0f }); - m_bottom_crosshair.Size({ m_crosshair_thickness, (float)ptMonitorBottomRight.y - (float)ptCursor.y - m_crosshair_radius }); - -} - -LRESULT CALLBACK InclusiveCrosshair::MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) noexcept -{ - if (nCode >= 0) - { - MSLLHOOKSTRUCT* hookData = (MSLLHOOKSTRUCT*)lParam; - if (wParam == WM_MOUSEMOVE) { - instance->UpdateCrosshairPosition(); - } - } - return CallNextHookEx(0, nCode, wParam, lParam); -} - -void InclusiveCrosshair::StartDrawing() -{ - Logger::info("Start drawing crosshairs."); - Trace::StartDrawingCrosshair(); - m_visible = true; - SetWindowPos(m_hwnd, HWND_TOPMOST, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN), GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN), 0); - ShowWindow(m_hwnd, SW_SHOWNOACTIVATE); - m_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, m_hinstance, 0); - UpdateCrosshairPosition(); -} - -void InclusiveCrosshair::StopDrawing() -{ - Logger::info("Stop drawing crosshairs."); - m_visible = false; - ShowWindow(m_hwnd, SW_HIDE); - UnhookWindowsHookEx(m_mouseHook); - m_mouseHook = NULL; -} - -void InclusiveCrosshair::SwitchActivationMode() -{ - PostMessage(m_hwnd, WM_SWITCH_ACTIVATION_MODE, 0, 0); -} - -void InclusiveCrosshair::ApplySettings(InclusiveCrosshairSettings& settings, bool applyToRunTimeObjects) -{ - m_crosshair_radius = (float)settings.crosshairRadius; - m_crosshair_thickness = (float)settings.crosshairThickness; - m_crosshair_color = settings.crosshairColor; - m_crosshair_opacity = max(0.f, min(1.f, (float)settings.crosshairOpacity / 100.0f)); - m_crosshair_border_color = settings.crosshairBorderColor; - m_crosshair_border_size = (float)settings.crosshairBorderSize; - - if (applyToRunTimeObjects) - { - // Runtime objects already created. Should update in the owner thread. - auto dispatcherQueue = m_dispatcherQueueController.DispatcherQueue(); - InclusiveCrosshairSettings localSettings = settings; - bool enqueueSucceeded = dispatcherQueue.TryEnqueue([=]() { - if (!m_destroyed) - { - // Apply new settings to runtime composition objects. - m_left_crosshair.Brush().as().Color(m_crosshair_color); - m_right_crosshair.Brush().as().Color(m_crosshair_color); - m_top_crosshair.Brush().as().Color(m_crosshair_color); - m_bottom_crosshair.Brush().as().Color(m_crosshair_color); - m_left_crosshair_border.Brush().as().Color(m_crosshair_border_color); - m_right_crosshair_border.Brush().as().Color(m_crosshair_border_color); - m_top_crosshair_border.Brush().as().Color(m_crosshair_border_color); - m_bottom_crosshair_border.Brush().as().Color(m_crosshair_border_color); - m_root.Opacity(m_crosshair_opacity); - UpdateCrosshairPosition(); - } - }); - if (!enqueueSucceeded) - { - Logger::error("Couldn't enqueue message to update the crosshair settings."); - } - } -} - -void InclusiveCrosshair::DestroyInclusiveCrosshair() -{ - StopDrawing(); - PostQuitMessage(0); -} - -LRESULT CALLBACK InclusiveCrosshair::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) noexcept -{ - switch (message) - { - case WM_NCCREATE: - instance->m_hwnd = hWnd; - return DefWindowProc(hWnd, message, wParam, lParam); - case WM_CREATE: - return instance->CreateInclusiveCrosshair() ? 0 : -1; - case WM_NCHITTEST: - return HTTRANSPARENT; - case WM_SWITCH_ACTIVATION_MODE: - if (instance->m_visible) - { - instance->StopDrawing(); - } - else - { - instance->StartDrawing(); - } - break; - case WM_DESTROY: - instance->DestroyInclusiveCrosshair(); - break; - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - return 0; -} - -bool InclusiveCrosshair::MyRegisterClass(HINSTANCE hInstance) -{ - WNDCLASS wc{}; - - m_hinstance = hInstance; - - SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); - if (!GetClassInfoW(hInstance, m_className, &wc)) - { - wc.lpfnWndProc = WndProc; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION); - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); - wc.lpszClassName = m_className; - - if (!RegisterClassW(&wc)) - { - return false; - } - } - - m_hwndOwner = CreateWindow(L"static", nullptr, WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, hInstance, nullptr); - - DWORD exStyle = WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP | WS_EX_TOOLWINDOW; - return CreateWindowExW(exStyle, m_className, m_windowTitle, WS_POPUP, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, m_hwndOwner, nullptr, hInstance, nullptr) != nullptr; -} - -void InclusiveCrosshair::Terminate() -{ - auto dispatcherQueue = m_dispatcherQueueController.DispatcherQueue(); - bool enqueueSucceeded = dispatcherQueue.TryEnqueue([=]() { - m_destroyed = true; - DestroyWindow(m_hwndOwner); - }); - if (!enqueueSucceeded) - { - Logger::error("Couldn't enqueue message to destroy the window."); - } -} - -#pragma region InclusiveCrosshair_API - -void InclusiveCrosshairApplySettings(InclusiveCrosshairSettings& settings) -{ - if (InclusiveCrosshair::instance != nullptr) - { - Logger::info("Applying settings."); - InclusiveCrosshair::instance->ApplySettings(settings, true); - } -} - -void InclusiveCrosshairSwitch() -{ - if (InclusiveCrosshair::instance != nullptr) - { - Logger::info("Switching activation mode."); - InclusiveCrosshair::instance->SwitchActivationMode(); - } -} - -void InclusiveCrosshairDisable() -{ - if (InclusiveCrosshair::instance != nullptr) - { - Logger::info("Terminating the crosshair instance."); - InclusiveCrosshair::instance->Terminate(); - } -} - -bool InclusiveCrosshairIsEnabled() -{ - return (InclusiveCrosshair::instance != nullptr); -} - -int InclusiveCrosshairMain(HINSTANCE hInstance, InclusiveCrosshairSettings& settings) -{ - Logger::info("Starting a crosshair instance."); - if (InclusiveCrosshair::instance != nullptr) - { - Logger::error("A crosshair instance was still working when trying to start a new one."); - return 0; - } - - // Perform application initialization: - InclusiveCrosshair crosshair; - InclusiveCrosshair::instance = &crosshair; - crosshair.ApplySettings(settings, false); - if (!crosshair.MyRegisterClass(hInstance)) - { - Logger::error("Couldn't initialize a crosshair instance."); - InclusiveCrosshair::instance = nullptr; - return FALSE; - } - Logger::info("Initialized the crosshair instance."); - - MSG msg; - - // Main message loop: - while (GetMessage(&msg, nullptr, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - Logger::info("Crosshair message loop ended."); - InclusiveCrosshair::instance = nullptr; - - return (int)msg.wParam; -} - -#pragma endregion InclusiveCrosshair_API diff --git a/src/modules/MouseUtils/MousePointerCrosshair/InclusiveCrosshair.h b/src/modules/MouseUtils/MousePointerCrosshair/InclusiveCrosshair.h deleted file mode 100644 index 086ef709b263..000000000000 --- a/src/modules/MouseUtils/MousePointerCrosshair/InclusiveCrosshair.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include "pch.h" - -constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_OPACITY = 75; -const winrt::Windows::UI::Color INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_COLOR = winrt::Windows::UI::ColorHelper::FromArgb(255, 255, 0, 0); -const winrt::Windows::UI::Color INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_BORDER_COLOR = winrt::Windows::UI::ColorHelper::FromArgb(255, 255, 255, 255); -constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_RADIUS = 20; -constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_THICKNESS = 5; -constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_BORDER_SIZE = 1; - -struct InclusiveCrosshairSettings -{ - winrt::Windows::UI::Color crosshairColor = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_COLOR; - winrt::Windows::UI::Color crosshairBorderColor = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_BORDER_COLOR; - int crosshairRadius = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_RADIUS; - int crosshairThickness = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_THICKNESS; - int crosshairOpacity = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_OPACITY; - int crosshairBorderSize = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIR_BORDER_SIZE; -}; - -int InclusiveCrosshairMain(HINSTANCE hinst, InclusiveCrosshairSettings& settings); -void InclusiveCrosshairDisable(); -bool InclusiveCrosshairIsEnabled(); -void InclusiveCrosshairSwitch(); -void InclusiveCrosshairApplySettings(InclusiveCrosshairSettings& settings); diff --git a/src/modules/MouseUtils/MousePointerCrosshair/resource.h b/src/modules/MouseUtils/MousePointerCrosshair/resource.h deleted file mode 100644 index e4ff6cf76a58..000000000000 --- a/src/modules/MouseUtils/MousePointerCrosshair/resource.h +++ /dev/null @@ -1,13 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by MousePointerCrosshair.rc - -////////////////////////////// -// Non-localizable - -#define FILE_DESCRIPTION "PowerToys MousePointerCrosshair" -#define INTERNAL_NAME "MousePointerCrosshair" -#define ORIGINAL_FILENAME "PowerToys.MousePointerCrosshair.dll" - -// Non-localizable -////////////////////////////// diff --git a/src/modules/MouseUtils/MousePointerCrosshair/trace.h b/src/modules/MouseUtils/MousePointerCrosshair/trace.h deleted file mode 100644 index d12eabc44acd..000000000000 --- a/src/modules/MouseUtils/MousePointerCrosshair/trace.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -class Trace -{ -public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - - // Log if the user has MousePointerCrosshair enabled or disabled - static void EnableMousePointerCrosshair(const bool enabled) noexcept; - - // Log that the user activated the module by having the crosshair be drawn - static void StartDrawingCrosshair() noexcept; -}; diff --git a/src/modules/MouseUtils/MousePointerCrosshairs/InclusiveCrosshairs.cpp b/src/modules/MouseUtils/MousePointerCrosshairs/InclusiveCrosshairs.cpp new file mode 100644 index 000000000000..c71a98bb0acf --- /dev/null +++ b/src/modules/MouseUtils/MousePointerCrosshairs/InclusiveCrosshairs.cpp @@ -0,0 +1,452 @@ +// InclusiveCrosshairs.cpp : Defines the entry point for the application. +// + +#include "pch.h" +#include "InclusiveCrosshairs.h" +#include "trace.h" + +#ifdef COMPOSITION +namespace winrt +{ + using namespace winrt::Windows::System; + using namespace winrt::Windows::UI::Composition; +} + +namespace ABI +{ + using namespace ABI::Windows::System; + using namespace ABI::Windows::UI::Composition::Desktop; +} +#endif + +struct InclusiveCrosshairs +{ + bool MyRegisterClass(HINSTANCE hInstance); + static InclusiveCrosshairs* instance; + void Terminate(); + void SwitchActivationMode(); + void ApplySettings(InclusiveCrosshairsSettings& settings, bool applyToRuntimeObjects); + +private: + enum class MouseButton + { + Left, + Right + }; + + void DestroyInclusiveCrosshairs(); + static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) noexcept; + void StartDrawing(); + void StopDrawing(); + bool CreateInclusiveCrosshairs(); + void UpdateCrosshairsPosition(); + HHOOK m_mouseHook = NULL; + static LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) noexcept; + + static constexpr auto m_className = L"MousePointerCrosshairs"; + static constexpr auto m_windowTitle = L"PowerToys Mouse Pointer Crosshairs"; + HWND m_hwndOwner = NULL; + HWND m_hwnd = NULL; + HINSTANCE m_hinstance = NULL; + static constexpr DWORD WM_SWITCH_ACTIVATION_MODE = WM_APP; + + winrt::DispatcherQueueController m_dispatcherQueueController{ nullptr }; + winrt::Compositor m_compositor{ nullptr }; + winrt::Desktop::DesktopWindowTarget m_target{ nullptr }; + winrt::ContainerVisual m_root{ nullptr }; + winrt::LayerVisual m_crosshairs_border_layer{ nullptr }; + winrt::LayerVisual m_crosshairs_layer{ nullptr }; + winrt::SpriteVisual m_left_crosshairs_border{ nullptr }; + winrt::SpriteVisual m_left_crosshairs{ nullptr }; + winrt::SpriteVisual m_right_crosshairs_border{ nullptr }; + winrt::SpriteVisual m_right_crosshairs{ nullptr }; + winrt::SpriteVisual m_top_crosshairs_border{ nullptr }; + winrt::SpriteVisual m_top_crosshairs{ nullptr }; + winrt::SpriteVisual m_bottom_crosshairs_border{ nullptr }; + winrt::SpriteVisual m_bottom_crosshairs{ nullptr }; + + bool m_visible = false; + bool m_destroyed = false; + + // Configurable Settings + winrt::Windows::UI::Color m_crosshairs_border_color = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_COLOR; + winrt::Windows::UI::Color m_crosshairs_color = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_COLOR; + float m_crosshairs_radius = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_RADIUS; + float m_crosshairs_thickness = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_THICKNESS; + float m_crosshairs_border_size = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_SIZE; + float m_crosshairs_opacity = max(0.f, min(1.f, (float)INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_OPACITY / 100.0f)); +}; + +InclusiveCrosshairs* InclusiveCrosshairs::instance = nullptr; + +bool InclusiveCrosshairs::CreateInclusiveCrosshairs() +{ + try + { + // We need a dispatcher queue. + DispatcherQueueOptions options = { + sizeof(options), + DQTYPE_THREAD_CURRENT, + DQTAT_COM_ASTA, + }; + ABI::IDispatcherQueueController* controller; + winrt::check_hresult(CreateDispatcherQueueController(options, &controller)); + *winrt::put_abi(m_dispatcherQueueController) = controller; + + // Create the compositor for our window. + m_compositor = winrt::Compositor(); + ABI::IDesktopWindowTarget* target; + winrt::check_hresult(m_compositor.as()->CreateDesktopWindowTarget(m_hwnd, false, &target)); + *winrt::put_abi(m_target) = target; + + // Our composition tree: + // + // [root] ContainerVisual + // \ [crosshairs border layer] LayerVisual + // \ [crosshairs border sprites] + // [crosshairs layer] LayerVisual + // \ [crosshairs sprites] + + m_root = m_compositor.CreateContainerVisual(); + m_root.RelativeSizeAdjustment({ 1.0f, 1.0f }); + m_target.Root(m_root); + + m_root.Opacity(m_crosshairs_opacity); + + m_crosshairs_border_layer = m_compositor.CreateLayerVisual(); + m_crosshairs_border_layer.RelativeSizeAdjustment({ 1.0f, 1.0f }); + m_root.Children().InsertAtTop(m_crosshairs_border_layer); + m_crosshairs_border_layer.Opacity(1.0f); + + m_crosshairs_layer = m_compositor.CreateLayerVisual(); + m_crosshairs_layer.RelativeSizeAdjustment({ 1.0f, 1.0f }); + + // Create the crosshairs sprites. + m_left_crosshairs_border = m_compositor.CreateSpriteVisual(); + m_left_crosshairs_border.AnchorPoint({ 1.0f, 0.5f }); + m_left_crosshairs_border.Brush(m_compositor.CreateColorBrush(m_crosshairs_border_color)); + m_crosshairs_border_layer.Children().InsertAtTop(m_left_crosshairs_border); + m_left_crosshairs = m_compositor.CreateSpriteVisual(); + m_left_crosshairs.AnchorPoint({ 1.0f, 0.5f }); + m_left_crosshairs.Brush(m_compositor.CreateColorBrush(m_crosshairs_color)); + m_crosshairs_layer.Children().InsertAtTop(m_left_crosshairs); + + m_right_crosshairs_border = m_compositor.CreateSpriteVisual(); + m_right_crosshairs_border.AnchorPoint({ 0.0f, 0.5f }); + m_right_crosshairs_border.Brush(m_compositor.CreateColorBrush(m_crosshairs_border_color)); + m_crosshairs_border_layer.Children().InsertAtTop(m_right_crosshairs_border); + m_right_crosshairs = m_compositor.CreateSpriteVisual(); + m_right_crosshairs.AnchorPoint({ 0.0f, 0.5f }); + m_right_crosshairs.Brush(m_compositor.CreateColorBrush(m_crosshairs_color)); + m_crosshairs_layer.Children().InsertAtTop(m_right_crosshairs); + + m_top_crosshairs_border = m_compositor.CreateSpriteVisual(); + m_top_crosshairs_border.AnchorPoint({ 0.5f, 1.0f }); + m_top_crosshairs_border.Brush(m_compositor.CreateColorBrush(m_crosshairs_border_color)); + m_crosshairs_border_layer.Children().InsertAtTop(m_top_crosshairs_border); + m_top_crosshairs = m_compositor.CreateSpriteVisual(); + m_top_crosshairs.AnchorPoint({ 0.5f, 1.0f }); + m_top_crosshairs.Brush(m_compositor.CreateColorBrush(m_crosshairs_color)); + m_crosshairs_layer.Children().InsertAtTop(m_top_crosshairs); + + m_bottom_crosshairs_border = m_compositor.CreateSpriteVisual(); + m_bottom_crosshairs_border.AnchorPoint({ 0.5f, 0.0f }); + m_bottom_crosshairs_border.Brush(m_compositor.CreateColorBrush(m_crosshairs_border_color)); + m_crosshairs_border_layer.Children().InsertAtTop(m_bottom_crosshairs_border); + m_bottom_crosshairs = m_compositor.CreateSpriteVisual(); + m_bottom_crosshairs.AnchorPoint({ 0.5f, 0.0f }); + m_bottom_crosshairs.Brush(m_compositor.CreateColorBrush(m_crosshairs_color)); + m_crosshairs_layer.Children().InsertAtTop(m_bottom_crosshairs); + + m_crosshairs_border_layer.Children().InsertAtTop(m_crosshairs_layer); + m_crosshairs_layer.Opacity(1.0f); + + UpdateCrosshairsPosition(); + + return true; + } + catch (...) + { + return false; + } +} + +void InclusiveCrosshairs::UpdateCrosshairsPosition() +{ + POINT ptCursor; + + GetCursorPos(&ptCursor); + + HMONITOR cursorMonitor = MonitorFromPoint(ptCursor, MONITOR_DEFAULTTONEAREST); + + if (cursorMonitor == NULL) + { + return; + } + + MONITORINFO monitorInfo; + monitorInfo.cbSize = sizeof(monitorInfo); + + if (!GetMonitorInfo(cursorMonitor, &monitorInfo)) + { + return; + } + + POINT ptMonitorUpperLeft; + ptMonitorUpperLeft.x = monitorInfo.rcMonitor.left; + ptMonitorUpperLeft.y = monitorInfo.rcMonitor.top; + + POINT ptMonitorBottomRight; + ptMonitorBottomRight.x = monitorInfo.rcMonitor.right; + ptMonitorBottomRight.y = monitorInfo.rcMonitor.bottom; + + // Convert everything to client coordinates. + ScreenToClient(m_hwnd, &ptCursor); + ScreenToClient(m_hwnd, &ptMonitorUpperLeft); + ScreenToClient(m_hwnd, &ptMonitorBottomRight); + + // Position crosshairs components around the mouse pointer. + m_left_crosshairs_border.Offset({ (float)ptCursor.x - m_crosshairs_radius + m_crosshairs_border_size, (float)ptCursor.y, .0f }); + m_left_crosshairs_border.Size({ (float)ptCursor.x - (float)ptMonitorUpperLeft.x - m_crosshairs_radius + m_crosshairs_border_size, m_crosshairs_thickness + m_crosshairs_border_size * 2 }); + m_left_crosshairs.Offset({ (float)ptCursor.x - m_crosshairs_radius, (float)ptCursor.y, .0f }); + m_left_crosshairs.Size({ (float)ptCursor.x - (float)ptMonitorUpperLeft.x - m_crosshairs_radius, m_crosshairs_thickness }); + + m_right_crosshairs_border.Offset({ (float)ptCursor.x + m_crosshairs_radius - m_crosshairs_border_size, (float)ptCursor.y, .0f }); + m_right_crosshairs_border.Size({ (float)ptMonitorBottomRight.x - (float)ptCursor.x - m_crosshairs_radius + m_crosshairs_border_size, m_crosshairs_thickness + m_crosshairs_border_size * 2 }); + m_right_crosshairs.Offset({ (float)ptCursor.x + m_crosshairs_radius, (float)ptCursor.y, .0f }); + m_right_crosshairs.Size({ (float)ptMonitorBottomRight.x - (float)ptCursor.x - m_crosshairs_radius, m_crosshairs_thickness }); + + m_top_crosshairs_border.Offset({ (float)ptCursor.x, (float)ptCursor.y - m_crosshairs_radius + m_crosshairs_border_size, .0f }); + m_top_crosshairs_border.Size({ m_crosshairs_thickness + m_crosshairs_border_size * 2, (float)ptCursor.y - (float)ptMonitorUpperLeft.y - m_crosshairs_radius + m_crosshairs_border_size }); + m_top_crosshairs.Offset({ (float)ptCursor.x, (float)ptCursor.y - m_crosshairs_radius, .0f }); + m_top_crosshairs.Size({ m_crosshairs_thickness, (float)ptCursor.y - (float)ptMonitorUpperLeft.y - m_crosshairs_radius }); + + m_bottom_crosshairs_border.Offset({ (float)ptCursor.x, (float)ptCursor.y + m_crosshairs_radius - m_crosshairs_border_size, .0f }); + m_bottom_crosshairs_border.Size({ m_crosshairs_thickness + m_crosshairs_border_size * 2, (float)ptMonitorBottomRight.y - (float)ptCursor.y - m_crosshairs_radius + m_crosshairs_border_size }); + m_bottom_crosshairs.Offset({ (float)ptCursor.x, (float)ptCursor.y + m_crosshairs_radius, .0f }); + m_bottom_crosshairs.Size({ m_crosshairs_thickness, (float)ptMonitorBottomRight.y - (float)ptCursor.y - m_crosshairs_radius }); + +} + +LRESULT CALLBACK InclusiveCrosshairs::MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) noexcept +{ + if (nCode >= 0) + { + MSLLHOOKSTRUCT* hookData = (MSLLHOOKSTRUCT*)lParam; + if (wParam == WM_MOUSEMOVE) { + instance->UpdateCrosshairsPosition(); + } + } + return CallNextHookEx(0, nCode, wParam, lParam); +} + +void InclusiveCrosshairs::StartDrawing() +{ + Logger::info("Start drawing crosshairs."); + Trace::StartDrawingCrosshairs(); + m_visible = true; + SetWindowPos(m_hwnd, HWND_TOPMOST, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN), GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN), 0); + ShowWindow(m_hwnd, SW_SHOWNOACTIVATE); + m_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, m_hinstance, 0); + UpdateCrosshairsPosition(); +} + +void InclusiveCrosshairs::StopDrawing() +{ + Logger::info("Stop drawing crosshairs."); + m_visible = false; + ShowWindow(m_hwnd, SW_HIDE); + UnhookWindowsHookEx(m_mouseHook); + m_mouseHook = NULL; +} + +void InclusiveCrosshairs::SwitchActivationMode() +{ + PostMessage(m_hwnd, WM_SWITCH_ACTIVATION_MODE, 0, 0); +} + +void InclusiveCrosshairs::ApplySettings(InclusiveCrosshairsSettings& settings, bool applyToRunTimeObjects) +{ + m_crosshairs_radius = (float)settings.crosshairsRadius; + m_crosshairs_thickness = (float)settings.crosshairsThickness; + m_crosshairs_color = settings.crosshairsColor; + m_crosshairs_opacity = max(0.f, min(1.f, (float)settings.crosshairsOpacity / 100.0f)); + m_crosshairs_border_color = settings.crosshairsBorderColor; + m_crosshairs_border_size = (float)settings.crosshairsBorderSize; + + if (applyToRunTimeObjects) + { + // Runtime objects already created. Should update in the owner thread. + auto dispatcherQueue = m_dispatcherQueueController.DispatcherQueue(); + InclusiveCrosshairsSettings localSettings = settings; + bool enqueueSucceeded = dispatcherQueue.TryEnqueue([=]() { + if (!m_destroyed) + { + // Apply new settings to runtime composition objects. + m_left_crosshairs.Brush().as().Color(m_crosshairs_color); + m_right_crosshairs.Brush().as().Color(m_crosshairs_color); + m_top_crosshairs.Brush().as().Color(m_crosshairs_color); + m_bottom_crosshairs.Brush().as().Color(m_crosshairs_color); + m_left_crosshairs_border.Brush().as().Color(m_crosshairs_border_color); + m_right_crosshairs_border.Brush().as().Color(m_crosshairs_border_color); + m_top_crosshairs_border.Brush().as().Color(m_crosshairs_border_color); + m_bottom_crosshairs_border.Brush().as().Color(m_crosshairs_border_color); + m_root.Opacity(m_crosshairs_opacity); + UpdateCrosshairsPosition(); + } + }); + if (!enqueueSucceeded) + { + Logger::error("Couldn't enqueue message to update the crosshairs settings."); + } + } +} + +void InclusiveCrosshairs::DestroyInclusiveCrosshairs() +{ + StopDrawing(); + PostQuitMessage(0); +} + +LRESULT CALLBACK InclusiveCrosshairs::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) noexcept +{ + switch (message) + { + case WM_NCCREATE: + instance->m_hwnd = hWnd; + return DefWindowProc(hWnd, message, wParam, lParam); + case WM_CREATE: + return instance->CreateInclusiveCrosshairs() ? 0 : -1; + case WM_NCHITTEST: + return HTTRANSPARENT; + case WM_SWITCH_ACTIVATION_MODE: + if (instance->m_visible) + { + instance->StopDrawing(); + } + else + { + instance->StartDrawing(); + } + break; + case WM_DESTROY: + instance->DestroyInclusiveCrosshairs(); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + +bool InclusiveCrosshairs::MyRegisterClass(HINSTANCE hInstance) +{ + WNDCLASS wc{}; + + m_hinstance = hInstance; + + SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + if (!GetClassInfoW(hInstance, m_className, &wc)) + { + wc.lpfnWndProc = WndProc; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION); + wc.hCursor = LoadCursor(nullptr, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); + wc.lpszClassName = m_className; + + if (!RegisterClassW(&wc)) + { + return false; + } + } + + m_hwndOwner = CreateWindow(L"static", nullptr, WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, hInstance, nullptr); + + DWORD exStyle = WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP | WS_EX_TOOLWINDOW; + return CreateWindowExW(exStyle, m_className, m_windowTitle, WS_POPUP, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, m_hwndOwner, nullptr, hInstance, nullptr) != nullptr; +} + +void InclusiveCrosshairs::Terminate() +{ + auto dispatcherQueue = m_dispatcherQueueController.DispatcherQueue(); + bool enqueueSucceeded = dispatcherQueue.TryEnqueue([=]() { + m_destroyed = true; + DestroyWindow(m_hwndOwner); + }); + if (!enqueueSucceeded) + { + Logger::error("Couldn't enqueue message to destroy the window."); + } +} + +#pragma region InclusiveCrosshairs_API + +void InclusiveCrosshairsApplySettings(InclusiveCrosshairsSettings& settings) +{ + if (InclusiveCrosshairs::instance != nullptr) + { + Logger::info("Applying settings."); + InclusiveCrosshairs::instance->ApplySettings(settings, true); + } +} + +void InclusiveCrosshairsSwitch() +{ + if (InclusiveCrosshairs::instance != nullptr) + { + Logger::info("Switching activation mode."); + InclusiveCrosshairs::instance->SwitchActivationMode(); + } +} + +void InclusiveCrosshairsDisable() +{ + if (InclusiveCrosshairs::instance != nullptr) + { + Logger::info("Terminating the crosshairs instance."); + InclusiveCrosshairs::instance->Terminate(); + } +} + +bool InclusiveCrosshairsIsEnabled() +{ + return (InclusiveCrosshairs::instance != nullptr); +} + +int InclusiveCrosshairsMain(HINSTANCE hInstance, InclusiveCrosshairsSettings& settings) +{ + Logger::info("Starting a crosshairs instance."); + if (InclusiveCrosshairs::instance != nullptr) + { + Logger::error("A crosshairs instance was still working when trying to start a new one."); + return 0; + } + + // Perform application initialization: + InclusiveCrosshairs crosshairs; + InclusiveCrosshairs::instance = &crosshairs; + crosshairs.ApplySettings(settings, false); + if (!crosshairs.MyRegisterClass(hInstance)) + { + Logger::error("Couldn't initialize a crosshairs instance."); + InclusiveCrosshairs::instance = nullptr; + return FALSE; + } + Logger::info("Initialized the crosshairs instance."); + + MSG msg; + + // Main message loop: + while (GetMessage(&msg, nullptr, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + Logger::info("Crosshairs message loop ended."); + InclusiveCrosshairs::instance = nullptr; + + return (int)msg.wParam; +} + +#pragma endregion InclusiveCrosshairs_API diff --git a/src/modules/MouseUtils/MousePointerCrosshairs/InclusiveCrosshairs.h b/src/modules/MouseUtils/MousePointerCrosshairs/InclusiveCrosshairs.h new file mode 100644 index 000000000000..cf4aae14a126 --- /dev/null +++ b/src/modules/MouseUtils/MousePointerCrosshairs/InclusiveCrosshairs.h @@ -0,0 +1,25 @@ +#pragma once +#include "pch.h" + +constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_OPACITY = 75; +const winrt::Windows::UI::Color INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_COLOR = winrt::Windows::UI::ColorHelper::FromArgb(255, 255, 0, 0); +const winrt::Windows::UI::Color INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_COLOR = winrt::Windows::UI::ColorHelper::FromArgb(255, 255, 255, 255); +constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_RADIUS = 20; +constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_THICKNESS = 5; +constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_SIZE = 1; + +struct InclusiveCrosshairsSettings +{ + winrt::Windows::UI::Color crosshairsColor = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_COLOR; + winrt::Windows::UI::Color crosshairsBorderColor = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_COLOR; + int crosshairsRadius = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_RADIUS; + int crosshairsThickness = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_THICKNESS; + int crosshairsOpacity = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_OPACITY; + int crosshairsBorderSize = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_SIZE; +}; + +int InclusiveCrosshairsMain(HINSTANCE hinst, InclusiveCrosshairsSettings& settings); +void InclusiveCrosshairsDisable(); +bool InclusiveCrosshairsIsEnabled(); +void InclusiveCrosshairsSwitch(); +void InclusiveCrosshairsApplySettings(InclusiveCrosshairsSettings& settings); diff --git a/src/modules/MouseUtils/MousePointerCrosshair/MousePointerCrosshair.rc b/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.rc similarity index 100% rename from src/modules/MouseUtils/MousePointerCrosshair/MousePointerCrosshair.rc rename to src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.rc diff --git a/src/modules/MouseUtils/MousePointerCrosshair/MousePointerCrosshair.vcxproj b/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj similarity index 94% rename from src/modules/MouseUtils/MousePointerCrosshair/MousePointerCrosshair.vcxproj rename to src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj index c1f783ca2906..b1b885098705 100644 --- a/src/modules/MouseUtils/MousePointerCrosshair/MousePointerCrosshair.vcxproj +++ b/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj @@ -15,9 +15,9 @@ 15.0 {eae14c0e-7a6b-45da-9080-a7d8c077ba6e} Win32Proj - MousePointerCrosshair + MousePointerCrosshairs 10.0.18362.0 - MousePointerCrosshair + MousePointerCrosshairs @@ -49,12 +49,12 @@ true $(SolutionDir)$(Platform)\$(Configuration)\modules\MouseUtils\ - PowerToys.MousePointerCrosshair + PowerToys.MousePointerCrosshairs false $(SolutionDir)$(Platform)\$(Configuration)\modules\MouseUtils\ - PowerToys.MousePointerCrosshair + PowerToys.MousePointerCrosshairs @@ -104,14 +104,14 @@ - + - + Create @@ -121,7 +121,7 @@ - + diff --git a/src/modules/MouseUtils/MousePointerCrosshair/MousePointerCrosshair.vcxproj.filters b/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj.filters similarity index 92% rename from src/modules/MouseUtils/MousePointerCrosshair/MousePointerCrosshair.vcxproj.filters rename to src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj.filters index 208f1a0ddaf5..26ed7965260e 100644 --- a/src/modules/MouseUtils/MousePointerCrosshair/MousePointerCrosshair.vcxproj.filters +++ b/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj.filters @@ -10,7 +10,7 @@ Source Files - + Source Files @@ -24,7 +24,7 @@ Resource Files - + Header Files @@ -49,7 +49,7 @@ - + Resource Files diff --git a/src/modules/MouseUtils/MousePointerCrosshair/dllmain.cpp b/src/modules/MouseUtils/MousePointerCrosshairs/dllmain.cpp similarity index 69% rename from src/modules/MouseUtils/MousePointerCrosshair/dllmain.cpp rename to src/modules/MouseUtils/MousePointerCrosshairs/dllmain.cpp index 532069e3968f..695b723c05d3 100644 --- a/src/modules/MouseUtils/MousePointerCrosshair/dllmain.cpp +++ b/src/modules/MouseUtils/MousePointerCrosshairs/dllmain.cpp @@ -2,7 +2,7 @@ #include #include #include "trace.h" -#include "InclusiveCrosshair.h" +#include "InclusiveCrosshairs.h" #include "common/utils/color.h" // Non-Localizable strings @@ -11,12 +11,12 @@ namespace const wchar_t JSON_KEY_PROPERTIES[] = L"properties"; const wchar_t JSON_KEY_VALUE[] = L"value"; const wchar_t JSON_KEY_ACTIVATION_SHORTCUT[] = L"activation_shortcut"; - const wchar_t JSON_KEY_CROSSHAIR_COLOR[] = L"crosshair_color"; - const wchar_t JSON_KEY_CROSSHAIR_OPACITY[] = L"crosshair_opacity"; - const wchar_t JSON_KEY_CROSSHAIR_RADIUS[] = L"crosshair_radius"; - const wchar_t JSON_KEY_CROSSHAIR_THICKNESS[] = L"crosshair_thickness"; - const wchar_t JSON_KEY_CROSSHAIR_BORDER_COLOR[] = L"crosshair_border_color"; - const wchar_t JSON_KEY_CROSSHAIR_BORDER_SIZE[] = L"crosshair_border_size"; + const wchar_t JSON_KEY_CROSSHAIRS_COLOR[] = L"crosshairs_color"; + const wchar_t JSON_KEY_CROSSHAIRS_OPACITY[] = L"crosshairs_opacity"; + const wchar_t JSON_KEY_CROSSHAIRS_RADIUS[] = L"crosshairs_radius"; + const wchar_t JSON_KEY_CROSSHAIRS_THICKNESS[] = L"crosshairs_thickness"; + const wchar_t JSON_KEY_CROSSHAIRS_BORDER_COLOR[] = L"crosshairs_border_color"; + const wchar_t JSON_KEY_CROSSHAIRS_BORDER_SIZE[] = L"crosshairs_border_size"; } extern "C" IMAGE_DOS_HEADER __ImageBase; @@ -42,12 +42,12 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv } // The PowerToy name that will be shown in the settings. -const static wchar_t* MODULE_NAME = L"MousePointerCrosshair"; +const static wchar_t* MODULE_NAME = L"MousePointerCrosshairs"; // Add a description that will we shown in the module settings page. const static wchar_t* MODULE_DESC = L""; // Implement the PowerToy Module Interface and all the required methods. -class MousePointerCrosshair : public PowertoyModuleIface +class MousePointerCrosshairs : public PowertoyModuleIface { private: // The PowerToy state. @@ -56,14 +56,14 @@ class MousePointerCrosshair : public PowertoyModuleIface // Hotkey to invoke the module HotkeyEx m_hotkey; - // Mouse Pointer Crosshair specific settings - InclusiveCrosshairSettings m_inclusiveCrosshairSettings; + // Mouse Pointer Crosshairs specific settings + InclusiveCrosshairsSettings m_inclusiveCrosshairsSettings; public: // Constructor - MousePointerCrosshair() + MousePointerCrosshairs() { - LoggerHelpers::init_logger(MODULE_NAME, L"ModuleInterface", LogSettings::mousePointerCrosshairLoggerName); + LoggerHelpers::init_logger(MODULE_NAME, L"ModuleInterface", LogSettings::mousePointerCrosshairsLoggerName); init_settings(); }; @@ -112,11 +112,11 @@ class MousePointerCrosshair : public PowertoyModuleIface parse_settings(values); - InclusiveCrosshairApplySettings(m_inclusiveCrosshairSettings); + InclusiveCrosshairsApplySettings(m_inclusiveCrosshairsSettings); } catch (std::exception&) { - Logger::error("Invalid json when trying to parse Mouse Pointer Crosshair settings json."); + Logger::error("Invalid json when trying to parse Mouse Pointer Crosshairs settings json."); } } @@ -124,16 +124,16 @@ class MousePointerCrosshair : public PowertoyModuleIface virtual void enable() { m_enabled = true; - Trace::EnableMousePointerCrosshair(true); - std::thread([=]() { InclusiveCrosshairMain(m_hModule, m_inclusiveCrosshairSettings); }).detach(); + Trace::EnableMousePointerCrosshairs(true); + std::thread([=]() { InclusiveCrosshairsMain(m_hModule, m_inclusiveCrosshairsSettings); }).detach(); } // Disable the powertoy virtual void disable() { m_enabled = false; - Trace::EnableMousePointerCrosshair(false); - InclusiveCrosshairDisable(); + Trace::EnableMousePointerCrosshairs(false); + InclusiveCrosshairsDisable(); } // Returns if the powertoys is enabled @@ -155,7 +155,7 @@ class MousePointerCrosshair : public PowertoyModuleIface virtual void OnHotkeyEx() override { - InclusiveCrosshairSwitch(); + InclusiveCrosshairsSwitch(); } // Load the settings file. void init_settings() @@ -164,12 +164,12 @@ class MousePointerCrosshair : public PowertoyModuleIface { // Load and parse the settings file for this PowerToy. PowerToysSettings::PowerToyValues settings = - PowerToysSettings::PowerToyValues::load_from_settings_file(MousePointerCrosshair::get_key()); + PowerToysSettings::PowerToyValues::load_from_settings_file(MousePointerCrosshairs::get_key()); parse_settings(settings); } catch (std::exception&) { - Logger::error("Invalid json when trying to load the Mouse Pointer Crosshair settings json from file."); + Logger::error("Invalid json when trying to load the Mouse Pointer Crosshairs settings json from file."); } } @@ -177,7 +177,7 @@ class MousePointerCrosshair : public PowertoyModuleIface { // TODO: refactor to use common/utils/json.h instead auto settingsObject = settings.get_raw_json(); - InclusiveCrosshairSettings inclusiveCrosshairSettings; + InclusiveCrosshairsSettings inclusiveCrosshairsSettings; if (settingsObject.GetView().Size()) { try @@ -210,13 +210,13 @@ class MousePointerCrosshair : public PowertoyModuleIface } catch (...) { - Logger::warn("Failed to initialize Mouse Pointer Crosshair activation shortcut"); + Logger::warn("Failed to initialize Mouse Pointer Crosshairs activation shortcut"); } try { // Parse Opacity - auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIR_OPACITY); - inclusiveCrosshairSettings.crosshairOpacity = (uint8_t)jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE); + auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_OPACITY); + inclusiveCrosshairsSettings.crosshairsOpacity = (uint8_t)jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE); } catch (...) { @@ -224,28 +224,28 @@ class MousePointerCrosshair : public PowertoyModuleIface } try { - // Parse crosshair color - auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIR_COLOR); - auto crosshairColor = (std::wstring)jsonPropertiesObject.GetNamedString(JSON_KEY_VALUE); + // Parse crosshairs color + auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_COLOR); + auto crosshairsColor = (std::wstring)jsonPropertiesObject.GetNamedString(JSON_KEY_VALUE); uint8_t r, g, b; - if (!checkValidRGB(crosshairColor, &r, &g, &b)) + if (!checkValidRGB(crosshairsColor, &r, &g, &b)) { - Logger::error("Crosshair color RGB value is invalid. Will use default value"); + Logger::error("Crosshairs color RGB value is invalid. Will use default value"); } else { - inclusiveCrosshairSettings.crosshairColor = winrt::Windows::UI::ColorHelper::FromArgb(255, r, g, b); + inclusiveCrosshairsSettings.crosshairsColor = winrt::Windows::UI::ColorHelper::FromArgb(255, r, g, b); } } catch (...) { - Logger::warn("Failed to initialize crosshair color from settings. Will use default value"); + Logger::warn("Failed to initialize crosshairs color from settings. Will use default value"); } try { // Parse Radius - auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIR_RADIUS); - inclusiveCrosshairSettings.crosshairRadius = (UINT)jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE); + auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_RADIUS); + inclusiveCrosshairsSettings.crosshairsRadius = (UINT)jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE); } catch (...) { @@ -254,8 +254,8 @@ class MousePointerCrosshair : public PowertoyModuleIface try { // Parse Thickness - auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIR_THICKNESS); - inclusiveCrosshairSettings.crosshairThickness = (UINT)jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE); + auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_THICKNESS); + inclusiveCrosshairsSettings.crosshairsThickness = (UINT)jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE); } catch (...) { @@ -263,28 +263,28 @@ class MousePointerCrosshair : public PowertoyModuleIface } try { - // Parse crosshair border color - auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIR_BORDER_COLOR); - auto crosshairBorderColor = (std::wstring)jsonPropertiesObject.GetNamedString(JSON_KEY_VALUE); + // Parse crosshairs border color + auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_BORDER_COLOR); + auto crosshairsBorderColor = (std::wstring)jsonPropertiesObject.GetNamedString(JSON_KEY_VALUE); uint8_t r, g, b; - if (!checkValidRGB(crosshairBorderColor, &r, &g, &b)) + if (!checkValidRGB(crosshairsBorderColor, &r, &g, &b)) { - Logger::error("Crosshair border color RGB value is invalid. Will use default value"); + Logger::error("Crosshairs border color RGB value is invalid. Will use default value"); } else { - inclusiveCrosshairSettings.crosshairBorderColor = winrt::Windows::UI::ColorHelper::FromArgb(255, r, g, b); + inclusiveCrosshairsSettings.crosshairsBorderColor = winrt::Windows::UI::ColorHelper::FromArgb(255, r, g, b); } } catch (...) { - Logger::warn("Failed to initialize crosshair border color from settings. Will use default value"); + Logger::warn("Failed to initialize crosshairs border color from settings. Will use default value"); } try { // Parse border size - auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIR_BORDER_SIZE); - inclusiveCrosshairSettings.crosshairBorderSize = (UINT)jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE); + auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_BORDER_SIZE); + inclusiveCrosshairsSettings.crosshairsBorderSize = (UINT)jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE); } catch (...) { @@ -293,20 +293,20 @@ class MousePointerCrosshair : public PowertoyModuleIface } else { - Logger::info("Mouse Pointer Crosshair settings are empty"); + Logger::info("Mouse Pointer Crosshairs settings are empty"); } if (!m_hotkey.modifiersMask) { - Logger::info("Mouse Pointer Crosshair is going to use default shortcut"); + Logger::info("Mouse Pointer Crosshairs is going to use default shortcut"); m_hotkey.modifiersMask = MOD_CONTROL | MOD_ALT; m_hotkey.vkCode = 0x50; // P key } - m_inclusiveCrosshairSettings = inclusiveCrosshairSettings; + m_inclusiveCrosshairsSettings = inclusiveCrosshairsSettings; } }; extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() { - return new MousePointerCrosshair(); + return new MousePointerCrosshairs(); } \ No newline at end of file diff --git a/src/modules/MouseUtils/MousePointerCrosshair/packages.config b/src/modules/MouseUtils/MousePointerCrosshairs/packages.config similarity index 100% rename from src/modules/MouseUtils/MousePointerCrosshair/packages.config rename to src/modules/MouseUtils/MousePointerCrosshairs/packages.config diff --git a/src/modules/MouseUtils/MousePointerCrosshair/pch.cpp b/src/modules/MouseUtils/MousePointerCrosshairs/pch.cpp similarity index 100% rename from src/modules/MouseUtils/MousePointerCrosshair/pch.cpp rename to src/modules/MouseUtils/MousePointerCrosshairs/pch.cpp diff --git a/src/modules/MouseUtils/MousePointerCrosshair/pch.h b/src/modules/MouseUtils/MousePointerCrosshairs/pch.h similarity index 100% rename from src/modules/MouseUtils/MousePointerCrosshair/pch.h rename to src/modules/MouseUtils/MousePointerCrosshairs/pch.h diff --git a/src/modules/MouseUtils/MousePointerCrosshairs/resource.h b/src/modules/MouseUtils/MousePointerCrosshairs/resource.h new file mode 100644 index 000000000000..b11ba74c8213 --- /dev/null +++ b/src/modules/MouseUtils/MousePointerCrosshairs/resource.h @@ -0,0 +1,13 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by MousePointerCrosshairs.rc + +////////////////////////////// +// Non-localizable + +#define FILE_DESCRIPTION "PowerToys MousePointerCrosshairs" +#define INTERNAL_NAME "MousePointerCrosshairs" +#define ORIGINAL_FILENAME "PowerToys.MousePointerCrosshairs.dll" + +// Non-localizable +////////////////////////////// diff --git a/src/modules/MouseUtils/MousePointerCrosshair/trace.cpp b/src/modules/MouseUtils/MousePointerCrosshairs/trace.cpp similarity index 75% rename from src/modules/MouseUtils/MousePointerCrosshair/trace.cpp rename to src/modules/MouseUtils/MousePointerCrosshairs/trace.cpp index b4fc60c92377..afc9844bc5a7 100644 --- a/src/modules/MouseUtils/MousePointerCrosshair/trace.cpp +++ b/src/modules/MouseUtils/MousePointerCrosshairs/trace.cpp @@ -18,23 +18,23 @@ void Trace::UnregisterProvider() noexcept TraceLoggingUnregister(g_hProvider); } -// Log if the user has MousePointerCrosshair enabled or disabled -void Trace::EnableMousePointerCrosshair(const bool enabled) noexcept +// Log if the user has MousePointerCrosshairs enabled or disabled +void Trace::EnableMousePointerCrosshairs(const bool enabled) noexcept { TraceLoggingWrite( g_hProvider, - "MousePointerCrosshair_EnableMousePointerCrosshair", + "MousePointerCrosshairs_EnableMousePointerCrosshairs", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), TraceLoggingBoolean(enabled, "Enabled")); } -// Log that the user activated the module by having the crosshair be drawn -void Trace::StartDrawingCrosshair() noexcept +// Log that the user activated the module by having the crosshairs be drawn +void Trace::StartDrawingCrosshairs() noexcept { TraceLoggingWrite( g_hProvider, - "MousePointerCrosshair_StartDrawingCrosshair", + "MousePointerCrosshairs_StartDrawingCrosshairs", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); } diff --git a/src/modules/MouseUtils/MousePointerCrosshairs/trace.h b/src/modules/MouseUtils/MousePointerCrosshairs/trace.h new file mode 100644 index 000000000000..d7373e5347e8 --- /dev/null +++ b/src/modules/MouseUtils/MousePointerCrosshairs/trace.h @@ -0,0 +1,14 @@ +#pragma once + +class Trace +{ +public: + static void RegisterProvider() noexcept; + static void UnregisterProvider() noexcept; + + // Log if the user has MousePointerCrosshairs enabled or disabled + static void EnableMousePointerCrosshairs(const bool enabled) noexcept; + + // Log that the user activated the module by having the crosshairs be drawn + static void StartDrawingCrosshairs() noexcept; +}; diff --git a/src/runner/main.cpp b/src/runner/main.cpp index f1b9a4896024..b3c43eaf30f2 100644 --- a/src/runner/main.cpp +++ b/src/runner/main.cpp @@ -151,7 +151,7 @@ int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow L"modules/MouseUtils/PowerToys.FindMyMouse.dll" , L"modules/MouseUtils/PowerToys.MouseHighlighter.dll", L"modules/AlwaysOnTop/PowerToys.AlwaysOnTopModuleInterface.dll", - L"modules/MouseUtils/PowerToys.MousePointerCrosshair.dll", + L"modules/MouseUtils/PowerToys.MousePointerCrosshairs.dll", }; const auto VCM_PATH = L"modules/VideoConference/PowerToys.VideoConferenceModule.dll"; if (const auto mf = LoadLibraryA("mf.dll")) diff --git a/src/settings-ui/Settings.UI.Library/EnabledModules.cs b/src/settings-ui/Settings.UI.Library/EnabledModules.cs index 3e074c2aaeae..475d185bd752 100644 --- a/src/settings-ui/Settings.UI.Library/EnabledModules.cs +++ b/src/settings-ui/Settings.UI.Library/EnabledModules.cs @@ -223,18 +223,18 @@ public bool AlwaysOnTop } } - private bool mousePointerCrosshair = true; + private bool mousePointerCrosshairs = true; - [JsonPropertyName("MousePointerCrosshair")] - public bool MousePointerCrosshair + [JsonPropertyName("MousePointerCrosshairs")] + public bool MousePointerCrosshairs { - get => mousePointerCrosshair; + get => mousePointerCrosshairs; set { - if (mousePointerCrosshair != value) + if (mousePointerCrosshairs != value) { LogTelemetryEvent(value); - mousePointerCrosshair = value; + mousePointerCrosshairs = value; } } } diff --git a/src/settings-ui/Settings.UI.Library/MousePointerCrosshairProperties.cs b/src/settings-ui/Settings.UI.Library/MousePointerCrosshairProperties.cs deleted file mode 100644 index 155add739656..000000000000 --- a/src/settings-ui/Settings.UI.Library/MousePointerCrosshairProperties.cs +++ /dev/null @@ -1,43 +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.Text.Json.Serialization; - -namespace Microsoft.PowerToys.Settings.UI.Library -{ - public class MousePointerCrosshairProperties - { - [JsonPropertyName("activation_shortcut")] - public HotkeySettings ActivationShortcut { get; set; } - - [JsonPropertyName("crosshair_color")] - public StringProperty CrosshairColor { get; set; } - - [JsonPropertyName("crosshair_opacity")] - public IntProperty CrosshairOpacity { get; set; } - - [JsonPropertyName("crosshair_radius")] - public IntProperty CrosshairRadius { get; set; } - - [JsonPropertyName("crosshair_thickness")] - public IntProperty CrosshairThickness { get; set; } - - [JsonPropertyName("crosshair_border_color")] - public StringProperty CrosshairBorderColor { get; set; } - - [JsonPropertyName("crosshair_border_size")] - public IntProperty CrosshairBorderSize { get; set; } - - public MousePointerCrosshairProperties() - { - ActivationShortcut = new HotkeySettings(false, true, true, false, 0x50); // Ctrl + Alt + P - CrosshairColor = new StringProperty("#FF0000"); - CrosshairOpacity = new IntProperty(75); - CrosshairRadius = new IntProperty(20); - CrosshairThickness = new IntProperty(5); - CrosshairBorderColor = new StringProperty("#FFFFFF"); - CrosshairBorderSize = new IntProperty(1); - } - } -} diff --git a/src/settings-ui/Settings.UI.Library/MousePointerCrosshairsProperties.cs b/src/settings-ui/Settings.UI.Library/MousePointerCrosshairsProperties.cs new file mode 100644 index 000000000000..8a3e4fd477da --- /dev/null +++ b/src/settings-ui/Settings.UI.Library/MousePointerCrosshairsProperties.cs @@ -0,0 +1,43 @@ +// 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.Text.Json.Serialization; + +namespace Microsoft.PowerToys.Settings.UI.Library +{ + public class MousePointerCrosshairsProperties + { + [JsonPropertyName("activation_shortcut")] + public HotkeySettings ActivationShortcut { get; set; } + + [JsonPropertyName("crosshairs_color")] + public StringProperty CrosshairsColor { get; set; } + + [JsonPropertyName("crosshairs_opacity")] + public IntProperty CrosshairsOpacity { get; set; } + + [JsonPropertyName("crosshairs_radius")] + public IntProperty CrosshairsRadius { get; set; } + + [JsonPropertyName("crosshairs_thickness")] + public IntProperty CrosshairsThickness { get; set; } + + [JsonPropertyName("crosshairs_border_color")] + public StringProperty CrosshairsBorderColor { get; set; } + + [JsonPropertyName("crosshairs_border_size")] + public IntProperty CrosshairsBorderSize { get; set; } + + public MousePointerCrosshairsProperties() + { + ActivationShortcut = new HotkeySettings(false, true, true, false, 0x50); // Ctrl + Alt + P + CrosshairsColor = new StringProperty("#FF0000"); + CrosshairsOpacity = new IntProperty(75); + CrosshairsRadius = new IntProperty(20); + CrosshairsThickness = new IntProperty(5); + CrosshairsBorderColor = new StringProperty("#FFFFFF"); + CrosshairsBorderSize = new IntProperty(1); + } + } +} diff --git a/src/settings-ui/Settings.UI.Library/MousePointerCrosshairSettings.cs b/src/settings-ui/Settings.UI.Library/MousePointerCrosshairsSettings.cs similarity index 68% rename from src/settings-ui/Settings.UI.Library/MousePointerCrosshairSettings.cs rename to src/settings-ui/Settings.UI.Library/MousePointerCrosshairsSettings.cs index 08c0aa2a431b..7c1f2532714a 100644 --- a/src/settings-ui/Settings.UI.Library/MousePointerCrosshairSettings.cs +++ b/src/settings-ui/Settings.UI.Library/MousePointerCrosshairsSettings.cs @@ -7,17 +7,17 @@ namespace Microsoft.PowerToys.Settings.UI.Library { - public class MousePointerCrosshairSettings : BasePTModuleSettings, ISettingsConfig + public class MousePointerCrosshairsSettings : BasePTModuleSettings, ISettingsConfig { - public const string ModuleName = "MousePointerCrosshair"; + public const string ModuleName = "MousePointerCrosshairs"; [JsonPropertyName("properties")] - public MousePointerCrosshairProperties Properties { get; set; } + public MousePointerCrosshairsProperties Properties { get; set; } - public MousePointerCrosshairSettings() + public MousePointerCrosshairsSettings() { Name = ModuleName; - Properties = new MousePointerCrosshairProperties(); + Properties = new MousePointerCrosshairsProperties(); Version = "1.0"; } diff --git a/src/settings-ui/Settings.UI.Library/MousePointerCrosshairSettingsIPCMessage.cs b/src/settings-ui/Settings.UI.Library/MousePointerCrosshairsSettingsIPCMessage.cs similarity index 65% rename from src/settings-ui/Settings.UI.Library/MousePointerCrosshairSettingsIPCMessage.cs rename to src/settings-ui/Settings.UI.Library/MousePointerCrosshairsSettingsIPCMessage.cs index 18fa5e21cb78..d54792a570dc 100644 --- a/src/settings-ui/Settings.UI.Library/MousePointerCrosshairSettingsIPCMessage.cs +++ b/src/settings-ui/Settings.UI.Library/MousePointerCrosshairsSettingsIPCMessage.cs @@ -7,16 +7,16 @@ namespace Microsoft.PowerToys.Settings.UI.Library { - public class MousePointerCrosshairSettingsIPCMessage + public class MousePointerCrosshairsSettingsIPCMessage { [JsonPropertyName("powertoys")] - public SndMousePointerCrosshairSettings Powertoys { get; set; } + public SndMousePointerCrosshairsSettings Powertoys { get; set; } - public MousePointerCrosshairSettingsIPCMessage() + public MousePointerCrosshairsSettingsIPCMessage() { } - public MousePointerCrosshairSettingsIPCMessage(SndMousePointerCrosshairSettings settings) + public MousePointerCrosshairsSettingsIPCMessage(SndMousePointerCrosshairsSettings settings) { this.Powertoys = settings; } diff --git a/src/settings-ui/Settings.UI.Library/SndMousePointerCrosshairSettings.cs b/src/settings-ui/Settings.UI.Library/SndMousePointerCrosshairsSettings.cs similarity index 55% rename from src/settings-ui/Settings.UI.Library/SndMousePointerCrosshairSettings.cs rename to src/settings-ui/Settings.UI.Library/SndMousePointerCrosshairsSettings.cs index 18576b2c384e..0d2e7c501477 100644 --- a/src/settings-ui/Settings.UI.Library/SndMousePointerCrosshairSettings.cs +++ b/src/settings-ui/Settings.UI.Library/SndMousePointerCrosshairsSettings.cs @@ -7,18 +7,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library { - public class SndMousePointerCrosshairSettings + public class SndMousePointerCrosshairsSettings { - [JsonPropertyName("MousePointerCrosshair")] - public MousePointerCrosshairSettings MousePointerCrosshair { get; set; } + [JsonPropertyName("MousePointerCrosshairs")] + public MousePointerCrosshairsSettings MousePointerCrosshairs { get; set; } - public SndMousePointerCrosshairSettings() + public SndMousePointerCrosshairsSettings() { } - public SndMousePointerCrosshairSettings(MousePointerCrosshairSettings settings) + public SndMousePointerCrosshairsSettings(MousePointerCrosshairsSettings settings) { - MousePointerCrosshair = settings; + MousePointerCrosshairs = settings; } public string ToJsonString() diff --git a/src/settings-ui/Settings.UI.Library/ViewModels/MouseUtilsViewModel.cs b/src/settings-ui/Settings.UI.Library/ViewModels/MouseUtilsViewModel.cs index befc0ddd3690..e336777dd953 100644 --- a/src/settings-ui/Settings.UI.Library/ViewModels/MouseUtilsViewModel.cs +++ b/src/settings-ui/Settings.UI.Library/ViewModels/MouseUtilsViewModel.cs @@ -19,9 +19,9 @@ public class MouseUtilsViewModel : Observable private MouseHighlighterSettings MouseHighlighterSettingsConfig { get; set; } - private MousePointerCrosshairSettings MousePointerCrosshairSettingsConfig { get; set; } + private MousePointerCrosshairsSettings MousePointerCrosshairsSettingsConfig { get; set; } - public MouseUtilsViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, ISettingsRepository findMyMouseSettingsRepository, ISettingsRepository mouseHighlighterSettingsRepository, ISettingsRepository mousePointerCrosshairSettingsRepository, Func ipcMSGCallBackFunc) + public MouseUtilsViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, ISettingsRepository findMyMouseSettingsRepository, ISettingsRepository mouseHighlighterSettingsRepository, ISettingsRepository mousePointerCrosshairsSettingsRepository, Func ipcMSGCallBackFunc) { SettingsUtils = settingsUtils; @@ -37,7 +37,7 @@ public MouseUtilsViewModel(ISettingsUtils settingsUtils, ISettingsRepository _isMousePointerCrosshairEnabled; + get => _isMousePointerCrosshairsEnabled; set { - if (_isMousePointerCrosshairEnabled != value) + if (_isMousePointerCrosshairsEnabled != value) { - _isMousePointerCrosshairEnabled = value; + _isMousePointerCrosshairsEnabled = value; - GeneralSettingsConfig.Enabled.MousePointerCrosshair = value; - OnPropertyChanged(nameof(_isMousePointerCrosshairEnabled)); + GeneralSettingsConfig.Enabled.MousePointerCrosshairs = value; + OnPropertyChanged(nameof(_isMousePointerCrosshairsEnabled)); OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig); SendConfigMSG(outgoing.ToString()); - NotifyMousePointerCrosshairPropertyChanged(); + NotifyMousePointerCrosshairsPropertyChanged(); } } } - public HotkeySettings MousePointerCrosshairActivationShortcut + public HotkeySettings MousePointerCrosshairsActivationShortcut { get { - return MousePointerCrosshairSettingsConfig.Properties.ActivationShortcut; + return MousePointerCrosshairsSettingsConfig.Properties.ActivationShortcut; } set { - if (MousePointerCrosshairSettingsConfig.Properties.ActivationShortcut != value) + if (MousePointerCrosshairsSettingsConfig.Properties.ActivationShortcut != value) { - MousePointerCrosshairSettingsConfig.Properties.ActivationShortcut = value; - NotifyMousePointerCrosshairPropertyChanged(); + MousePointerCrosshairsSettingsConfig.Properties.ActivationShortcut = value; + NotifyMousePointerCrosshairsPropertyChanged(); } } } - public string MousePointerCrosshairColor + public string MousePointerCrosshairsColor { get { - return _mousePointerCrosshairColor; + return _mousePointerCrosshairsColor; } set @@ -470,74 +470,74 @@ public string MousePointerCrosshairColor // #FFFFFF if any exceptions are encountered, e.g. from passing in a null value. // This extra handling is added here to deal with FxCop warnings. value = (value != null) ? SettingsUtilities.ToRGBHex(value) : "#FFFFFF"; - if (!value.Equals(_mousePointerCrosshairColor, StringComparison.OrdinalIgnoreCase)) + if (!value.Equals(_mousePointerCrosshairsColor, StringComparison.OrdinalIgnoreCase)) { - _mousePointerCrosshairColor = value; - MousePointerCrosshairSettingsConfig.Properties.CrosshairColor.Value = value; - NotifyMousePointerCrosshairPropertyChanged(); + _mousePointerCrosshairsColor = value; + MousePointerCrosshairsSettingsConfig.Properties.CrosshairsColor.Value = value; + NotifyMousePointerCrosshairsPropertyChanged(); } } } - public int MousePointerCrosshairOpacity + public int MousePointerCrosshairsOpacity { get { - return _mousePointerCrosshairOpacity; + return _mousePointerCrosshairsOpacity; } set { - if (value != _mousePointerCrosshairOpacity) + if (value != _mousePointerCrosshairsOpacity) { - _mousePointerCrosshairOpacity = value; - MousePointerCrosshairSettingsConfig.Properties.CrosshairOpacity.Value = value; - NotifyMousePointerCrosshairPropertyChanged(); + _mousePointerCrosshairsOpacity = value; + MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOpacity.Value = value; + NotifyMousePointerCrosshairsPropertyChanged(); } } } - public int MousePointerCrosshairRadius + public int MousePointerCrosshairsRadius { get { - return _mousePointerCrosshairRadius; + return _mousePointerCrosshairsRadius; } set { - if (value != _mousePointerCrosshairRadius) + if (value != _mousePointerCrosshairsRadius) { - _mousePointerCrosshairRadius = value; - MousePointerCrosshairSettingsConfig.Properties.CrosshairRadius.Value = value; - NotifyMousePointerCrosshairPropertyChanged(); + _mousePointerCrosshairsRadius = value; + MousePointerCrosshairsSettingsConfig.Properties.CrosshairsRadius.Value = value; + NotifyMousePointerCrosshairsPropertyChanged(); } } } - public int MousePointerCrosshairThickness + public int MousePointerCrosshairsThickness { get { - return _mousePointerCrosshairThickness; + return _mousePointerCrosshairsThickness; } set { - if (value != _mousePointerCrosshairThickness) + if (value != _mousePointerCrosshairsThickness) { - _mousePointerCrosshairThickness = value; - MousePointerCrosshairSettingsConfig.Properties.CrosshairThickness.Value = value; - NotifyMousePointerCrosshairPropertyChanged(); + _mousePointerCrosshairsThickness = value; + MousePointerCrosshairsSettingsConfig.Properties.CrosshairsThickness.Value = value; + NotifyMousePointerCrosshairsPropertyChanged(); } } } - public string MousePointerCrosshairBorderColor + public string MousePointerCrosshairsBorderColor { get { - return _mousePointerCrosshairBorderColor; + return _mousePointerCrosshairsBorderColor; } set @@ -546,41 +546,41 @@ public string MousePointerCrosshairBorderColor // #FFFFFF if any exceptions are encountered, e.g. from passing in a null value. // This extra handling is added here to deal with FxCop warnings. value = (value != null) ? SettingsUtilities.ToRGBHex(value) : "#FFFFFF"; - if (!value.Equals(_mousePointerCrosshairBorderColor, StringComparison.OrdinalIgnoreCase)) + if (!value.Equals(_mousePointerCrosshairsBorderColor, StringComparison.OrdinalIgnoreCase)) { - _mousePointerCrosshairBorderColor = value; - MousePointerCrosshairSettingsConfig.Properties.CrosshairBorderColor.Value = value; - NotifyMousePointerCrosshairPropertyChanged(); + _mousePointerCrosshairsBorderColor = value; + MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderColor.Value = value; + NotifyMousePointerCrosshairsPropertyChanged(); } } } - public int MousePointerCrosshairBorderSize + public int MousePointerCrosshairsBorderSize { get { - return _mousePointerCrosshairBorderSize; + return _mousePointerCrosshairsBorderSize; } set { - if (value != _mousePointerCrosshairBorderSize) + if (value != _mousePointerCrosshairsBorderSize) { - _mousePointerCrosshairBorderSize = value; - MousePointerCrosshairSettingsConfig.Properties.CrosshairBorderSize.Value = value; - NotifyMousePointerCrosshairPropertyChanged(); + _mousePointerCrosshairsBorderSize = value; + MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderSize.Value = value; + NotifyMousePointerCrosshairsPropertyChanged(); } } } - public void NotifyMousePointerCrosshairPropertyChanged([CallerMemberName] string propertyName = null) + public void NotifyMousePointerCrosshairsPropertyChanged([CallerMemberName] string propertyName = null) { OnPropertyChanged(propertyName); - SndMousePointerCrosshairSettings outsettings = new SndMousePointerCrosshairSettings(MousePointerCrosshairSettingsConfig); - SndModuleSettings ipcMessage = new SndModuleSettings(outsettings); + SndMousePointerCrosshairsSettings outsettings = new SndMousePointerCrosshairsSettings(MousePointerCrosshairsSettingsConfig); + SndModuleSettings ipcMessage = new SndModuleSettings(outsettings); SendConfigMSG(ipcMessage.ToJsonString()); - SettingsUtils.SaveSettings(MousePointerCrosshairSettingsConfig.ToJsonString(), MousePointerCrosshairSettings.ModuleName); + SettingsUtils.SaveSettings(MousePointerCrosshairsSettingsConfig.ToJsonString(), MousePointerCrosshairsSettings.ModuleName); } private Func SendConfigMSG { get; } @@ -602,12 +602,12 @@ public void NotifyMousePointerCrosshairPropertyChanged([CallerMemberName] string private int _highlightFadeDelayMs; private int _highlightFadeDurationMs; - private bool _isMousePointerCrosshairEnabled; - private string _mousePointerCrosshairColor; - private int _mousePointerCrosshairOpacity; - private int _mousePointerCrosshairRadius; - private int _mousePointerCrosshairThickness; - private string _mousePointerCrosshairBorderColor; - private int _mousePointerCrosshairBorderSize; + private bool _isMousePointerCrosshairsEnabled; + private string _mousePointerCrosshairsColor; + private int _mousePointerCrosshairsOpacity; + private int _mousePointerCrosshairsRadius; + private int _mousePointerCrosshairsThickness; + private string _mousePointerCrosshairsBorderColor; + private int _mousePointerCrosshairsBorderSize; } } diff --git a/src/settings-ui/Settings.UI/Assets/FluentIcons/FluentIconsMouseCrosshair.png b/src/settings-ui/Settings.UI/Assets/FluentIcons/FluentIconsMouseCrosshairs.png similarity index 100% rename from src/settings-ui/Settings.UI/Assets/FluentIcons/FluentIconsMouseCrosshair.png rename to src/settings-ui/Settings.UI/Assets/FluentIcons/FluentIconsMouseCrosshairs.png diff --git a/src/settings-ui/Settings.UI/OOBE/Views/OobeMouseUtils.xaml b/src/settings-ui/Settings.UI/OOBE/Views/OobeMouseUtils.xaml index 5f1cca7e33b6..3cc42b2b6717 100644 --- a/src/settings-ui/Settings.UI/OOBE/Views/OobeMouseUtils.xaml +++ b/src/settings-ui/Settings.UI/OOBE/Views/OobeMouseUtils.xaml @@ -22,9 +22,9 @@ Style="{ThemeResource OobeSubtitleStyle}" /> - - +