Only clone layout from parent desktop when creating new virtual desktop (#1904)

* Fix issue #1343

* Add Unit Tests

* Revert non intended rename

* Address PR comments
This commit is contained in:
stefansjfw
2020-04-10 16:29:18 +02:00
committed by GitHub
parent 629ba763d7
commit f589dd2f26
5 changed files with 99 additions and 33 deletions

View File

@@ -681,7 +681,7 @@ void FancyZones::AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept
//const bool flash = m_settings->GetSettings()->zoneSetChange_flashZones && newWorkArea;
const bool flash = false;
auto zoneWindow = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, flash);
auto zoneWindow = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, flash, newWorkArea);
if (zoneWindow)
{
m_zoneWindowMap[monitor] = std::move(zoneWindow);

View File

@@ -212,6 +212,11 @@ namespace JSONHelpers
customZoneSetsMap.clear();
activeDeviceId.clear();
}
inline void SetDeviceInfo(const std::wstring& deviceId, DeviceInfoData data)
{
deviceInfoMap[deviceId] = data;
}
#endif
inline void SetActiveDeviceId(const std::wstring& deviceId)

View File

@@ -205,7 +205,7 @@ public:
ZoneWindow(HINSTANCE hinstance);
~ZoneWindow();
bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones);
bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea);
IFACEMETHODIMP MoveSizeEnter(HWND window, bool dragEnabled) noexcept;
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept;
@@ -240,7 +240,7 @@ protected:
private:
void LoadSettings() noexcept;
void InitializeZoneSets(MONITORINFO const& mi) noexcept;
void InitializeZoneSets(bool newWorkArea) noexcept;
void CalculateZoneSet() noexcept;
void UpdateActiveZoneSet(_In_opt_ IZoneSet* zoneSet) noexcept;
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
@@ -297,7 +297,7 @@ ZoneWindow::~ZoneWindow()
Gdiplus::GdiplusShutdown(gdiplusToken);
}
bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones)
bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea)
{
m_host.copy_from(host);
@@ -316,7 +316,7 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit
m_uniqueId = uniqueId;
LoadSettings();
InitializeZoneSets(mi);
InitializeZoneSets(newWorkArea);
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)
@@ -543,10 +543,10 @@ void ZoneWindow::LoadSettings() noexcept
JSONHelpers::FancyZonesDataInstance().AddDevice(m_uniqueId);
}
void ZoneWindow::InitializeZoneSets(MONITORINFO const& mi) noexcept
void ZoneWindow::InitializeZoneSets(bool newWorkArea) noexcept
{
auto parent = m_host->GetParentZoneWindow(m_monitor);
if (parent)
if (newWorkArea && parent)
{
// Update device info with device info from parent virtual desktop (if empty).
JSONHelpers::FancyZonesDataInstance().CloneDeviceInfo(parent->UniqueId(), m_uniqueId);
@@ -787,10 +787,10 @@ LRESULT CALLBACK ZoneWindow::s_WndProc(HWND window, UINT message, WPARAM wparam,
DefWindowProc(window, message, wparam, lparam);
}
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones) noexcept
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea) noexcept
{
auto self = winrt::make_self<ZoneWindow>(hinstance);
if (self->Init(host, hinstance, monitor, uniqueId, flashZones))
if (self->Init(host, hinstance, monitor, uniqueId, flashZones, newWorkArea))
{
return self;
}

View File

@@ -105,4 +105,4 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow
};
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor,
const std::wstring& uniqueId, bool flashZones) noexcept;
const std::wstring& uniqueId, bool flashZones, bool newWorkArea) noexcept;

View File

