Skip to content

Commit

Permalink
Polished the functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan100sic committed Oct 28, 2020
1 parent 97ee020 commit 1390bf2
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 19 deletions.
17 changes: 8 additions & 9 deletions src/modules/fancyzones/lib/ZoneWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ struct ZoneWindow : public winrt::implements<ZoneWindow, IZoneWindow>
void CalculateZoneSet() noexcept;
void UpdateActiveZoneSet(_In_opt_ IZoneSet* zoneSet) noexcept;
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
void OnPaintD2D() noexcept;
void OnKeyUp(WPARAM wparam) noexcept;
std::vector<size_t> ZonesFromPoint(POINT pt) noexcept;
void CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::InputMode mode) noexcept;
Expand Down Expand Up @@ -233,10 +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);
}

// UpdateWindow(m_window.get());
return S_OK;
}

Expand Down Expand Up @@ -374,6 +372,7 @@ ZoneWindow::ShowZoneWindow() noexcept

SetWindowPos(window, windowInsertAfter, 0, 0, 0, 0, flags);
m_zoneWindowDrawing->Show(m_showAnimationDuration);
m_zoneWindowDrawing->DrawActiveZoneSet(m_activeZoneSet->GetZones(), m_highlightZone, m_host);
}

IFACEMETHODIMP_(void)
Expand Down Expand Up @@ -505,6 +504,12 @@ LRESULT ZoneWindow::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept
case WM_ERASEBKGND:
return 1;

case WM_PAINT:
{
m_zoneWindowDrawing->ForceRender();
break;
}

default:
{
return DefWindowProc(m_window.get(), message, wparam, lparam);
Expand All @@ -513,12 +518,6 @@ LRESULT ZoneWindow::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept
return 0;
}

void ZoneWindow::OnPaintD2D() noexcept
{
m_zoneWindowDrawing->DrawActiveZoneSet(m_activeZoneSet->GetZones(), m_highlightZone, m_host);
m_zoneWindowDrawing->Render();
}

void ZoneWindow::OnKeyUp(WPARAM wparam) noexcept
{
bool fRedraw = false;
Expand Down
70 changes: 62 additions & 8 deletions src/modules/fancyzones/lib/ZoneWindowDrawing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ namespace NonLocalizable
const wchar_t SegoeUiFont[] = L"Segoe ui";
}

void ZoneWindowDrawing::DrawBackdrop()
{
// Lock is being held
m_renderTarget->Clear(D2D1::ColorF(0.f, 0.f, 0.f, 0.f));
}

float ZoneWindowDrawing::GetAnimationAlpha()
{
// Lock is being held
Expand Down Expand Up @@ -79,6 +73,7 @@ ZoneWindowDrawing::ZoneWindowDrawing(HWND window)
m_window = window;
m_renderTarget = nullptr;
m_animationDuration = 0;
m_shouldRender = false;

// Obtain the size of the drawing area.
if (!GetClientRect(window, &m_clientRect))
Expand All @@ -97,6 +92,29 @@ ZoneWindowDrawing::ZoneWindowDrawing(HWND window)
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()
Expand All @@ -108,10 +126,15 @@ void ZoneWindowDrawing::Render()
return;
}

m_cv.wait(lock, [this]() { return (bool)m_shouldRender; });

m_renderTarget->BeginDraw();
DrawBackdrop();

float animationAlpha = GetAnimationAlpha();

// Draw backdrop
m_renderTarget->Clear(D2D1::ColorF(0.f, 0.f, 0.f, 0.f));

for (auto drawableRect : m_sceneRects)
{
ID2D1SolidColorBrush* borderBrush = nullptr;
Expand Down Expand Up @@ -167,6 +190,7 @@ void ZoneWindowDrawing::Render()
}

m_renderTarget->EndDraw();
m_shouldRender = false;
}

void ZoneWindowDrawing::Hide()
Expand All @@ -181,20 +205,27 @@ void ZoneWindowDrawing::Hide()

void ZoneWindowDrawing::Show(unsigned animationMillis)
{
m_lowLatencyLock = true;
std::unique_lock lock(m_mutex);
m_lowLatencyLock = false;

if (!m_tAnimationStart)
{
ShowWindow(m_window, SW_SHOWDEFAULT);
m_tAnimationStart = std::chrono::steady_clock().now();
m_animationDuration = animationMillis;
m_animationDuration = max(1u, animationMillis);
m_shouldRender = true;
m_cv.notify_all();
}
}

void ZoneWindowDrawing::DrawActiveZoneSet(const std::vector<winrt::com_ptr<IZone>>& zones,
const std::vector<size_t>& highlightZones,
winrt::com_ptr<IZoneWindowHost> host)
{
m_lowLatencyLock = true;
std::unique_lock lock(m_mutex);
m_lowLatencyLock = false;

m_sceneRects = {};

Expand Down Expand Up @@ -256,4 +287,27 @@ void ZoneWindowDrawing::DrawActiveZoneSet(const std::vector<winrt::com_ptr<IZone
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();
}
12 changes: 10 additions & 2 deletions src/modules/fancyzones/lib/ZoneWindowDrawing.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,27 @@ class ZoneWindowDrawing
std::mutex m_mutex;
std::vector<DrawableRect> m_sceneRects;

void DrawBackdrop();
float GetAnimationAlpha();
static ID2D1Factory* GetD2DFactory();
static IDWriteFactory* GetWriteFactory();
static D2D1_COLOR_F ConvertColor(COLORREF color);
static D2D1_RECT_F ConvertRect(RECT rect);
void Render();
void StopRendering();

std::atomic<bool> m_shouldRender;
std::atomic<bool> m_abortThread;
std::atomic<bool> m_lowLatencyLock;
std::condition_variable m_cv;
std::thread m_renderThread;

public:

~ZoneWindowDrawing();
ZoneWindowDrawing(HWND window);
void Render();
void Hide();
void Show(unsigned animationMillis);
void ForceRender();
void DrawActiveZoneSet(const std::vector<winrt::com_ptr<IZone>>& zones,
const std::vector<size_t>& highlightZones,
winrt::com_ptr<IZoneWindowHost> host);
Expand Down

0 comments on commit 1390bf2

Please sign in to comment.