mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
[FancyZones] Open window in a zone fix (#18193)
* removed background thread monitoring virtual desktops * removed virtual desktop callbacks * centralize work with virtual desktops * updated virtual desktops sync * app zone history logs * logs * get uwp process path * spell
This commit is contained in:
@@ -68,6 +68,23 @@ inline std::wstring get_process_path(HWND window) noexcept
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::wstring get_process_path_waiting_uwp(HWND window)
|
||||||
|
{
|
||||||
|
const static std::wstring appFrameHost = L"ApplicationFrameHost.exe";
|
||||||
|
|
||||||
|
int attempt = 0;
|
||||||
|
auto processPath = get_process_path(window);
|
||||||
|
|
||||||
|
while (++attempt < 30 && processPath.length() >= appFrameHost.length() &&
|
||||||
|
processPath.compare(processPath.length() - appFrameHost.length(), appFrameHost.length(), appFrameHost) == 0)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
|
processPath = get_process_path(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
return processPath;
|
||||||
|
}
|
||||||
|
|
||||||
inline std::wstring get_module_filename(HMODULE mod = nullptr)
|
inline std::wstring get_module_filename(HMODULE mod = nullptr)
|
||||||
{
|
{
|
||||||
wchar_t buffer[MAX_PATH + 1];
|
wchar_t buffer[MAX_PATH + 1];
|
||||||
|
|||||||
@@ -59,12 +59,6 @@ public:
|
|||||||
m_hinstance(hinstance),
|
m_hinstance(hinstance),
|
||||||
m_windowMoveHandler([this]() {
|
m_windowMoveHandler([this]() {
|
||||||
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
|
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
|
||||||
}),
|
|
||||||
m_virtualDesktop([this]() {
|
|
||||||
PostMessage(m_window, WM_PRIV_VD_INIT, 0, 0);
|
|
||||||
},
|
|
||||||
[this]() {
|
|
||||||
PostMessage(m_window, WM_PRIV_VD_UPDATE, 0, 0);
|
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
this->disableModuleCallback = std::move(disableModuleCallback);
|
this->disableModuleCallback = std::move(disableModuleCallback);
|
||||||
@@ -92,7 +86,7 @@ public:
|
|||||||
monitor = NULL;
|
monitor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_windowMoveHandler.MoveSizeStart(window, monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId));
|
m_windowMoveHandler.MoveSizeStart(window, monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen) noexcept
|
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen) noexcept
|
||||||
@@ -101,12 +95,12 @@ public:
|
|||||||
{
|
{
|
||||||
monitor = NULL;
|
monitor = NULL;
|
||||||
}
|
}
|
||||||
m_windowMoveHandler.MoveSizeUpdate(monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId));
|
m_windowMoveHandler.MoveSizeUpdate(monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept
|
void MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept
|
||||||
{
|
{
|
||||||
m_windowMoveHandler.MoveSizeEnd(window, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId));
|
m_windowMoveHandler.MoveSizeEnd(window, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
@@ -189,10 +183,7 @@ private:
|
|||||||
HWND m_window{};
|
HWND m_window{};
|
||||||
WindowMoveHandler m_windowMoveHandler;
|
WindowMoveHandler m_windowMoveHandler;
|
||||||
MonitorWorkAreaHandler m_workAreaHandler;
|
MonitorWorkAreaHandler m_workAreaHandler;
|
||||||
VirtualDesktop m_virtualDesktop;
|
|
||||||
|
|
||||||
GUID m_previousDesktopId{}; // UUID of previously active virtual desktop.
|
|
||||||
GUID m_currentDesktopId{}; // UUID of the current virtual desktop.
|
|
||||||
wil::unique_handle m_terminateEditorEvent; // Handle of FancyZonesEditor.exe we launch and wait on
|
wil::unique_handle m_terminateEditorEvent; // Handle of FancyZonesEditor.exe we launch and wait on
|
||||||
|
|
||||||
OnThreadExecutor m_dpiUnawareThread;
|
OnThreadExecutor m_dpiUnawareThread;
|
||||||
@@ -258,8 +249,6 @@ FancyZones::Run() noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_virtualDesktop.Init();
|
|
||||||
|
|
||||||
m_dpiUnawareThread.submit(OnThreadExecutor::task_t{ [] {
|
m_dpiUnawareThread.submit(OnThreadExecutor::task_t{ [] {
|
||||||
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
|
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
|
||||||
SetThreadDpiHostingBehavior(DPI_HOSTING_BEHAVIOR_MIXED);
|
SetThreadDpiHostingBehavior(DPI_HOSTING_BEHAVIOR_MIXED);
|
||||||
@@ -274,8 +263,7 @@ FancyZones::Run() noexcept
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AppliedLayouts::instance().SetVirtualDesktopCheckCallback(std::bind(&VirtualDesktop::IsVirtualDesktopIdSavedInRegistry, &m_virtualDesktop, std::placeholders::_1));
|
PostMessage(m_window, WM_PRIV_VD_INIT, 0, 0);
|
||||||
AppZoneHistory::instance().SetVirtualDesktopCheckCallback(std::bind(&VirtualDesktop::IsVirtualDesktopIdSavedInRegistry, &m_virtualDesktop, std::placeholders::_1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IFancyZones
|
// IFancyZones
|
||||||
@@ -289,8 +277,6 @@ FancyZones::Destroy() noexcept
|
|||||||
DestroyWindow(m_window);
|
DestroyWindow(m_window);
|
||||||
m_window = nullptr;
|
m_window = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_virtualDesktop.UnInit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IFancyZonesCallback
|
// IFancyZonesCallback
|
||||||
@@ -343,7 +329,7 @@ void FancyZones::MoveWindowIntoZone(HWND window, winrt::com_ptr<IWorkArea> workA
|
|||||||
|
|
||||||
bool FancyZones::MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primary) noexcept
|
bool FancyZones::MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primary) noexcept
|
||||||
{
|
{
|
||||||
auto workAreaMap = m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId);
|
auto workAreaMap = m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
||||||
if (workAreaMap.empty())
|
if (workAreaMap.empty())
|
||||||
{
|
{
|
||||||
Logger::trace(L"No work area for the current desktop.");
|
Logger::trace(L"No work area for the current desktop.");
|
||||||
@@ -390,8 +376,8 @@ void FancyZones::WindowCreated(HWND window) noexcept
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto desktopId = m_virtualDesktop.GetDesktopId(window);
|
auto desktopId = VirtualDesktop::instance().GetDesktopId(window);
|
||||||
if (desktopId.has_value() && *desktopId != m_currentDesktopId)
|
if (desktopId.has_value() && *desktopId != VirtualDesktop::instance().GetCurrentVirtualDesktopId())
|
||||||
{
|
{
|
||||||
// Switch between virtual desktops results with posting same windows messages that also indicate
|
// Switch between virtual desktops results with posting same windows messages that also indicate
|
||||||
// creation of new window. We need to check if window being processed is on currently active desktop.
|
// creation of new window. We need to check if window being processed is on currently active desktop.
|
||||||
@@ -537,7 +523,7 @@ void FancyZones::ToggleEditor() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
wil::unique_cotaskmem_string virtualDesktopId;
|
wil::unique_cotaskmem_string virtualDesktopId;
|
||||||
if (!SUCCEEDED(StringFromCLSID(m_currentDesktopId, &virtualDesktopId)))
|
if (!SUCCEEDED(StringFromCLSID(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), &virtualDesktopId)))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -806,28 +792,7 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept
|
|||||||
if (changeType == DisplayChangeType::VirtualDesktop ||
|
if (changeType == DisplayChangeType::VirtualDesktop ||
|
||||||
changeType == DisplayChangeType::Initialization)
|
changeType == DisplayChangeType::Initialization)
|
||||||
{
|
{
|
||||||
m_previousDesktopId = m_currentDesktopId;
|
VirtualDesktop::instance().UpdateVirtualDesktopId();
|
||||||
|
|
||||||
auto currentVirtualDesktopId = m_virtualDesktop.GetCurrentVirtualDesktopIdFromRegistry();
|
|
||||||
if (!currentVirtualDesktopId.has_value())
|
|
||||||
{
|
|
||||||
Logger::info("Virtual Desktop id from top level window");
|
|
||||||
currentVirtualDesktopId = m_virtualDesktop.GetDesktopIdByTopLevelWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentVirtualDesktopId.has_value())
|
|
||||||
{
|
|
||||||
m_currentDesktopId = *currentVirtualDesktopId;
|
|
||||||
if (m_previousDesktopId != GUID_NULL && m_currentDesktopId != m_previousDesktopId)
|
|
||||||
{
|
|
||||||
Trace::VirtualDesktopChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_currentDesktopId == GUID_NULL)
|
|
||||||
{
|
|
||||||
Logger::warn("Couldn't retrieve virtual desktop id");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changeType == DisplayChangeType::Initialization)
|
if (changeType == DisplayChangeType::Initialization)
|
||||||
{
|
{
|
||||||
@@ -848,16 +813,16 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept
|
|||||||
|
|
||||||
void FancyZones::AddWorkArea(HMONITOR monitor, const std::wstring& deviceId) noexcept
|
void FancyZones::AddWorkArea(HMONITOR monitor, const std::wstring& deviceId) noexcept
|
||||||
{
|
{
|
||||||
if (m_workAreaHandler.IsNewWorkArea(m_currentDesktopId, monitor))
|
if (m_workAreaHandler.IsNewWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), monitor))
|
||||||
{
|
{
|
||||||
wil::unique_cotaskmem_string virtualDesktopIdStr;
|
wil::unique_cotaskmem_string virtualDesktopIdStr;
|
||||||
if (!SUCCEEDED(StringFromCLSID(m_currentDesktopId, &virtualDesktopIdStr)))
|
if (!SUCCEEDED(StringFromCLSID(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), &virtualDesktopIdStr)))
|
||||||
{
|
{
|
||||||
Logger::debug(L"Add new work area on virtual desktop {}", virtualDesktopIdStr.get());
|
Logger::debug(L"Add new work area on virtual desktop {}", virtualDesktopIdStr.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
FancyZonesDataTypes::DeviceIdData uniqueId;
|
FancyZonesDataTypes::DeviceIdData uniqueId;
|
||||||
uniqueId.virtualDesktopId = m_currentDesktopId;
|
uniqueId.virtualDesktopId = VirtualDesktop::instance().GetCurrentVirtualDesktopId();
|
||||||
|
|
||||||
if (monitor)
|
if (monitor)
|
||||||
{
|
{
|
||||||
@@ -869,7 +834,7 @@ void FancyZones::AddWorkArea(HMONITOR monitor, const std::wstring& deviceId) noe
|
|||||||
}
|
}
|
||||||
|
|
||||||
FancyZonesDataTypes::DeviceIdData parentId{};
|
FancyZonesDataTypes::DeviceIdData parentId{};
|
||||||
auto parentArea = m_workAreaHandler.GetWorkArea(m_previousDesktopId, monitor);
|
auto parentArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetPreviousVirtualDesktopId(), monitor);
|
||||||
if (parentArea)
|
if (parentArea)
|
||||||
{
|
{
|
||||||
parentId = parentArea->UniqueId();
|
parentId = parentArea->UniqueId();
|
||||||
@@ -878,7 +843,7 @@ void FancyZones::AddWorkArea(HMONITOR monitor, const std::wstring& deviceId) noe
|
|||||||
auto workArea = MakeWorkArea(m_hinstance, monitor, uniqueId, parentId);
|
auto workArea = MakeWorkArea(m_hinstance, monitor, uniqueId, parentId);
|
||||||
if (workArea)
|
if (workArea)
|
||||||
{
|
{
|
||||||
m_workAreaHandler.AddWorkArea(m_currentDesktopId, monitor, workArea);
|
m_workAreaHandler.AddWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), monitor, workArea);
|
||||||
AppliedLayouts::instance().SaveData();
|
AppliedLayouts::instance().SaveData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -935,7 +900,7 @@ void FancyZones::UpdateWorkAreas() noexcept
|
|||||||
|
|
||||||
void FancyZones::UpdateWindowsPositions(bool suppressMove) noexcept
|
void FancyZones::UpdateWindowsPositions(bool suppressMove) noexcept
|
||||||
{
|
{
|
||||||
for (const auto [window, desktopId] : m_virtualDesktop.GetWindowsRelatedToDesktops())
|
for (const auto [window, desktopId] : VirtualDesktop::instance().GetWindowsRelatedToDesktops())
|
||||||
{
|
{
|
||||||
auto zoneIndexSet = FancyZonesWindowProperties::RetrieveZoneIndexProperty(window);
|
auto zoneIndexSet = FancyZonesWindowProperties::RetrieveZoneIndexProperty(window);
|
||||||
auto workArea = m_workAreaHandler.GetWorkArea(window, desktopId);
|
auto workArea = m_workAreaHandler.GetWorkArea(window, desktopId);
|
||||||
@@ -951,7 +916,7 @@ void FancyZones::CycleTabs(bool reverse) noexcept
|
|||||||
auto window = GetForegroundWindow();
|
auto window = GetForegroundWindow();
|
||||||
HMONITOR current = WorkAreaKeyFromWindow(window);
|
HMONITOR current = WorkAreaKeyFromWindow(window);
|
||||||
|
|
||||||
auto workArea = m_workAreaHandler.GetWorkArea(m_currentDesktopId, current);
|
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), current);
|
||||||
if (workArea)
|
if (workArea)
|
||||||
{
|
{
|
||||||
workArea->CycleTabs(window, reverse);
|
workArea->CycleTabs(window, reverse);
|
||||||
@@ -969,7 +934,7 @@ bool FancyZones::OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexce
|
|||||||
auto currMonitorInfo = std::find(std::begin(monitorInfo), std::end(monitorInfo), current);
|
auto currMonitorInfo = std::find(std::begin(monitorInfo), std::end(monitorInfo), current);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
auto workArea = m_workAreaHandler.GetWorkArea(m_currentDesktopId, *currMonitorInfo);
|
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), *currMonitorInfo);
|
||||||
if (m_windowMoveHandler.MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, false /* cycle through zones */, workArea))
|
if (m_windowMoveHandler.MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, false /* cycle through zones */, workArea))
|
||||||
{
|
{
|
||||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->ZoneSet());
|
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->ZoneSet());
|
||||||
@@ -996,7 +961,7 @@ bool FancyZones::OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexce
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto workArea = m_workAreaHandler.GetWorkArea(m_currentDesktopId, current);
|
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), current);
|
||||||
// Single monitor environment, or combined multi-monitor environment.
|
// Single monitor environment, or combined multi-monitor environment.
|
||||||
if (FancyZonesSettings::settings().restoreSize)
|
if (FancyZonesSettings::settings().restoreSize)
|
||||||
{
|
{
|
||||||
@@ -1036,7 +1001,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
|||||||
{
|
{
|
||||||
// Multi monitor environment.
|
// Multi monitor environment.
|
||||||
// First, try to stay on the same monitor
|
// First, try to stay on the same monitor
|
||||||
bool success = ProcessDirectedSnapHotkey(window, vkCode, false, m_workAreaHandler.GetWorkArea(m_currentDesktopId, current));
|
bool success = ProcessDirectedSnapHotkey(window, vkCode, false, m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), current));
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -1055,7 +1020,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto workArea = m_workAreaHandler.GetWorkArea(m_currentDesktopId, monitor);
|
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), monitor);
|
||||||
if (workArea)
|
if (workArea)
|
||||||
{
|
{
|
||||||
auto zoneSet = workArea->ZoneSet();
|
auto zoneSet = workArea->ZoneSet();
|
||||||
@@ -1103,7 +1068,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
|||||||
// Sanity check: the current monitor is valid
|
// Sanity check: the current monitor is valid
|
||||||
if (currentMonitorRect.top <= currentMonitorRect.bottom)
|
if (currentMonitorRect.top <= currentMonitorRect.bottom)
|
||||||
{
|
{
|
||||||
auto workArea = m_workAreaHandler.GetWorkArea(m_currentDesktopId, current);
|
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), current);
|
||||||
if (workArea)
|
if (workArea)
|
||||||
{
|
{
|
||||||
auto zoneSet = workArea->ZoneSet();
|
auto zoneSet = workArea->ZoneSet();
|
||||||
@@ -1150,7 +1115,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Single monitor environment, or combined multi-monitor environment.
|
// Single monitor environment, or combined multi-monitor environment.
|
||||||
return ProcessDirectedSnapHotkey(window, vkCode, true, m_workAreaHandler.GetWorkArea(m_currentDesktopId, current));
|
return ProcessDirectedSnapHotkey(window, vkCode, true, m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), current));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1194,7 +1159,7 @@ bool FancyZones::ProcessDirectedSnapHotkey(HWND window, DWORD vkCode, bool cycle
|
|||||||
|
|
||||||
void FancyZones::RegisterVirtualDesktopUpdates() noexcept
|
void FancyZones::RegisterVirtualDesktopUpdates() noexcept
|
||||||
{
|
{
|
||||||
auto guids = m_virtualDesktop.GetVirtualDesktopIdsFromRegistry();
|
auto guids = VirtualDesktop::instance().GetVirtualDesktopIdsFromRegistry();
|
||||||
if (guids.has_value())
|
if (guids.has_value())
|
||||||
{
|
{
|
||||||
m_workAreaHandler.RegisterUpdates(*guids);
|
m_workAreaHandler.RegisterUpdates(*guids);
|
||||||
@@ -1202,8 +1167,8 @@ void FancyZones::RegisterVirtualDesktopUpdates() noexcept
|
|||||||
AppliedLayouts::instance().RemoveDeletedVirtualDesktops(*guids);
|
AppliedLayouts::instance().RemoveDeletedVirtualDesktops(*guids);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppZoneHistory::instance().SyncVirtualDesktops(m_currentDesktopId);
|
AppZoneHistory::instance().SyncVirtualDesktops();
|
||||||
AppliedLayouts::instance().SyncVirtualDesktops(m_currentDesktopId);
|
AppliedLayouts::instance().SyncVirtualDesktops();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyZones::UpdateHotkey(int hotkeyId, const PowerToysSettings::HotkeyObject& hotkeyObject, bool enable) noexcept
|
void FancyZones::UpdateHotkey(int hotkeyId, const PowerToysSettings::HotkeyObject& hotkeyObject, bool enable) noexcept
|
||||||
@@ -1263,8 +1228,6 @@ void FancyZones::SettingsUpdate(SettingId id)
|
|||||||
void FancyZones::OnEditorExitEvent() noexcept
|
void FancyZones::OnEditorExitEvent() noexcept
|
||||||
{
|
{
|
||||||
// Collect information about changes in zone layout after editor exited.
|
// Collect information about changes in zone layout after editor exited.
|
||||||
AppZoneHistory::instance().SyncVirtualDesktops(m_currentDesktopId);
|
|
||||||
AppliedLayouts::instance().SyncVirtualDesktops(m_currentDesktopId);
|
|
||||||
UpdateZoneSets();
|
UpdateZoneSets();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1286,7 +1249,7 @@ bool FancyZones::ShouldProcessSnapHotkey(DWORD vkCode) noexcept
|
|||||||
{
|
{
|
||||||
HMONITOR monitor = WorkAreaKeyFromWindow(window);
|
HMONITOR monitor = WorkAreaKeyFromWindow(window);
|
||||||
|
|
||||||
auto workArea = m_workAreaHandler.GetWorkArea(m_currentDesktopId, monitor);
|
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), monitor);
|
||||||
if (workArea && workArea->ZoneSet() && workArea->ZoneSet()->LayoutType() != FancyZonesDataTypes::ZoneSetLayoutType::Blank)
|
if (workArea && workArea->ZoneSet() && workArea->ZoneSet()->LayoutType() != FancyZonesDataTypes::ZoneSetLayoutType::Blank)
|
||||||
{
|
{
|
||||||
if (vkCode == VK_UP || vkCode == VK_DOWN)
|
if (vkCode == VK_UP || vkCode == VK_DOWN)
|
||||||
@@ -1317,7 +1280,7 @@ void FancyZones::ApplyQuickLayout(int key) noexcept
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto workArea = m_workAreaHandler.GetWorkAreaFromCursor(m_currentDesktopId);
|
auto workArea = m_workAreaHandler.GetWorkAreaFromCursor(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
||||||
AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), layout.value());
|
AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), layout.value());
|
||||||
AppliedLayouts::instance().SaveData();
|
AppliedLayouts::instance().SaveData();
|
||||||
UpdateZoneSets();
|
UpdateZoneSets();
|
||||||
@@ -1328,7 +1291,7 @@ void FancyZones::FlashZones() noexcept
|
|||||||
{
|
{
|
||||||
if (FancyZonesSettings::settings().flashZonesOnQuickSwitch && !m_windowMoveHandler.IsDragEnabled())
|
if (FancyZonesSettings::settings().flashZonesOnQuickSwitch && !m_windowMoveHandler.IsDragEnabled())
|
||||||
{
|
{
|
||||||
for (auto [monitor, workArea] : m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId))
|
for (auto [monitor, workArea] : m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId()))
|
||||||
{
|
{
|
||||||
workArea->FlashZones();
|
workArea->FlashZones();
|
||||||
}
|
}
|
||||||
@@ -1347,7 +1310,7 @@ std::vector<HMONITOR> FancyZones::GetMonitorsSorted() noexcept
|
|||||||
std::vector<std::pair<HMONITOR, RECT>> FancyZones::GetRawMonitorData() noexcept
|
std::vector<std::pair<HMONITOR, RECT>> FancyZones::GetRawMonitorData() noexcept
|
||||||
{
|
{
|
||||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo;
|
std::vector<std::pair<HMONITOR, RECT>> monitorInfo;
|
||||||
const auto& activeWorkAreaMap = m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId);
|
const auto& activeWorkAreaMap = m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
||||||
for (const auto& [monitor, workArea] : activeWorkAreaMap)
|
for (const auto& [monitor, workArea] : activeWorkAreaMap)
|
||||||
{
|
{
|
||||||
if (workArea->ZoneSet() != nullptr)
|
if (workArea->ZoneSet() != nullptr)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <FancyZonesLib/GuidUtils.h>
|
#include <FancyZonesLib/GuidUtils.h>
|
||||||
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
||||||
#include <FancyZonesLib/JsonHelpers.h>
|
#include <FancyZonesLib/JsonHelpers.h>
|
||||||
|
#include <FancyZonesLib/VirtualDesktop.h>
|
||||||
#include <FancyZonesLib/util.h>
|
#include <FancyZonesLib/util.h>
|
||||||
|
|
||||||
namespace JsonUtils
|
namespace JsonUtils
|
||||||
@@ -221,11 +222,6 @@ AppZoneHistory& AppZoneHistory::instance()
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppZoneHistory::SetVirtualDesktopCheckCallback(std::function<bool(GUID)> callback)
|
|
||||||
{
|
|
||||||
m_virtualDesktopCheckCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppZoneHistory::LoadData()
|
void AppZoneHistory::LoadData()
|
||||||
{
|
{
|
||||||
auto file = AppZoneHistoryFileName();
|
auto file = AppZoneHistoryFileName();
|
||||||
@@ -253,22 +249,20 @@ void AppZoneHistory::SaveData()
|
|||||||
{
|
{
|
||||||
bool dirtyFlag = false;
|
bool dirtyFlag = false;
|
||||||
std::unordered_map<std::wstring, std::vector<FancyZonesDataTypes::AppZoneHistoryData>> updatedHistory;
|
std::unordered_map<std::wstring, std::vector<FancyZonesDataTypes::AppZoneHistoryData>> updatedHistory;
|
||||||
if (m_virtualDesktopCheckCallback)
|
|
||||||
|
for (const auto& [path, dataVector] : m_history)
|
||||||
{
|
{
|
||||||
for (const auto& [path, dataVector] : m_history)
|
auto updatedVector = dataVector;
|
||||||
|
for (auto& data : updatedVector)
|
||||||
{
|
{
|
||||||
auto updatedVector = dataVector;
|
if (!VirtualDesktop::instance().IsVirtualDesktopIdSavedInRegistry(data.deviceId.virtualDesktopId))
|
||||||
for (auto& data : updatedVector)
|
|
||||||
{
|
{
|
||||||
if (!m_virtualDesktopCheckCallback(data.deviceId.virtualDesktopId))
|
data.deviceId.virtualDesktopId = GUID_NULL;
|
||||||
{
|
dirtyFlag = true;
|
||||||
data.deviceId.virtualDesktopId = GUID_NULL;
|
|
||||||
dirtyFlag = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedHistory.insert(std::make_pair(path, updatedVector));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatedHistory.insert(std::make_pair(path, updatedVector));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirtyFlag)
|
if (dirtyFlag)
|
||||||
@@ -288,7 +282,7 @@ bool AppZoneHistory::SetAppLastZones(HWND window, const FancyZonesDataTypes::Dev
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto processPath = get_process_path(window);
|
auto processPath = get_process_path_waiting_uwp(window);
|
||||||
if (processPath.empty())
|
if (processPath.empty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -343,7 +337,7 @@ bool AppZoneHistory::RemoveAppLastZone(HWND window, const FancyZonesDataTypes::D
|
|||||||
{
|
{
|
||||||
Logger::info(L"Add app zone history, device: {}, layout: {}", deviceId.toString(), zoneSetId);
|
Logger::info(L"Add app zone history, device: {}, layout: {}", deviceId.toString(), zoneSetId);
|
||||||
|
|
||||||
auto processPath = get_process_path(window);
|
auto processPath = get_process_path_waiting_uwp(window);
|
||||||
if (!processPath.empty())
|
if (!processPath.empty())
|
||||||
{
|
{
|
||||||
auto history = m_history.find(processPath);
|
auto history = m_history.find(processPath);
|
||||||
@@ -404,25 +398,50 @@ const AppZoneHistory::TAppZoneHistoryMap& AppZoneHistory::GetFullAppZoneHistory(
|
|||||||
|
|
||||||
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::DeviceIdData& deviceId) const noexcept
|
||||||
{
|
{
|
||||||
auto iter = m_history.find(appPath);
|
auto app = appPath;
|
||||||
if (iter != m_history.end())
|
auto pos = appPath.find_last_of('\\');
|
||||||
|
if (pos != std::string::npos && pos + 1 < appPath.length())
|
||||||
{
|
{
|
||||||
auto historyVector = iter->second;
|
app = appPath.substr(pos + 1);
|
||||||
for (const auto& history : historyVector)
|
}
|
||||||
|
|
||||||
|
auto srcVirtualDesktopIDStr = FancyZonesUtils::GuidToString(deviceId.virtualDesktopId);
|
||||||
|
if (srcVirtualDesktopIDStr)
|
||||||
|
{
|
||||||
|
Logger::debug(L"Get {} zone history on monitor: {}, virtual desktop: {}", app, deviceId.deviceName, srcVirtualDesktopIDStr.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto iter = m_history.find(appPath);
|
||||||
|
if (iter == m_history.end())
|
||||||
|
{
|
||||||
|
Logger::info("App history not found");
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto historyVector = iter->second;
|
||||||
|
for (const auto& history : historyVector)
|
||||||
|
{
|
||||||
|
if (history.deviceId.deviceName == deviceId.deviceName)
|
||||||
{
|
{
|
||||||
if (history.deviceId == deviceId)
|
auto vdStr = FancyZonesUtils::GuidToString(history.deviceId.virtualDesktopId);
|
||||||
|
if (vdStr)
|
||||||
|
{
|
||||||
|
Logger::debug(L"App zone history found on the device {} with virtual desktop {}", history.deviceId.deviceName, vdStr.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (history.deviceId.virtualDesktopId == deviceId.virtualDesktopId || history.deviceId.virtualDesktopId == GUID_NULL)
|
||||||
{
|
{
|
||||||
return history;
|
return history;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppZoneHistory::IsAnotherWindowOfApplicationInstanceZoned(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId) const noexcept
|
bool AppZoneHistory::IsAnotherWindowOfApplicationInstanceZoned(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId) const noexcept
|
||||||
{
|
{
|
||||||
auto processPath = get_process_path(window);
|
auto processPath = get_process_path_waiting_uwp(window);
|
||||||
if (!processPath.empty())
|
if (!processPath.empty())
|
||||||
{
|
{
|
||||||
auto history = m_history.find(processPath);
|
auto history = m_history.find(processPath);
|
||||||
@@ -456,7 +475,7 @@ bool AppZoneHistory::IsAnotherWindowOfApplicationInstanceZoned(HWND window, cons
|
|||||||
|
|
||||||
void AppZoneHistory::UpdateProcessIdToHandleMap(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId)
|
void AppZoneHistory::UpdateProcessIdToHandleMap(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId)
|
||||||
{
|
{
|
||||||
auto processPath = get_process_path(window);
|
auto processPath = get_process_path_waiting_uwp(window);
|
||||||
if (!processPath.empty())
|
if (!processPath.empty())
|
||||||
{
|
{
|
||||||
auto history = m_history.find(processPath);
|
auto history = m_history.find(processPath);
|
||||||
@@ -479,39 +498,75 @@ 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::DeviceIdData& deviceId, const std::wstring_view& zoneSetId) const
|
||||||
{
|
{
|
||||||
auto processPath = get_process_path(window);
|
auto processPath = get_process_path_waiting_uwp(window);
|
||||||
if (!processPath.empty())
|
if (processPath.empty())
|
||||||
{
|
{
|
||||||
auto history = m_history.find(processPath);
|
Logger::error("Process path is empty");
|
||||||
if (history != std::end(m_history))
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto srcVirtualDesktopIDStr = FancyZonesUtils::GuidToString(deviceId.virtualDesktopId);
|
||||||
|
auto app = processPath;
|
||||||
|
auto pos = processPath.find_last_of('\\');
|
||||||
|
if (pos != std::string::npos && pos + 1 < processPath.length())
|
||||||
|
{
|
||||||
|
app = processPath.substr(pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srcVirtualDesktopIDStr)
|
||||||
|
{
|
||||||
|
Logger::debug(L"Get {} zone history on monitor: {}, virtual desktop: {}", app, deviceId.deviceName, srcVirtualDesktopIDStr.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto history = m_history.find(processPath);
|
||||||
|
if (history == std::end(m_history))
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& perDesktopData = history->second;
|
||||||
|
for (const auto& data : perDesktopData)
|
||||||
|
{
|
||||||
|
if (data.zoneSetUuid == zoneSetId && data.deviceId.deviceName == deviceId.deviceName)
|
||||||
{
|
{
|
||||||
const auto& perDesktopData = history->second;
|
auto vdStr = FancyZonesUtils::GuidToString(data.deviceId.virtualDesktopId);
|
||||||
for (const auto& data : perDesktopData)
|
if (vdStr)
|
||||||
{
|
{
|
||||||
if (data.zoneSetUuid == zoneSetId && data.deviceId == deviceId)
|
Logger::debug(L"App zone history found on the device {} with virtual desktop {}", data.deviceId.deviceName, vdStr.value());
|
||||||
{
|
}
|
||||||
return data.zoneIndexSet;
|
|
||||||
}
|
if (data.deviceId.virtualDesktopId == deviceId.virtualDesktopId || data.deviceId.virtualDesktopId == GUID_NULL)
|
||||||
|
{
|
||||||
|
return data.zoneIndexSet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppZoneHistory::SyncVirtualDesktops(GUID currentVirtualDesktopId)
|
void AppZoneHistory::SyncVirtualDesktops()
|
||||||
{
|
{
|
||||||
// Explorer persists current virtual desktop identifier to registry on a per session basis,
|
// Explorer persists current virtual desktop identifier to registry on a per session basis,
|
||||||
// but only after first virtual desktop switch happens. If the user hasn't switched virtual
|
// but only after first virtual desktop switch happens. If the user hasn't switched virtual
|
||||||
// desktops in this session value in registry will be empty and we will use default GUID in
|
// desktops in this session value in registry will be empty and we will use default GUID in
|
||||||
// that case (00000000-0000-0000-0000-000000000000).
|
// that case (00000000-0000-0000-0000-000000000000).
|
||||||
|
|
||||||
auto currentVirtualDesktopStr = FancyZonesUtils::GuidToString(currentVirtualDesktopId);
|
auto savedInRegistryVirtualDesktopID = VirtualDesktop::instance().GetCurrentVirtualDesktopIdFromRegistry();
|
||||||
if (currentVirtualDesktopStr)
|
if (!savedInRegistryVirtualDesktopID.has_value() || savedInRegistryVirtualDesktopID.value() == GUID_NULL)
|
||||||
{
|
{
|
||||||
Logger::info(L"AppZoneHistory Sync virtual desktops: current {}", currentVirtualDesktopStr.value());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto currentVirtualDesktopStr = FancyZonesUtils::GuidToString(savedInRegistryVirtualDesktopID.value());
|
||||||
|
if (!currentVirtualDesktopStr.has_value())
|
||||||
|
{
|
||||||
|
Logger::error(L"Failed to convert virtual desktop GUID to string");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::info(L"AppZoneHistory Sync virtual desktops: current {}", currentVirtualDesktopStr.value());
|
||||||
|
|
||||||
bool dirtyFlag = false;
|
bool dirtyFlag = false;
|
||||||
|
|
||||||
for (auto& [path, perDesktopData] : m_history)
|
for (auto& [path, perDesktopData] : m_history)
|
||||||
@@ -520,28 +575,15 @@ void AppZoneHistory::SyncVirtualDesktops(GUID currentVirtualDesktopId)
|
|||||||
{
|
{
|
||||||
if (data.deviceId.virtualDesktopId == GUID_NULL)
|
if (data.deviceId.virtualDesktopId == GUID_NULL)
|
||||||
{
|
{
|
||||||
data.deviceId.virtualDesktopId = currentVirtualDesktopId;
|
data.deviceId.virtualDesktopId = savedInRegistryVirtualDesktopID.value();
|
||||||
dirtyFlag = true;
|
dirtyFlag = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m_virtualDesktopCheckCallback && !m_virtualDesktopCheckCallback(data.deviceId.virtualDesktopId))
|
|
||||||
{
|
|
||||||
data.deviceId.virtualDesktopId = GUID_NULL;
|
|
||||||
dirtyFlag = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirtyFlag)
|
if (dirtyFlag)
|
||||||
{
|
{
|
||||||
wil::unique_cotaskmem_string virtualDesktopIdStr;
|
Logger::info(L"Update Virtual Desktop id to {}", currentVirtualDesktopStr.value());
|
||||||
if (SUCCEEDED(StringFromCLSID(currentVirtualDesktopId, &virtualDesktopIdStr)))
|
|
||||||
{
|
|
||||||
Logger::info(L"Update Virtual Desktop id to {}", virtualDesktopIdStr.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveData();
|
SaveData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,8 +52,7 @@ public:
|
|||||||
void UpdateProcessIdToHandleMap(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId);
|
void UpdateProcessIdToHandleMap(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId);
|
||||||
ZoneIndexSet GetAppLastZoneIndexSet(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId, const std::wstring_view& zoneSetId) const;
|
ZoneIndexSet GetAppLastZoneIndexSet(HWND window, const FancyZonesDataTypes::DeviceIdData& deviceId, const std::wstring_view& zoneSetId) const;
|
||||||
|
|
||||||
void SetVirtualDesktopCheckCallback(std::function<bool(GUID)> callback);
|
void SyncVirtualDesktops();
|
||||||
void SyncVirtualDesktops(GUID currentVirtualDesktopId);
|
|
||||||
void RemoveDeletedVirtualDesktops(const std::vector<GUID>& activeDesktops);
|
void RemoveDeletedVirtualDesktops(const std::vector<GUID>& activeDesktops);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -61,5 +60,4 @@ private:
|
|||||||
~AppZoneHistory() = default;
|
~AppZoneHistory() = default;
|
||||||
|
|
||||||
TAppZoneHistoryMap m_history;
|
TAppZoneHistoryMap m_history;
|
||||||
std::function<bool(GUID)> m_virtualDesktopCheckCallback;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <FancyZonesLib/FancyZonesData/LayoutDefaults.h>
|
#include <FancyZonesLib/FancyZonesData/LayoutDefaults.h>
|
||||||
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
||||||
#include <FancyZonesLib/JsonHelpers.h>
|
#include <FancyZonesLib/JsonHelpers.h>
|
||||||
|
#include <FancyZonesLib/VirtualDesktop.h>
|
||||||
#include <FancyZonesLib/util.h>
|
#include <FancyZonesLib/util.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -244,19 +245,17 @@ void AppliedLayouts::SaveData()
|
|||||||
{
|
{
|
||||||
bool dirtyFlag = false;
|
bool dirtyFlag = false;
|
||||||
TAppliedLayoutsMap updatedMap;
|
TAppliedLayoutsMap updatedMap;
|
||||||
if (m_virtualDesktopCheckCallback)
|
|
||||||
|
for (const auto& [id, data] : m_layouts)
|
||||||
{
|
{
|
||||||
for (const auto& [id, data] : m_layouts)
|
auto updatedId = id;
|
||||||
|
if (!VirtualDesktop::instance().IsVirtualDesktopIdSavedInRegistry(id.virtualDesktopId))
|
||||||
{
|
{
|
||||||
auto updatedId = id;
|
updatedId.virtualDesktopId = GUID_NULL;
|
||||||
if (!m_virtualDesktopCheckCallback(id.virtualDesktopId))
|
dirtyFlag = true;
|
||||||
{
|
|
||||||
updatedId.virtualDesktopId = GUID_NULL;
|
|
||||||
dirtyFlag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
updatedMap.insert({ updatedId, data });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatedMap.insert({ updatedId, data });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirtyFlag)
|
if (dirtyFlag)
|
||||||
@@ -269,28 +268,31 @@ void AppliedLayouts::SaveData()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppliedLayouts::SetVirtualDesktopCheckCallback(std::function<bool(GUID)> callback)
|
void AppliedLayouts::SyncVirtualDesktops()
|
||||||
{
|
|
||||||
m_virtualDesktopCheckCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppliedLayouts::SyncVirtualDesktops(GUID currentVirtualDesktopId)
|
|
||||||
{
|
{
|
||||||
// Explorer persists current virtual desktop identifier to registry on a per session basis,
|
// Explorer persists current virtual desktop identifier to registry on a per session basis,
|
||||||
// but only after first virtual desktop switch happens. If the user hasn't switched virtual
|
// but only after first virtual desktop switch happens. If the user hasn't switched virtual
|
||||||
// desktops in this session value in registry will be empty and we will use default GUID in
|
// desktops in this session value in registry will be empty and we will use default GUID in
|
||||||
// that case (00000000-0000-0000-0000-000000000000).
|
// that case (00000000-0000-0000-0000-000000000000).
|
||||||
|
|
||||||
auto currentVirtualDesktopStr = FancyZonesUtils::GuidToString(currentVirtualDesktopId);
|
auto savedInRegistryVirtualDesktopID = VirtualDesktop::instance().GetCurrentVirtualDesktopIdFromRegistry();
|
||||||
if (currentVirtualDesktopStr)
|
if (!savedInRegistryVirtualDesktopID.has_value() || savedInRegistryVirtualDesktopID.value() == GUID_NULL)
|
||||||
{
|
{
|
||||||
Logger::info(L"AppliedLayouts Sync virtual desktops: current {}", currentVirtualDesktopStr.value());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto currentVirtualDesktopStr = FancyZonesUtils::GuidToString(savedInRegistryVirtualDesktopID.value());
|
||||||
|
if (!currentVirtualDesktopStr.has_value())
|
||||||
|
{
|
||||||
|
Logger::error(L"Failed to convert virtual desktop GUID to string");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::info(L"AppliedLayouts Sync virtual desktops: current {}", currentVirtualDesktopStr.value());
|
||||||
|
|
||||||
bool dirtyFlag = false;
|
bool dirtyFlag = false;
|
||||||
|
|
||||||
std::vector<FancyZonesDataTypes::DeviceIdData> replaceWithCurrentId{};
|
std::vector<FancyZonesDataTypes::DeviceIdData> replaceWithCurrentId{};
|
||||||
std::vector<FancyZonesDataTypes::DeviceIdData> replaceWithNullId{};
|
|
||||||
|
|
||||||
for (const auto& [id, data] : m_layouts)
|
for (const auto& [id, data] : m_layouts)
|
||||||
{
|
{
|
||||||
@@ -299,38 +301,18 @@ void AppliedLayouts::SyncVirtualDesktops(GUID currentVirtualDesktopId)
|
|||||||
replaceWithCurrentId.push_back(id);
|
replaceWithCurrentId.push_back(id);
|
||||||
dirtyFlag = true;
|
dirtyFlag = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m_virtualDesktopCheckCallback && !m_virtualDesktopCheckCallback(id.virtualDesktopId))
|
|
||||||
{
|
|
||||||
replaceWithNullId.push_back(id);
|
|
||||||
dirtyFlag = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& id : replaceWithCurrentId)
|
for (const auto& id : replaceWithCurrentId)
|
||||||
{
|
{
|
||||||
auto mapEntry = m_layouts.extract(id);
|
auto mapEntry = m_layouts.extract(id);
|
||||||
mapEntry.key().virtualDesktopId = currentVirtualDesktopId;
|
mapEntry.key().virtualDesktopId = savedInRegistryVirtualDesktopID.value();
|
||||||
m_layouts.insert(std::move(mapEntry));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& id : replaceWithNullId)
|
|
||||||
{
|
|
||||||
auto mapEntry = m_layouts.extract(id);
|
|
||||||
mapEntry.key().virtualDesktopId = GUID_NULL;
|
|
||||||
m_layouts.insert(std::move(mapEntry));
|
m_layouts.insert(std::move(mapEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirtyFlag)
|
if (dirtyFlag)
|
||||||
{
|
{
|
||||||
wil::unique_cotaskmem_string virtualDesktopIdStr;
|
Logger::info(L"Update Virtual Desktop id to {}", currentVirtualDesktopStr.value());
|
||||||
if (SUCCEEDED(StringFromCLSID(currentVirtualDesktopId, &virtualDesktopIdStr)))
|
|
||||||
{
|
|
||||||
Logger::info(L"Update Virtual Desktop id to {}", virtualDesktopIdStr.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveData();
|
SaveData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ public:
|
|||||||
void LoadData();
|
void LoadData();
|
||||||
void SaveData();
|
void SaveData();
|
||||||
|
|
||||||
void SetVirtualDesktopCheckCallback(std::function<bool(GUID)> callback);
|
void SyncVirtualDesktops();
|
||||||
void SyncVirtualDesktops(GUID currentVirtualDesktopId);
|
|
||||||
void RemoveDeletedVirtualDesktops(const std::vector<GUID>& activeDesktops);
|
void RemoveDeletedVirtualDesktops(const std::vector<GUID>& activeDesktops);
|
||||||
|
|
||||||
std::optional<Layout> GetDeviceLayout(const FancyZonesDataTypes::DeviceIdData& id) const noexcept;
|
std::optional<Layout> GetDeviceLayout(const FancyZonesDataTypes::DeviceIdData& id) const noexcept;
|
||||||
@@ -67,5 +66,4 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<FileWatcher> m_fileWatcher;
|
std::unique_ptr<FileWatcher> m_fileWatcher;
|
||||||
TAppliedLayoutsMap m_layouts;
|
TAppliedLayoutsMap m_layouts;
|
||||||
std::function<bool(GUID)> m_virtualDesktopCheckCallback;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "MonitorWorkAreaHandler.h"
|
#include "MonitorWorkAreaHandler.h"
|
||||||
#include "VirtualDesktop.h"
|
#include "VirtualDesktop.h"
|
||||||
|
#include "WorkArea.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include <common/logger/logger.h>
|
#include <common/logger/logger.h>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "VirtualDesktop.h"
|
#include "VirtualDesktop.h"
|
||||||
|
|
||||||
#include <common/logger/logger.h>
|
#include <common/logger/logger.h>
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
// Non-Localizable strings
|
// Non-Localizable strings
|
||||||
namespace NonLocalizable
|
namespace NonLocalizable
|
||||||
@@ -72,9 +73,7 @@ HKEY GetVirtualDesktopsRegKey()
|
|||||||
return virtualDesktopsKey.get();
|
return virtualDesktopsKey.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualDesktop::VirtualDesktop(const std::function<void()>& vdInitCallback, const std::function<void()>& vdUpdatedCallback) :
|
VirtualDesktop::VirtualDesktop()
|
||||||
m_vdInitCallback(vdInitCallback),
|
|
||||||
m_vdUpdatedCallback(vdUpdatedCallback)
|
|
||||||
{
|
{
|
||||||
auto res = CoCreateInstance(CLSID_VirtualDesktopManager, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&m_vdManager));
|
auto res = CoCreateInstance(CLSID_VirtualDesktopManager, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&m_vdManager));
|
||||||
if (FAILED(res))
|
if (FAILED(res))
|
||||||
@@ -91,20 +90,10 @@ VirtualDesktop::~VirtualDesktop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualDesktop::Init()
|
VirtualDesktop& VirtualDesktop::instance()
|
||||||
{
|
{
|
||||||
m_vdInitCallback();
|
static VirtualDesktop self;
|
||||||
|
return self;
|
||||||
m_terminateVirtualDesktopTrackerEvent.reset(CreateEvent(nullptr, FALSE, FALSE, nullptr));
|
|
||||||
m_virtualDesktopTrackerThread.submit(OnThreadExecutor::task_t{ [&] { HandleVirtualDesktopUpdates(); } });
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualDesktop::UnInit()
|
|
||||||
{
|
|
||||||
if (m_terminateVirtualDesktopTrackerEvent)
|
|
||||||
{
|
|
||||||
SetEvent(m_terminateVirtualDesktopTrackerEvent.get());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<GUID> VirtualDesktop::GetCurrentVirtualDesktopIdFromRegistry() const
|
std::optional<GUID> VirtualDesktop::GetCurrentVirtualDesktopIdFromRegistry() const
|
||||||
@@ -180,6 +169,25 @@ std::optional<std::vector<GUID>> VirtualDesktop::GetVirtualDesktopIdsFromRegistr
|
|||||||
return GetVirtualDesktopIdsFromRegistry(GetVirtualDesktopsRegKey());
|
return GetVirtualDesktopIdsFromRegistry(GetVirtualDesktopsRegKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VirtualDesktop::IsVirtualDesktopIdSavedInRegistry(GUID id) const
|
||||||
|
{
|
||||||
|
auto ids = GetVirtualDesktopIdsFromRegistry();
|
||||||
|
if (!ids.has_value())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& regId : *ids)
|
||||||
|
{
|
||||||
|
if (regId == id)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool VirtualDesktop::IsWindowOnCurrentDesktop(HWND window) const
|
bool VirtualDesktop::IsWindowOnCurrentDesktop(HWND window) const
|
||||||
{
|
{
|
||||||
std::optional<GUID> id = GetDesktopId(window);
|
std::optional<GUID> id = GetDesktopId(window);
|
||||||
@@ -227,6 +235,40 @@ std::vector<std::pair<HWND, GUID>> VirtualDesktop::GetWindowsRelatedToDesktops()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GUID VirtualDesktop::GetCurrentVirtualDesktopId() const noexcept
|
||||||
|
{
|
||||||
|
return m_currentVirtualDesktopId;
|
||||||
|
}
|
||||||
|
|
||||||
|
GUID VirtualDesktop::GetPreviousVirtualDesktopId() const noexcept
|
||||||
|
{
|
||||||
|
return m_previousDesktopId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualDesktop::UpdateVirtualDesktopId() noexcept
|
||||||
|
{
|
||||||
|
m_previousDesktopId = m_currentVirtualDesktopId;
|
||||||
|
|
||||||
|
auto currentVirtualDesktopId = GetCurrentVirtualDesktopIdFromRegistry();
|
||||||
|
if (!currentVirtualDesktopId.has_value())
|
||||||
|
{
|
||||||
|
Logger::info("No Virtual Desktop Id found in registry");
|
||||||
|
currentVirtualDesktopId = VirtualDesktop::instance().GetDesktopIdByTopLevelWindows();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentVirtualDesktopId.has_value())
|
||||||
|
{
|
||||||
|
m_currentVirtualDesktopId = *currentVirtualDesktopId;
|
||||||
|
|
||||||
|
if (m_currentVirtualDesktopId == GUID_NULL)
|
||||||
|
{
|
||||||
|
Logger::warn("Couldn't retrieve virtual desktop id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace::VirtualDesktopChanged();
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<GUID> VirtualDesktop::GetDesktopIdByTopLevelWindows() const
|
std::optional<GUID> VirtualDesktop::GetDesktopIdByTopLevelWindows() const
|
||||||
{
|
{
|
||||||
using result_t = std::vector<HWND>;
|
using result_t = std::vector<HWND>;
|
||||||
@@ -251,28 +293,3 @@ std::optional<GUID> VirtualDesktop::GetDesktopIdByTopLevelWindows() const
|
|||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualDesktop::HandleVirtualDesktopUpdates()
|
|
||||||
{
|
|
||||||
HKEY virtualDesktopsRegKey = GetVirtualDesktopsRegKey();
|
|
||||||
if (!virtualDesktopsRegKey)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
HANDLE regKeyEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
|
||||||
HANDLE events[2] = { regKeyEvent, m_terminateVirtualDesktopTrackerEvent.get() };
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (RegNotifyChangeKeyValue(virtualDesktopsRegKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET, regKeyEvent, TRUE) != ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (WaitForMultipleObjects(2, events, FALSE, INFINITE) != (WAIT_OBJECT_0 + 0))
|
|
||||||
{
|
|
||||||
// if terminateEvent is signalized or WaitForMultipleObjects failed, terminate thread execution
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_vdUpdatedCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +1,34 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "WorkArea.h"
|
|
||||||
#include "on_thread_executor.h"
|
|
||||||
|
|
||||||
class VirtualDesktop
|
class VirtualDesktop
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VirtualDesktop(const std::function<void()>& vdInitCallback, const std::function<void()>& vdUpdatedCallback);
|
static VirtualDesktop& instance();
|
||||||
~VirtualDesktop();
|
|
||||||
|
|
||||||
inline bool IsVirtualDesktopIdSavedInRegistry(GUID id) const
|
// saved values
|
||||||
{
|
GUID GetCurrentVirtualDesktopId() const noexcept;
|
||||||
auto ids = GetVirtualDesktopIdsFromRegistry();
|
GUID GetPreviousVirtualDesktopId() const noexcept;
|
||||||
if (!ids.has_value())
|
void UpdateVirtualDesktopId() noexcept;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& regId : *ids)
|
|
||||||
{
|
|
||||||
if (regId == id)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
void UnInit();
|
|
||||||
|
|
||||||
std::optional<GUID> GetCurrentVirtualDesktopIdFromRegistry() const;
|
|
||||||
std::optional<std::vector<GUID>> GetVirtualDesktopIdsFromRegistry() const;
|
|
||||||
|
|
||||||
|
// IVirtualDesktopManager
|
||||||
bool IsWindowOnCurrentDesktop(HWND window) const;
|
bool IsWindowOnCurrentDesktop(HWND window) const;
|
||||||
std::optional<GUID> GetDesktopId(HWND window) const;
|
std::optional<GUID> GetDesktopId(HWND window) const;
|
||||||
std::optional<GUID> GetDesktopIdByTopLevelWindows() const;
|
std::optional<GUID> GetDesktopIdByTopLevelWindows() const;
|
||||||
|
|
||||||
std::vector<std::pair<HWND, GUID>> GetWindowsRelatedToDesktops() const;
|
std::vector<std::pair<HWND, GUID>> GetWindowsRelatedToDesktops() const;
|
||||||
|
|
||||||
|
// registry
|
||||||
|
std::optional<GUID> GetCurrentVirtualDesktopIdFromRegistry() const;
|
||||||
|
std::optional<std::vector<GUID>> GetVirtualDesktopIdsFromRegistry() const;
|
||||||
|
bool IsVirtualDesktopIdSavedInRegistry(GUID id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void()> m_vdInitCallback;
|
VirtualDesktop();
|
||||||
std::function<void()> m_vdUpdatedCallback;
|
~VirtualDesktop();
|
||||||
|
|
||||||
IVirtualDesktopManager* m_vdManager;
|
IVirtualDesktopManager* m_vdManager{nullptr};
|
||||||
|
|
||||||
OnThreadExecutor m_virtualDesktopTrackerThread;
|
GUID m_currentVirtualDesktopId{};
|
||||||
wil::unique_handle m_terminateVirtualDesktopTrackerEvent;
|
GUID m_previousDesktopId{};
|
||||||
|
|
||||||
std::optional<std::vector<GUID>> GetVirtualDesktopIdsFromRegistry(HKEY hKey) const;
|
std::optional<std::vector<GUID>> GetVirtualDesktopIdsFromRegistry(HKEY hKey) const;
|
||||||
void HandleVirtualDesktopUpdates();
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ bool FancyZonesWindowUtils::IsCandidateForZoning(HWND window)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring processPath = get_process_path(window);
|
std::wstring processPath = get_process_path_waiting_uwp(window);
|
||||||
CharUpperBuffW(const_cast<std::wstring&>(processPath).data(), (DWORD)processPath.length());
|
CharUpperBuffW(const_cast<std::wstring&>(processPath).data(), (DWORD)processPath.length());
|
||||||
if (IsExcludedByUser(processPath))
|
if (IsExcludedByUser(processPath))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -388,7 +388,16 @@ WorkArea::GetWindowZoneIndexes(HWND window) const noexcept
|
|||||||
{
|
{
|
||||||
return AppZoneHistory::instance().GetAppLastZoneIndexSet(window, m_uniqueId, zoneSetId.get());
|
return AppZoneHistory::instance().GetAppLastZoneIndexSet(window, m_uniqueId, zoneSetId.get());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::error(L"Failed to convert to string layout GUID on the requested work area");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::error(L"No layout initialized on the requested work area");
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user