diff --git a/src/common/monitors.cpp b/src/common/monitors.cpp index c96a78c86e..4acb0d0484 100644 --- a/src/common/monitors.cpp +++ b/src/common/monitors.cpp @@ -1,8 +1,9 @@ #include "pch.h" -#include "common.h" #include "monitors.h" +#include "common.h" + bool operator==(const ScreenSize& lhs, const ScreenSize& rhs) { auto lhs_tuple = std::make_tuple(lhs.rect.left, lhs.rect.right, lhs.rect.top, lhs.rect.bottom); @@ -10,48 +11,47 @@ bool operator==(const ScreenSize& lhs, const ScreenSize& rhs) return lhs_tuple == rhs_tuple; } -static BOOL CALLBACK get_displays_enum_cb(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) +static BOOL CALLBACK GetDisplaysEnumCb(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) { - MONITORINFOEX monitor_info; - monitor_info.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(monitor, &monitor_info); - reinterpret_cast*>(data)->emplace_back(monitor, monitor_info.rcWork); + MONITORINFOEX monitorInfo; + monitorInfo.cbSize = sizeof(MONITORINFOEX); + if (GetMonitorInfo(monitor, &monitorInfo)) + { + reinterpret_cast*>(data)->emplace_back(monitor, monitorInfo.rcWork); + } return true; }; -static BOOL CALLBACK get_displays_enum_cb_with_toolbar(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) +static BOOL CALLBACK GetDisplaysEnumCbWithNonWorkingArea(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) { - MONITORINFOEX monitor_info; - monitor_info.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(monitor, &monitor_info); - reinterpret_cast*>(data)->emplace_back(monitor, monitor_info.rcMonitor); + MONITORINFOEX monitorInfo; + monitorInfo.cbSize = sizeof(MONITORINFOEX); + if (GetMonitorInfo(monitor, &monitorInfo)) + { + reinterpret_cast*>(data)->emplace_back(monitor, monitorInfo.rcMonitor); + } return true; }; -std::vector MonitorInfo::GetMonitors(bool include_toolbar) +std::vector MonitorInfo::GetMonitors(bool includeNonWorkingArea) { std::vector monitors; - EnumDisplayMonitors(NULL, NULL, include_toolbar ? get_displays_enum_cb_with_toolbar : get_displays_enum_cb, reinterpret_cast(&monitors)); + EnumDisplayMonitors(NULL, NULL, includeNonWorkingArea ? GetDisplaysEnumCbWithNonWorkingArea : GetDisplaysEnumCb, reinterpret_cast(&monitors)); std::sort(begin(monitors), end(monitors), [](const MonitorInfo& lhs, const MonitorInfo& rhs) { return lhs.rect < rhs.rect; }); return monitors; } -int MonitorInfo::GetMonitorsCount() +static BOOL CALLBACK GetPrimaryDisplayEnumCb(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) { - return GetMonitors(true).size(); -} + MONITORINFOEX monitorInfo; + monitorInfo.cbSize = sizeof(MONITORINFOEX); -static BOOL CALLBACK get_primary_display_enum_cb(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) -{ - MONITORINFOEX monitor_info; - monitor_info.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(monitor, &monitor_info); - if (monitor_info.dwFlags & MONITORINFOF_PRIMARY) + if (GetMonitorInfo(monitor, &monitorInfo) && (monitorInfo.dwFlags & MONITORINFOF_PRIMARY)) { reinterpret_cast(data)->handle = monitor; - reinterpret_cast(data)->rect = monitor_info.rcWork; + reinterpret_cast(data)->rect = monitorInfo.rcWork; } return true; }; @@ -59,26 +59,6 @@ static BOOL CALLBACK get_primary_display_enum_cb(HMONITOR monitor, HDC hdc, LPRE MonitorInfo MonitorInfo::GetPrimaryMonitor() { MonitorInfo primary({}, {}); - EnumDisplayMonitors(NULL, NULL, get_primary_display_enum_cb, reinterpret_cast(&primary)); + EnumDisplayMonitors(NULL, NULL, GetPrimaryDisplayEnumCb, reinterpret_cast(&primary)); return primary; } - -MonitorInfo MonitorInfo::GetFromWindow(HWND hwnd) -{ - auto monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); - return GetFromHandle(monitor); -} - -MonitorInfo MonitorInfo::GetFromPoint(POINT p) -{ - auto monitor = MonitorFromPoint(p, MONITOR_DEFAULTTONEAREST); - return GetFromHandle(monitor); -} - -MonitorInfo MonitorInfo::GetFromHandle(HMONITOR monitor) -{ - MONITORINFOEX monitor_info; - monitor_info.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(monitor, &monitor_info); - return MonitorInfo(monitor, monitor_info.rcWork); -} diff --git a/src/common/monitors.h b/src/common/monitors.h index ebe77fabd2..b375fedd52 100644 --- a/src/common/monitors.h +++ b/src/common/monitors.h @@ -31,16 +31,8 @@ struct MonitorInfo : ScreenSize HMONITOR handle; // Returns monitor rects ordered from left to right - static std::vector GetMonitors(bool include_toolbar); - static int GetMonitorsCount(); - // Return primary display + static std::vector GetMonitors(bool includeNonWorkingArea); static MonitorInfo GetPrimaryMonitor(); - // Return monitor on which hwnd window is displayed - static MonitorInfo GetFromWindow(HWND hwnd); - // Return monitor nearest to a point - static MonitorInfo GetFromPoint(POINT p); - // Return monitor info given a HMONITOR - static MonitorInfo GetFromHandle(HMONITOR monitor); }; bool operator==(const ScreenSize& lhs, const ScreenSize& rhs); diff --git a/src/modules/fancyzones/lib/Zone.cpp b/src/modules/fancyzones/lib/Zone.cpp index 5460bbe82e..620dbae9f5 100644 --- a/src/modules/fancyzones/lib/Zone.cpp +++ b/src/modules/fancyzones/lib/Zone.cpp @@ -1,5 +1,8 @@ #include "pch.h" + +#include + #include #include #include "Zone.h" @@ -68,6 +71,45 @@ void Zone::SizeWindowToZone(HWND window, HWND zoneWindow) noexcept SizeWindowToRect(window, ComputeActualZoneRect(window, zoneWindow)); } +static BOOL CALLBACK saveDisplayToVector(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) +{ + reinterpret_cast*>(data)->emplace_back(monitor); + return true; +} + +bool allMonitorsHaveSameDpiScaling() +{ + std::vector monitors; + EnumDisplayMonitors(NULL, NULL, saveDisplayToVector, reinterpret_cast(&monitors)); + + if (monitors.size() < 2) + { + return true; + } + + UINT firstMonitorDpiX; + UINT firstMonitorDpiY; + + if (S_OK != GetDpiForMonitor(monitors[0], MDT_EFFECTIVE_DPI, &firstMonitorDpiX, &firstMonitorDpiY)) + { + return false; + } + + for (int i = 1; i < monitors.size(); i++) + { + UINT iteratedMonitorDpiX; + UINT iteratedMonitorDpiY; + + if (S_OK != GetDpiForMonitor(monitors[i], MDT_EFFECTIVE_DPI, &iteratedMonitorDpiX, &iteratedMonitorDpiY) || + iteratedMonitorDpiX != firstMonitorDpiX) + { + return false; + } + } + + return true; +} + RECT Zone::ComputeActualZoneRect(HWND window, HWND zoneWindow) noexcept { // Take care of 1px border @@ -101,7 +143,7 @@ RECT Zone::ComputeActualZoneRect(HWND window, HWND zoneWindow) noexcept const auto taskbar_top_size = std::abs(mi.rcMonitor.top - mi.rcWork.top); OffsetRect(&newWindowRect, -taskbar_left_size, -taskbar_top_size); - if (accountForUnawareness && MonitorInfo::GetMonitorsCount() > 1) + if (accountForUnawareness && !allMonitorsHaveSameDpiScaling()) { newWindowRect.left = max(mi.rcMonitor.left, newWindowRect.left); newWindowRect.right = min(mi.rcMonitor.right - taskbar_left_size, newWindowRect.right);