diff --git a/src/modules/fancyzones/lib/FancyZones.cpp b/src/modules/fancyzones/lib/FancyZones.cpp index 1d8cb6c7e..770d61dbb 100644 --- a/src/modules/fancyzones/lib/FancyZones.cpp +++ b/src/modules/fancyzones/lib/FancyZones.cpp @@ -937,17 +937,13 @@ void FancyZones::AddZoneWindow(HMONITOR monitor, const std::wstring& deviceId) n uniqueId = ZoneWindowUtils::GenerateUniqueIdAllMonitorsArea(virtualDesktopId.get()); } - // "Turning FLASHING_ZONE option off" - //const bool flash = m_settings->GetSettings()->zoneSetChange_flashZones; - const bool flash = false; - std::wstring parentId{}; auto parentArea = m_workAreaHandler.GetWorkArea(m_previousDesktopId, monitor); if (parentArea) { parentId = parentArea->UniqueId(); } - auto workArea = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, parentId, flash); + auto workArea = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, parentId); if (workArea) { m_workAreaHandler.AddWorkArea(m_currentDesktopId, monitor, workArea); diff --git a/src/modules/fancyzones/lib/ZoneWindow.cpp b/src/modules/fancyzones/lib/ZoneWindow.cpp index 09499186f..672a77723 100644 --- a/src/modules/fancyzones/lib/ZoneWindow.cpp +++ b/src/modules/fancyzones/lib/ZoneWindow.cpp @@ -61,54 +61,6 @@ namespace ZoneWindowUtils return result; } - - void PaintZoneWindow(HDC hdc, - HWND window, - bool hasActiveZoneSet, - COLORREF hostZoneColor, - COLORREF hostZoneBorderColor, - COLORREF hostZoneHighlightColor, - int hostZoneHighlightOpacity, - IZoneSet::ZonesMap zones, - std::vector highlightZone, - bool flashMode) - { - PAINTSTRUCT ps; - HDC oldHdc = hdc; - if (!hdc) - { - hdc = BeginPaint(window, &ps); - } - - RECT clientRect; - GetClientRect(window, &clientRect); - - wil::unique_hdc hdcMem; - HPAINTBUFFER bufferedPaint = BeginBufferedPaint(hdc, &clientRect, BPBF_TOPDOWNDIB, nullptr, &hdcMem); - if (bufferedPaint) - { - ZoneWindowDrawing::DrawBackdrop(hdcMem, clientRect); - - if (hasActiveZoneSet) - { - ZoneWindowDrawing::DrawActiveZoneSet(hdcMem, - hostZoneColor, - hostZoneBorderColor, - hostZoneHighlightColor, - hostZoneHighlightOpacity, - zones, - highlightZone, - flashMode); - } - - EndBufferedPaint(bufferedPaint, TRUE); - } - - if (!oldHdc) - { - EndPaint(window, &ps); - } - } } struct ZoneWindow : public winrt::implements @@ -117,7 +69,7 @@ public: ZoneWindow(HINSTANCE hinstance); ~ZoneWindow(); - bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones); + bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId); IFACEMETHODIMP MoveSizeEnter(HWND window) noexcept; IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) noexcept; @@ -157,18 +109,15 @@ private: void CalculateZoneSet() noexcept; void UpdateActiveZoneSet(_In_opt_ IZoneSet* zoneSet) noexcept; LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept; - void OnPaint(HDC hdc) noexcept; void OnKeyUp(WPARAM wparam) noexcept; std::vector ZonesFromPoint(POINT pt) noexcept; void CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::InputMode mode) noexcept; - void FlashZones() noexcept; winrt::com_ptr m_host; HMONITOR m_monitor{}; std::wstring m_uniqueId; // Parsed deviceId + resolution + virtualDesktopId wil::unique_hwnd m_window{}; // Hidden tool window used to represent current monitor desktop work area. HWND m_windowMoveSize{}; - bool m_flashMode{}; winrt::com_ptr m_activeZoneSet; std::vector> m_zoneSets; std::vector m_initialHighlightZone; @@ -177,10 +126,7 @@ private: size_t m_keyCycle{}; static const UINT m_showAnimationDuration = 200; // ms static const UINT m_flashDuration = 700; // ms - - std::atomic m_animating; - OnThreadExecutor m_paintExecutor; - ULONG_PTR gdiplusToken; + std::unique_ptr m_zoneWindowDrawing; }; ZoneWindow::ZoneWindow(HINSTANCE hinstance) @@ -192,19 +138,13 @@ ZoneWindow::ZoneWindow(HINSTANCE hinstance) wcex.lpszClassName = NonLocalizable::ToolWindowClassName; wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW); RegisterClassExW(&wcex); - - Gdiplus::GdiplusStartupInput gdiplusStartupInput; - Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); - m_paintExecutor.submit(OnThreadExecutor::task_t{ []() { BufferedPaintInit(); } }); } ZoneWindow::~ZoneWindow() { - Gdiplus::GdiplusShutdown(gdiplusToken); - m_paintExecutor.submit(OnThreadExecutor::task_t{ []() { BufferedPaintUnInit(); } }); } -bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones) +bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId) { m_host.copy_from(host); @@ -240,22 +180,7 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit MakeWindowTransparent(m_window.get()); - // Ignore flashZones - /* - if (flashZones) - { - // Don't flash if the foreground window is in full screen mode - RECT windowRect; - if (!(GetWindowRect(GetForegroundWindow(), &windowRect) && - windowRect.left == mi.rcMonitor.left && - windowRect.top == mi.rcMonitor.top && - windowRect.right == mi.rcMonitor.right && - windowRect.bottom == mi.rcMonitor.bottom)) - { - FlashZones(); - } - } - */ + m_zoneWindowDrawing = std::make_unique(m_window.get()); return true; } @@ -307,8 +232,9 @@ IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnable if (redraw) { - InvalidateRect(m_window.get(), nullptr, true); + m_zoneWindowDrawing->DrawActiveZoneSet(m_activeZoneSet->GetZones(), m_highlightZone, m_host); } + return S_OK; } @@ -406,10 +332,6 @@ ZoneWindow::CycleActiveZoneSet(DWORD wparam) noexcept { InvalidateRect(m_window.get(), nullptr, true); } - else - { - FlashZones(); - } } IFACEMETHODIMP_(void) @@ -440,8 +362,6 @@ ZoneWindow::ShowZoneWindow() noexcept return; } - m_flashMode = false; - UINT flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE; HWND windowInsertAfter = m_windowMoveSize; @@ -451,18 +371,8 @@ ZoneWindow::ShowZoneWindow() noexcept } SetWindowPos(window, windowInsertAfter, 0, 0, 0, 0, flags); - - std::thread{ [this, strong_this{ get_strong() }]() { - m_animating = true; - auto window = m_window.get(); - AnimateWindow(window, m_showAnimationDuration, AW_BLEND); - InvalidateRect(window, nullptr, true); - if (!m_host->InMoveSize()) - { - HideZoneWindow(); - } - m_animating = false; - } }.detach(); + m_zoneWindowDrawing->Show(m_showAnimationDuration); + m_zoneWindowDrawing->DrawActiveZoneSet(m_activeZoneSet->GetZones(), m_highlightZone, m_host); } IFACEMETHODIMP_(void) @@ -470,7 +380,7 @@ ZoneWindow::HideZoneWindow() noexcept { if (m_window) { - ShowWindow(m_window.get(), SW_HIDE); + m_zoneWindowDrawing->Hide(); m_keyLast = 0; m_windowMoveSize = nullptr; m_highlightZone = {}; @@ -489,7 +399,7 @@ ZoneWindow::ClearSelectedZones() noexcept if (m_highlightZone.size()) { m_highlightZone.clear(); - InvalidateRect(m_window.get(), nullptr, true); + m_zoneWindowDrawing->DrawActiveZoneSet(m_activeZoneSet->GetZones(), m_highlightZone, m_host); } } @@ -533,7 +443,7 @@ void ZoneWindow::CalculateZoneSet() noexcept activeZoneSet.type, m_monitor, sensitivityRadius)); - + RECT workArea; if (m_monitor) { @@ -556,9 +466,9 @@ void ZoneWindow::CalculateZoneSet() noexcept bool showSpacing = deviceInfoData->showSpacing; int spacing = showSpacing ? deviceInfoData->spacing : 0; int zoneCount = deviceInfoData->zoneCount; - + zoneSet->CalculateZones(workArea, zoneCount, spacing); - UpdateActiveZoneSet(zoneSet.get()); + UpdateActiveZoneSet(zoneSet.get()); } } @@ -594,16 +504,11 @@ LRESULT ZoneWindow::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept case WM_ERASEBKGND: return 1; - case WM_PRINTCLIENT: - { - OnPaint(reinterpret_cast(wparam)); - } - break; case WM_PAINT: { - OnPaint(NULL); + m_zoneWindowDrawing->ForceRender(); + break; } - break; default: { @@ -613,52 +518,6 @@ LRESULT ZoneWindow::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept return 0; } -void ZoneWindow::OnPaint(HDC hdc) noexcept -{ - HWND window = m_window.get(); - bool hasActiveZoneSet = m_activeZoneSet && m_host; - COLORREF hostZoneColor{}; - COLORREF hostZoneBorderColor{}; - COLORREF hostZoneHighlightColor{}; - int hostZoneHighlightOpacity{}; - IZoneSet::ZonesMap zones; - std::vector highlightZone = m_highlightZone; - bool flashMode = m_flashMode; - - if (hasActiveZoneSet) - { - hostZoneColor = m_host->GetZoneColor(); - hostZoneBorderColor = m_host->GetZoneBorderColor(); - hostZoneHighlightColor = m_host->GetZoneHighlightColor(); - hostZoneHighlightOpacity = m_host->GetZoneHighlightOpacity(); - zones = m_activeZoneSet->GetZones(); - } - - OnThreadExecutor::task_t task{ - [=]() { - ZoneWindowUtils::PaintZoneWindow(hdc, - window, - hasActiveZoneSet, - hostZoneColor, - hostZoneBorderColor, - hostZoneHighlightColor, - hostZoneHighlightOpacity, - zones, - highlightZone, - flashMode); - } }; - - if (m_animating) - { - task(); - } - else - { - m_paintExecutor.cancel(); - m_paintExecutor.submit(std::move(task)); - } -} - void ZoneWindow::OnKeyUp(WPARAM wparam) noexcept { bool fRedraw = false; @@ -667,7 +526,7 @@ void ZoneWindow::OnKeyUp(WPARAM wparam) noexcept if ((wparam >= '0') && (wparam <= '9')) { CycleActiveZoneSetInternal(static_cast(wparam), Trace::ZoneWindow::InputMode::Keyboard); - InvalidateRect(m_window.get(), nullptr, true); + m_zoneWindowDrawing->DrawActiveZoneSet(m_activeZoneSet->GetZones(), m_highlightZone, m_host); } } @@ -728,21 +587,6 @@ void ZoneWindow::CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::Inp m_highlightZone = {}; } -void ZoneWindow::FlashZones() noexcept -{ - // "Turning FLASHING_ZONE option off" - if (true) - { - return; - } - - m_flashMode = true; - - ShowWindow(m_window.get(), SW_SHOWNA); - std::thread([window = m_window.get()]() { - AnimateWindow(window, m_flashDuration, AW_HIDE | AW_BLEND); - }).detach(); -} #pragma endregion LRESULT CALLBACK ZoneWindow::s_WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept @@ -759,10 +603,10 @@ LRESULT CALLBACK ZoneWindow::s_WndProc(HWND window, UINT message, WPARAM wparam, DefWindowProc(window, message, wparam, lparam); } -winrt::com_ptr MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones) noexcept +winrt::com_ptr MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId) noexcept { auto self = winrt::make_self(hinstance); - if (self->Init(host, hinstance, monitor, uniqueId, parentUniqueId, flashZones)) + if (self->Init(host, hinstance, monitor, uniqueId, parentUniqueId)) { return self; } diff --git a/src/modules/fancyzones/lib/ZoneWindow.h b/src/modules/fancyzones/lib/ZoneWindow.h index aeeb318f2..9eb70d9c7 100644 --- a/src/modules/fancyzones/lib/ZoneWindow.h +++ b/src/modules/fancyzones/lib/ZoneWindow.h @@ -127,4 +127,4 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow }; winrt::com_ptr MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, - const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones) noexcept; + const std::wstring& uniqueId, const std::wstring& parentUniqueId) noexcept; diff --git a/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp b/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp index e47951eab..b90186bd9 100644 --- a/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp +++ b/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp @@ -11,155 +11,303 @@ namespace NonLocalizable const wchar_t SegoeUiFont[] = L"Segoe ui"; } -namespace +float ZoneWindowDrawing::GetAnimationAlpha() { - void InitRGB(_Out_ RGBQUAD* quad, BYTE alpha, COLORREF color) + // Lock is being held + if (!m_animation) { - ZeroMemory(quad, sizeof(*quad)); - quad->rgbReserved = alpha; - quad->rgbRed = GetRValue(color) * alpha / 255; - quad->rgbGreen = GetGValue(color) * alpha / 255; - quad->rgbBlue = GetBValue(color) * alpha / 255; + return 1.f; } - void FillRectARGB(wil::unique_hdc& hdc, RECT const* prcFill, BYTE alpha, COLORREF color, bool blendAlpha) + auto tNow = std::chrono::steady_clock().now(); + auto alpha = (tNow - m_animation->tStart).count() / (1e6f * m_animation->duration); + if (alpha < 1.f) { - BITMAPINFO bi; - ZeroMemory(&bi, sizeof(bi)); - bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bi.bmiHeader.biWidth = 1; - bi.bmiHeader.biHeight = 1; - bi.bmiHeader.biPlanes = 1; - bi.bmiHeader.biBitCount = 32; - bi.bmiHeader.biCompression = BI_RGB; - - RECT fillRect; - CopyRect(&fillRect, prcFill); - - RGBQUAD bitmapBits; - InitRGB(&bitmapBits, alpha, color); - StretchDIBits( - hdc.get(), - fillRect.left, - fillRect.top, - fillRect.right - fillRect.left, - fillRect.bottom - fillRect.top, - 0, - 0, - 1, - 1, - &bitmapBits, - &bi, - DIB_RGB_COLORS, - SRCCOPY); + return alpha; } - - BYTE OpacitySettingToAlpha(int opacity) + else { - return static_cast(opacity * 2.55); - } - - void DrawIndex(wil::unique_hdc& hdc, FancyZonesUtils::Rect rect, size_t index) - { - Gdiplus::Graphics g(hdc.get()); - - Gdiplus::FontFamily fontFamily(NonLocalizable::SegoeUiFont); - Gdiplus::Font font(&fontFamily, 80, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); - Gdiplus::SolidBrush solidBrush(Gdiplus::Color(255, 0, 0, 0)); - - std::wstring text = std::to_wstring(index); - - g.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); - Gdiplus::StringFormat stringFormat = new Gdiplus::StringFormat(); - stringFormat.SetAlignment(Gdiplus::StringAlignmentCenter); - stringFormat.SetLineAlignment(Gdiplus::StringAlignmentCenter); - - Gdiplus::RectF gdiRect(static_cast(rect.left()), - static_cast(rect.top()), - static_cast(rect.width()), - static_cast(rect.height())); - - g.DrawString(text.c_str(), -1, &font, gdiRect, &stringFormat, &solidBrush); - } - - void DrawZone(wil::unique_hdc& hdc, ZoneWindowDrawing::ColorSetting const& colorSetting, winrt::com_ptr zone, bool flashMode)noexcept - { - RECT zoneRect = zone->GetZoneRect(); - - Gdiplus::Graphics g(hdc.get()); - Gdiplus::Color fillColor(colorSetting.fillAlpha, GetRValue(colorSetting.fill), GetGValue(colorSetting.fill), GetBValue(colorSetting.fill)); - Gdiplus::Color borderColor(colorSetting.borderAlpha, GetRValue(colorSetting.border), GetGValue(colorSetting.border), GetBValue(colorSetting.border)); - - Gdiplus::Rect rectangle(zoneRect.left, zoneRect.top, zoneRect.right - zoneRect.left - 1, zoneRect.bottom - zoneRect.top - 1); - - Gdiplus::Pen pen(borderColor, static_cast(colorSetting.thickness)); - g.FillRectangle(new Gdiplus::SolidBrush(fillColor), rectangle); - g.DrawRectangle(&pen, rectangle); - - if (!flashMode) - { - DrawIndex(hdc, zoneRect, zone->Id() + 1); - } + return 1.f; } } -namespace ZoneWindowDrawing +ID2D1Factory* ZoneWindowDrawing::GetD2DFactory() { - void DrawBackdrop(wil::unique_hdc& hdc, RECT const& clientRect) noexcept + static auto pD2DFactory = [] { + ID2D1Factory* res = nullptr; + D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &res); + return res; + }(); + return pD2DFactory; +} + +IDWriteFactory* ZoneWindowDrawing::GetWriteFactory() +{ + static auto pDWriteFactory = [] { + IUnknown* res = nullptr; + DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &res); + return reinterpret_cast(res); + }(); + return pDWriteFactory; +} + +D2D1_COLOR_F ZoneWindowDrawing::ConvertColor(COLORREF color) +{ + return D2D1::ColorF(GetRValue(color) / 255.f, + GetGValue(color) / 255.f, + GetBValue(color) / 255.f, + 1.f); +} + +D2D1_RECT_F ZoneWindowDrawing::ConvertRect(RECT rect) +{ + return D2D1::RectF((float)rect.left + 0.5f, (float)rect.top + 0.5f, (float)rect.right - 0.5f, (float)rect.bottom - 0.5f); +} + +ZoneWindowDrawing::ZoneWindowDrawing(HWND window) +{ + m_window = window; + m_renderTarget = nullptr; + m_shouldRender = false; + + // Obtain the size of the drawing area. + if (!GetClientRect(window, &m_clientRect)) { - FillRectARGB(hdc, &clientRect, 0, RGB(0, 0, 0), false); + return; } - void DrawActiveZoneSet(wil::unique_hdc& hdc, - COLORREF zoneColor, - COLORREF zoneBorderColor, - COLORREF highlightColor, - int zoneOpacity, - const IZoneSet::ZonesMap& zones, - const std::vector& highlightZones, - bool flashMode) noexcept + // Create a Direct2D render target + // We should always use the DPI value of 96 since we're running in DPI aware mode + GetD2DFactory()->CreateHwndRenderTarget( + D2D1::RenderTargetProperties( + D2D1_RENDER_TARGET_TYPE_DEFAULT, + D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), + 96.f, + 96.f), + D2D1::HwndRenderTargetProperties( + window, + D2D1::SizeU( + m_clientRect.right - m_clientRect.left, + m_clientRect.bottom - m_clientRect.top)), + &m_renderTarget); + + m_renderThread = std::thread([this]() { + while (!m_abortThread) + { + // Force repeated rendering while in the animation loop. + // Yield if low latency locking was requested + if (!m_lowLatencyLock) + { + float animationAlpha; + { + std::unique_lock lock(m_mutex); + animationAlpha = GetAnimationAlpha(); + } + + if (animationAlpha < 1.f) + { + m_shouldRender = true; + } + } + + Render(); + } + }); +} + +void ZoneWindowDrawing::Render() +{ + std::unique_lock lock(m_mutex); + + if (!m_renderTarget) { - // { fillAlpha, fill, borderAlpha, border, thickness } - ColorSetting colorViewer{ OpacitySettingToAlpha(zoneOpacity), 0, 255, RGB(40, 50, 60), -2 }; - ColorSetting colorHighlight{ OpacitySettingToAlpha(zoneOpacity), 0, 255, 0, -2 }; - ColorSetting const colorFlash{ OpacitySettingToAlpha(zoneOpacity), RGB(81, 92, 107), 200, RGB(104, 118, 138), -2 }; + return; + } - // First draw the inactive zones - for (auto iter = zones.begin(); iter != zones.end(); iter++) + m_cv.wait(lock, [this]() { return (bool)m_shouldRender; }); + + m_renderTarget->BeginDraw(); + + float animationAlpha = GetAnimationAlpha(); + + // Draw backdrop + m_renderTarget->Clear(D2D1::ColorF(0.f, 0.f, 0.f, 0.f)); + + ID2D1SolidColorBrush* textBrush = nullptr; + IDWriteTextFormat* textFormat = nullptr; + + m_renderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black, animationAlpha), &textBrush); + auto writeFactory = GetWriteFactory(); + + if (writeFactory) + { + writeFactory->CreateTextFormat(NonLocalizable::SegoeUiFont, nullptr, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 80.f, L"en-US", &textFormat); + } + + for (auto drawableRect : m_sceneRects) + { + ID2D1SolidColorBrush* borderBrush = nullptr; + ID2D1SolidColorBrush* fillBrush = nullptr; + + // Need to copy the rect from m_sceneRects + drawableRect.borderColor.a *= animationAlpha; + drawableRect.fillColor.a *= animationAlpha; + + m_renderTarget->CreateSolidColorBrush(drawableRect.borderColor, &borderBrush); + m_renderTarget->CreateSolidColorBrush(drawableRect.fillColor, &fillBrush); + + if (fillBrush) { - winrt::com_ptr zone = iter->second; - size_t zoneId = zone->Id(); - if (!zone) - { - continue; - } - - auto zoneIt = std::find(highlightZones.begin(), highlightZones.end(), zoneId); - if (zoneIt == highlightZones.end()) - { - if (flashMode) - { - DrawZone(hdc, colorFlash, zone, flashMode); - } - else - { - colorViewer.fill = zoneColor; - colorViewer.border = zoneBorderColor; - DrawZone(hdc, colorViewer, zone, flashMode); - } - } + m_renderTarget->FillRectangle(drawableRect.rect, fillBrush); + fillBrush->Release(); } - // Draw the active zones on top of the inactive zones - for (const auto& zoneId : highlightZones) + if (borderBrush) { - colorHighlight.fill = highlightColor; - colorHighlight.border = zoneBorderColor; - - if (zones.contains(zoneId)) - { - DrawZone(hdc, colorHighlight, zones.at(zoneId), flashMode); - } + m_renderTarget->DrawRectangle(drawableRect.rect, borderBrush); + borderBrush->Release(); } + + std::wstring idStr = std::to_wstring(drawableRect.id + 1); + + if (textFormat && textBrush) + { + textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER); + textFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); + m_renderTarget->DrawTextW(idStr.c_str(), (UINT32)idStr.size(), textFormat, drawableRect.rect, textBrush); + } + } + + if (textFormat) + { + textFormat->Release(); + } + + if (textBrush) + { + textBrush->Release(); + } + + m_renderTarget->EndDraw(); + m_shouldRender = false; +} + +void ZoneWindowDrawing::Hide() +{ + m_lowLatencyLock = true; + std::unique_lock lock(m_mutex); + m_lowLatencyLock = false; + + if (m_animation) + { + m_animation.reset(); + ShowWindow(m_window, SW_HIDE); } } + +void ZoneWindowDrawing::Show(unsigned animationMillis) +{ + m_lowLatencyLock = true; + std::unique_lock lock(m_mutex); + m_lowLatencyLock = false; + + if (!m_animation) + { + ShowWindow(m_window, SW_SHOWDEFAULT); + if (animationMillis > 0) + { + m_animation.emplace(AnimationInfo{ std::chrono::steady_clock().now(), animationMillis }); + } + m_shouldRender = true; + m_cv.notify_all(); + } +} + +void ZoneWindowDrawing::DrawActiveZoneSet(const IZoneSet::ZonesMap& zones, + const std::vector& highlightZones, + winrt::com_ptr host) +{ + m_lowLatencyLock = true; + std::unique_lock lock(m_mutex); + m_lowLatencyLock = false; + + m_sceneRects = {}; + + auto borderColor = ConvertColor(host->GetZoneBorderColor()); + auto inactiveColor = ConvertColor(host->GetZoneColor()); + auto highlightColor = ConvertColor(host->GetZoneHighlightColor()); + + inactiveColor.a = host->GetZoneHighlightOpacity() / 100.f; + highlightColor.a = host->GetZoneHighlightOpacity() / 100.f; + + std::vector isHighlighted(zones.size() + 1, false); + for (size_t x : highlightZones) + { + isHighlighted[x] = true; + } + + // First draw the inactive zones + for (const auto& [zoneId, zone] : zones) + { + if (!zone) + { + continue; + } + + if (!isHighlighted[zoneId]) + { + DrawableRect drawableRect{ + .rect = ConvertRect(zone->GetZoneRect()), + .borderColor = borderColor, + .fillColor = inactiveColor, + .id = zone->Id() + }; + + m_sceneRects.push_back(drawableRect); + } + } + + // Draw the active zones on top of the inactive zones + for (const auto& [zoneId, zone] : zones) + { + if (!zone) + { + continue; + } + + if (isHighlighted[zoneId]) + { + DrawableRect drawableRect{ + .rect = ConvertRect(zone->GetZoneRect()), + .borderColor = borderColor, + .fillColor = highlightColor, + .id = zone->Id() + }; + + m_sceneRects.push_back(drawableRect); + } + } + + m_shouldRender = true; + m_cv.notify_all(); +} + +void ZoneWindowDrawing::ForceRender() +{ + m_lowLatencyLock = true; + std::unique_lock lock(m_mutex); + m_lowLatencyLock = false; + m_shouldRender = true; + m_cv.notify_all(); +} + +ZoneWindowDrawing::~ZoneWindowDrawing() +{ + { + std::unique_lock lock(m_mutex); + m_abortThread = true; + m_shouldRender = true; + } + m_cv.notify_all(); + m_renderThread.join(); +} diff --git a/src/modules/fancyzones/lib/ZoneWindowDrawing.h b/src/modules/fancyzones/lib/ZoneWindowDrawing.h index 35932a57b..879452430 100644 --- a/src/modules/fancyzones/lib/ZoneWindowDrawing.h +++ b/src/modules/fancyzones/lib/ZoneWindowDrawing.h @@ -4,29 +4,59 @@ #include #include #include +#include +#include #include "util.h" #include "Zone.h" #include "ZoneSet.h" +#include "FancyZones.h" -namespace ZoneWindowDrawing +class ZoneWindowDrawing { - struct ColorSetting + struct DrawableRect { - BYTE fillAlpha{}; - COLORREF fill{}; - BYTE borderAlpha{}; - COLORREF border{}; - int thickness{}; + D2D1_RECT_F rect; + D2D1_COLOR_F borderColor; + D2D1_COLOR_F fillColor; + size_t id; }; - void DrawBackdrop(wil::unique_hdc& hdc, RECT const& clientRect) noexcept; - void DrawActiveZoneSet(wil::unique_hdc& hdc, - COLORREF zoneColor, - COLORREF zoneBorderColor, - COLORREF highlightColor, - int zoneOpacity, - const IZoneSet::ZonesMap& zones, + struct AnimationInfo + { + std::chrono::steady_clock::time_point tStart; + unsigned duration; + }; + + HWND m_window; + RECT m_clientRect; + ID2D1HwndRenderTarget* m_renderTarget; + std::optional m_animation; + + std::mutex m_mutex; + std::vector m_sceneRects; + + float GetAnimationAlpha(); + static ID2D1Factory* GetD2DFactory(); + static IDWriteFactory* GetWriteFactory(); + static D2D1_COLOR_F ConvertColor(COLORREF color); + static D2D1_RECT_F ConvertRect(RECT rect); + void Render(); + + std::atomic m_shouldRender; + std::atomic m_abortThread; + std::atomic m_lowLatencyLock; + std::condition_variable m_cv; + std::thread m_renderThread; + +public: + + ~ZoneWindowDrawing(); + ZoneWindowDrawing(HWND window); + void Hide(); + void Show(unsigned animationMillis); + void ForceRender(); + void DrawActiveZoneSet(const IZoneSet::ZonesMap& zones, const std::vector& highlightZones, - bool flashMode) noexcept; -} + winrt::com_ptr host); +}; diff --git a/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp index 73c3a46c2..913fcf530 100644 --- a/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp @@ -114,7 +114,7 @@ namespace FancyZonesUnitTests TEST_METHOD(CreateZoneWindow) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); testZoneWindow(zoneWindow); auto* activeZoneSet{ zoneWindow->ActiveZoneSet() }; @@ -125,7 +125,7 @@ namespace FancyZonesUnitTests TEST_METHOD(CreateZoneWindowNoHinst) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), {}, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), {}, m_monitor, m_uniqueId.str(), {}); testZoneWindow(zoneWindow); auto* activeZoneSet{ zoneWindow->ActiveZoneSet() }; @@ -136,7 +136,7 @@ namespace FancyZonesUnitTests TEST_METHOD(CreateZoneWindowNoHinstFlashZones) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), {}, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), {}, m_monitor, m_uniqueId.str(), {}); testZoneWindow(zoneWindow); auto* activeZoneSet{ zoneWindow->ActiveZoneSet() }; @@ -147,13 +147,7 @@ namespace FancyZonesUnitTests TEST_METHOD(CreateZoneWindowNoMonitor) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, {}, m_uniqueId.str(), {}, false); - testZoneWindow(zoneWindow); - } - - TEST_METHOD(CreateZoneWindowNoMonitorFlashZones) - { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, {}, m_uniqueId.str(), {}, true); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, {}, m_uniqueId.str(), {}); testZoneWindow(zoneWindow); } @@ -161,7 +155,7 @@ namespace FancyZonesUnitTests { // Generate unique id without device id std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, {}, m_virtualDesktopId); - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, uniqueId, {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, uniqueId, {}); const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom); const std::wstring expectedUniqueId = L"FallbackDevice_" + std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom) + L"_" + m_virtualDesktopId; @@ -179,7 +173,7 @@ namespace FancyZonesUnitTests { // Generate unique id without virtual desktop id std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, m_deviceId, {}); - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, uniqueId, {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, uniqueId, {}); const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom); Assert::IsNotNull(zoneWindow.get()); @@ -208,7 +202,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath); //temp file read on initialization - auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); testZoneWindow(actual); @@ -232,7 +226,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath); //temp file read on initialization - auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); testZoneWindow(actual); @@ -268,7 +262,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath); //temp file read on initialization - auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); testZoneWindow(actual); @@ -315,7 +309,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath); //temp file read on initialization - auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); testZoneWindow(actual); @@ -362,7 +356,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath); //temp file read on initialization - auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); testZoneWindow(actual); @@ -384,11 +378,11 @@ namespace FancyZonesUnitTests m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo); winrt::com_ptr zoneWindowHost = winrt::make_self(); - auto parentZoneWindow = MakeZoneWindow(zoneWindowHost.get(), m_hInst, m_monitor, m_parentUniqueId.str(), {}, false); + auto parentZoneWindow = MakeZoneWindow(zoneWindowHost.get(), m_hInst, m_monitor, m_parentUniqueId.str(), {}); zoneWindowHost->m_zoneWindow = parentZoneWindow.get(); // newWorkArea = true - zoneWindow will be cloned from parent - auto actualZoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), m_parentUniqueId.str(), false); + auto actualZoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), m_parentUniqueId.str()); Assert::IsNotNull(actualZoneWindow->ActiveZoneSet()); const auto actualZoneSet = actualZoneWindow->ActiveZoneSet()->GetZones(); @@ -414,11 +408,11 @@ namespace FancyZonesUnitTests m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo); winrt::com_ptr zoneWindowHost = winrt::make_self(); - auto parentZoneWindow = MakeZoneWindow(zoneWindowHost.get(), m_hInst, m_monitor, m_parentUniqueId.str(), {}, false); + auto parentZoneWindow = MakeZoneWindow(zoneWindowHost.get(), m_hInst, m_monitor, m_parentUniqueId.str(), {}); zoneWindowHost->m_zoneWindow = parentZoneWindow.get(); // newWorkArea = false - zoneWindow won't be cloned from parent - auto actualZoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto actualZoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); Assert::IsNotNull(actualZoneWindow->ActiveZoneSet()); @@ -475,7 +469,7 @@ namespace FancyZonesUnitTests public: TEST_METHOD(MoveSizeEnter) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); const auto expected = S_OK; const auto actual = zoneWindow->MoveSizeEnter(Mocks::Window()); @@ -485,7 +479,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeEnterTwice) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); const auto expected = S_OK; @@ -497,7 +491,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeUpdate) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); const auto expected = S_OK; const auto actual = zoneWindow->MoveSizeUpdate(POINT{ 0, 0 }, true, false); @@ -507,7 +501,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeUpdatePointNegativeCoordinates) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); const auto expected = S_OK; const auto actual = zoneWindow->MoveSizeUpdate(POINT{ -10, -10 }, true, false); @@ -517,7 +511,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeUpdatePointBigCoordinates) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); const auto expected = S_OK; const auto actual = zoneWindow->MoveSizeUpdate(POINT{ m_monitorInfo.rcMonitor.right + 1, m_monitorInfo.rcMonitor.bottom + 1 }, true, false); @@ -527,7 +521,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeEnd) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); const auto window = Mocks::Window(); zoneWindow->MoveSizeEnter(window); @@ -544,7 +538,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeEndWindowNotAdded) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); const auto window = Mocks::Window(); zoneWindow->MoveSizeEnter(window); @@ -560,7 +554,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeEndDifferentWindows) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); const auto window = Mocks::Window(); zoneWindow->MoveSizeEnter(window); @@ -573,7 +567,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeEndWindowNotSet) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); const auto expected = E_INVALIDARG; const auto actual = zoneWindow->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 }); @@ -583,7 +577,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeEndInvalidPoint) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); const auto window = Mocks::Window(); zoneWindow->MoveSizeEnter(window); @@ -600,7 +594,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveWindowIntoZoneByIndex) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); Assert::IsNotNull(zoneWindow->ActiveZoneSet()); zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0); @@ -610,7 +604,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveWindowIntoZoneByDirectionAndIndex) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); Assert::IsNotNull(zoneWindow->ActiveZoneSet()); const auto window = Mocks::WindowCreate(m_hInst); @@ -625,7 +619,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveWindowIntoZoneByDirectionManyTimes) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); Assert::IsNotNull(zoneWindow->ActiveZoneSet()); const auto window = Mocks::WindowCreate(m_hInst); @@ -642,7 +636,7 @@ namespace FancyZonesUnitTests TEST_METHOD(SaveWindowProcessToZoneIndexNullptrWindow) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); Assert::IsNotNull(zoneWindow->ActiveZoneSet()); zoneWindow->SaveWindowProcessToZoneIndex(nullptr); @@ -653,7 +647,7 @@ namespace FancyZonesUnitTests TEST_METHOD(SaveWindowProcessToZoneIndexNoWindowAdded) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); Assert::IsNotNull(zoneWindow->ActiveZoneSet()); auto window = Mocks::WindowCreate(m_hInst); @@ -668,7 +662,7 @@ namespace FancyZonesUnitTests TEST_METHOD(SaveWindowProcessToZoneIndexNoWindowAddedWithFilledAppZoneHistory) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); Assert::IsNotNull(zoneWindow->ActiveZoneSet()); const auto window = Mocks::WindowCreate(m_hInst); @@ -696,7 +690,7 @@ namespace FancyZonesUnitTests TEST_METHOD(SaveWindowProcessToZoneIndexWindowAdded) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); Assert::IsNotNull(zoneWindow->ActiveZoneSet()); auto window = Mocks::WindowCreate(m_hInst); @@ -726,7 +720,7 @@ namespace FancyZonesUnitTests TEST_METHOD(WhenWindowIsNotResizablePlacingItIntoTheZoneShouldNotResizeIt) { - auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}, false); + auto zoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); Assert::IsNotNull(zoneWindow->ActiveZoneSet()); auto window = Mocks::WindowCreate(m_hInst);