mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-07 11:46:30 +02:00
[FancyZones]Monitor identification (#19077)
* moved monitors identifying * changed device id * get wmi info * convert old data * save/load applied layouts * changed monitor identification * id comparison * save/load app zone history * moved com and security init * update ids in editor * lib fix * updated tests * changed comparison * tests * updated id comparison * updated log * moved definition * spell check * resolve conflicts * refactoring * update serial numbers if possible
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <FancyZonesLib/GuidUtils.h>
|
||||
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
||||
#include <FancyZonesLib/JsonHelpers.h>
|
||||
#include <FancyZonesLib/MonitorUtils.h>
|
||||
#include <FancyZonesLib/VirtualDesktop.h>
|
||||
#include <FancyZonesLib/util.h>
|
||||
|
||||
@@ -16,7 +17,7 @@ namespace JsonUtils
|
||||
struct AppZoneHistoryJSON
|
||||
{
|
||||
private:
|
||||
static std::optional<FancyZonesDataTypes::DeviceIdData> DeviceIdFromJson(const json::JsonObject& json)
|
||||
static std::optional<FancyZonesDataTypes::WorkAreaId> DeviceIdFromJson(const json::JsonObject& json)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -24,6 +25,8 @@ namespace JsonUtils
|
||||
{
|
||||
json::JsonObject device = json.GetNamedObject(NonLocalizable::AppZoneHistoryIds::DeviceID);
|
||||
std::wstring monitor = device.GetNamedString(NonLocalizable::AppZoneHistoryIds::MonitorID).c_str();
|
||||
std::wstring monitorInstance = device.GetNamedString(NonLocalizable::AppZoneHistoryIds::MonitorInstanceID, L"").c_str();
|
||||
std::wstring monitorSerialNumber = device.GetNamedString(NonLocalizable::AppZoneHistoryIds::MonitorSerialNumberID, L"").c_str();
|
||||
std::wstring virtualDesktop = device.GetNamedString(NonLocalizable::AppZoneHistoryIds::VirtualDesktopID).c_str();
|
||||
|
||||
auto virtualDesktopGuid = FancyZonesUtils::GuidFromString(virtualDesktop);
|
||||
@@ -32,8 +35,25 @@ namespace JsonUtils
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return FancyZonesDataTypes::DeviceIdData{
|
||||
.deviceName = monitor,
|
||||
FancyZonesDataTypes::DeviceId deviceId{};
|
||||
if (monitorInstance.empty())
|
||||
{
|
||||
// old data
|
||||
deviceId = MonitorUtils::Display::ConvertObsoleteDeviceId(monitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceId.id = monitor;
|
||||
deviceId.instanceId = monitorInstance;
|
||||
}
|
||||
|
||||
FancyZonesDataTypes::MonitorId monitorId{
|
||||
.deviceId = deviceId,
|
||||
.serialNumber = monitorSerialNumber
|
||||
};
|
||||
|
||||
return FancyZonesDataTypes::WorkAreaId{
|
||||
.monitorId = monitorId,
|
||||
.virtualDesktopId = virtualDesktopGuid.value(),
|
||||
};
|
||||
}
|
||||
@@ -46,8 +66,8 @@ namespace JsonUtils
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return FancyZonesDataTypes::DeviceIdData{
|
||||
.deviceName = bcDeviceId->deviceName,
|
||||
return FancyZonesDataTypes::WorkAreaId{
|
||||
.monitorId = { .deviceId = MonitorUtils::Display::ConvertObsoleteDeviceId(bcDeviceId->deviceName) },
|
||||
.virtualDesktopId = bcDeviceId->virtualDesktopId,
|
||||
};
|
||||
}
|
||||
@@ -80,7 +100,7 @@ namespace JsonUtils
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
data.deviceId = deviceIdOpt.value();
|
||||
data.workAreaId = deviceIdOpt.value();
|
||||
data.zoneSetUuid = json.GetNamedString(NonLocalizable::AppZoneHistoryIds::LayoutIdID);
|
||||
|
||||
if (!FancyZonesUtils::IsValidGuid(data.zoneSetUuid))
|
||||
@@ -152,8 +172,11 @@ namespace JsonUtils
|
||||
}
|
||||
|
||||
json::JsonObject device{};
|
||||
device.SetNamedValue(NonLocalizable::AppZoneHistoryIds::MonitorID, json::value(data.deviceId.deviceName));
|
||||
auto virtualDesktopStr = FancyZonesUtils::GuidToString(data.deviceId.virtualDesktopId);
|
||||
device.SetNamedValue(NonLocalizable::AppZoneHistoryIds::MonitorID, json::value(data.workAreaId.monitorId.deviceId.id));
|
||||
device.SetNamedValue(NonLocalizable::AppZoneHistoryIds::MonitorInstanceID, json::value(data.workAreaId.monitorId.deviceId.instanceId));
|
||||
device.SetNamedValue(NonLocalizable::AppZoneHistoryIds::MonitorSerialNumberID, json::value(data.workAreaId.monitorId.serialNumber));
|
||||
|
||||
auto virtualDesktopStr = FancyZonesUtils::GuidToString(data.workAreaId.virtualDesktopId);
|
||||
if (virtualDesktopStr)
|
||||
{
|
||||
device.SetNamedValue(NonLocalizable::AppZoneHistoryIds::VirtualDesktopID, json::value(virtualDesktopStr.value()));
|
||||
@@ -255,9 +278,9 @@ void AppZoneHistory::SaveData()
|
||||
auto updatedVector = dataVector;
|
||||
for (auto& data : updatedVector)
|
||||
{
|
||||
if (!VirtualDesktop::instance().IsVirtualDesktopIdSavedInRegistry(data.deviceId.virtualDesktopId))
|
||||
if (!VirtualDesktop::instance().IsVirtualDesktopIdSavedInRegistry(data.workAreaId.virtualDesktopId))
|
||||
{
|
||||
data.deviceId.virtualDesktopId = GUID_NULL;
|
||||
data.workAreaId.virtualDesktopId = GUID_NULL;
|
||||
dirtyFlag = true;
|
||||
}
|
||||
}
|
||||
@@ -275,9 +298,40 @@ void AppZoneHistory::SaveData()
|
||||
}
|
||||
}
|
||||
|
||||
bool AppZoneHistory::SetAppLastZones(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId, const std::wstring& zoneSetId, const ZoneIndexSet& zoneIndexSet)
|
||||
void AppZoneHistory::AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::MonitorId>& ids)
|
||||
{
|
||||
if (IsAnotherWindowOfApplicationInstanceZoned(window, deviceId))
|
||||
bool dirtyFlag = false;
|
||||
|
||||
for (auto iter = m_history.begin(); iter != m_history.end(); ++iter)
|
||||
{
|
||||
auto& [app, data] = *iter;
|
||||
for (auto& dataIter = data.begin(); dataIter != data.end(); ++dataIter)
|
||||
{
|
||||
auto& dataMonitorId = dataIter->workAreaId.monitorId;
|
||||
if (dataMonitorId.serialNumber.empty() && !dataMonitorId.deviceId.isDefault())
|
||||
{
|
||||
for (const auto& monitorId : ids)
|
||||
{
|
||||
if (dataMonitorId.deviceId.id == monitorId.deviceId.id && dataMonitorId.deviceId.instanceId == monitorId.deviceId.instanceId)
|
||||
{
|
||||
dataMonitorId.serialNumber = monitorId.serialNumber;
|
||||
dirtyFlag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dirtyFlag)
|
||||
{
|
||||
SaveData();
|
||||
}
|
||||
}
|
||||
|
||||
bool AppZoneHistory::SetAppLastZones(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId, const std::wstring& zoneSetId, const ZoneIndexSet& zoneIndexSet)
|
||||
{
|
||||
if (IsAnotherWindowOfApplicationInstanceZoned(window, workAreaId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -288,7 +342,7 @@ bool AppZoneHistory::SetAppLastZones(HWND window, const FancyZonesDataTypes::Dev
|
||||
return false;
|
||||
}
|
||||
|
||||
Logger::info(L"Add app zone history, device: {}, layout: {}", deviceId.toString(), zoneSetId);
|
||||
Logger::info(L"Add app zone history, device: {}, layout: {}", workAreaId.toString(), zoneSetId);
|
||||
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(window, &processId);
|
||||
@@ -299,7 +353,7 @@ bool AppZoneHistory::SetAppLastZones(HWND window, const FancyZonesDataTypes::Dev
|
||||
auto& perDesktopData = history->second;
|
||||
for (auto& data : perDesktopData)
|
||||
{
|
||||
if (data.deviceId == deviceId)
|
||||
if (data.workAreaId == workAreaId)
|
||||
{
|
||||
// application already has history on this work area, update it with new window position
|
||||
data.processIdToHandleMap[processId] = window;
|
||||
@@ -315,7 +369,7 @@ bool AppZoneHistory::SetAppLastZones(HWND window, const FancyZonesDataTypes::Dev
|
||||
processIdToHandleMap[processId] = window;
|
||||
FancyZonesDataTypes::AppZoneHistoryData data{ .processIdToHandleMap = processIdToHandleMap,
|
||||
.zoneSetUuid = zoneSetId,
|
||||
.deviceId = deviceId,
|
||||
.workAreaId = workAreaId,
|
||||
.zoneIndexSet = zoneIndexSet };
|
||||
|
||||
if (m_history.contains(processPath))
|
||||
@@ -333,9 +387,9 @@ bool AppZoneHistory::SetAppLastZones(HWND window, const FancyZonesDataTypes::Dev
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AppZoneHistory::RemoveAppLastZone(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId, const std::wstring_view& zoneSetId)
|
||||
bool AppZoneHistory::RemoveAppLastZone(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId, const std::wstring_view& zoneSetId)
|
||||
{
|
||||
Logger::info(L"Add app zone history, device: {}, layout: {}", deviceId.toString(), zoneSetId);
|
||||
Logger::info(L"Add app zone history, device: {}, layout: {}", workAreaId.toString(), zoneSetId);
|
||||
|
||||
auto processPath = get_process_path_waiting_uwp(window);
|
||||
if (!processPath.empty())
|
||||
@@ -346,9 +400,9 @@ bool AppZoneHistory::RemoveAppLastZone(HWND window, const FancyZonesDataTypes::D
|
||||
auto& perDesktopData = history->second;
|
||||
for (auto data = std::begin(perDesktopData); data != std::end(perDesktopData);)
|
||||
{
|
||||
if (data->deviceId == deviceId && data->zoneSetUuid == zoneSetId)
|
||||
if (data->workAreaId == workAreaId && data->zoneSetUuid == zoneSetId)
|
||||
{
|
||||
if (!IsAnotherWindowOfApplicationInstanceZoned(window, deviceId))
|
||||
if (!IsAnotherWindowOfApplicationInstanceZoned(window, workAreaId))
|
||||
{
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(window, &processId);
|
||||
@@ -396,7 +450,7 @@ const AppZoneHistory::TAppZoneHistoryMap& AppZoneHistory::GetFullAppZoneHistory(
|
||||
return m_history;
|
||||
}
|
||||
|
||||
std::optional<FancyZonesDataTypes::AppZoneHistoryData> AppZoneHistory::GetZoneHistory(const std::wstring& appPath, const FancyZonesDataTypes::DeviceIdData& deviceId) const noexcept
|
||||
std::optional<FancyZonesDataTypes::AppZoneHistoryData> AppZoneHistory::GetZoneHistory(const std::wstring& appPath, const FancyZonesDataTypes::WorkAreaId& workAreaId) const noexcept
|
||||
{
|
||||
auto app = appPath;
|
||||
auto pos = appPath.find_last_of('\\');
|
||||
@@ -405,10 +459,10 @@ std::optional<FancyZonesDataTypes::AppZoneHistoryData> AppZoneHistory::GetZoneHi
|
||||
app = appPath.substr(pos + 1);
|
||||
}
|
||||
|
||||
auto srcVirtualDesktopIDStr = FancyZonesUtils::GuidToString(deviceId.virtualDesktopId);
|
||||
auto srcVirtualDesktopIDStr = FancyZonesUtils::GuidToString(workAreaId.virtualDesktopId);
|
||||
if (srcVirtualDesktopIDStr)
|
||||
{
|
||||
Logger::debug(L"Get {} zone history on monitor: {}, virtual desktop: {}", app, deviceId.deviceName, srcVirtualDesktopIDStr.value());
|
||||
Logger::debug(L"Get {} zone history on monitor: {}, virtual desktop: {}", app, workAreaId.toString(), srcVirtualDesktopIDStr.value());
|
||||
}
|
||||
|
||||
auto iter = m_history.find(appPath);
|
||||
@@ -421,15 +475,15 @@ std::optional<FancyZonesDataTypes::AppZoneHistoryData> AppZoneHistory::GetZoneHi
|
||||
auto historyVector = iter->second;
|
||||
for (const auto& history : historyVector)
|
||||
{
|
||||
if (history.deviceId.deviceName == deviceId.deviceName)
|
||||
if (history.workAreaId == workAreaId)
|
||||
{
|
||||
auto vdStr = FancyZonesUtils::GuidToString(history.deviceId.virtualDesktopId);
|
||||
auto vdStr = FancyZonesUtils::GuidToString(history.workAreaId.virtualDesktopId);
|
||||
if (vdStr)
|
||||
{
|
||||
Logger::debug(L"App zone history found on the device {} with virtual desktop {}", history.deviceId.deviceName, vdStr.value());
|
||||
Logger::debug(L"App zone history found on the device {} with virtual desktop {}", history.workAreaId.toString(), vdStr.value());
|
||||
}
|
||||
|
||||
if (history.deviceId.virtualDesktopId == deviceId.virtualDesktopId || history.deviceId.virtualDesktopId == GUID_NULL)
|
||||
if (history.workAreaId.virtualDesktopId == workAreaId.virtualDesktopId || history.workAreaId.virtualDesktopId == GUID_NULL)
|
||||
{
|
||||
return history;
|
||||
}
|
||||
@@ -439,7 +493,7 @@ std::optional<FancyZonesDataTypes::AppZoneHistoryData> AppZoneHistory::GetZoneHi
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool AppZoneHistory::IsAnotherWindowOfApplicationInstanceZoned(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId) const noexcept
|
||||
bool AppZoneHistory::IsAnotherWindowOfApplicationInstanceZoned(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId) const noexcept
|
||||
{
|
||||
auto processPath = get_process_path_waiting_uwp(window);
|
||||
if (!processPath.empty())
|
||||
@@ -450,7 +504,7 @@ bool AppZoneHistory::IsAnotherWindowOfApplicationInstanceZoned(HWND window, cons
|
||||
auto& perDesktopData = history->second;
|
||||
for (auto& data : perDesktopData)
|
||||
{
|
||||
if (data.deviceId == deviceId)
|
||||
if (data.workAreaId == workAreaId)
|
||||
{
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(window, &processId);
|
||||
@@ -473,7 +527,7 @@ bool AppZoneHistory::IsAnotherWindowOfApplicationInstanceZoned(HWND window, cons
|
||||
return false;
|
||||
}
|
||||
|
||||
void AppZoneHistory::UpdateProcessIdToHandleMap(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId)
|
||||
void AppZoneHistory::UpdateProcessIdToHandleMap(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId)
|
||||
{
|
||||
auto processPath = get_process_path_waiting_uwp(window);
|
||||
if (!processPath.empty())
|
||||
@@ -484,7 +538,7 @@ void AppZoneHistory::UpdateProcessIdToHandleMap(HWND window, const FancyZonesDat
|
||||
auto& perDesktopData = history->second;
|
||||
for (auto& data : perDesktopData)
|
||||
{
|
||||
if (data.deviceId == deviceId)
|
||||
if (data.workAreaId == workAreaId)
|
||||
{
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(window, &processId);
|
||||
@@ -496,7 +550,7 @@ void AppZoneHistory::UpdateProcessIdToHandleMap(HWND window, const FancyZonesDat
|
||||
}
|
||||
}
|
||||
|
||||
ZoneIndexSet AppZoneHistory::GetAppLastZoneIndexSet(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId, const std::wstring_view& zoneSetId) const
|
||||
ZoneIndexSet AppZoneHistory::GetAppLastZoneIndexSet(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId, const std::wstring_view& zoneSetId) const
|
||||
{
|
||||
auto processPath = get_process_path_waiting_uwp(window);
|
||||
if (processPath.empty())
|
||||
@@ -505,7 +559,7 @@ ZoneIndexSet AppZoneHistory::GetAppLastZoneIndexSet(HWND window, const FancyZone
|
||||
return {};
|
||||
}
|
||||
|
||||
auto srcVirtualDesktopIDStr = FancyZonesUtils::GuidToString(deviceId.virtualDesktopId);
|
||||
auto srcVirtualDesktopIDStr = FancyZonesUtils::GuidToString(workAreaId.virtualDesktopId);
|
||||
auto app = processPath;
|
||||
auto pos = processPath.find_last_of('\\');
|
||||
if (pos != std::string::npos && pos + 1 < processPath.length())
|
||||
@@ -515,7 +569,7 @@ ZoneIndexSet AppZoneHistory::GetAppLastZoneIndexSet(HWND window, const FancyZone
|
||||
|
||||
if (srcVirtualDesktopIDStr)
|
||||
{
|
||||
Logger::debug(L"Get {} zone history on monitor: {}, virtual desktop: {}", app, deviceId.deviceName, srcVirtualDesktopIDStr.value());
|
||||
Logger::debug(L"Get {} zone history on monitor: {}, virtual desktop: {}", app, workAreaId.toString(), srcVirtualDesktopIDStr.value());
|
||||
}
|
||||
|
||||
auto history = m_history.find(processPath);
|
||||
@@ -527,15 +581,15 @@ ZoneIndexSet AppZoneHistory::GetAppLastZoneIndexSet(HWND window, const FancyZone
|
||||
const auto& perDesktopData = history->second;
|
||||
for (const auto& data : perDesktopData)
|
||||
{
|
||||
if (data.zoneSetUuid == zoneSetId && data.deviceId.deviceName == deviceId.deviceName)
|
||||
if (data.zoneSetUuid == zoneSetId && data.workAreaId == workAreaId)
|
||||
{
|
||||
auto vdStr = FancyZonesUtils::GuidToString(data.deviceId.virtualDesktopId);
|
||||
auto vdStr = FancyZonesUtils::GuidToString(data.workAreaId.virtualDesktopId);
|
||||
if (vdStr)
|
||||
{
|
||||
Logger::debug(L"App zone history found on the device {} with virtual desktop {}", data.deviceId.deviceName, vdStr.value());
|
||||
Logger::debug(L"App zone history found on the device {} with virtual desktop {}", data.workAreaId.toString(), vdStr.value());
|
||||
}
|
||||
|
||||
if (data.deviceId.virtualDesktopId == deviceId.virtualDesktopId || data.deviceId.virtualDesktopId == GUID_NULL)
|
||||
if (data.workAreaId.virtualDesktopId == workAreaId.virtualDesktopId || data.workAreaId.virtualDesktopId == GUID_NULL)
|
||||
{
|
||||
return data.zoneIndexSet;
|
||||
}
|
||||
@@ -573,9 +627,9 @@ void AppZoneHistory::SyncVirtualDesktops()
|
||||
{
|
||||
for (auto& data : perDesktopData)
|
||||
{
|
||||
if (data.deviceId.virtualDesktopId == GUID_NULL)
|
||||
if (data.workAreaId.virtualDesktopId == GUID_NULL)
|
||||
{
|
||||
data.deviceId.virtualDesktopId = savedInRegistryVirtualDesktopID.value();
|
||||
data.workAreaId.virtualDesktopId = savedInRegistryVirtualDesktopID.value();
|
||||
dirtyFlag = true;
|
||||
}
|
||||
}
|
||||
@@ -598,9 +652,9 @@ void AppZoneHistory::RemoveDeletedVirtualDesktops(const std::vector<GUID>& activ
|
||||
auto& perDesktopData = it->second;
|
||||
for (auto desktopIt = std::begin(perDesktopData); desktopIt != std::end(perDesktopData);)
|
||||
{
|
||||
if (desktopIt->deviceId.virtualDesktopId != GUID_NULL && !active.contains(desktopIt->deviceId.virtualDesktopId))
|
||||
if (desktopIt->workAreaId.virtualDesktopId != GUID_NULL && !active.contains(desktopIt->workAreaId.virtualDesktopId))
|
||||
{
|
||||
auto virtualDesktopIdStr = FancyZonesUtils::GuidToString(desktopIt->deviceId.virtualDesktopId);
|
||||
auto virtualDesktopIdStr = FancyZonesUtils::GuidToString(desktopIt->workAreaId.virtualDesktopId);
|
||||
if (virtualDesktopIdStr)
|
||||
{
|
||||
Logger::info(L"Remove Virtual Desktop id {} from app-zone-history", virtualDesktopIdStr.value());
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace NonLocalizable
|
||||
const static wchar_t* DeviceIdID = L"device-id";
|
||||
const static wchar_t* DeviceID = L"device";
|
||||
const static wchar_t* MonitorID = L"monitor";
|
||||
const static wchar_t* MonitorInstanceID = L"monitor-instance";
|
||||
const static wchar_t* MonitorSerialNumberID = L"serial-number";
|
||||
const static wchar_t* VirtualDesktopID = L"virtual-desktop";
|
||||
}
|
||||
}
|
||||
@@ -39,18 +41,19 @@ public:
|
||||
|
||||
void LoadData();
|
||||
void SaveData();
|
||||
void AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::MonitorId>& ids);
|
||||
|
||||
bool SetAppLastZones(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId, const std::wstring& zoneSetId, const ZoneIndexSet& zoneIndexSet);
|
||||
bool RemoveAppLastZone(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId, const std::wstring_view& zoneSetId);
|
||||
bool SetAppLastZones(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId, const std::wstring& zoneSetId, const ZoneIndexSet& zoneIndexSet);
|
||||
bool RemoveAppLastZone(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId, const std::wstring_view& zoneSetId);
|
||||
|
||||
void RemoveApp(const std::wstring& appPath);
|
||||
|
||||
const TAppZoneHistoryMap& GetFullAppZoneHistory() const noexcept;
|
||||
std::optional<FancyZonesDataTypes::AppZoneHistoryData> GetZoneHistory(const std::wstring& appPath, const FancyZonesDataTypes::DeviceIdData& deviceId) const noexcept;
|
||||
std::optional<FancyZonesDataTypes::AppZoneHistoryData> GetZoneHistory(const std::wstring& appPath, const FancyZonesDataTypes::WorkAreaId& workAreaId) const noexcept;
|
||||
|
||||
bool IsAnotherWindowOfApplicationInstanceZoned(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId) const noexcept;
|
||||
void UpdateProcessIdToHandleMap(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId);
|
||||
ZoneIndexSet GetAppLastZoneIndexSet(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId, const std::wstring_view& zoneSetId) const;
|
||||
bool IsAnotherWindowOfApplicationInstanceZoned(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId) const noexcept;
|
||||
void UpdateProcessIdToHandleMap(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId);
|
||||
ZoneIndexSet GetAppLastZoneIndexSet(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId, const std::wstring_view& zoneSetId) const;
|
||||
|
||||
void SyncVirtualDesktops();
|
||||
void RemoveDeletedVirtualDesktops(const std::vector<GUID>& activeDesktops);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <FancyZonesLib/FancyZonesData/LayoutDefaults.h>
|
||||
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
||||
#include <FancyZonesLib/JsonHelpers.h>
|
||||
#include <FancyZonesLib/MonitorUtils.h>
|
||||
#include <FancyZonesLib/VirtualDesktop.h>
|
||||
#include <FancyZonesLib/util.h>
|
||||
|
||||
@@ -72,7 +73,7 @@ namespace JsonUtils
|
||||
struct AppliedLayoutsJSON
|
||||
{
|
||||
private:
|
||||
static std::optional<FancyZonesDataTypes::DeviceIdData> DeviceIdFromJson(const json::JsonObject& json)
|
||||
static std::optional<FancyZonesDataTypes::WorkAreaId> WorkAreaIdFromJson(const json::JsonObject& json)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -80,6 +81,8 @@ namespace JsonUtils
|
||||
{
|
||||
json::JsonObject device = json.GetNamedObject(NonLocalizable::AppliedLayoutsIds::DeviceID);
|
||||
std::wstring monitor = device.GetNamedString(NonLocalizable::AppliedLayoutsIds::MonitorID).c_str();
|
||||
std::wstring monitorInstance = device.GetNamedString(NonLocalizable::AppliedLayoutsIds::MonitorInstanceID, L"").c_str();
|
||||
std::wstring monitorSerialNumber = device.GetNamedString(NonLocalizable::AppliedLayoutsIds::MonitorSerialNumberID, L"").c_str();
|
||||
std::wstring virtualDesktop = device.GetNamedString(NonLocalizable::AppliedLayoutsIds::VirtualDesktopID).c_str();
|
||||
|
||||
auto virtualDesktopGuid = FancyZonesUtils::GuidFromString(virtualDesktop);
|
||||
@@ -88,8 +91,25 @@ namespace JsonUtils
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return FancyZonesDataTypes::DeviceIdData{
|
||||
.deviceName = monitor,
|
||||
FancyZonesDataTypes::DeviceId deviceId{};
|
||||
if (monitorInstance.empty())
|
||||
{
|
||||
// old data
|
||||
deviceId = MonitorUtils::Display::ConvertObsoleteDeviceId(monitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceId.id = monitor;
|
||||
deviceId.instanceId = monitorInstance;
|
||||
}
|
||||
|
||||
FancyZonesDataTypes::MonitorId monitorId{
|
||||
.deviceId = deviceId,
|
||||
.serialNumber = monitorSerialNumber
|
||||
};
|
||||
|
||||
return FancyZonesDataTypes::WorkAreaId{
|
||||
.monitorId = monitorId,
|
||||
.virtualDesktopId = virtualDesktopGuid.value(),
|
||||
};
|
||||
}
|
||||
@@ -102,8 +122,8 @@ namespace JsonUtils
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return FancyZonesDataTypes::DeviceIdData{
|
||||
.deviceName = bcDeviceId->deviceName,
|
||||
return FancyZonesDataTypes::WorkAreaId{
|
||||
.monitorId = { .deviceId = MonitorUtils::Display::ConvertObsoleteDeviceId(bcDeviceId->deviceName) },
|
||||
.virtualDesktopId = bcDeviceId->virtualDesktopId,
|
||||
};
|
||||
}
|
||||
@@ -115,7 +135,7 @@ namespace JsonUtils
|
||||
}
|
||||
|
||||
public:
|
||||
FancyZonesDataTypes::DeviceIdData deviceId;
|
||||
FancyZonesDataTypes::WorkAreaId workAreaId;
|
||||
Layout data;
|
||||
|
||||
static std::optional<AppliedLayoutsJSON> FromJson(const json::JsonObject& json)
|
||||
@@ -124,7 +144,7 @@ namespace JsonUtils
|
||||
{
|
||||
AppliedLayoutsJSON result;
|
||||
|
||||
auto deviceIdOpt = DeviceIdFromJson(json);
|
||||
auto deviceIdOpt = WorkAreaIdFromJson(json);
|
||||
if (!deviceIdOpt.has_value())
|
||||
{
|
||||
return std::nullopt;
|
||||
@@ -136,7 +156,7 @@ namespace JsonUtils
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
result.deviceId = std::move(deviceIdOpt.value());
|
||||
result.workAreaId = std::move(deviceIdOpt.value());
|
||||
result.data = std::move(layout.value());
|
||||
return result;
|
||||
}
|
||||
@@ -149,9 +169,11 @@ namespace JsonUtils
|
||||
static json::JsonObject ToJson(const AppliedLayoutsJSON& value)
|
||||
{
|
||||
json::JsonObject device{};
|
||||
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorID, json::value(value.deviceId.deviceName));
|
||||
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorID, json::value(value.workAreaId.monitorId.deviceId.id));
|
||||
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorInstanceID, json::value(value.workAreaId.monitorId.deviceId.instanceId));
|
||||
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorSerialNumberID, json::value(value.workAreaId.monitorId.serialNumber));
|
||||
|
||||
auto virtualDesktopStr = FancyZonesUtils::GuidToString(value.deviceId.virtualDesktopId);
|
||||
auto virtualDesktopStr = FancyZonesUtils::GuidToString(value.workAreaId.virtualDesktopId);
|
||||
if (virtualDesktopStr)
|
||||
{
|
||||
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::VirtualDesktopID, json::value(virtualDesktopStr.value()));
|
||||
@@ -176,9 +198,9 @@ namespace JsonUtils
|
||||
{
|
||||
// skip default layouts in case if they were applied to different resolutions on the same monitor.
|
||||
// NOTE: keep the default layout check for users who update PT version from the v0.57
|
||||
if (!map.contains(obj->deviceId) && !isLayoutDefault(obj->data))
|
||||
if (!map.contains(obj->workAreaId) && !isLayoutDefault(obj->data))
|
||||
{
|
||||
map[obj->deviceId] = std::move(obj->data);
|
||||
map[obj->workAreaId] = std::move(obj->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,7 +216,7 @@ namespace JsonUtils
|
||||
for (const auto& [id, data] : map)
|
||||
{
|
||||
AppliedLayoutsJSON obj{};
|
||||
obj.deviceId = id;
|
||||
obj.workAreaId = id;
|
||||
obj.data = data;
|
||||
layoutArray.Append(AppliedLayoutsJSON::ToJson(obj));
|
||||
}
|
||||
@@ -268,6 +290,41 @@ void AppliedLayouts::SaveData()
|
||||
}
|
||||
}
|
||||
|
||||
void AppliedLayouts::AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::MonitorId>& ids)
|
||||
{
|
||||
bool dirtyFlag = false;
|
||||
|
||||
std::vector<std::pair<FancyZonesDataTypes::WorkAreaId, std::wstring>> replaceWithSerialNumber{};
|
||||
for (auto iter = m_layouts.begin(); iter != m_layouts.end(); ++iter)
|
||||
{
|
||||
const auto& [id, layout] = *iter;
|
||||
if (id.monitorId.serialNumber.empty() && !id.monitorId.deviceId.isDefault())
|
||||
{
|
||||
for (const auto& monitorId : ids)
|
||||
{
|
||||
if (id.monitorId.deviceId.id == monitorId.deviceId.id && id.monitorId.deviceId.instanceId == monitorId.deviceId.instanceId)
|
||||
{
|
||||
replaceWithSerialNumber.push_back({ id, monitorId.serialNumber });
|
||||
dirtyFlag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& id : replaceWithSerialNumber)
|
||||
{
|
||||
auto mapEntry = m_layouts.extract(id.first);
|
||||
mapEntry.key().monitorId.serialNumber = id.second;
|
||||
m_layouts.insert(std::move(mapEntry));
|
||||
}
|
||||
|
||||
if (dirtyFlag)
|
||||
{
|
||||
SaveData();
|
||||
}
|
||||
}
|
||||
|
||||
void AppliedLayouts::SyncVirtualDesktops()
|
||||
{
|
||||
// Explorer persists current virtual desktop identifier to registry on a per session basis,
|
||||
@@ -292,7 +349,7 @@ void AppliedLayouts::SyncVirtualDesktops()
|
||||
|
||||
bool dirtyFlag = false;
|
||||
|
||||
std::vector<FancyZonesDataTypes::DeviceIdData> replaceWithCurrentId{};
|
||||
std::vector<FancyZonesDataTypes::WorkAreaId> replaceWithCurrentId{};
|
||||
|
||||
for (const auto& [id, data] : m_layouts)
|
||||
{
|
||||
@@ -351,7 +408,7 @@ void AppliedLayouts::RemoveDeletedVirtualDesktops(const std::vector<GUID>& activ
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Layout> AppliedLayouts::GetDeviceLayout(const FancyZonesDataTypes::DeviceIdData& id) const noexcept
|
||||
std::optional<Layout> AppliedLayouts::GetDeviceLayout(const FancyZonesDataTypes::WorkAreaId& id) const noexcept
|
||||
{
|
||||
auto iter = m_layouts.find(id);
|
||||
if (iter != m_layouts.end())
|
||||
@@ -367,19 +424,19 @@ const AppliedLayouts::TAppliedLayoutsMap& AppliedLayouts::GetAppliedLayoutMap()
|
||||
return m_layouts;
|
||||
}
|
||||
|
||||
bool AppliedLayouts::IsLayoutApplied(const FancyZonesDataTypes::DeviceIdData& id) const noexcept
|
||||
bool AppliedLayouts::IsLayoutApplied(const FancyZonesDataTypes::WorkAreaId& id) const noexcept
|
||||
{
|
||||
auto iter = m_layouts.find(id);
|
||||
return iter != m_layouts.end();
|
||||
}
|
||||
|
||||
bool AppliedLayouts::ApplyLayout(const FancyZonesDataTypes::DeviceIdData& deviceId, Layout layout)
|
||||
bool AppliedLayouts::ApplyLayout(const FancyZonesDataTypes::WorkAreaId& deviceId, Layout layout)
|
||||
{
|
||||
m_layouts[deviceId] = std::move(layout);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AppliedLayouts::ApplyDefaultLayout(const FancyZonesDataTypes::DeviceIdData& deviceId)
|
||||
bool AppliedLayouts::ApplyDefaultLayout(const FancyZonesDataTypes::WorkAreaId& deviceId)
|
||||
{
|
||||
Logger::info(L"Set default layout on {}", deviceId.toString());
|
||||
|
||||
@@ -408,7 +465,7 @@ bool AppliedLayouts::ApplyDefaultLayout(const FancyZonesDataTypes::DeviceIdData&
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AppliedLayouts::CloneLayout(const FancyZonesDataTypes::DeviceIdData& srcId, const FancyZonesDataTypes::DeviceIdData& dstId)
|
||||
bool AppliedLayouts::CloneLayout(const FancyZonesDataTypes::WorkAreaId& srcId, const FancyZonesDataTypes::WorkAreaId& dstId)
|
||||
{
|
||||
if (srcId == dstId || m_layouts.find(srcId) == m_layouts.end())
|
||||
{
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace NonLocalizable
|
||||
const static wchar_t* DeviceIdID = L"device-id";
|
||||
const static wchar_t* DeviceID = L"device";
|
||||
const static wchar_t* MonitorID = L"monitor";
|
||||
const static wchar_t* MonitorInstanceID = L"monitor-instance";
|
||||
const static wchar_t* MonitorSerialNumberID = L"serial-number";
|
||||
const static wchar_t* VirtualDesktopID = L"virtual-desktop";
|
||||
const static wchar_t* AppliedLayoutID = L"applied-layout";
|
||||
const static wchar_t* UuidID = L"uuid";
|
||||
@@ -32,7 +34,7 @@ namespace NonLocalizable
|
||||
class AppliedLayouts
|
||||
{
|
||||
public:
|
||||
using TAppliedLayoutsMap = std::unordered_map<FancyZonesDataTypes::DeviceIdData, Layout>;
|
||||
using TAppliedLayoutsMap = std::unordered_map<FancyZonesDataTypes::WorkAreaId, Layout>;
|
||||
|
||||
static AppliedLayouts& instance();
|
||||
|
||||
@@ -47,18 +49,19 @@ public:
|
||||
|
||||
void LoadData();
|
||||
void SaveData();
|
||||
void AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::MonitorId>& ids);
|
||||
|
||||
void SyncVirtualDesktops();
|
||||
void RemoveDeletedVirtualDesktops(const std::vector<GUID>& activeDesktops);
|
||||
|
||||
std::optional<Layout> GetDeviceLayout(const FancyZonesDataTypes::DeviceIdData& id) const noexcept;
|
||||
std::optional<Layout> GetDeviceLayout(const FancyZonesDataTypes::WorkAreaId& id) const noexcept;
|
||||
const TAppliedLayoutsMap& GetAppliedLayoutMap() const noexcept;
|
||||
|
||||
bool IsLayoutApplied(const FancyZonesDataTypes::DeviceIdData& id) const noexcept;
|
||||
bool IsLayoutApplied(const FancyZonesDataTypes::WorkAreaId& id) const noexcept;
|
||||
|
||||
bool ApplyLayout(const FancyZonesDataTypes::DeviceIdData& deviceId, Layout layout);
|
||||
bool ApplyDefaultLayout(const FancyZonesDataTypes::DeviceIdData& deviceId);
|
||||
bool CloneLayout(const FancyZonesDataTypes::DeviceIdData& srcId, const FancyZonesDataTypes::DeviceIdData& dstId);
|
||||
bool ApplyLayout(const FancyZonesDataTypes::WorkAreaId& deviceId, Layout layout);
|
||||
bool ApplyDefaultLayout(const FancyZonesDataTypes::WorkAreaId& deviceId);
|
||||
bool CloneLayout(const FancyZonesDataTypes::WorkAreaId& srcId, const FancyZonesDataTypes::WorkAreaId& dstId);
|
||||
|
||||
private:
|
||||
AppliedLayouts();
|
||||
|
||||
Reference in New Issue
Block a user