[FancyZones] Clasify strings in FancyZones to localizable and non-localizable (#5315)

* Clasify strings in FancyZones to localizable and non-localizable

* Address PR comments

* Better handling of FirePropertyChanged event

* Address PR comments

* Update properties
This commit is contained in:
vldmr11080 2020-08-11 13:51:06 +02:00 committed by GitHub
parent b8b6dbe791
commit 145347f7ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 362 additions and 190 deletions

View File

@ -82,7 +82,10 @@ public:
s_llKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), NULL); s_llKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), NULL);
if (!s_llKeyboardHook) if (!s_llKeyboardHook)
{ {
MessageBoxW(NULL, L"Cannot install keyboard listener.", L"PowerToys - FancyZones", MB_OK | MB_ICONERROR); MessageBoxW(NULL,
GET_RESOURCE_STRING(IDS_KEYBOARD_LISTENER_ERROR).c_str(),
GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
MB_OK | MB_ICONERROR);
} }
} }
@ -103,7 +106,10 @@ public:
} }
else else
{ {
MessageBoxW(NULL, L"Cannot install Windows event listener.", L"PowerToys - FancyZones", MB_OK | MB_ICONERROR); MessageBoxW(NULL,
GET_RESOURCE_STRING(IDS_WINDOW_EVENT_LISTENER_ERROR).c_str(),
GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
MB_OK | MB_ICONERROR);
} }
} }

View File

