mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 10:16:24 +02:00
This PR adds new options for disabling wrap, updates the wrapping model, extends the simulator and cursor logging. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #45116 - [ ] Closes: #44955 - [ ] Closes: #44827 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx The PR adds a new option for disabling cursor wrapping, exposing three options: None - wrapping is not disabled, Ctrl key - if this is pressed then wrapping is disabled, Shift key - if this is pressed then wrapping is disabled, this would enable a user to temporarily disable wrapping if they wanted to get close to a monitor edge without wrapping (auto-hide status bar for example). The cursor wrap edge model has been updated to mirror Windows monitor-to-monitor cursor movement, this should ensure there aren't any non-wrappable edges. A new test tool has been added 'CursorLog' this is a monitor aware, dpi/scaling aware Win32 application that captures mouse movement across monitors to a log file, the log contains one line per mouse movement which includes: Monitor, x, y, scale, dpi. The wrapping simulator has been updated to include the new wrapping model and support mouse cursor log playback. ## Validation Steps Performed The updated CursorWrap has been tested on a single monitor (laptop) and multi-monitor desktop PC with monitors being offset to test edge/wrapping behavior. --------- Co-authored-by: Mike Hall <mikehall@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: vanzue <vanzue@outlook.com>
132 lines
5.4 KiB
C++
132 lines
5.4 KiB
C++
// 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.
|
|
|
|
#pragma once
|
|
|
|
#include <Windows.h>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <utility>
|
|
|
|
/// <summary>
|
|
/// Utility class for discovering and loading PowerToy module settings
|
|
/// </summary>
|
|
class SettingsLoader
|
|
{
|
|
public:
|
|
SettingsLoader();
|
|
~SettingsLoader();
|
|
|
|
/// <summary>
|
|
/// Load settings for a PowerToy module
|
|
/// </summary>
|
|
/// <param name="moduleName">Name of the module (e.g., "CursorWrap")</param>
|
|
/// <param name="moduleDllPath">Full path to the module DLL (for checking local settings.json)</param>
|
|
/// <returns>JSON settings string, or empty string if not found</returns>
|
|
std::wstring LoadSettings(const std::wstring& moduleName, const std::wstring& moduleDllPath);
|
|
|
|
/// <summary>
|
|
/// Get the settings file path for a module
|
|
/// </summary>
|
|
/// <param name="moduleName">Name of the module</param>
|
|
/// <returns>Full path to the settings.json file</returns>
|
|
std::wstring GetSettingsPath(const std::wstring& moduleName) const;
|
|
|
|
/// <summary>
|
|
/// Display settings information for a module
|
|
/// </summary>
|
|
/// <param name="moduleName">Name of the module</param>
|
|
/// <param name="moduleDllPath">Path to the module DLL</param>
|
|
void DisplaySettingsInfo(const std::wstring& moduleName, const std::wstring& moduleDllPath);
|
|
|
|
/// <summary>
|
|
/// Get a specific setting value
|
|
/// </summary>
|
|
/// <param name="moduleName">Name of the module</param>
|
|
/// <param name="moduleDllPath">Path to the module DLL</param>
|
|
/// <param name="key">Setting key to retrieve</param>
|
|
/// <returns>Value as string, or empty if not found</returns>
|
|
std::wstring GetSettingValue(const std::wstring& moduleName, const std::wstring& moduleDllPath, const std::wstring& key);
|
|
|
|
/// <summary>
|
|
/// Set a specific setting value
|
|
/// </summary>
|
|
/// <param name="moduleName">Name of the module</param>
|
|
/// <param name="moduleDllPath">Path to the module DLL</param>
|
|
/// <param name="key">Setting key to set</param>
|
|
/// <param name="value">Value to set</param>
|
|
/// <returns>True if successful</returns>
|
|
bool SetSettingValue(const std::wstring& moduleName, const std::wstring& moduleDllPath, const std::wstring& key, const std::wstring& value);
|
|
|
|
/// <summary>
|
|
/// Find the actual settings file path (handles case-insensitivity)
|
|
/// </summary>
|
|
/// <param name="moduleName">Name of the module</param>
|
|
/// <param name="moduleDllPath">Path to the module DLL</param>
|
|
/// <returns>Actual path to settings.json, or empty if not found</returns>
|
|
std::wstring FindSettingsFilePath(const std::wstring& moduleName, const std::wstring& moduleDllPath);
|
|
|
|
private:
|
|
/// <summary>
|
|
/// Get the PowerToys root settings directory
|
|
/// </summary>
|
|
/// <returns>Path to %LOCALAPPDATA%\Microsoft\PowerToys</returns>
|
|
std::wstring GetPowerToysSettingsRoot() const;
|
|
|
|
/// <summary>
|
|
/// Read a text file into a string
|
|
/// </summary>
|
|
/// <param name="filePath">Path to the file</param>
|
|
/// <returns>File contents as a string</returns>
|
|
std::wstring ReadFileContents(const std::wstring& filePath) const;
|
|
|
|
/// <summary>
|
|
/// Write a string to a text file
|
|
/// </summary>
|
|
/// <param name="filePath">Path to the file</param>
|
|
/// <param name="contents">Contents to write</param>
|
|
/// <returns>True if successful</returns>
|
|
bool WriteFileContents(const std::wstring& filePath, const std::wstring& contents) const;
|
|
|
|
/// <summary>
|
|
/// Parse settings properties from JSON and display them
|
|
/// </summary>
|
|
/// <param name="settingsJson">JSON string containing settings</param>
|
|
/// <param name="indent">Indentation level</param>
|
|
void DisplayJsonProperties(const std::wstring& settingsJson, int indent = 0);
|
|
|
|
/// <summary>
|
|
/// Parse a hotkey object from JSON and format it as a string (e.g., "Win+Alt+U")
|
|
/// </summary>
|
|
/// <param name="json">JSON string</param>
|
|
/// <param name="objStart">Start position of the hotkey object</param>
|
|
/// <param name="objEnd">Output: end position of the hotkey object</param>
|
|
/// <returns>Formatted hotkey string, or empty if not a valid hotkey</returns>
|
|
std::string ParseHotkeyObject(const std::string& json, size_t objStart, size_t& objEnd);
|
|
|
|
/// <summary>
|
|
/// Check if a JSON object appears to be a hotkey settings object
|
|
/// </summary>
|
|
/// <param name="json">JSON string</param>
|
|
/// <param name="objStart">Start position of the object</param>
|
|
/// <returns>True if this looks like a hotkey object</returns>
|
|
bool IsHotkeyObject(const std::string& json, size_t objStart);
|
|
|
|
/// <summary>
|
|
/// Prompt user for yes/no confirmation
|
|
/// </summary>
|
|
/// <param name="prompt">The question to ask</param>
|
|
/// <returns>True if user answered yes</returns>
|
|
bool PromptYesNo(const std::wstring& prompt);
|
|
|
|
/// <summary>
|
|
/// Add a new property to the JSON settings file
|
|
/// </summary>
|
|
/// <param name="json">The JSON string to modify</param>
|
|
/// <param name="key">The property key to add</param>
|
|
/// <param name="value">The value to set</param>
|
|
/// <returns>Modified JSON string, or empty if failed</returns>
|
|
std::string AddNewProperty(const std::string& json, const std::string& key, const std::string& value);
|
|
};
|