Compare window desktop id with currently active work area desktop id. (#2110)

* Compare window desktop id with currently active work area desktop id.

* Improve error handling and conform to coding guidelines.

* Move virtual desktop helper functions to ZoneWindowUtils namespace.

* Ensure thread safety when creating instance of VirtualDesktopManager.

* Remove static qualifier from ServiceProvider.

* Return instead of break, as there is no need to check for other monitors, virtual desktop is the same for all.

* Move virtual desktop related helper functions to separate files.

* Skip comparing desktop ids if zone window has empty GUID for desktop id.

* Add comment describion scenario for which we need this fix.
This commit is contained in:
vldmr11080 2020-04-21 19:57:21 +02:00 committed by GitHub
parent b5dfe6320d
commit 5ac7eddd03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 80 additions and 1 deletions

View File

@ -9,6 +9,7 @@
#include "lib/JsonHelpers.h"
#include "lib/ZoneSet.h"
#include "trace.h"
#include "VirtualDesktopUtils.h"
#include <functional>
#include <common/common.h>
@ -349,17 +350,28 @@ FancyZones::VirtualDesktopInitialize() noexcept
IFACEMETHODIMP_(void)
FancyZones::WindowCreated(HWND window) noexcept
{
std::shared_lock readLock(m_lock);
if (m_settings->GetSettings()->appLastZone_moveWindows && IsInterestingWindow(window))
{
for (const auto& [monitor, zoneWindow] : m_zoneWindowMap)
{
// WindowCreated is also invoked when a virtual desktop switch occurs, we need a way
// to figure out when that happens to avoid moving windows that should not be moved.
GUID windowDesktopId{};
GUID zoneWindowDesktopId{};
if (VirtualDesktopUtils::GetWindowDesktopId(window, &windowDesktopId) &&
VirtualDesktopUtils::GetZoneWindowDesktopId(zoneWindow.get(), &zoneWindowDesktopId) &&
(windowDesktopId != zoneWindowDesktopId))
{
return;
}
const auto activeZoneSet = zoneWindow->ActiveZoneSet();
if (activeZoneSet)
{
const auto& fancyZonesData = JSONHelpers::FancyZonesDataInstance();
wil::unique_cotaskmem_string guidString;
if (SUCCEEDED_LOG(StringFromCLSID(activeZoneSet->Id(), &guidString)))
if (SUCCEEDED(StringFromCLSID(activeZoneSet->Id(), &guidString)))
{
int zoneIndex = fancyZonesData.GetAppLastZoneIndex(window, zoneWindow->UniqueId(), guidString.get());
if (zoneIndex != -1)

View File

@ -103,6 +103,7 @@
<ClInclude Include="Settings.h" />
<ClInclude Include="trace.h" />
<ClInclude Include="util.h" />
<ClInclude Include="VirtualDesktopUtils.h" />
<ClInclude Include="Zone.h" />
<ClInclude Include="ZoneSet.h" />
<ClInclude Include="ZoneWindow.h" />
@ -117,6 +118,7 @@
<ClCompile Include="Settings.cpp" />
<ClCompile Include="trace.cpp" />
<ClCompile Include="util.cpp" />
<ClCompile Include="VirtualDesktopUtils.cpp" />
<ClCompile Include="Zone.cpp" />
<ClCompile Include="ZoneSet.cpp" />
<ClCompile Include="ZoneWindow.cpp" />

View File

@ -48,6 +48,9 @@
<ClInclude Include="JsonHelpers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="VirtualDesktopUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
@ -77,6 +80,9 @@
<ClCompile Include="util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="VirtualDesktopUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="fancyzones.rc">

View File

@ -0,0 +1,49 @@
#include "pch.h"
#include "VirtualDesktopUtils.h"
namespace VirtualDesktopUtils
{
const CLSID CLSID_ImmersiveShell = { 0xC2F03A33, 0x21F5, 0x47FA, 0xB4, 0xBB, 0x15, 0x63, 0x62, 0xA2, 0xF2, 0x39 };
const wchar_t GUID_EmptyGUID[] = L"{00000000-0000-0000-0000-000000000000}";
IServiceProvider* GetServiceProvider()
{
IServiceProvider* provider{ nullptr };
if (FAILED(CoCreateInstance(CLSID_ImmersiveShell, nullptr, CLSCTX_LOCAL_SERVER, __uuidof(provider), (PVOID*)&provider)))
{
return nullptr;
}
return provider;
}
IVirtualDesktopManager* GetVirtualDesktopManager()
{
IVirtualDesktopManager* manager{ nullptr };
IServiceProvider* serviceProvider = GetServiceProvider();
if (serviceProvider == nullptr || FAILED(serviceProvider->QueryService(__uuidof(manager), &manager)))
{
return nullptr;
}
return manager;
}
bool GetWindowDesktopId(HWND topLevelWindow, GUID* desktopId)
{
static IVirtualDesktopManager* virtualDesktopManager = GetVirtualDesktopManager();
return (virtualDesktopManager != nullptr) &&
SUCCEEDED(virtualDesktopManager->GetWindowDesktopId(topLevelWindow, desktopId));
}
bool GetZoneWindowDesktopId(IZoneWindow* zoneWindow, GUID* desktopId)
{
// Format: <device-id>_<resolution>_<virtual-desktop-id>
std::wstring uniqueId = zoneWindow->UniqueId();
std::wstring virtualDesktopId = uniqueId.substr(uniqueId.rfind('_') + 1);
if (virtualDesktopId == GUID_EmptyGUID)
{
return false;
}
return SUCCEEDED(CLSIDFromString(virtualDesktopId.c_str(), desktopId));
}
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "ZoneWindow.h"
namespace VirtualDesktopUtils
{
bool GetWindowDesktopId(HWND topLevelWindow, GUID* desktopId);
bool GetZoneWindowDesktopId(IZoneWindow* zoneWindow, GUID* desktopId);
}

View File

@ -7,6 +7,7 @@ namespace ZoneWindowUtils
const std::wstring& GetActiveZoneSetTmpPath();
const std::wstring& GetAppliedZoneSetTmpPath();
const std::wstring& GetCustomZoneSetsTmpPath();
std::wstring GenerateUniqueId(HMONITOR monitor, PCWSTR deviceId, PCWSTR virtualDesktopId);
}