@ -13,6 +13,9 @@ namespace FancyZonesEditor
/// </summary> /// </summary>
public partial class CanvasEditor : UserControl public partial class CanvasEditor : UserControl
{ {
// Non-localizable strings
private const string PropertyUpdateLayoutID = "UpdateLayout";
private CanvasLayoutModel _model; private CanvasLayoutModel _model;
public CanvasEditor() public CanvasEditor()
@ -35,7 +38,7 @@ namespace FancyZonesEditor
private void OnModelChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) private void OnModelChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
if (e.PropertyName == "Zones") if (e.PropertyName == PropertyUpdateLayoutID)
{ {
UpdateZoneRects(); UpdateZoneRects();
} }

View File

@ -16,7 +16,12 @@ namespace FancyZonesEditor
/// </summary> /// </summary>
public partial class GridEditor : UserControl public partial class GridEditor : UserControl
{ {
public static readonly DependencyProperty ModelProperty = DependencyProperty.Register("Model", typeof(GridLayoutModel), typeof(GridEditor), new PropertyMetadata(null, OnGridDimensionsChanged)); // Non-localizable strings
private const string PropertyRowsChangedID = "Rows";
private const string PropertyColumnsChangedID = "Columns";
private const string ObjectDependencyID = "Model";
public static readonly DependencyProperty ModelProperty = DependencyProperty.Register(ObjectDependencyID, typeof(GridLayoutModel), typeof(GridEditor), new PropertyMetadata(null, OnGridDimensionsChanged));
private static int gridEditorUniqueIdCounter = 0; private static int gridEditorUniqueIdCounter = 0;
@ -336,7 +341,7 @@ namespace FancyZonesEditor
private void OnGridDimensionsChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) private void OnGridDimensionsChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
// Only enter if this is the newest instance // Only enter if this is the newest instance
if (((e.PropertyName == "Rows") || (e.PropertyName == "Columns")) && gridEditorUniqueId == gridEditorUniqueIdCounter) if (((e.PropertyName == PropertyRowsChangedID) || (e.PropertyName == PropertyColumnsChangedID)) && gridEditorUniqueId == gridEditorUniqueIdCounter)
{ {
OnGridDimensionsChanged(); OnGridDimensionsChanged();
} }

View File

@ -17,7 +17,12 @@ namespace FancyZonesEditor
/// </summary> /// </summary>
public partial class GridZone : UserControl public partial class GridZone : UserControl
{ {
public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(GridZone), new PropertyMetadata(false, OnSelectionChanged)); // Non-localizable strings
private const string ObjectDependencyID = "IsSelected";
private const string GridZoneBackgroundBrushID = "GridZoneBackgroundBrush";
private const string PropertyIsShiftKeyPressedID = "IsShiftKeyPressed";
public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register(ObjectDependencyID, typeof(bool), typeof(GridZone), new PropertyMetadata(false, OnSelectionChanged));
public event SplitEventHandler Split; public event SplitEventHandler Split;
@ -45,7 +50,7 @@ namespace FancyZonesEditor
private void OnSelectionChanged() private void OnSelectionChanged()
{ {
Background = IsSelected ? SystemParameters.WindowGlassBrush : App.Current.Resources["GridZoneBackgroundBrush"] as SolidColorBrush; Background = IsSelected ? SystemParameters.WindowGlassBrush : App.Current.Resources[GridZoneBackgroundBrushID] as SolidColorBrush;
} }
public bool IsSelected public bool IsSelected
@ -69,7 +74,7 @@ namespace FancyZonesEditor
private void ZoneSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) private void ZoneSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
if (e.PropertyName == "IsShiftKeyPressed") if (e.PropertyName == PropertyIsShiftKeyPressedID)
{ {
_switchOrientation = ((App)Application.Current).ZoneSettings.IsShiftKeyPressed; _switchOrientation = ((App)Application.Current).ZoneSettings.IsShiftKeyPressed;
if (_lastPos.X != -1) if (_lastPos.X != -1)

View File

@ -17,7 +17,13 @@ namespace FancyZonesEditor
/// </summary> /// </summary>
public partial class LayoutPreview : UserControl public partial class LayoutPreview : UserControl
{ {
public static readonly DependencyProperty IsActualSizeProperty = DependencyProperty.Register("IsActualSize", typeof(bool), typeof(LayoutPreview), new PropertyMetadata(false)); // Non-localizable strings
private const string PropertyZoneCountID = "ZoneCount";
private const string PropertyShowSpacingID = "ShowSpacing";
private const string PropertySpacingID = "Spacing";
private const string ObjectDependencyID = "IsActualSize";
public static readonly DependencyProperty IsActualSizeProperty = DependencyProperty.Register(ObjectDependencyID, typeof(bool), typeof(LayoutPreview), new PropertyMetadata(false));
private LayoutModel _model; private LayoutModel _model;
private List<Int32Rect> _zones = new List<Int32Rect>(); private List<Int32Rect> _zones = new List<Int32Rect>();
@ -43,11 +49,11 @@ namespace FancyZonesEditor
private void ZoneSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) private void ZoneSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
if (e.PropertyName == "ZoneCount") if (e.PropertyName == PropertyZoneCountID)
{ {
RenderPreview(); RenderPreview();
} }
else if ((e.PropertyName == "ShowSpacing") || (e.PropertyName == "Spacing")) else if ((e.PropertyName == PropertyShowSpacingID) || (e.PropertyName == PropertySpacingID))
{ {
if (_model is GridLayoutModel) if (_model is GridLayoutModel)
{ {

View File

@ -20,6 +20,8 @@ namespace FancyZonesEditor
// TODO: share the constants b/w C# Editor and FancyZoneLib // TODO: share the constants b/w C# Editor and FancyZoneLib
public const int MaxZones = 40; public const int MaxZones = 40;
private readonly Settings _settings = ((App)Application.Current).ZoneSettings; private readonly Settings _settings = ((App)Application.Current).ZoneSettings;
// Localizable string
private static readonly string _defaultNamePrefix = "Custom Layout "; private static readonly string _defaultNamePrefix = "Custom Layout ";
public int WrapPanelItemSize { get; set; } = 262; public int WrapPanelItemSize { get; set; } = 262;

View File

@ -14,6 +14,12 @@ namespace FancyZonesEditor.Models
// Free form Layout Model, which specifies independent zone rects // Free form Layout Model, which specifies independent zone rects
public class CanvasLayoutModel : LayoutModel public class CanvasLayoutModel : LayoutModel
{ {
// Localizable strings
private const string ErrorPersistingCanvasLayout = "Error persisting canvas layout";
// Non-localizable strings
private const string ModelTypeID = "canvas";
public CanvasLayoutModel(string uuid, string name, LayoutType type, IList<Int32Rect> zones, int workAreaWidth, int workAreaHeight) public CanvasLayoutModel(string uuid, string name, LayoutType type, IList<Int32Rect> zones, int workAreaWidth, int workAreaHeight)
: base(uuid, name, type) : base(uuid, name, type)
{ {
@ -56,7 +62,7 @@ namespace FancyZonesEditor.Models
public void RemoveZoneAt(int index) public void RemoveZoneAt(int index)
{ {
Zones.RemoveAt(index); Zones.RemoveAt(index);
FirePropertyChanged("Zones"); UpdateLayout();
} }
// AddZone // AddZone
@ -64,7 +70,12 @@ namespace FancyZonesEditor.Models
public void AddZone(Int32Rect zone) public void AddZone(Int32Rect zone)
{ {
Zones.Add(zone); Zones.Add(zone);
FirePropertyChanged("Zones"); UpdateLayout();
}
private void UpdateLayout()
{
FirePropertyChanged();
} }
// Clone // Clone
@ -178,7 +189,7 @@ namespace FancyZonesEditor.Models
{ {
Uuid = "{" + Guid.ToString().ToUpper() + "}", Uuid = "{" + Guid.ToString().ToUpper() + "}",
Name = Name, Name = Name,
Type = "canvas", Type = ModelTypeID,
Info = layoutInfo, Info = layoutInfo,
}; };
@ -194,7 +205,7 @@ namespace FancyZonesEditor.Models
} }
catch (Exception ex) catch (Exception ex)
{ {
ShowExceptionMessageBox("Error persisting canvas layout", ex); ShowExceptionMessageBox(ErrorPersistingCanvasLayout, ex);
} }
} }
} }

View File

@ -14,6 +14,12 @@ namespace FancyZonesEditor.Models
// Grid-styled Layout Model, which specifies rows, columns, percentage sizes, and row/column spans // Grid-styled Layout Model, which specifies rows, columns, percentage sizes, and row/column spans
public class GridLayoutModel : LayoutModel public class GridLayoutModel : LayoutModel
{ {
// Localizable strings
private const string ErrorPersistingGridLayout = "Error persisting grid layout";
// Non-localizable strings
private const string ModelTypeID = "grid";
// Rows - number of rows in the Grid // Rows - number of rows in the Grid
public int Rows public int Rows
{ {
@ -220,7 +226,7 @@ namespace FancyZonesEditor.Models
{ {
Uuid = "{" + Guid.ToString().ToUpper() + "}", Uuid = "{" + Guid.ToString().ToUpper() + "}",
Name = Name, Name = Name,
Type = "grid", Type = ModelTypeID,
Info = layoutInfo, Info = layoutInfo,
}; };
JsonSerializerOptions options = new JsonSerializerOptions JsonSerializerOptions options = new JsonSerializerOptions
@ -235,7 +241,7 @@ namespace FancyZonesEditor.Models
} }
catch (Exception ex) catch (Exception ex)
{ {
ShowExceptionMessageBox("Error persisting grid layout", ex); ShowExceptionMessageBox(ErrorPersistingGridLayout, ex);
} }
} }
} }

View File

@ -61,9 +61,11 @@ namespace FancyZonesEditor.Models
private const string PriorityGridJsonTag = "priority-grid"; private const string PriorityGridJsonTag = "priority-grid";
private const string CustomJsonTag = "custom"; private const string CustomJsonTag = "custom";
private const string PowerToysIssuesLink = "https://aka.ms/powerToysReportBug";
public static void ShowExceptionMessageBox(string message, Exception exception = null) public static void ShowExceptionMessageBox(string message, Exception exception = null)
{ {
string fullMessage = ErrorMessageBoxMessage + "https://aka.ms/powerToysReportBug \n" + message; string fullMessage = ErrorMessageBoxMessage + PowerToysIssuesLink + " \n" + message;
if (exception != null) if (exception != null)
{ {
fullMessage += ": " + exception.Message; fullMessage += ": " + exception.Message;

View File

@ -60,9 +60,19 @@ namespace FancyZonesEditor
private const string ErrorInvalidArgs = "FancyZones Editor arguments are invalid."; private const string ErrorInvalidArgs = "FancyZones Editor arguments are invalid.";
private const string ErrorNonStandaloneApp = "FancyZones Editor should not be run as standalone application."; private const string ErrorNonStandaloneApp = "FancyZones Editor should not be run as standalone application.";
// Non-localizable strings // Displayed layout names are localizable strings, but their underlying json tags are not.
private const string ZonesSettingsFile = "\\Microsoft\\PowerToys\\FancyZones\\zones-settings.json"; private const string FocusLayoutID = "Focus";
private const string ColumnsLayoutID = "Columns";
private const string RowsLayoutID = "Rows";
private const string GridLayoutID = "Grid";
private const string PriorityGridLayoutID = "Priority Grid";
private const string CreateNewCustomLabel = "Create new custom";
// Non-localizable strings
public static readonly string RegistryPath = "SOFTWARE\\SuperFancyZones";
public static readonly string FullRegistryPath = "HKEY_CURRENT_USER\\" + RegistryPath;
private const string ZonesSettingsFile = "\\Microsoft\\PowerToys\\FancyZones\\zones-settings.json";
private const string ActiveZoneSetsTmpFileName = "FancyZonesActiveZoneSets.json"; private const string ActiveZoneSetsTmpFileName = "FancyZonesActiveZoneSets.json";
private const string AppliedZoneSetsTmpFileName = "FancyZonesAppliedZoneSets.json"; private const string AppliedZoneSetsTmpFileName = "FancyZonesAppliedZoneSets.json";
private const string DeletedCustomZoneSetsTmpFileName = "FancyZonesDeletedCustomZoneSets.json"; private const string DeletedCustomZoneSetsTmpFileName = "FancyZonesDeletedCustomZoneSets.json";
@ -79,6 +89,15 @@ namespace FancyZonesEditor
private const string EditorSpacingJsonTag = "editor-spacing"; private const string EditorSpacingJsonTag = "editor-spacing";
private const string EditorZoneCountJsonTag = "editor-zone-count"; private const string EditorZoneCountJsonTag = "editor-zone-count";
private const string FocusJsonTag = "focus";
private const string ColumnsJsonTag = "columns";
private const string RowsJsonTag = "rows";
private const string GridJsonTag = "grid";
private const string PriorityGridJsonTag = "priority-grid";
private const string CustomJsonTag = "custom";
private const string DebugMode = "Debug";
// hard coded data for all the "Priority Grid" configurations that are unique to "Grid" // hard coded data for all the "Priority Grid" configurations that are unique to "Grid"
private static readonly byte[][] _priorityData = new byte[][] private static readonly byte[][] _priorityData = new byte[][]
{ {
@ -128,30 +147,30 @@ namespace FancyZonesEditor
// Initialize the five default layout models: Focus, Columns, Rows, Grid, and PriorityGrid // Initialize the five default layout models: Focus, Columns, Rows, Grid, and PriorityGrid
DefaultModels = new List<LayoutModel>(5); DefaultModels = new List<LayoutModel>(5);
_focusModel = new CanvasLayoutModel("Focus", LayoutType.Focus); _focusModel = new CanvasLayoutModel(FocusLayoutID, LayoutType.Focus);
DefaultModels.Add(_focusModel); DefaultModels.Add(_focusModel);
_columnsModel = new GridLayoutModel("Columns", LayoutType.Columns) _columnsModel = new GridLayoutModel(ColumnsLayoutID, LayoutType.Columns)
{ {
Rows = 1, Rows = 1,
RowPercents = new List<int>(1) { _multiplier }, RowPercents = new List<int>(1) { _multiplier },
}; };
DefaultModels.Add(_columnsModel); DefaultModels.Add(_columnsModel);
_rowsModel = new GridLayoutModel("Rows", LayoutType.Rows) _rowsModel = new GridLayoutModel(RowsLayoutID, LayoutType.Rows)
{ {
Columns = 1, Columns = 1,
ColumnPercents = new List<int>(1) { _multiplier }, ColumnPercents = new List<int>(1) { _multiplier },
}; };
DefaultModels.Add(_rowsModel); DefaultModels.Add(_rowsModel);
_gridModel = new GridLayoutModel("Grid", LayoutType.Grid); _gridModel = new GridLayoutModel(GridLayoutID, LayoutType.Grid);
DefaultModels.Add(_gridModel); DefaultModels.Add(_gridModel);
_priorityGridModel = new GridLayoutModel("Priority Grid", LayoutType.PriorityGrid); _priorityGridModel = new GridLayoutModel(PriorityGridLayoutID, LayoutType.PriorityGrid);
DefaultModels.Add(_priorityGridModel); DefaultModels.Add(_priorityGridModel);
_blankCustomModel = new CanvasLayoutModel("Create new custom", LayoutType.Blank); _blankCustomModel = new CanvasLayoutModel(CreateNewCustomLabel, LayoutType.Blank);
UpdateLayoutModels(); UpdateLayoutModels();
} }
@ -421,22 +440,22 @@ namespace FancyZonesEditor
{ {
switch (layoutType) switch (layoutType)
{ {
case "focus": case FocusJsonTag:
ActiveZoneSetLayoutType = LayoutType.Focus; ActiveZoneSetLayoutType = LayoutType.Focus;
break; break;
case "columns": case ColumnsJsonTag:
ActiveZoneSetLayoutType = LayoutType.Columns; ActiveZoneSetLayoutType = LayoutType.Columns;
break; break;
case "rows": case RowsJsonTag:
ActiveZoneSetLayoutType = LayoutType.Rows; ActiveZoneSetLayoutType = LayoutType.Rows;
break; break;
case "grid": case GridJsonTag:
ActiveZoneSetLayoutType = LayoutType.Grid; ActiveZoneSetLayoutType = LayoutType.Grid;
break; break;
case "priority-grid": case PriorityGridJsonTag:
ActiveZoneSetLayoutType = LayoutType.PriorityGrid; ActiveZoneSetLayoutType = LayoutType.PriorityGrid;
break; break;
case "custom": case CustomJsonTag:
ActiveZoneSetLayoutType = LayoutType.Custom; ActiveZoneSetLayoutType = LayoutType.Custom;
break; break;
} }
@ -461,7 +480,7 @@ namespace FancyZonesEditor
if (args.Length == 2) if (args.Length == 2)
{ {
if (args[1].Equals("Debug")) if (args[1].Equals(DebugMode))
{ {
ParseDeviceInfoData(ParseDeviceMode.Debug); ParseDeviceInfoData(ParseDeviceMode.Debug);
} }
@ -529,9 +548,6 @@ namespace FancyZonesEditor
private static ObservableCollection<LayoutModel> _customModels; private static ObservableCollection<LayoutModel> _customModels;
public static readonly string RegistryPath = "SOFTWARE\\SuperFancyZones";
public static readonly string FullRegistryPath = "HKEY_CURRENT_USER\\" + RegistryPath;
public static bool IsPredefinedLayout(LayoutModel model) public static bool IsPredefinedLayout(LayoutModel model)
{ {
return model.Type != LayoutType.Custom; return model.Type != LayoutType.Custom;

View File

@ -32,6 +32,14 @@ namespace
constexpr int CUSTOM_POSITIONING_LEFT_TOP_PADDING = 16; constexpr int CUSTOM_POSITIONING_LEFT_TOP_PADDING = 16;
} }
// Non-localizable strings
namespace NonLocalizable
{
const wchar_t ToolWindowClassName[] = L"SuperFancyZones";
const wchar_t FZEditorExecutablePath[] = L"modules\\FancyZones\\FancyZonesEditor.exe";
const wchar_t SplashClassName[] = L"MsoSplash";
}
struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZonesCallback, IZoneWindowHost> struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZonesCallback, IZoneWindowHost>
{ {
public: public:
@ -301,14 +309,16 @@ FancyZones::Run() noexcept
wcex.cbSize = sizeof(WNDCLASSEX); wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpfnWndProc = s_WndProc; wcex.lpfnWndProc = s_WndProc;
wcex.hInstance = m_hinstance; wcex.hInstance = m_hinstance;
wcex.lpszClassName = L"SuperFancyZones"; wcex.lpszClassName = NonLocalizable::ToolWindowClassName;
RegisterClassExW(&wcex); RegisterClassExW(&wcex);
BufferedPaintInit(); BufferedPaintInit();
m_window = CreateWindowExW(WS_EX_TOOLWINDOW, L"SuperFancyZones", L"", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, m_hinstance, this); m_window = CreateWindowExW(WS_EX_TOOLWINDOW, NonLocalizable::ToolWindowClassName, L"", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, m_hinstance, this);
if (!m_window) if (!m_window)
{
return; return;
}
RegisterHotKey(m_window, 1, m_settings->GetSettings()->editorHotkey.get_modifiers(), m_settings->GetSettings()->editorHotkey.get_code()); RegisterHotKey(m_window, 1, m_settings->GetSettings()->editorHotkey.get_modifiers(), m_settings->GetSettings()->editorHotkey.get_code());
@ -363,7 +373,7 @@ bool FancyZones::ShouldProcessNewWindow(HWND window) noexcept
// Avoid processing splash screens, already stamped (zoned) windows, or those windows // Avoid processing splash screens, already stamped (zoned) windows, or those windows
// that belong to excluded applications list. // that belong to excluded applications list.
if (IsSplashScreen(window) || if (IsSplashScreen(window) ||
(reinterpret_cast<size_t>(::GetProp(window, MULTI_ZONE_STAMP)) != 0) || (reinterpret_cast<size_t>(::GetProp(window, ZonedWindowProperties::PropertyMultipleZoneID)) != 0) ||
!IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray)) !IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray))
{ {
return false; return false;
@ -715,7 +725,7 @@ void FancyZones::ToggleEditor() noexcept
SHELLEXECUTEINFO sei{ sizeof(sei) }; SHELLEXECUTEINFO sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI }; sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = L"modules\\FancyZones\\FancyZonesEditor.exe"; sei.lpFile = NonLocalizable::FZEditorExecutablePath;
sei.lpParameters = params.c_str(); sei.lpParameters = params.c_str();
sei.nShow = SW_SHOWNORMAL; sei.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sei); ShellExecuteEx(&sei);
@ -1016,7 +1026,7 @@ void FancyZones::UpdateZoneWindows() noexcept
void FancyZones::UpdateWindowsPositions() noexcept void FancyZones::UpdateWindowsPositions() noexcept
{ {
auto callback = [](HWND window, LPARAM data) -> BOOL { auto callback = [](HWND window, LPARAM data) -> BOOL {
size_t bitmask = reinterpret_cast<size_t>(::GetProp(window, MULTI_ZONE_STAMP)); size_t bitmask = reinterpret_cast<size_t>(::GetProp(window, ZonedWindowProperties::PropertyMultipleZoneID));
if (bitmask != 0) if (bitmask != 0)
{ {
@ -1145,14 +1155,13 @@ void FancyZones::RegisterVirtualDesktopUpdates(std::vector<GUID>& ids) noexcept
bool FancyZones::IsSplashScreen(HWND window) bool FancyZones::IsSplashScreen(HWND window)
{ {
wchar_t splashClassName[] = L"MsoSplash"; // shouldn't be localized
wchar_t className[MAX_PATH]; wchar_t className[MAX_PATH];
if (GetClassName(window, className, MAX_PATH) == 0) if (GetClassName(window, className, MAX_PATH) == 0)
{ {
return false; return false;
} }
return wcscmp(splashClassName, className) == 0; return wcscmp(NonLocalizable::SplashClassName, className) == 0;
} }
void FancyZones::OnEditorExitEvent() noexcept void FancyZones::OnEditorExitEvent() noexcept

View File

@ -22,19 +22,19 @@ namespace NonLocalizable
const wchar_t FancyZonesStr[] = L"FancyZones"; const wchar_t FancyZonesStr[] = L"FancyZones";
const wchar_t LayoutsStr[] = L"Layouts"; const wchar_t LayoutsStr[] = L"Layouts";
const wchar_t NullStr[] = L"null"; const wchar_t NullStr[] = L"null";
}
namespace const wchar_t FancyZonesDataFile[] = L"zones-settings.json";
{ const wchar_t FancyZonesAppZoneHistoryFile[] = L"app-zone-history.json";
const wchar_t* FANCY_ZONES_DATA_FILE = L"zones-settings.json"; const wchar_t DefaultGuid[] = L"{00000000-0000-0000-0000-000000000000}";
const wchar_t* FANCY_ZONES_APP_ZONE_HISTORY_FILE = L"app-zone-history.json"; const wchar_t RegistryPath[] = L"Software\\SuperFancyZones";
const wchar_t* DEFAULT_GUID = L"{00000000-0000-0000-0000-000000000000}";
const wchar_t* REG_SETTINGS = L"Software\\SuperFancyZones";
const wchar_t ActiveZoneSetsTmpFileName[] = L"FancyZonesActiveZoneSets.json"; const wchar_t ActiveZoneSetsTmpFileName[] = L"FancyZonesActiveZoneSets.json";
const wchar_t AppliedZoneSetsTmpFileName[] = L"FancyZonesAppliedZoneSets.json"; const wchar_t AppliedZoneSetsTmpFileName[] = L"FancyZonesAppliedZoneSets.json";
const wchar_t DeletedCustomZoneSetsTmpFileName[] = L"FancyZonesDeletedCustomZoneSets.json"; const wchar_t DeletedCustomZoneSetsTmpFileName[] = L"FancyZonesDeletedCustomZoneSets.json";
}
namespace
{
std::wstring ExtractVirtualDesktopId(const std::wstring& deviceId) std::wstring ExtractVirtualDesktopId(const std::wstring& deviceId)
{ {
// Format: <device-id>_<resolution>_<virtual-desktop-id> // Format: <device-id>_<resolution>_<virtual-desktop-id>
@ -71,12 +71,12 @@ FancyZonesData& FancyZonesDataInstance()
FancyZonesData::FancyZonesData() FancyZonesData::FancyZonesData()
{ {
std::wstring saveFolderPath = PTSettingsHelper::get_module_save_folder_location(NonLocalizable::FancyZonesStr); std::wstring saveFolderPath = PTSettingsHelper::get_module_save_folder_location(NonLocalizable::FancyZonesStr);
zonesSettingsFileName = saveFolderPath + L"\\" + std::wstring(FANCY_ZONES_DATA_FILE); zonesSettingsFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesDataFile);
appZoneHistoryFileName = saveFolderPath + L"\\" + std::wstring(FANCY_ZONES_APP_ZONE_HISTORY_FILE); appZoneHistoryFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesAppZoneHistoryFile);
activeZoneSetTmpFileName = GetTempDirPath() + ActiveZoneSetsTmpFileName; activeZoneSetTmpFileName = GetTempDirPath() + NonLocalizable::ActiveZoneSetsTmpFileName;
appliedZoneSetTmpFileName = GetTempDirPath() + AppliedZoneSetsTmpFileName; appliedZoneSetTmpFileName = GetTempDirPath() + NonLocalizable::AppliedZoneSetsTmpFileName;
deletedCustomZoneSetsTmpFileName = GetTempDirPath() + DeletedCustomZoneSetsTmpFileName; deletedCustomZoneSetsTmpFileName = GetTempDirPath() + NonLocalizable::DeletedCustomZoneSetsTmpFileName;
} }
std::optional<FancyZonesDataTypes::DeviceInfoData> FancyZonesData::FindDeviceInfo(const std::wstring& zoneWindowId) const std::optional<FancyZonesDataTypes::DeviceInfoData> FancyZonesData::FindDeviceInfo(const std::wstring& zoneWindowId) const
@ -141,7 +141,7 @@ void FancyZonesData::UpdatePrimaryDesktopData(const std::wstring& desktopId)
{ {
for (auto& data : perDesktopData) for (auto& data : perDesktopData)
{ {
if (ExtractVirtualDesktopId(data.deviceId) == DEFAULT_GUID) if (ExtractVirtualDesktopId(data.deviceId) == NonLocalizable::DefaultGuid)
{ {
data.deviceId = replaceDesktopId(data.deviceId); data.deviceId = replaceDesktopId(data.deviceId);
} }
@ -150,7 +150,7 @@ void FancyZonesData::UpdatePrimaryDesktopData(const std::wstring& desktopId)
std::vector<std::wstring> toReplace{}; std::vector<std::wstring> toReplace{};
for (const auto& [id, data] : deviceInfoMap) for (const auto& [id, data] : deviceInfoMap)
{ {
if (ExtractVirtualDesktopId(id) == DEFAULT_GUID) if (ExtractVirtualDesktopId(id) == NonLocalizable::DefaultGuid)
{ {
toReplace.push_back(id); toReplace.push_back(id);
} }
@ -290,10 +290,10 @@ bool FancyZonesData::RemoveAppLastZone(HWND window, const std::wstring_view& dev
} }
// if there is another instance of same application placed in the same zone don't erase history // if there is another instance of same application placed in the same zone don't erase history
size_t windowZoneStamp = reinterpret_cast<size_t>(::GetProp(window, MULTI_ZONE_STAMP)); size_t windowZoneStamp = reinterpret_cast<size_t>(::GetProp(window, ZonedWindowProperties::PropertyMultipleZoneID));
for (auto placedWindow : data->processIdToHandleMap) for (auto placedWindow : data->processIdToHandleMap)
{ {
size_t placedWindowZoneStamp = reinterpret_cast<size_t>(::GetProp(placedWindow.second, MULTI_ZONE_STAMP)); size_t placedWindowZoneStamp = reinterpret_cast<size_t>(::GetProp(placedWindow.second, ZonedWindowProperties::PropertyMultipleZoneID));
if (IsWindow(placedWindow.second) && (windowZoneStamp == placedWindowZoneStamp)) if (IsWindow(placedWindow.second) && (windowZoneStamp == placedWindowZoneStamp))
{ {
return false; return false;
@ -477,7 +477,7 @@ void FancyZonesData::MigrateCustomZoneSetsFromRegistry()
{ {
std::scoped_lock lock{ dataLock }; std::scoped_lock lock{ dataLock };
wchar_t key[256]; wchar_t key[256];
StringCchPrintf(key, ARRAYSIZE(key), L"%s\\%s", REG_SETTINGS, NonLocalizable::LayoutsStr); StringCchPrintf(key, ARRAYSIZE(key), L"%s\\%s", NonLocalizable::RegistryPath, NonLocalizable::LayoutsStr);
HKEY hkey; HKEY hkey;
if (RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) if (RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS)
{ {

View File

@ -4,6 +4,37 @@
#include "lib/FancyZones.h" #include "lib/FancyZones.h"
#include "trace.h" #include "trace.h"
// Non-Localizable strings
namespace NonLocalizable
{
// FancyZones settings descriptions are localized, but underlying toggle (spinner, color picker) names are not.
const wchar_t ShiftDragID[] = L"fancyzones_shiftDrag";
const wchar_t MouseSwitchID[] = L"fancyzones_mouseSwitch";
const wchar_t OverrideSnapHotKeysID[] = L"fancyzones_overrideSnapHotkeys";
const wchar_t MoveWindowAcrossMonitorsID[] = L"fancyzones_moveWindowAcrossMonitors";
const wchar_t DisplayChangeMoveWindowsID[] = L"fancyzones_displayChange_moveWindows";
const wchar_t ZoneSetChangeMoveWindowsID[] = L"fancyzones_zoneSetChange_moveWindows";
const wchar_t AppLastZoneMoveWindowsID[] = L"fancyzones_appLastZone_moveWindows";
const wchar_t OpenWindowOnActiveMonitorID[] = L"fancyzones_openWindowOnActiveMonitor";
const wchar_t RestoreSizeID[] = L"fancyzones_restoreSize";
const wchar_t UseCursorPosEditorStartupScreenID[] = L"use_cursorpos_editor_startupscreen";
const wchar_t ShowOnAllMonitorsID[] = L"fancyzones_show_on_all_monitors";
const wchar_t SpanZonesAcrossMonitorsID[] = L"fancyzones_span_zones_across_monitors";
const wchar_t MakeDraggedWindowTransparentID[] = L"fancyzones_makeDraggedWindowTransparent";
const wchar_t ZoneColorID[] = L"fancyzones_zoneColor";
const wchar_t ZoneBorderColorID[] = L"fancyzones_zoneBorderColor";
const wchar_t ZoneHighlightColorID[] = L"fancyzones_zoneHighlightColor";
const wchar_t EditorHotkeyID[] = L"fancyzones_editor_hotkey";
const wchar_t ExcludedAppsID[] = L"fancyzones_excluded_apps";
const wchar_t ZoneHighlightOpacityID[] = L"fancyzones_highlight_opacity";
const wchar_t ToggleEditorActionID[] = L"ToggledFZEditor";
const wchar_t IconKeyID[] = L"pt-fancy-zones";
const wchar_t OverviewURL[] = L"https://aka.ms/PowerToysOverview_FancyZones";
const wchar_t VideoURL[] = L"https://youtu.be/rTtGzZYAXgY";
}
struct FancyZonesSettings : winrt::implements<FancyZonesSettings, IFancyZonesSettings> struct FancyZonesSettings : winrt::implements<FancyZonesSettings, IFancyZonesSettings>
{ {
public: public:
@ -37,29 +68,23 @@ private:
bool* value; bool* value;
int resourceId; int resourceId;
} m_configBools[13 /* 14 */] = { // "Turning FLASHING_ZONE option off" } m_configBools[13 /* 14 */] = { // "Turning FLASHING_ZONE option off"
{ L"fancyzones_shiftDrag", &m_settings.shiftDrag, IDS_SETTING_DESCRIPTION_SHIFTDRAG }, { NonLocalizable::ShiftDragID, &m_settings.shiftDrag, IDS_SETTING_DESCRIPTION_SHIFTDRAG },
{ L"fancyzones_mouseSwitch", &m_settings.mouseSwitch, IDS_SETTING_DESCRIPTION_MOUSESWITCH }, { NonLocalizable::MouseSwitchID, &m_settings.mouseSwitch, IDS_SETTING_DESCRIPTION_MOUSESWITCH },
{ L"fancyzones_overrideSnapHotkeys", &m_settings.overrideSnapHotkeys, IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS }, { NonLocalizable::OverrideSnapHotKeysID, &m_settings.overrideSnapHotkeys, IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS },
{ L"fancyzones_moveWindowAcrossMonitors", &m_settings.moveWindowAcrossMonitors, IDS_SETTING_DESCRIPTION_MOVE_WINDOW_ACROSS_MONITORS }, { NonLocalizable::MoveWindowAcrossMonitorsID, &m_settings.moveWindowAcrossMonitors, IDS_SETTING_DESCRIPTION_MOVE_WINDOW_ACROSS_MONITORS },
// "Turning FLASHING_ZONE option off" // "Turning FLASHING_ZONE option off"
//{ L"fancyzones_zoneSetChange_flashZones", &m_settings.zoneSetChange_flashZones, IDS_SETTING_DESCRIPTION_ZONESETCHANGE_FLASHZONES }, //{ L"fancyzones_zoneSetChange_flashZones", &m_settings.zoneSetChange_flashZones, IDS_SETTING_DESCRIPTION_ZONESETCHANGE_FLASHZONES },
{ L"fancyzones_displayChange_moveWindows", &m_settings.displayChange_moveWindows, IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS }, { NonLocalizable::DisplayChangeMoveWindowsID, &m_settings.displayChange_moveWindows, IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS },
{ L"fancyzones_zoneSetChange_moveWindows", &m_settings.zoneSetChange_moveWindows, IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS }, { NonLocalizable::ZoneSetChangeMoveWindowsID, &m_settings.zoneSetChange_moveWindows, IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS },
{ L"fancyzones_appLastZone_moveWindows", &m_settings.appLastZone_moveWindows, IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS }, { NonLocalizable::AppLastZoneMoveWindowsID, &m_settings.appLastZone_moveWindows, IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS },
{ L"fancyzones_openWindowOnActiveMonitor", &m_settings.openWindowOnActiveMonitor, IDS_SETTING_DESCRIPTION_OPEN_WINDOW_ON_ACTIVE_MONITOR }, { NonLocalizable::OpenWindowOnActiveMonitorID, &m_settings.openWindowOnActiveMonitor, IDS_SETTING_DESCRIPTION_OPEN_WINDOW_ON_ACTIVE_MONITOR },
{ L"fancyzones_restoreSize", &m_settings.restoreSize, IDS_SETTING_DESCRIPTION_RESTORESIZE }, { NonLocalizable::RestoreSizeID, &m_settings.restoreSize, IDS_SETTING_DESCRIPTION_RESTORESIZE },
{ L"use_cursorpos_editor_startupscreen", &m_settings.use_cursorpos_editor_startupscreen, IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN }, { NonLocalizable::UseCursorPosEditorStartupScreenID, &m_settings.use_cursorpos_editor_startupscreen, IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN },
{ L"fancyzones_show_on_all_monitors", &m_settings.showZonesOnAllMonitors, IDS_SETTING_DESCRIPTION_SHOW_FANCY_ZONES_ON_ALL_MONITORS }, { NonLocalizable::ShowOnAllMonitorsID, &m_settings.showZonesOnAllMonitors, IDS_SETTING_DESCRIPTION_SHOW_FANCY_ZONES_ON_ALL_MONITORS},
{ L"fancyzones_span_zones_across_monitors", &m_settings.spanZonesAcrossMonitors, IDS_SETTING_DESCRIPTION_SPAN_ZONES_ACROSS_MONITORS }, { NonLocalizable::SpanZonesAcrossMonitorsID, &m_settings.spanZonesAcrossMonitors, IDS_SETTING_DESCRIPTION_SPAN_ZONES_ACROSS_MONITORS },
{ L"fancyzones_makeDraggedWindowTransparent", &m_settings.makeDraggedWindowTransparent, IDS_SETTING_DESCRIPTION_MAKE_DRAGGED_WINDOW_TRANSPARENT }, { NonLocalizable::MakeDraggedWindowTransparentID, &m_settings.makeDraggedWindowTransparent, IDS_SETTING_DESCRIPTION_MAKE_DRAGGED_WINDOW_TRANSPARENT},
}; };
const std::wstring m_zoneColorName = L"fancyzones_zoneColor";
const std::wstring m_zoneBorderColorName = L"fancyzones_zoneBorderColor";
const std::wstring m_zoneHighlightName = L"fancyzones_zoneHighlightColor";
const std::wstring m_editorHotkeyName = L"fancyzones_editor_hotkey";
const std::wstring m_excludedAppsName = L"fancyzones_excluded_apps";
const std::wstring m_zoneHighlightOpacity = L"fancyzones_highlight_opacity";
}; };
IFACEMETHODIMP_(bool) FancyZonesSettings::GetConfig(_Out_ PWSTR buffer, _Out_ int *buffer_size) noexcept IFACEMETHODIMP_(bool) FancyZonesSettings::GetConfig(_Out_ PWSTR buffer, _Out_ int *buffer_size) noexcept
@ -68,32 +93,32 @@ IFACEMETHODIMP_(bool) FancyZonesSettings::GetConfig(_Out_ PWSTR buffer, _Out_ in
// Pass a string literal or a resource id to Settings::set_description(). // Pass a string literal or a resource id to Settings::set_description().
settings.set_description(IDS_SETTING_DESCRIPTION); settings.set_description(IDS_SETTING_DESCRIPTION);
settings.set_icon_key(L"pt-fancy-zones"); settings.set_icon_key(NonLocalizable::IconKeyID);
settings.set_overview_link(L"https://aka.ms/PowerToysOverview_FancyZones"); settings.set_overview_link(NonLocalizable::OverviewURL);
settings.set_video_link(L"https://youtu.be/rTtGzZYAXgY"); settings.set_video_link(NonLocalizable::VideoURL);
// Add a custom action property. When using this settings type, the "PowertoyModuleIface::call_custom_action()" // Add a custom action property. When using this settings type, the "PowertoyModuleIface::call_custom_action()"
// method should be overridden as well. // method should be overridden as well.
settings.add_custom_action( settings.add_custom_action(
L"ToggledFZEditor", // action name. NonLocalizable::ToggleEditorActionID, // action name.
IDS_SETTING_LAUNCH_EDITOR_LABEL, IDS_SETTING_LAUNCH_EDITOR_LABEL,
IDS_SETTING_LAUNCH_EDITOR_BUTTON, IDS_SETTING_LAUNCH_EDITOR_BUTTON,
IDS_SETTING_LAUNCH_EDITOR_DESCRIPTION IDS_SETTING_LAUNCH_EDITOR_DESCRIPTION
); );
settings.add_hotkey(m_editorHotkeyName, IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL, m_settings.editorHotkey); settings.add_hotkey(NonLocalizable::EditorHotkeyID, IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL, m_settings.editorHotkey);
for (auto const& setting : m_configBools) for (auto const& setting : m_configBools)
{ {
settings.add_bool_toggle(setting.name, setting.resourceId, *setting.value); settings.add_bool_toggle(setting.name, setting.resourceId, *setting.value);
} }
settings.add_color_picker(m_zoneHighlightName, IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, m_settings.zoneHighlightColor); settings.add_color_picker(NonLocalizable::ZoneHighlightColorID, IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, m_settings.zoneHighlightColor);
settings.add_color_picker(m_zoneColorName, IDS_SETTING_DESCRIPTION_ZONECOLOR, m_settings.zoneColor); settings.add_color_picker(NonLocalizable::ZoneColorID, IDS_SETTING_DESCRIPTION_ZONECOLOR, m_settings.zoneColor);
settings.add_color_picker(m_zoneBorderColorName, IDS_SETTING_DESCRIPTION_ZONE_BORDER_COLOR, m_settings.zoneBorderColor); settings.add_color_picker(NonLocalizable::ZoneBorderColorID, IDS_SETTING_DESCRIPTION_ZONE_BORDER_COLOR, m_settings.zoneBorderColor);
settings.add_int_spinner(m_zoneHighlightOpacity, IDS_SETTINGS_HIGHLIGHT_OPACITY, m_settings.zoneHighlightOpacity, 0, 100, 1); settings.add_int_spinner(NonLocalizable::ZoneHighlightOpacityID, IDS_SETTINGS_HIGHLIGHT_OPACITY, m_settings.zoneHighlightOpacity, 0, 100, 1);
settings.add_multiline_string(m_excludedAppsName, IDS_SETTING_EXCLUDED_APPS_DESCRIPTION, m_settings.excludedApps); settings.add_multiline_string(NonLocalizable::ExcludedAppsID, IDS_SETTING_EXCLUDED_APPS_DESCRIPTION, m_settings.excludedApps);
return settings.serialize_to_buffer(buffer, buffer_size); return settings.serialize_to_buffer(buffer, buffer_size);
} }
@ -116,7 +141,7 @@ IFACEMETHODIMP_(void) FancyZonesSettings::CallCustomAction(PCWSTR action) noexce
PowerToysSettings::CustomActionObject action_object = PowerToysSettings::CustomActionObject action_object =
PowerToysSettings::CustomActionObject::from_json_string(action); PowerToysSettings::CustomActionObject::from_json_string(action);
if (m_callback && action_object.get_name() == L"ToggledFZEditor") if (m_callback && action_object.get_name() == NonLocalizable::ToggleEditorActionID)
{ {
m_callback->ToggleEditor(); m_callback->ToggleEditor();
} }
@ -137,27 +162,27 @@ void FancyZonesSettings::LoadSettings(PCWSTR config, bool fromFile) noexcept try
} }
} }
if (auto val = values.get_string_value(m_zoneColorName)) if (auto val = values.get_string_value(NonLocalizable::ZoneColorID))
{ {
m_settings.zoneColor = std::move(*val); m_settings.zoneColor = std::move(*val);
} }
if (auto val = values.get_string_value(m_zoneBorderColorName)) if (auto val = values.get_string_value(NonLocalizable::ZoneBorderColorID))
{ {
m_settings.zoneBorderColor = std::move(*val); m_settings.zoneBorderColor = std::move(*val);
} }
if (auto val = values.get_string_value(m_zoneHighlightName)) if (auto val = values.get_string_value(NonLocalizable::ZoneHighlightColorID))
{ {
m_settings.zoneHighlightColor = std::move(*val); m_settings.zoneHighlightColor = std::move(*val);
} }
if (const auto val = values.get_json(m_editorHotkeyName)) if (const auto val = values.get_json(NonLocalizable::EditorHotkeyID))
{ {
m_settings.editorHotkey = PowerToysSettings::HotkeyObject::from_json(*val); m_settings.editorHotkey = PowerToysSettings::HotkeyObject::from_json(*val);
} }
if (auto val = values.get_string_value(m_excludedAppsName)) if (auto val = values.get_string_value(NonLocalizable::ExcludedAppsID))
{ {
m_settings.excludedApps = std::move(*val); m_settings.excludedApps = std::move(*val);
m_settings.excludedAppsArray.clear(); m_settings.excludedAppsArray.clear();
@ -180,7 +205,7 @@ void FancyZonesSettings::LoadSettings(PCWSTR config, bool fromFile) noexcept try
} }
} }
if (auto val = values.get_int_value(m_zoneHighlightOpacity)) if (auto val = values.get_int_value(NonLocalizable::ZoneHighlightOpacityID))
{ {
m_settings.zoneHighlightOpacity = *val; m_settings.zoneHighlightOpacity = *val;
} }
@ -196,12 +221,12 @@ void FancyZonesSettings::SaveSettings() noexcept try
values.add_property(setting.name, *setting.value); values.add_property(setting.name, *setting.value);
} }
values.add_property(m_zoneColorName, m_settings.zoneColor); values.add_property(NonLocalizable::ZoneColorID, m_settings.zoneColor);
values.add_property(m_zoneBorderColorName, m_settings.zoneBorderColor); values.add_property(NonLocalizable::ZoneBorderColorID, m_settings.zoneBorderColor);
values.add_property(m_zoneHighlightName, m_settings.zoneHighlightColor); values.add_property(NonLocalizable::ZoneHighlightColorID, m_settings.zoneHighlightColor);
values.add_property(m_zoneHighlightOpacity, m_settings.zoneHighlightOpacity); values.add_property(NonLocalizable::ZoneHighlightOpacityID, m_settings.zoneHighlightOpacity);
values.add_property(m_editorHotkeyName, m_settings.editorHotkey.get_json()); values.add_property(NonLocalizable::EditorHotkeyID, m_settings.editorHotkey.get_json());
values.add_property(m_excludedAppsName, m_settings.excludedApps); values.add_property(NonLocalizable::ExcludedAppsID, m_settings.excludedApps);
values.save_to_settings_file(); values.save_to_settings_file();
} }

View File

@ -1,11 +1,17 @@
#pragma once #pragma once
#define MULTI_ZONE_STAMP L"FancyZones_zones"
#define RESTORE_SIZE_STAMP L"FancyZones_RestoreSize"
#define RESTORE_ORIGIN_STAMP L"FancyZones_RestoreOrigin"
#define MULTI_MONITOR_MODE_DEVICE L"FancyZonesMultiMonitorDevice"
#include <common/settings_objects.h> #include <common/settings_objects.h>
// Zoned window properties are not localized.
namespace ZonedWindowProperties
{
const wchar_t PropertyMultipleZoneID[] = L"FancyZones_zones";
const wchar_t PropertyRestoreSizeID[] = L"FancyZones_RestoreSize";
const wchar_t PropertyRestoreOriginID[] = L"FancyZones_RestoreOrigin";
const wchar_t MultiMonitorDeviceID[] = L"FancyZones_MultiMonitorDevice";
}
struct Settings struct Settings
{ {
// The values specified here are the defaults. // The values specified here are the defaults.

View File

@ -2,13 +2,17 @@
#include "VirtualDesktopUtils.h" #include "VirtualDesktopUtils.h"
namespace VirtualDesktopUtils // Non-Localizable strings
namespace NonLocalizable
{ {
const CLSID CLSID_ImmersiveShell = { 0xC2F03A33, 0x21F5, 0x47FA, 0xB4, 0xBB, 0x15, 0x63, 0x62, 0xA2, 0xF2, 0x39 };
const wchar_t RegCurrentVirtualDesktop[] = L"CurrentVirtualDesktop"; const wchar_t RegCurrentVirtualDesktop[] = L"CurrentVirtualDesktop";
const wchar_t RegVirtualDesktopIds[] = L"VirtualDesktopIDs"; const wchar_t RegVirtualDesktopIds[] = L"VirtualDesktopIDs";
const wchar_t RegKeyVirtualDesktops[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\VirtualDesktops"; const wchar_t RegKeyVirtualDesktops[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\VirtualDesktops";
}
namespace VirtualDesktopUtils
{
const CLSID CLSID_ImmersiveShell = { 0xC2F03A33, 0x21F5, 0x47FA, 0xB4, 0xBB, 0x15, 0x63, 0x62, 0xA2, 0xF2, 0x39 };
IServiceProvider* GetServiceProvider() IServiceProvider* GetServiceProvider()
{ {
@ -64,7 +68,7 @@ namespace VirtualDesktopUtils
if (RegOpenKeyExW(HKEY_CURRENT_USER, sessionKeyPath, 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS) if (RegOpenKeyExW(HKEY_CURRENT_USER, sessionKeyPath, 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
{ {
DWORD size = sizeof(GUID); DWORD size = sizeof(GUID);
if (RegQueryValueExW(key.get(), RegCurrentVirtualDesktop, 0, nullptr, reinterpret_cast<BYTE*>(&value), &size) == ERROR_SUCCESS) if (RegQueryValueExW(key.get(), NonLocalizable::RegCurrentVirtualDesktop, 0, nullptr, reinterpret_cast<BYTE*>(&value), &size) == ERROR_SUCCESS)
{ {
*desktopId = value; *desktopId = value;
return true; return true;
@ -99,13 +103,13 @@ namespace VirtualDesktopUtils
} }
DWORD bufferCapacity; DWORD bufferCapacity;
// request regkey binary buffer capacity only // request regkey binary buffer capacity only
if (RegQueryValueExW(hKey, RegVirtualDesktopIds, 0, nullptr, nullptr, &bufferCapacity) != ERROR_SUCCESS) if (RegQueryValueExW(hKey, NonLocalizable::RegVirtualDesktopIds, 0, nullptr, nullptr, &bufferCapacity) != ERROR_SUCCESS)
{ {
return false; return false;
} }
std::unique_ptr<BYTE[]> buffer = std::make_unique<BYTE[]>(bufferCapacity); std::unique_ptr<BYTE[]> buffer = std::make_unique<BYTE[]>(bufferCapacity);
// request regkey binary content // request regkey binary content
if (RegQueryValueExW(hKey, RegVirtualDesktopIds, 0, nullptr, buffer.get(), &bufferCapacity) != ERROR_SUCCESS) if (RegQueryValueExW(hKey, NonLocalizable::RegVirtualDesktopIds, 0, nullptr, buffer.get(), &bufferCapacity) != ERROR_SUCCESS)
{ {
return false; return false;
} }
@ -147,7 +151,7 @@ namespace VirtualDesktopUtils
HKEY OpenVirtualDesktopsRegKey() HKEY OpenVirtualDesktopsRegKey()
{ {
HKEY hKey{ nullptr }; HKEY hKey{ nullptr };
if (RegOpenKeyEx(HKEY_CURRENT_USER, RegKeyVirtualDesktops, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) if (RegOpenKeyEx(HKEY_CURRENT_USER, NonLocalizable::RegKeyVirtualDesktops, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{ {
return hKey; return hKey;
} }

View File

@ -16,9 +16,11 @@
extern "C" IMAGE_DOS_HEADER __ImageBase; extern "C" IMAGE_DOS_HEADER __ImageBase;
namespace // Non-Localizable strings
namespace NonLocalizable
{ {
const wchar_t TOAST_TITLE[] = L"FancyZones"; const wchar_t FancyZonesRunAsAdminInfoPage[] = L"https://aka.ms/powertoysDetectedElevatedHelp";
const wchar_t ToastNotificationButtonUrl[] = L"powertoys://cant_drag_elevated_disable/";
} }
namespace WindowMoveHandlerUtils namespace WindowMoveHandlerUtils
@ -335,7 +337,7 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c
{ {
if (WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent()) if (WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
{ {
::RemoveProp(window, RESTORE_SIZE_STAMP); ::RemoveProp(window, ZonedWindowProperties::PropertyRestoreSizeID);
} }
else if (!IsWindowMaximized(window)) else if (!IsWindowMaximized(window))
{ {
@ -361,7 +363,7 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c
} }
} }
} }
::RemoveProp(window, MULTI_ZONE_STAMP); ::RemoveProp(window, ZonedWindowProperties::PropertyMultipleZoneID);
} }
m_inMoveSize = false; m_inMoveSize = false;
@ -401,11 +403,11 @@ void WindowMoveHandlerPrivate::WarnIfElevationIsRequired(HWND window) noexcept
if (!warning_shown && !is_cant_drag_elevated_warning_disabled()) if (!warning_shown && !is_cant_drag_elevated_warning_disabled())
{ {
std::vector<notifications::action_t> actions = { std::vector<notifications::action_t> actions = {
notifications::link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_LEARN_MORE), L"https://aka.ms/powertoysDetectedElevatedHelp" }, 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), L"powertoys://cant_drag_elevated_disable/" } notifications::link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN), NonLocalizable::ToastNotificationButtonUrl }
}; };
notifications::show_toast_with_activations(GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED), notifications::show_toast_with_activations(GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED),
TOAST_TITLE, GET_RESOURCE_STRING(IDS_FANCYZONES),
{}, {},
std::move(actions)); std::move(actions));
warning_shown = true; warning_shown = true;

View File

@ -699,7 +699,7 @@ bool ZoneSet::CalculateGridZones(Rect workArea, FancyZonesDataTypes::GridLayoutI
void ZoneSet::StampWindow(HWND window, size_t bitmask) noexcept void ZoneSet::StampWindow(HWND window, size_t bitmask) noexcept
{ {
SetProp(window, MULTI_ZONE_STAMP, reinterpret_cast<HANDLE>(bitmask)); SetProp(window, ZonedWindowProperties::PropertyMultipleZoneID, reinterpret_cast<HANDLE>(bitmask));
} }
winrt::com_ptr<IZoneSet> MakeZoneSet(ZoneSetConfig const& config) noexcept winrt::com_ptr<IZoneSet> MakeZoneSet(ZoneSetConfig const& config) noexcept

View File

@ -15,6 +15,13 @@
#include <gdiplus.h> #include <gdiplus.h>
// Non-Localizable strings
namespace NonLocalizable
{
const wchar_t SegoeUiFont[] = L"Segoe ui";
const wchar_t ToolWindowClassName[] = L"SuperFancyZones_ZoneWindow";
}
namespace ZoneWindowUtils namespace ZoneWindowUtils
{ {
std::wstring GenerateUniqueId(HMONITOR monitor, PCWSTR deviceId, PCWSTR virtualDesktopId) std::wstring GenerateUniqueId(HMONITOR monitor, PCWSTR deviceId, PCWSTR virtualDesktopId)
@ -36,7 +43,7 @@ namespace ZoneWindowUtils
std::wstring GenerateUniqueIdAllMonitorsArea(PCWSTR virtualDesktopId) std::wstring GenerateUniqueIdAllMonitorsArea(PCWSTR virtualDesktopId)
{ {
std::wstring result{ MULTI_MONITOR_MODE_DEVICE }; std::wstring result{ ZonedWindowProperties::MultiMonitorDeviceID };
RECT combinedResolution = GetAllMonitorsCombinedRect<&MONITORINFO::rcMonitor>(); RECT combinedResolution = GetAllMonitorsCombinedRect<&MONITORINFO::rcMonitor>();
@ -71,7 +78,7 @@ namespace ZoneWindowDrawUtils
{ {
Gdiplus::Graphics g(hdc.get()); Gdiplus::Graphics g(hdc.get());
Gdiplus::FontFamily fontFamily(L"Segoe ui"); Gdiplus::FontFamily fontFamily(NonLocalizable::SegoeUiFont);
Gdiplus::Font font(&fontFamily, 80, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::Font font(&fontFamily, 80, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel);
Gdiplus::SolidBrush solidBrush(Gdiplus::Color(255, 0, 0, 0)); Gdiplus::SolidBrush solidBrush(Gdiplus::Color(255, 0, 0, 0));
@ -253,7 +260,7 @@ ZoneWindow::ZoneWindow(HINSTANCE hinstance)
wcex.cbSize = sizeof(WNDCLASSEX); wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpfnWndProc = s_WndProc; wcex.lpfnWndProc = s_WndProc;
wcex.hInstance = hinstance; wcex.hInstance = hinstance;
wcex.lpszClassName = L"SuperFancyZones_ZoneWindow"; wcex.lpszClassName = NonLocalizable::ToolWindowClassName;
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW); wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
RegisterClassExW(&wcex); RegisterClassExW(&wcex);
@ -292,7 +299,7 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit
InitializeZoneSets(parentUniqueId); InitializeZoneSets(parentUniqueId);
m_window = wil::unique_hwnd{ m_window = wil::unique_hwnd{
CreateWindowExW(WS_EX_TOOLWINDOW, L"SuperFancyZones_ZoneWindow", L"", WS_POPUP, workAreaRect.left(), workAreaRect.top(), workAreaRect.width(), workAreaRect.height(), nullptr, nullptr, hinstance, this) CreateWindowExW(WS_EX_TOOLWINDOW, NonLocalizable::ToolWindowClassName, L"", WS_POPUP, workAreaRect.left(), workAreaRect.top(), workAreaRect.width(), workAreaRect.height(), nullptr, nullptr, hinstance, this)
}; };
if (!m_window) if (!m_window)

View File

@ -28,10 +28,13 @@ BEGIN
IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL "Configure the zone editor hotkey" IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL "Configure the zone editor hotkey"
IDS_SETTING_EXCLUDED_APPS_DESCRIPTION "To exclude an application from snapping to zones add its name here (one per line). Excluded apps will react to the Windows Snap regardless of all other settings." IDS_SETTING_EXCLUDED_APPS_DESCRIPTION "To exclude an application from snapping to zones add its name here (one per line). Excluded apps will react to the Windows Snap regardless of all other settings."
IDS_SETTINGS_HIGHLIGHT_OPACITY "Zone opacity (%)" IDS_SETTINGS_HIGHLIGHT_OPACITY "Zone opacity (%)"
IDS_FANCYZONES L"FancyZones" IDS_FANCYZONES "FancyZones"
IDS_CANT_DRAG_ELEVATED L"We've detected an application running with administrator privileges. This blocks some functionality in PowerToys. Visit our wiki page to learn more." IDS_CANT_DRAG_ELEVATED "We've detected an application running with administrator privileges. This blocks some functionality in PowerToys. Visit our wiki page to learn more."
IDS_CANT_DRAG_ELEVATED_LEARN_MORE L"Learn more" IDS_CANT_DRAG_ELEVATED_LEARN_MORE "Learn more"
IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN L"Don't show again" IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN "Don't show again"
IDS_KEYBOARD_LISTENER_ERROR "Cannot install keyboard listener."
IDS_WINDOW_EVENT_LISTENER_ERROR "Cannot install Windows event listener."
IDS_POWERTOYS_FANCYZONES "PowerToys - FancyZones"
END END
1 VERSIONINFO 1 VERSIONINFO

View File

@ -40,3 +40,6 @@
#define IDS_CANT_DRAG_ELEVATED 126 #define IDS_CANT_DRAG_ELEVATED 126
#define IDS_CANT_DRAG_ELEVATED_LEARN_MORE 127 #define IDS_CANT_DRAG_ELEVATED_LEARN_MORE 127
#define IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN 128 #define IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN 128
#define IDS_KEYBOARD_LISTENER_ERROR 129
#define IDS_WINDOW_EVENT_LISTENER_ERROR 130
#define IDS_POWERTOYS_FANCYZONES 131

View File

@ -5,9 +5,59 @@
#include "lib/FancyZonesData.h" #include "lib/FancyZonesData.h"
#include "lib/FancyZonesDataTypes.h" #include "lib/FancyZonesDataTypes.h"
// Telemetry strings should not be localized.
#define LoggingProviderKey "Microsoft.PowerToys"
#define EventEnableFancyZonesKey "FancyZones_EnableFancyZones"
#define EventKeyDownKey "FancyZones_OnKeyDown"
#define EventZoneSettingsChangedKey "FancyZones_ZoneSettingsChanged"
#define EventEditorLaunchKey "FancyZones_EditorLaunch"
#define EventSettingsChangedKey "FancyZones_SettingsChanged"
#define EventDesktopChangedKey "FancyZones_VirtualDesktopChanged"
#define EventZoneWindowKeyUpKey "FancyZones_ZoneWindowKeyUp"
#define EventMoveSizeEndKey "FancyZones_MoveSizeEnd"
#define EventCycleActiveZoneSetKey "FancyZones_CycleActiveZoneSet"
#define EventEnabledKey "Enabled"
#define PressedKeyCodeKey "Hotkey"
#define PressedWindowKey "WindowsKey"
#define PressedControlKey "ControlKey"
#define MoveSizeActionKey "InMoveSize"
#define AppsInHistoryCountKey "AppsInHistoryCount"
#define CustomZoneSetCountKey "CustomZoneSetCount"
#define NumberOfZonesForEachCustomZoneSetKey "NumberOfZonesForEachCustomZoneSet"
#define ActiveZoneSetsCountKey "ActiveZoneSetsCount"
#define ActiveZoneSetsListKey "ActiveZoneSetsList"
#define EditorLaunchValueKey "Value"
#define ShiftDragKey "ShiftDrag"
#define MouseSwitchKey "MouseSwitch"
#define MoveWindowsOnDisplayChangeKey "MoveWindowsOnDisplayChange"
#define FlashZonesOnZoneSetChangeKey "FlashZonesOnZoneSetChange"
#define MoveWindowsOnZoneSetChangeKey "MoveWindowsOnZoneSetChange"
#define OverrideSnapHotKeysKey "OverrideSnapHotKeys"
#define MoveWindowAcrossMonitorsKey "MoveWindowAcrossMonitors"
#define MoveWindowsToLastZoneOnAppOpeningKey "MoveWindowsToLastZoneOnAppOpening"
#define OpenWindowOnActiveMonitorKey "OpenWindowOnActiveMonitor"
#define RestoreSizeKey "RestoreSize"
#define UseCursorPosOnEditorStartupKey "UseCursorPosOnEditorStartup"
#define ShowZonesOnAllMonitorsKey "ShowZonesOnAllMonitors"
#define SpanZonesAcrossMonitorsKey "SpanZonesAcrossMonitors"
#define MakeDraggedWindowTransparentKey "MakeDraggedWindowTransparent"
#define ZoneColorKey "ZoneColor"
#define ZoneBorderColorKey "ZoneBorderColor"
#define ZoneHighlightColorKey "ZoneHighlightColor"
#define ZoneHighlightOpacityKey "ZoneHighlightOpacity"
#define HotkeyKey "Hotkey"
#define ExcludedAppsCountKey "ExcludedAppsCount"
#define KeyboardValueKey "KeyboardValue"
#define ActiveSetKey "ActiveSet"
#define NumberOfZonesKey "NumberOfZones"
#define NumberOfWindowsKey "NumberOfWindows"
#define InputModeKey "InputMode"
TRACELOGGING_DEFINE_PROVIDER( TRACELOGGING_DEFINE_PROVIDER(
g_hProvider, g_hProvider,
"Microsoft.PowerToys", LoggingProviderKey,
// {38e8889b-9731-53f5-e901-e8a7c1753074} // {38e8889b-9731-53f5-e901-e8a7c1753074}
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
TraceLoggingOptionProjectTelemetry()); TraceLoggingOptionProjectTelemetry());
@ -51,23 +101,23 @@ void Trace::FancyZones::EnableFancyZones(bool enabled) noexcept
{ {
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"FancyZones_EnableFancyZones", EventEnableFancyZonesKey,
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingBoolean(enabled, "Enabled")); TraceLoggingBoolean(enabled, EventEnabledKey));
} }
void Trace::FancyZones::OnKeyDown(DWORD vkCode, bool win, bool control, bool inMoveSize) noexcept void Trace::FancyZones::OnKeyDown(DWORD vkCode, bool win, bool control, bool inMoveSize) noexcept
{ {
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"FancyZones_OnKeyDown", EventKeyDownKey,
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingValue(vkCode, "Hotkey"), TraceLoggingValue(vkCode, PressedKeyCodeKey),
TraceLoggingBoolean(win, "WindowsKey"), TraceLoggingBoolean(win, PressedWindowKey),
TraceLoggingBoolean(control, "ControlKey"), TraceLoggingBoolean(control, PressedControlKey),
TraceLoggingBoolean(inMoveSize, "InMoveSize")); TraceLoggingBoolean(inMoveSize, MoveSizeActionKey));
} }
void Trace::FancyZones::DataChanged() noexcept void Trace::FancyZones::DataChanged() noexcept
@ -142,24 +192,24 @@ void Trace::FancyZones::DataChanged() noexcept
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"FancyZones_ZoneSettingsChanged", EventZoneSettingsChangedKey,
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingInt32(appsHistorySize, "AppsInHistoryCount"), TraceLoggingInt32(appsHistorySize, AppsInHistoryCountKey),
TraceLoggingInt32(static_cast<int>(customZones.size()), "CustomZoneSetCount"), TraceLoggingInt32(static_cast<int>(customZones.size()), CustomZoneSetCountKey),
TraceLoggingInt32Array(customZonesArray.get(), static_cast<int>(customZones.size()), "NumberOfZonesForEachCustomZoneSet"), TraceLoggingInt32Array(customZonesArray.get(), static_cast<int>(customZones.size()), NumberOfZonesForEachCustomZoneSetKey),
TraceLoggingInt32(static_cast<int>(devices.size()), "ActiveZoneSetsCount"), TraceLoggingInt32(static_cast<int>(devices.size()), ActiveZoneSetsCountKey),
TraceLoggingWideString(activeZoneSetInfo.c_str(), "ActiveZoneSetsList")); TraceLoggingWideString(activeZoneSetInfo.c_str(), ActiveZoneSetsListKey));
} }
void Trace::FancyZones::EditorLaunched(int value) noexcept void Trace::FancyZones::EditorLaunched(int value) noexcept
{ {
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"FancyZones_EditorLaunch", EventEditorLaunchKey,
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingInt32(value, "Value")); TraceLoggingInt32(value, EditorLaunchValueKey));
} }
void Trace::SettingsChanged(const Settings& settings) noexcept void Trace::SettingsChanged(const Settings& settings) noexcept
@ -174,36 +224,36 @@ void Trace::SettingsChanged(const Settings& settings) noexcept
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"FancyZones_SettingsChanged", EventSettingsChangedKey,
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingBoolean(settings.shiftDrag, "ShiftDrag"), TraceLoggingBoolean(settings.shiftDrag, ShiftDragKey),
TraceLoggingBoolean(settings.mouseSwitch, "MouseSwitch"), TraceLoggingBoolean(settings.mouseSwitch, MouseSwitchKey),
TraceLoggingBoolean(settings.displayChange_moveWindows, "MoveWindowsOnDisplayChange"), TraceLoggingBoolean(settings.displayChange_moveWindows, MoveWindowsOnDisplayChangeKey),
TraceLoggingBoolean(settings.zoneSetChange_flashZones, "FlashZonesOnZoneSetChange"), TraceLoggingBoolean(settings.zoneSetChange_flashZones, FlashZonesOnZoneSetChangeKey),
TraceLoggingBoolean(settings.zoneSetChange_moveWindows, "MoveWindowsOnZoneSetChange"), TraceLoggingBoolean(settings.zoneSetChange_moveWindows, MoveWindowsOnZoneSetChangeKey),
TraceLoggingBoolean(settings.overrideSnapHotkeys, "OverrideSnapHotKeys"), TraceLoggingBoolean(settings.overrideSnapHotkeys, OverrideSnapHotKeysKey),
TraceLoggingBoolean(settings.moveWindowAcrossMonitors, "MoveWindowAcrossMonitors"), TraceLoggingBoolean(settings.moveWindowAcrossMonitors, MoveWindowAcrossMonitorsKey),
TraceLoggingBoolean(settings.appLastZone_moveWindows, "MoveWindowsToLastZoneOnAppOpening"), TraceLoggingBoolean(settings.appLastZone_moveWindows, MoveWindowsToLastZoneOnAppOpeningKey),
TraceLoggingBoolean(settings.openWindowOnActiveMonitor, "OpenWindowOnActiveMonitor"), TraceLoggingBoolean(settings.openWindowOnActiveMonitor, OpenWindowOnActiveMonitorKey),
TraceLoggingBoolean(settings.restoreSize, "RestoreSize"), TraceLoggingBoolean(settings.restoreSize, RestoreSizeKey),
TraceLoggingBoolean(settings.use_cursorpos_editor_startupscreen, "UseCursorPosOnEditorStartup"), TraceLoggingBoolean(settings.use_cursorpos_editor_startupscreen, UseCursorPosOnEditorStartupKey),
TraceLoggingBoolean(settings.showZonesOnAllMonitors, "ShowZonesOnAllMonitors"), TraceLoggingBoolean(settings.showZonesOnAllMonitors, ShowZonesOnAllMonitorsKey),
TraceLoggingBoolean(settings.spanZonesAcrossMonitors, "SpanZonesAcrossMonitors"), TraceLoggingBoolean(settings.spanZonesAcrossMonitors, SpanZonesAcrossMonitorsKey),
TraceLoggingBoolean(settings.makeDraggedWindowTransparent, "MakeDraggedWindowTransparent"), TraceLoggingBoolean(settings.makeDraggedWindowTransparent, MakeDraggedWindowTransparentKey),
TraceLoggingWideString(settings.zoneColor.c_str(), "ZoneColor"), TraceLoggingWideString(settings.zoneColor.c_str(), ZoneColorKey),
TraceLoggingWideString(settings.zoneBorderColor.c_str(), "ZoneBorderColor"), TraceLoggingWideString(settings.zoneBorderColor.c_str(), ZoneBorderColorKey),
TraceLoggingWideString(settings.zoneHighlightColor.c_str(), "ZoneHighlightColor"), TraceLoggingWideString(settings.zoneHighlightColor.c_str(), ZoneHighlightColorKey),
TraceLoggingInt32(settings.zoneHighlightOpacity, "ZoneHighlightOpacity"), TraceLoggingInt32(settings.zoneHighlightOpacity, ZoneHighlightOpacityKey),
TraceLoggingWideString(hotkeyStr.c_str(), "Hotkey"), TraceLoggingWideString(hotkeyStr.c_str(), HotkeyKey),
TraceLoggingInt32(static_cast<int>(settings.excludedAppsArray.size()), "ExcludedAppsCount")); TraceLoggingInt32(static_cast<int>(settings.excludedAppsArray.size()), ExcludedAppsCountKey));
} }
void Trace::VirtualDesktopChanged() noexcept void Trace::VirtualDesktopChanged() noexcept
{ {
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"FancyZones_VirtualDesktopChanged", EventDesktopChangedKey,
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
} }
@ -212,10 +262,10 @@ void Trace::ZoneWindow::KeyUp(WPARAM wParam) noexcept
{ {
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"FancyZones_ZoneWindowKeyUp", EventZoneWindowKeyUpKey,
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingValue(wParam, "KeyboardValue")); TraceLoggingValue(wParam, KeyboardValueKey));
} }
void Trace::ZoneWindow::MoveSizeEnd(_In_opt_ winrt::com_ptr<IZoneSet> activeSet) noexcept void Trace::ZoneWindow::MoveSizeEnd(_In_opt_ winrt::com_ptr<IZoneSet> activeSet) noexcept
@ -223,12 +273,12 @@ void Trace::ZoneWindow::MoveSizeEnd(_In_opt_ winrt::com_ptr<IZoneSet> activeSet)
auto const zoneInfo = GetZoneSetInfo(activeSet); auto const zoneInfo = GetZoneSetInfo(activeSet);
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"FancyZones_MoveSizeEnd", EventMoveSizeEndKey,
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingValue(reinterpret_cast<void*>(activeSet.get()), "ActiveSet"), TraceLoggingValue(reinterpret_cast<void*>(activeSet.get()), ActiveSetKey),
TraceLoggingValue(zoneInfo.NumberOfZones, "NumberOfZones"), TraceLoggingValue(zoneInfo.NumberOfZones, NumberOfZonesKey),
TraceLoggingValue(zoneInfo.NumberOfWindows, "NumberOfWindows")); TraceLoggingValue(zoneInfo.NumberOfWindows, NumberOfWindowsKey));
} }
void Trace::ZoneWindow::CycleActiveZoneSet(_In_opt_ winrt::com_ptr<IZoneSet> activeSet, InputMode mode) noexcept void Trace::ZoneWindow::CycleActiveZoneSet(_In_opt_ winrt::com_ptr<IZoneSet> activeSet, InputMode mode) noexcept
@ -236,11 +286,11 @@ void Trace::ZoneWindow::CycleActiveZoneSet(_In_opt_ winrt::com_ptr<IZoneSet> act
auto const zoneInfo = GetZoneSetInfo(activeSet); auto const zoneInfo = GetZoneSetInfo(activeSet);
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"FancyZones_CycleActiveZoneSet", EventCycleActiveZoneSetKey,
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingValue(reinterpret_cast<void*>(activeSet.get()), "ActiveSet"), TraceLoggingValue(reinterpret_cast<void*>(activeSet.get()), ActiveSetKey),
TraceLoggingValue(zoneInfo.NumberOfZones, "NumberOfZones"), TraceLoggingValue(zoneInfo.NumberOfZones, NumberOfZonesKey),
TraceLoggingValue(zoneInfo.NumberOfWindows, "NumberOfWindows"), TraceLoggingValue(zoneInfo.NumberOfWindows, NumberOfWindowsKey),
TraceLoggingValue(static_cast<int>(mode), "InputMode")); TraceLoggingValue(static_cast<int>(mode), InputModeKey));
} }

View File

@ -7,10 +7,11 @@
#include <sstream> #include <sstream>
namespace // Non-Localizable strings
namespace NonLocalizable
{ {
const wchar_t POWER_TOYS_APP_POWER_LAUCHER[] = L"POWERLAUNCHER.EXE"; const wchar_t PowerToysAppPowerLauncher[] = L"POWERLAUNCHER.EXE";
const wchar_t POWER_TOYS_APP_FANCY_ZONES_EDITOR[] = L"FANCYZONESEDITOR.EXE"; const wchar_t PowerToysAppFZEditor[] = L"FANCYZONESEDITOR.EXE";
} }
typedef BOOL(WINAPI* GetDpiForMonitorInternalFunc)(HMONITOR, UINT, UINT*, UINT*); typedef BOOL(WINAPI* GetDpiForMonitorInternalFunc)(HMONITOR, UINT, UINT*, UINT*);
@ -167,11 +168,11 @@ bool IsInterestingWindow(HWND window, const std::vector<std::wstring>& excludedA
{ {
return false; return false;
} }
if (find_app_name_in_path(filtered.process_path, { POWER_TOYS_APP_POWER_LAUCHER })) if (find_app_name_in_path(filtered.process_path, { NonLocalizable::PowerToysAppPowerLauncher }))
{ {
return false; return false;
} }
if (find_app_name_in_path(filtered.process_path, { POWER_TOYS_APP_FANCY_ZONES_EDITOR })) if (find_app_name_in_path(filtered.process_path, { NonLocalizable::PowerToysAppFZEditor }))
{ {
return false; return false;
} }
@ -191,7 +192,7 @@ bool IsWindowMaximized(HWND window) noexcept
void SaveWindowSizeAndOrigin(HWND window) noexcept void SaveWindowSizeAndOrigin(HWND window) noexcept
{ {
HANDLE handle = GetPropW(window, RESTORE_SIZE_STAMP); HANDLE handle = GetPropW(window, ZonedWindowProperties::PropertyRestoreSizeID);
if (handle) if (handle)
{ {
// Size already set, skip // Size already set, skip
@ -213,15 +214,15 @@ void SaveWindowSizeAndOrigin(HWND window) noexcept
std::array<int, 2> windowOriginData = { originX, originY }; std::array<int, 2> windowOriginData = { originX, originY };
HANDLE rawData; HANDLE rawData;
memcpy(&rawData, windowSizeData.data(), sizeof rawData); memcpy(&rawData, windowSizeData.data(), sizeof rawData);
SetPropW(window, RESTORE_SIZE_STAMP, rawData); SetPropW(window, ZonedWindowProperties::PropertyRestoreSizeID, rawData);
memcpy(&rawData, windowOriginData.data(), sizeof rawData); memcpy(&rawData, windowOriginData.data(), sizeof rawData);
SetPropW(window, RESTORE_ORIGIN_STAMP, rawData); SetPropW(window, ZonedWindowProperties::PropertyRestoreOriginID, rawData);
} }
} }
void RestoreWindowSize(HWND window) noexcept void RestoreWindowSize(HWND window) noexcept
{ {
auto windowSizeData = GetPropW(window, RESTORE_SIZE_STAMP); auto windowSizeData = GetPropW(window, ZonedWindowProperties::PropertyRestoreSizeID);
if (windowSizeData) if (windowSizeData)
{ {
std::array<int, 2> windowSize; std::array<int, 2> windowSize;
@ -238,13 +239,13 @@ void RestoreWindowSize(HWND window) noexcept
SizeWindowToRect(window, rect); SizeWindowToRect(window, rect);
} }
::RemoveProp(window, RESTORE_SIZE_STAMP); ::RemoveProp(window, ZonedWindowProperties::PropertyRestoreSizeID);
} }
} }
void RestoreWindowOrigin(HWND window) noexcept void RestoreWindowOrigin(HWND window) noexcept
{ {
auto windowOriginData = GetPropW(window, RESTORE_ORIGIN_STAMP); auto windowOriginData = GetPropW(window, ZonedWindowProperties::PropertyRestoreOriginID);
if (windowOriginData) if (windowOriginData)
{ {
std::array<int, 2> windowOrigin; std::array<int, 2> windowOrigin;
@ -266,7 +267,7 @@ void RestoreWindowOrigin(HWND window) noexcept
SizeWindowToRect(window, rect); SizeWindowToRect(window, rect);
} }
::RemoveProp(window, RESTORE_ORIGIN_STAMP); ::RemoveProp(window, ZonedWindowProperties::PropertyRestoreOriginID);
} }
} }