mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-11 05:52:19 +02:00
[FancyZones] Enable to manually zone child windows (#6182)
* Enable to manually zone child windows * Refactor IsInterestingWindow in 2 separate functions * Remove enum
This commit is contained in:
@@ -346,11 +346,12 @@ FancyZones::VirtualDesktopInitialize() noexcept
|
|||||||
|
|
||||||
bool FancyZones::ShouldProcessNewWindow(HWND window) noexcept
|
bool FancyZones::ShouldProcessNewWindow(HWND window) noexcept
|
||||||
{
|
{
|
||||||
|
using namespace FancyZonesUtils;
|
||||||
// Avoid processing splash screens, already stamped (zoned) windows, or those windows
|
// Avoid processing splash screens, already stamped (zoned) windows, or those windows
|
||||||
// that belong to excluded applications list.
|
// that belong to excluded applications list.
|
||||||
if (IsSplashScreen(window) ||
|
if (IsSplashScreen(window) ||
|
||||||
(reinterpret_cast<size_t>(::GetProp(window, ZonedWindowProperties::PropertyMultipleZoneID)) != 0) ||
|
(reinterpret_cast<size_t>(::GetProp(window, ZonedWindowProperties::PropertyMultipleZoneID)) != 0) ||
|
||||||
!FancyZonesUtils::IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray))
|
!IsCandidateForLastKnownZone(window, m_settings->GetSettings()->excludedAppsArray))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1031,7 +1032,7 @@ void FancyZones::UpdateWindowsPositions() noexcept
|
|||||||
void FancyZones::CycleActiveZoneSet(DWORD vkCode) noexcept
|
void FancyZones::CycleActiveZoneSet(DWORD vkCode) noexcept
|
||||||
{
|
{
|
||||||
auto window = GetForegroundWindow();
|
auto window = GetForegroundWindow();
|
||||||
if (FancyZonesUtils::IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray))
|
if (FancyZonesUtils::IsCandidateForZoning(window, m_settings->GetSettings()->excludedAppsArray))
|
||||||
{
|
{
|
||||||
const HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
const HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
||||||
if (monitor)
|
if (monitor)
|
||||||
@@ -1248,7 +1249,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
|||||||
bool FancyZones::OnSnapHotkey(DWORD vkCode) noexcept
|
bool FancyZones::OnSnapHotkey(DWORD vkCode) noexcept
|
||||||
{
|
{
|
||||||
auto window = GetForegroundWindow();
|
auto window = GetForegroundWindow();
|
||||||
if (FancyZonesUtils::IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray))
|
if (FancyZonesUtils::IsCandidateForZoning(window, m_settings->GetSettings()->excludedAppsArray))
|
||||||
{
|
{
|
||||||
if (m_settings->GetSettings()->moveWindowsBasedOnPosition)
|
if (m_settings->GetSettings()->moveWindowsBasedOnPosition)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ bool WindowMoveHandler::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DW
|
|||||||
|
|
||||||
void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
||||||
{
|
{
|
||||||
if (!FancyZonesUtils::IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray) || WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
|
if (!FancyZonesUtils::IsCandidateForZoning(window, m_settings->GetSettings()->excludedAppsArray) || WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -303,7 +303,7 @@ void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptS
|
|||||||
|
|
||||||
void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
||||||
{
|
{
|
||||||
if (window != m_windowMoveSize && !FancyZonesUtils::IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray))
|
if (window != m_windowMoveSize && !FancyZonesUtils::IsCandidateForZoning(window, m_settings->GetSettings()->excludedAppsArray))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -307,7 +307,11 @@ IFACEMETHODIMP ZoneWindow::MoveSizeEnd(HWND window, POINT const& ptScreen) noexc
|
|||||||
MapWindowPoints(nullptr, m_window.get(), &ptClient, 1);
|
MapWindowPoints(nullptr, m_window.get(), &ptClient, 1);
|
||||||
m_activeZoneSet->MoveWindowIntoZoneByIndexSet(window, m_window.get(), m_highlightZone);
|
m_activeZoneSet->MoveWindowIntoZoneByIndexSet(window, m_window.get(), m_highlightZone);
|
||||||
|
|
||||||
SaveWindowProcessToZoneIndex(window);
|
auto windowInfo = FancyZonesUtils::GetFancyZonesWindowInfo(window);
|
||||||
|
if (windowInfo.noVisibleOwner)
|
||||||
|
{
|
||||||
|
SaveWindowProcessToZoneIndex(window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Trace::ZoneWindow::MoveSizeEnd(m_activeZoneSet);
|
Trace::ZoneWindow::MoveSizeEnd(m_activeZoneSet);
|
||||||
|
|
||||||
@@ -338,7 +342,11 @@ ZoneWindow::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, boo
|
|||||||
{
|
{
|
||||||
if (m_activeZoneSet->MoveWindowIntoZoneByDirectionAndIndex(window, m_window.get(), vkCode, cycle))
|
if (m_activeZoneSet->MoveWindowIntoZoneByDirectionAndIndex(window, m_window.get(), vkCode, cycle))
|
||||||
{
|
{
|
||||||
SaveWindowProcessToZoneIndex(window);
|
auto windowInfo = FancyZonesUtils::GetFancyZonesWindowInfo(window);
|
||||||
|
if (windowInfo.noVisibleOwner)
|
||||||
|
{
|
||||||
|
SaveWindowProcessToZoneIndex(window);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,48 +38,23 @@ namespace
|
|||||||
return rect.top == rect.bottom || rect.left == rect.right;
|
return rect.top == rect.bottom || rect.left == rect.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
FancyZonesUtils::FancyZonesWindowInfo GetFancyZonesWindowInfo(HWND window)
|
bool IsZonableByProcessPath(const std::wstring& processPath, const std::vector<std::wstring>& excludedApps)
|
||||||
{
|
{
|
||||||
FancyZonesUtils::FancyZonesWindowInfo result;
|
// Filter out user specified apps
|
||||||
if (GetAncestor(window, GA_ROOT) != window || !IsWindowVisible(window))
|
CharUpperBuffW(const_cast<std::wstring&>(processPath).data(), (DWORD)processPath.length());
|
||||||
|
if (find_app_name_in_path(processPath, excludedApps))
|
||||||
{
|
{
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
auto style = GetWindowLong(window, GWL_STYLE);
|
if (find_app_name_in_path(processPath, { NonLocalizable::PowerToysAppPowerLauncher }))
|
||||||
auto exStyle = GetWindowLong(window, GWL_EXSTYLE);
|
|
||||||
// WS_POPUP need to have a border or minimize/maximize buttons,
|
|
||||||
// otherwise the window is "not interesting"
|
|
||||||
if ((style & WS_POPUP) == WS_POPUP &&
|
|
||||||
(style & WS_THICKFRAME) == 0 &&
|
|
||||||
(style & WS_MINIMIZEBOX) == 0 &&
|
|
||||||
(style & WS_MAXIMIZEBOX) == 0)
|
|
||||||
{
|
{
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
if ((style & WS_CHILD) == WS_CHILD ||
|
if (find_app_name_in_path(processPath, { NonLocalizable::PowerToysAppFZEditor }))
|
||||||
(style & WS_DISABLED) == WS_DISABLED ||
|
|
||||||
(exStyle & WS_EX_TOOLWINDOW) == WS_EX_TOOLWINDOW ||
|
|
||||||
(exStyle & WS_EX_NOACTIVATE) == WS_EX_NOACTIVATE)
|
|
||||||
{
|
{
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
std::array<char, 256> class_name;
|
return true;
|
||||||
GetClassNameA(window, class_name.data(), static_cast<int>(class_name.size()));
|
|
||||||
if (is_system_window(window, class_name.data()))
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
auto process_path = get_process_path(window);
|
|
||||||
// Check for Cortana:
|
|
||||||
if (strcmp(class_name.data(), "Windows.UI.Core.CoreWindow") == 0 &&
|
|
||||||
process_path.ends_with(L"SearchUI.exe"))
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result.processPath = std::move(process_path);
|
|
||||||
result.standardWindow = true;
|
|
||||||
result.noVisibleOwner = HasNoVisibleOwner(window);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +201,51 @@ namespace FancyZonesUtils
|
|||||||
::SetWindowPlacement(window, &placement);
|
::SetWindowPlacement(window, &placement);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsInterestingWindow(HWND window, const std::vector<std::wstring>& excludedApps) noexcept
|
FancyZonesWindowInfo GetFancyZonesWindowInfo(HWND window)
|
||||||
|
{
|
||||||
|
FancyZonesWindowInfo result;
|
||||||
|
if (GetAncestor(window, GA_ROOT) != window || !IsWindowVisible(window))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
auto style = GetWindowLong(window, GWL_STYLE);
|
||||||
|
auto exStyle = GetWindowLong(window, GWL_EXSTYLE);
|
||||||
|
// WS_POPUP need to have a border or minimize/maximize buttons,
|
||||||
|
// otherwise the window is "not interesting"
|
||||||
|
if ((style & WS_POPUP) == WS_POPUP &&
|
||||||
|
(style & WS_THICKFRAME) == 0 &&
|
||||||
|
(style & WS_MINIMIZEBOX) == 0 &&
|
||||||
|
(style & WS_MAXIMIZEBOX) == 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if ((style & WS_CHILD) == WS_CHILD ||
|
||||||
|
(style & WS_DISABLED) == WS_DISABLED ||
|
||||||
|
(exStyle & WS_EX_TOOLWINDOW) == WS_EX_TOOLWINDOW ||
|
||||||
|
(exStyle & WS_EX_NOACTIVATE) == WS_EX_NOACTIVATE)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::array<char, 256> class_name;
|
||||||
|
GetClassNameA(window, class_name.data(), static_cast<int>(class_name.size()));
|
||||||
|
if (is_system_window(window, class_name.data()))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
auto process_path = get_process_path(window);
|
||||||
|
// Check for Cortana:
|
||||||
|
if (strcmp(class_name.data(), "Windows.UI.Core.CoreWindow") == 0 &&
|
||||||
|
process_path.ends_with(L"SearchUI.exe"))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.processPath = std::move(process_path);
|
||||||
|
result.standardWindow = true;
|
||||||
|
result.noVisibleOwner = HasNoVisibleOwner(window);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsCandidateForLastKnownZone(HWND window, const std::vector<std::wstring>& excludedApps) noexcept
|
||||||
{
|
{
|
||||||
auto windowInfo = GetFancyZonesWindowInfo(window);
|
auto windowInfo = GetFancyZonesWindowInfo(window);
|
||||||
auto zonable = windowInfo.standardWindow && windowInfo.noVisibleOwner;
|
auto zonable = windowInfo.standardWindow && windowInfo.noVisibleOwner;
|
||||||
@@ -234,21 +253,20 @@ namespace FancyZonesUtils
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Filter out user specified apps
|
|
||||||
CharUpperBuffW(windowInfo.processPath.data(), (DWORD)windowInfo.processPath.length());
|
return IsZonableByProcessPath(windowInfo.processPath, excludedApps);
|
||||||
if (find_app_name_in_path(windowInfo.processPath, excludedApps))
|
}
|
||||||
|
|
||||||
|
bool IsCandidateForZoning(HWND window, const std::vector<std::wstring>& excludedApps) noexcept
|
||||||
|
{
|
||||||
|
auto windowInfo = GetFancyZonesWindowInfo(window);
|
||||||
|
|
||||||
|
if (!windowInfo.standardWindow)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (find_app_name_in_path(windowInfo.processPath, { NonLocalizable::PowerToysAppPowerLauncher }))
|
|
||||||
{
|
return IsZonableByProcessPath(windowInfo.processPath, excludedApps);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (find_app_name_in_path(windowInfo.processPath, { NonLocalizable::PowerToysAppFZEditor }))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsWindowMaximized(HWND window) noexcept
|
bool IsWindowMaximized(HWND window) noexcept
|
||||||
|
|||||||
@@ -181,7 +181,10 @@ namespace FancyZonesUtils
|
|||||||
void OrderMonitors(std::vector<std::pair<HMONITOR, RECT>>& monitorInfo);
|
void OrderMonitors(std::vector<std::pair<HMONITOR, RECT>>& monitorInfo);
|
||||||
void SizeWindowToRect(HWND window, RECT rect) noexcept;
|
void SizeWindowToRect(HWND window, RECT rect) noexcept;
|
||||||
|
|
||||||
bool IsInterestingWindow(HWND window, const std::vector<std::wstring>& excludedApps) noexcept;
|
FancyZonesWindowInfo GetFancyZonesWindowInfo(HWND window);
|
||||||
|
bool IsCandidateForLastKnownZone(HWND window, const std::vector<std::wstring>& excludedApps) noexcept;
|
||||||
|
bool IsCandidateForZoning(HWND window, const std::vector<std::wstring>& excludedApps) noexcept;
|
||||||
|
|
||||||
bool IsWindowMaximized(HWND window) noexcept;
|
bool IsWindowMaximized(HWND window) noexcept;
|
||||||
void SaveWindowSizeAndOrigin(HWND window) noexcept;
|
void SaveWindowSizeAndOrigin(HWND window) noexcept;
|
||||||
void RestoreWindowSize(HWND window) noexcept;
|
void RestoreWindowSize(HWND window) noexcept;
|
||||||
|
|||||||
Reference in New Issue
Block a user