[FancyZones] Do not zone window if it should be maximized (#6619)
* Do not zone window if it should be maximized * Update comment * Remove uneeded field * Address PR comment
This commit is contained in:
parent
eaf54ca525
commit
3d36779e19
4 changed files with 54 additions and 59 deletions
|
@ -52,6 +52,15 @@ namespace WindowMoveHandlerUtils
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MoveSize related window properties
|
||||||
|
struct MoveSizeWindowInfo
|
||||||
|
{
|
||||||
|
// True if from the styles the window looks like a standard window
|
||||||
|
bool standardWindow = false;
|
||||||
|
// True if the window is a top-level window that does not have a visible owner
|
||||||
|
bool noVisibleOwner = false;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class WindowMoveHandlerPrivate
|
class WindowMoveHandlerPrivate
|
||||||
|
@ -104,7 +113,7 @@ private:
|
||||||
|
|
||||||
HWND m_windowMoveSize{}; // The window that is being moved/sized
|
HWND m_windowMoveSize{}; // The window that is being moved/sized
|
||||||
bool m_inMoveSize{}; // Whether or not a move/size operation is currently active
|
bool m_inMoveSize{}; // Whether or not a move/size operation is currently active
|
||||||
FancyZonesUtils::FancyZonesWindowInfo m_moveSizeStartWindowInfo; // WindowInfo of the window at the moment when dragging started
|
WindowMoveHandlerUtils::MoveSizeWindowInfo m_moveSizeWindowInfo; // MoveSizeWindowInfo of the window at the moment when dragging started
|
||||||
winrt::com_ptr<IZoneWindow> m_zoneWindowMoveSize; // "Active" ZoneWindow, where the move/size is happening. Will update as drag moves between monitors.
|
winrt::com_ptr<IZoneWindow> m_zoneWindowMoveSize; // "Active" ZoneWindow, where the move/size is happening. Will update as drag moves between monitors.
|
||||||
bool m_dragEnabled{}; // True if we should be showing zone hints while dragging
|
bool m_dragEnabled{}; // True if we should be showing zone hints while dragging
|
||||||
|
|
||||||
|
@ -184,7 +193,8 @@ void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POIN
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_moveSizeStartWindowInfo = FancyZonesUtils::GetFancyZonesWindowInfo(window);
|
m_moveSizeWindowInfo.noVisibleOwner = FancyZonesUtils::HasNoVisibleOwner(window);
|
||||||
|
m_moveSizeWindowInfo.standardWindow = FancyZonesUtils::IsStandardWindow(window);
|
||||||
m_inMoveSize = true;
|
m_inMoveSize = true;
|
||||||
|
|
||||||
auto iter = zoneWindowMap.find(monitor);
|
auto iter = zoneWindowMap.find(monitor);
|
||||||
|
@ -325,12 +335,15 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c
|
||||||
auto zoneWindow = std::move(m_zoneWindowMoveSize);
|
auto zoneWindow = std::move(m_zoneWindowMoveSize);
|
||||||
ResetWindowTransparency();
|
ResetWindowTransparency();
|
||||||
|
|
||||||
auto windowInfo = FancyZonesUtils::GetFancyZonesWindowInfo(window);
|
bool hasNoVisibleOwnoer = FancyZonesUtils::HasNoVisibleOwner(window);
|
||||||
|
bool isStandardWindow = FancyZonesUtils::IsStandardWindow(window);
|
||||||
|
|
||||||
if (windowInfo.standardWindow == false && windowInfo.noVisibleOwner == false &&
|
if ((isStandardWindow == false && hasNoVisibleOwnoer == false &&
|
||||||
m_moveSizeStartWindowInfo.standardWindow == true && m_moveSizeStartWindowInfo.noVisibleOwner == true)
|
m_moveSizeWindowInfo.standardWindow == true && m_moveSizeWindowInfo.noVisibleOwner == true) ||
|
||||||
|
FancyZonesUtils::IsWindowMaximized(window))
|
||||||
{
|
{
|
||||||
// Abort the zoning, this is a Chromium based tab that is merged back with an existing window
|
// Abort the zoning, this is a Chromium based tab that is merged back with an existing window
|
||||||
|
// or if the window is maximized by Windows when the cursor hits the screen top border
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -272,8 +272,7 @@ 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);
|
||||||
|
|
||||||
auto windowInfo = FancyZonesUtils::GetFancyZonesWindowInfo(window);
|
if (FancyZonesUtils::HasNoVisibleOwner(window))
|
||||||
if (windowInfo.noVisibleOwner)
|
|
||||||
{
|
{
|
||||||
SaveWindowProcessToZoneIndex(window);
|
SaveWindowProcessToZoneIndex(window);
|
||||||
}
|
}
|
||||||
|
@ -307,8 +306,7 @@ 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))
|
||||||
{
|
{
|
||||||
auto windowInfo = FancyZonesUtils::GetFancyZonesWindowInfo(window);
|
if (FancyZonesUtils::HasNoVisibleOwner(window))
|
||||||
if (windowInfo.noVisibleOwner)
|
|
||||||
{
|
{
|
||||||
SaveWindowProcessToZoneIndex(window);
|
SaveWindowProcessToZoneIndex(window);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,26 +18,6 @@ namespace NonLocalizable
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
bool HasNoVisibleOwner(HWND window) noexcept
|
|
||||||
{
|
|
||||||
auto owner = GetWindow(window, GW_OWNER);
|
|
||||||
if (owner == nullptr)
|
|
||||||
{
|
|
||||||
return true; // There is no owner at all
|
|
||||||
}
|
|
||||||
if (!IsWindowVisible(owner))
|
|
||||||
{
|
|
||||||
return true; // Owner is invisible
|
|
||||||
}
|
|
||||||
RECT rect;
|
|
||||||
if (!GetWindowRect(owner, &rect))
|
|
||||||
{
|
|
||||||
return false; // Could not get the rect, return true (and filter out the window) just in case
|
|
||||||
}
|
|
||||||
// It is enough that the window is zero-sized in one dimension only.
|
|
||||||
return rect.top == rect.bottom || rect.left == rect.right;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsZonableByProcessPath(const std::wstring& processPath, const std::vector<std::wstring>& excludedApps)
|
bool IsZonableByProcessPath(const std::wstring& processPath, const std::vector<std::wstring>& excludedApps)
|
||||||
{
|
{
|
||||||
// Filter out user specified apps
|
// Filter out user specified apps
|
||||||
|
@ -201,12 +181,31 @@ namespace FancyZonesUtils
|
||||||
::SetWindowPlacement(window, &placement);
|
::SetWindowPlacement(window, &placement);
|
||||||
}
|
}
|
||||||
|
|
||||||
FancyZonesWindowInfo GetFancyZonesWindowInfo(HWND window)
|
bool HasNoVisibleOwner(HWND window) noexcept
|
||||||
|
{
|
||||||
|
auto owner = GetWindow(window, GW_OWNER);
|
||||||
|
if (owner == nullptr)
|
||||||
|
{
|
||||||
|
return true; // There is no owner at all
|
||||||
|
}
|
||||||
|
if (!IsWindowVisible(owner))
|
||||||
|
{
|
||||||
|
return true; // Owner is invisible
|
||||||
|
}
|
||||||
|
RECT rect;
|
||||||
|
if (!GetWindowRect(owner, &rect))
|
||||||
|
{
|
||||||
|
return false; // Could not get the rect, return true (and filter out the window) just in case
|
||||||
|
}
|
||||||
|
// It is enough that the window is zero-sized in one dimension only.
|
||||||
|
return rect.top == rect.bottom || rect.left == rect.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsStandardWindow(HWND window)
|
||||||
{
|
{
|
||||||
FancyZonesWindowInfo result;
|
|
||||||
if (GetAncestor(window, GA_ROOT) != window || !IsWindowVisible(window))
|
if (GetAncestor(window, GA_ROOT) != window || !IsWindowVisible(window))
|
||||||
{
|
{
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
auto style = GetWindowLong(window, GWL_STYLE);
|
auto style = GetWindowLong(window, GWL_STYLE);
|
||||||
auto exStyle = GetWindowLong(window, GWL_EXSTYLE);
|
auto exStyle = GetWindowLong(window, GWL_EXSTYLE);
|
||||||
|
@ -217,56 +216,51 @@ namespace FancyZonesUtils
|
||||||
(style & WS_MINIMIZEBOX) == 0 &&
|
(style & WS_MINIMIZEBOX) == 0 &&
|
||||||
(style & WS_MAXIMIZEBOX) == 0)
|
(style & WS_MAXIMIZEBOX) == 0)
|
||||||
{
|
{
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
if ((style & WS_CHILD) == WS_CHILD ||
|
if ((style & WS_CHILD) == WS_CHILD ||
|
||||||
(style & WS_DISABLED) == WS_DISABLED ||
|
(style & WS_DISABLED) == WS_DISABLED ||
|
||||||
(exStyle & WS_EX_TOOLWINDOW) == WS_EX_TOOLWINDOW ||
|
(exStyle & WS_EX_TOOLWINDOW) == WS_EX_TOOLWINDOW ||
|
||||||
(exStyle & WS_EX_NOACTIVATE) == WS_EX_NOACTIVATE)
|
(exStyle & WS_EX_NOACTIVATE) == WS_EX_NOACTIVATE)
|
||||||
{
|
{
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
std::array<char, 256> class_name;
|
std::array<char, 256> class_name;
|
||||||
GetClassNameA(window, class_name.data(), static_cast<int>(class_name.size()));
|
GetClassNameA(window, class_name.data(), static_cast<int>(class_name.size()));
|
||||||
if (is_system_window(window, class_name.data()))
|
if (is_system_window(window, class_name.data()))
|
||||||
{
|
{
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
auto process_path = get_process_path(window);
|
auto process_path = get_process_path(window);
|
||||||
// Check for Cortana:
|
// Check for Cortana:
|
||||||
if (strcmp(class_name.data(), "Windows.UI.Core.CoreWindow") == 0 &&
|
if (strcmp(class_name.data(), "Windows.UI.Core.CoreWindow") == 0 &&
|
||||||
process_path.ends_with(L"SearchUI.exe"))
|
process_path.ends_with(L"SearchUI.exe"))
|
||||||
{
|
{
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
result.processPath = std::move(process_path);
|
|
||||||
result.standardWindow = true;
|
return true;
|
||||||
result.noVisibleOwner = HasNoVisibleOwner(window);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsCandidateForLastKnownZone(HWND window, const std::vector<std::wstring>& excludedApps) noexcept
|
bool IsCandidateForLastKnownZone(HWND window, const std::vector<std::wstring>& excludedApps) noexcept
|
||||||
{
|
{
|
||||||
auto windowInfo = GetFancyZonesWindowInfo(window);
|
auto zonable = IsStandardWindow(window) && HasNoVisibleOwner(window);
|
||||||
auto zonable = windowInfo.standardWindow && windowInfo.noVisibleOwner;
|
|
||||||
if (!zonable)
|
if (!zonable)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IsZonableByProcessPath(windowInfo.processPath, excludedApps);
|
return IsZonableByProcessPath(get_process_path(window), excludedApps);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsCandidateForZoning(HWND window, const std::vector<std::wstring>& excludedApps) noexcept
|
bool IsCandidateForZoning(HWND window, const std::vector<std::wstring>& excludedApps) noexcept
|
||||||
{
|
{
|
||||||
auto windowInfo = GetFancyZonesWindowInfo(window);
|
if (!IsStandardWindow(window))
|
||||||
|
|
||||||
if (!windowInfo.standardWindow)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IsZonableByProcessPath(windowInfo.processPath, excludedApps);
|
return IsZonableByProcessPath(get_process_path(window), excludedApps);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsWindowMaximized(HWND window) noexcept
|
bool IsWindowMaximized(HWND window) noexcept
|
||||||
|
|
|
@ -5,17 +5,6 @@
|
||||||
|
|
||||||
namespace FancyZonesUtils
|
namespace FancyZonesUtils
|
||||||
{
|
{
|
||||||
// Window properties relevant to FancyZones
|
|
||||||
struct FancyZonesWindowInfo
|
|
||||||
{
|
|
||||||
// True if from the styles the window looks like a standard window
|
|
||||||
bool standardWindow = false;
|
|
||||||
// True if the window is a top-level window that does not have a visible owner
|
|
||||||
bool noVisibleOwner = false;
|
|
||||||
// Path to the executable owning the window
|
|
||||||
std::wstring processPath;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Rect
|
struct Rect
|
||||||
{
|
{
|
||||||
Rect() {}
|
Rect() {}
|
||||||
|
@ -200,7 +189,8 @@ 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;
|
||||||
|
|
||||||
FancyZonesWindowInfo GetFancyZonesWindowInfo(HWND window);
|
bool HasNoVisibleOwner(HWND window) noexcept;
|
||||||
|
bool IsStandardWindow(HWND window);
|
||||||
bool IsCandidateForLastKnownZone(HWND window, const std::vector<std::wstring>& excludedApps) noexcept;
|
bool IsCandidateForLastKnownZone(HWND window, const std::vector<std::wstring>& excludedApps) noexcept;
|
||||||
bool IsCandidateForZoning(HWND window, const std::vector<std::wstring>& excludedApps) noexcept;
|
bool IsCandidateForZoning(HWND window, const std::vector<std::wstring>& excludedApps) noexcept;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue