mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
Make FancyZone distinguish different modern apps.
This commit is contained in:
committed by
Bartosz Sosnowski
parent
5d75feebdc
commit
0b86941a3b
@@ -168,12 +168,11 @@ IFACEMETHODIMP_(void) FancyZones::WindowCreated(HWND window) noexcept
|
|||||||
{
|
{
|
||||||
if (m_settings->GetSettings().appLastZone_moveWindows)
|
if (m_settings->GetSettings().appLastZone_moveWindows)
|
||||||
{
|
{
|
||||||
wchar_t processPath[MAX_PATH] = { 0 };
|
auto processPath = GetProcessPath(window);
|
||||||
DWORD modulePathSize = GetProcessPath(window, processPath, static_cast<DWORD>(MAX_PATH));
|
if (!processPath.empty())
|
||||||
if (modulePathSize > 0)
|
|
||||||
{
|
{
|
||||||
INT zoneIndex = -1;
|
INT zoneIndex = -1;
|
||||||
LRESULT res = RegistryHelpers::GetAppLastZone(window, processPath, &zoneIndex);
|
LRESULT res = RegistryHelpers::GetAppLastZone(window, processPath.data(), &zoneIndex);
|
||||||
if ((res == ERROR_SUCCESS) && (zoneIndex != -1))
|
if ((res == ERROR_SUCCESS) && (zoneIndex != -1))
|
||||||
{
|
{
|
||||||
MoveWindowIntoZoneByIndex(window, zoneIndex);
|
MoveWindowIntoZoneByIndex(window, zoneIndex);
|
||||||
@@ -670,11 +669,10 @@ void FancyZones::MoveSizeEndInternal(HWND window, POINT const& ptScreen, require
|
|||||||
{
|
{
|
||||||
::RemoveProp(window, ZONE_STAMP);
|
::RemoveProp(window, ZONE_STAMP);
|
||||||
|
|
||||||
wchar_t processPath[MAX_PATH]{};
|
auto processPath = GetProcessPath(window);
|
||||||
DWORD processPathSize = GetProcessPath(window, processPath, static_cast<DWORD>(MAX_PATH));
|
if (!processPath.empty())
|
||||||
if (processPathSize > 0)
|
|
||||||
{
|
{
|
||||||
RegistryHelpers::SaveAppLastZone(window, processPath, -1);
|
RegistryHelpers::SaveAppLastZone(window, processPath.data(), -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1252,14 +1252,13 @@ int ZoneWindow::GetSwitchButtonIndexFromPoint(POINT ptClient) noexcept
|
|||||||
|
|
||||||
IFACEMETHODIMP_(void) ZoneWindow::SaveWindowProcessToZoneIndex(HWND window) noexcept
|
IFACEMETHODIMP_(void) ZoneWindow::SaveWindowProcessToZoneIndex(HWND window) noexcept
|
||||||
{
|
{
|
||||||
wchar_t processPath[MAX_PATH] = { 0 };
|
auto processPath = GetProcessPath(window);
|
||||||
DWORD processPathSize = GetProcessPath(window, processPath, static_cast<DWORD>(MAX_PATH));
|
if (!processPath.empty())
|
||||||
if (processPathSize > 0)
|
|
||||||
{
|
{
|
||||||
DWORD zoneIndex = static_cast<DWORD>(m_activeZoneSet->GetZoneIndexFromWindow(window));
|
DWORD zoneIndex = static_cast<DWORD>(m_activeZoneSet->GetZoneIndexFromWindow(window));
|
||||||
if (zoneIndex != -1)
|
if (zoneIndex != -1)
|
||||||
{
|
{
|
||||||
RegistryHelpers::SaveAppLastZone(window, processPath, zoneIndex);
|
RegistryHelpers::SaveAppLastZone(window, processPath.data(), zoneIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,19 +134,52 @@ inline void ParseDeviceId(PCWSTR deviceId, PWSTR parsedId, size_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline DWORD GetProcessPath(HWND window, LPWSTR processPath, DWORD processPathMaxSize) noexcept
|
inline std::wstring GetProcessPathByPID(DWORD pid)
|
||||||
{
|
{
|
||||||
|
wil::unique_handle process(OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, TRUE, pid));
|
||||||
|
std::wstring name;
|
||||||
|
if (process && process.get() != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
name.resize(MAX_PATH);
|
||||||
|
DWORD name_length = static_cast<DWORD>(name.length());
|
||||||
|
QueryFullProcessImageNameW(process.get(), 0, (LPWSTR)name.data(), &name_length);
|
||||||
|
name.resize(name_length);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::wstring GetProcessPath(HWND window) noexcept
|
||||||
|
{
|
||||||
|
const static std::wstring app_frame_host = L"ApplicationFrameHost.exe";
|
||||||
DWORD pid{};
|
DWORD pid{};
|
||||||
GetWindowThreadProcessId(window, &pid);
|
GetWindowThreadProcessId(window, &pid);
|
||||||
|
auto name = GetProcessPathByPID(pid);
|
||||||
DWORD numCopiedChars = 0;
|
if (name.length() >= app_frame_host.length() &&
|
||||||
wil::unique_handle windowProcessHandle(OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, TRUE, pid));
|
name.compare(name.length() - app_frame_host.length(), app_frame_host.length(), app_frame_host) == 0)
|
||||||
if (windowProcessHandle && (windowProcessHandle.get() != INVALID_HANDLE_VALUE))
|
|
||||||
{
|
{
|
||||||
// numCopiedChars first holds the size of processPath[], will then hold amount of characters returned by QueryFullProcessImageNameW
|
// It is a UWP app. We will enumarate the windows and look for one created
|
||||||
// if QueryFullProcessImageNameW fails, numCopiedChars will be zero.
|
// by something with a different PID
|
||||||
numCopiedChars = processPathMaxSize;
|
DWORD new_pid = pid;
|
||||||
QueryFullProcessImageNameW(windowProcessHandle.get(), 0, processPath, &numCopiedChars);
|
EnumChildWindows(window, [](HWND hwnd, LPARAM param) -> BOOL
|
||||||
|
{
|
||||||
|
auto new_pid_ptr = reinterpret_cast<DWORD*>(param);
|
||||||
|
DWORD pid;
|
||||||
|
GetWindowThreadProcessId(hwnd, &pid);
|
||||||
|
if (pid != *new_pid_ptr)
|
||||||
|
{
|
||||||
|
*new_pid_ptr = pid;
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
return numCopiedChars;
|
else
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}, reinterpret_cast<LPARAM>(&new_pid));
|
||||||
|
// If we have a new pid, get the new name.
|
||||||
|
if (new_pid != pid)
|
||||||
|
{
|
||||||
|
return GetProcessPathByPID(new_pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user