@@ -55,6 +55,7 @@ namespace FancyZonesUnitTests
{
const std::wstring m_deviceId = L"\\\\?\\DISPLAY#DELA026#5&10a58c63&0&UID16777488#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}";
const std::wstring m_virtualDesktopId = L"MyVirtualDesktopId";
std::wstringstream m_parentUniqueId;
std::wstringstream m_uniqueId;
HINSTANCE m_hInst{};
@@ -75,6 +76,7 @@ namespace FancyZonesUnitTests
m_monitorInfo.cbSize = sizeof(m_monitorInfo);
Assert::AreNotEqual(0, GetMonitorInfoW(m_monitor, &m_monitorInfo));
m_parentUniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{61FA9FC0-26A6-4B37-A834-491C148DFC57}";
m_uniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{39B25DD2-130D-4B5D-8851-4791D66B1539}";
Assert::IsFalse(ZoneWindowUtils::GetActiveZoneSetTmpPath().empty());
@@ -113,7 +115,7 @@ namespace FancyZonesUnitTests
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
return MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
return MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
}
void testZoneWindow(winrt::com_ptr<IZoneWindow> zoneWindow)
@@ -129,14 +131,14 @@ namespace FancyZonesUnitTests
public:
TEST_METHOD(CreateZoneWindow)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
testZoneWindow(m_zoneWindow);
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
}
TEST_METHOD(CreateZoneWindowNoHinst)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), false, false);
testZoneWindow(m_zoneWindow);
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
@@ -144,7 +146,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(CreateZoneWindowNoHinstFlashZones)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), true);
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), true, false);
testZoneWindow(m_zoneWindow);
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
@@ -152,7 +154,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(CreateZoneWindowNoMonitor)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), false, false);
Assert::IsNull(m_zoneWindow.get());
Assert::IsNotNull(m_hostPtr);
@@ -160,7 +162,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(CreateZoneWindowNoMonitorFlashZones)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), true);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), true, false);
Assert::IsNull(m_zoneWindow.get());
Assert::IsNotNull(m_hostPtr);
@@ -170,7 +172,7 @@ namespace FancyZonesUnitTests
{
// Generate unique id without device id
std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, nullptr, m_virtualDesktopId.c_str());
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false, false);
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
const std::wstring expectedUniqueId = L"FallbackDevice_" + std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom) + L"_" + m_virtualDesktopId;
@@ -186,7 +188,7 @@ namespace FancyZonesUnitTests
{
// Generate unique id without virtual desktop id
std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, m_deviceId.c_str(), nullptr);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false, false);
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
Assert::IsNotNull(m_zoneWindow.get());
@@ -213,7 +215,7 @@ namespace FancyZonesUnitTests
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
//temp file read on initialization
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
testZoneWindow(actual);
@@ -237,7 +239,7 @@ namespace FancyZonesUnitTests
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
//temp file read on initialization
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
testZoneWindow(actual);
@@ -273,7 +275,7 @@ namespace FancyZonesUnitTests
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
//temp file read on initialization
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
testZoneWindow(actual);
@@ -320,7 +322,7 @@ namespace FancyZonesUnitTests
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
//temp file read on initialization
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
testZoneWindow(actual);
@@ -367,7 +369,7 @@ namespace FancyZonesUnitTests
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
//temp file read on initialization
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
testZoneWindow(actual);
@@ -376,9 +378,68 @@ namespace FancyZonesUnitTests
Assert::AreEqual((size_t)1, actualZoneSet.size());
}
TEST_METHOD (CreateZoneWindowClonedFromParent)
{
using namespace JSONHelpers;
const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid;
const int spacing = 10;
const int zoneCount = 5;
const auto customSetGuid = Helpers::CreateGuidString();
const auto parentZoneSet = ZoneSetData{ customSetGuid, type };
const auto parentDeviceInfo = DeviceInfoData{ parentZoneSet, true, spacing, zoneCount };
m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo);
auto parentZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_parentUniqueId.str(), false, false);
m_zoneWindowHost.m_zoneWindow = parentZoneWindow.get();
// newWorkArea = true - zoneWindow will be cloned from parent
auto actualZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, true);
Assert::IsNotNull(actualZoneWindow->ActiveZoneSet());
const auto actualZoneSet = actualZoneWindow->ActiveZoneSet()->GetZones();
Assert::AreEqual((size_t)zoneCount, actualZoneSet.size());
Assert::IsTrue(m_fancyZonesData.GetDeviceInfoMap().contains(m_uniqueId.str()));
auto currentDeviceInfo = m_fancyZonesData.GetDeviceInfoMap().at(m_uniqueId.str());
Assert::AreEqual(zoneCount, currentDeviceInfo.zoneCount);
Assert::AreEqual(spacing, currentDeviceInfo.spacing);
Assert::AreEqual(static_cast<int>(type), static_cast<int>(currentDeviceInfo.activeZoneSet.type));
}
TEST_METHOD (CreateZoneWindowNotClonedFromParent)
{
using namespace JSONHelpers;
const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid;
const int spacing = 10;
const int zoneCount = 5;
const auto customSetGuid = Helpers::CreateGuidString();
const auto parentZoneSet = ZoneSetData{ customSetGuid, type };
const auto parentDeviceInfo = DeviceInfoData{ parentZoneSet, true, spacing, zoneCount };
m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo);
auto parentZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_parentUniqueId.str(), false, false);
m_zoneWindowHost.m_zoneWindow = parentZoneWindow.get();
// newWorkArea = false - zoneWindow won't be cloned from parent
auto actualZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
Assert::IsNull(actualZoneWindow->ActiveZoneSet());
Assert::IsTrue(m_fancyZonesData.GetDeviceInfoMap().contains(m_uniqueId.str()));
auto currentDeviceInfo = m_fancyZonesData.GetDeviceInfoMap().at(m_uniqueId.str());
// default values
Assert::AreEqual(false, currentDeviceInfo.showSpacing);
Assert::AreEqual(0, currentDeviceInfo.zoneCount);
Assert::AreEqual(0, currentDeviceInfo.spacing);
Assert::AreEqual(std::wstring{ L"null" }, currentDeviceInfo.activeZoneSet.uuid);
Assert::AreEqual(static_cast<int>(ZoneSetLayoutType::Blank), static_cast<int>(currentDeviceInfo.activeZoneSet.type));
}
TEST_METHOD(MoveSizeEnter)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
const auto expected = S_OK;
const auto actual = m_zoneWindow->MoveSizeEnter(Mocks::Window(), true);
@@ -389,7 +450,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(MoveSizeEnterTwice)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
const auto expected = E_INVALIDARG;
@@ -402,7 +463,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(MoveSizeUpdate)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
const auto expected = S_OK;
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ 0, 0 }, true);
@@ -413,7 +474,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(MoveSizeUpdatePointNegativeCoordinates)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
const auto expected = S_OK;
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ -10, -10 }, true);
@@ -424,7 +485,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(MoveSizeUpdatePointBigCoordinates)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
const auto expected = S_OK;
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ m_monitorInfo.rcMonitor.right + 1, m_monitorInfo.rcMonitor.bottom + 1 }, true);
@@ -468,7 +529,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(MoveSizeEndDifferentWindows)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
const auto window = Mocks::Window();
m_zoneWindow->MoveSizeEnter(window, true);
@@ -481,7 +542,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(MoveSizeEndWindowNotSet)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
const auto expected = E_INVALIDARG;
const auto actual = m_zoneWindow->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 });
@@ -508,7 +569,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(MoveWindowIntoZoneByIndexNoActiveZoneSet)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
@@ -526,7 +587,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(MoveWindowIntoZoneByDirectionNoActiveZoneSet)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
@@ -564,7 +625,7 @@ namespace FancyZonesUnitTests
TEST_METHOD(SaveWindowProcessToZoneIndexNoActiveZoneSet)
{
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
m_zoneWindow->SaveWindowProcessToZoneIndex(Mocks::Window());