[FancyZones] Rename ZoneWindowDrawing -> ZonesDrawing (#14464)

* [FancyZones] Rename ZoneWindowDrawing -> ZonesOverlay

* [FancyZones] Rename ZoneWindowDrawing -> ZonesOverlay in tools and docs

Co-authored-by: float4 <float4-unspecified-mail>
This commit is contained in:
FLOAT4 2021-11-25 17:39:03 +02:00 committed by GitHub
parent 375ce4c798
commit 5381486c25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 75 additions and 70 deletions

View File

@ -15,7 +15,7 @@ TODO
#### [`ZoneSet.cpp`](/src/modules/fancyzones/lib/ZoneSet.cpp)
TODO
#### [`ZoneWindow.cpp`](/src/modules/fancyzones/lib/ZoneWindow.cpp)
#### [`WorkArea.cpp`](/src/modules/fancyzones/lib/WorkArea.cpp)
TODO
## FancyZones Editor

View File

@ -2,17 +2,17 @@
---
1. `Zone` - Class which is basically wrapper around rectangle structure, representing one zone inside applied zone layout. ZoneSet is holding array of these which represent zone layout.
2. `ZoneSet` - Class implementing actual zone layout applied. What this means is that ZoneSet is responsible for actual calculation of rectangle coordinates (whether is grid or canvas layout) and moving window through them. ZoneWindow holds ZoneSet structure which represents currently active zone set.
3. `ZoneWindow` - Class representing work area, which is defined by monitor and current virtual desktop. For an example, if You have two monitors connected and two virtual desktops, You have 4 work areas available, and each of them can have separate zone layout. ZoneWindow is describing single work area. As mentioned before it holds active ZoneSet.
2. `ZoneSet` - Class implementing actual zone layout applied. What this means is that ZoneSet is responsible for actual calculation of rectangle coordinates (whether is grid or canvas layout) and moving window through them. WorkArea holds ZoneSet structure which represents currently active zone set.
3. `WorkArea` - Class representing work area, which is defined by monitor and current virtual desktop. For an example, if You have two monitors connected and two virtual desktops, You have 4 work areas available, and each of them can have separate zone layout. WorkArea is describing single work area. As mentioned before it holds active ZoneSet.
4. `FancyZones` - Top level entity and entry point for all user actions (which goes through actual module interface). Some of the main responsibilities of FancyZones class:
1. Starting FancyZones Editor (C#) with appropriate command line arguments on user request.
2. Keeping track of ZoneWindow per monitor (currently active work area on each connected monitor).
2. Keeping track of WorkArea per monitor (currently active work area on each connected monitor).
3. Keeping track of active virtual desktops. This is performed in separate thread by polling VirtualDesktopIDs registry key and parsing its content.
4. Detecting every change in work environment, such as creating / destroying / switching between virtual desktops, closing FancyZones Editor, changing display settings and handling those changes.
### Proposal for modifications of handling described in 4.4:
Currently after each of the mentioned changes in work environment we are calling EnumDisplayMonitors windows API, and passing callback function to it. EnumDisplayMonitors works asynchronous and triggers that callback for each work area available (as mentioned in previous example, for two monitors and two virtual desktops, we have this callback triggered four times). As mentioned previously, we have ZoneWindow class as our representation of this work area. And what we do, every time this callback is triggered we destroy previous ZoneWindow object for that work area and create new one, even though that it is most likely that nothing has changed (e.g. just switching back and forth between virtual desktops). This constant creation and deletion of ZoneWindow has caused some problems in the past and it's not ideal for some other fixes we would like to make in the multi-monitor/multi-desktop scenario.
Currently after each of the mentioned changes in work environment we are calling EnumDisplayMonitors windows API, and passing callback function to it. EnumDisplayMonitors works asynchronous and triggers that callback for each work area available (as mentioned in previous example, for two monitors and two virtual desktops, we have this callback triggered four times). As mentioned previously, we have WorkArea class as our representation of this work area. And what we do, every time this callback is triggered we destroy previous WorkArea object for that work area and create new one, even though that it is most likely that nothing has changed (e.g. just switching back and forth between virtual desktops). This constant creation and deletion of WorkArea has caused some problems in the past and it's not ideal for some other fixes we would like to make in the multi-monitor/multi-desktop scenario.
As mentioned in 4.3 we already have tracker of virtual desktops implemented. Idea is to use this functionality and to extend it bit more, so we can track if work area (ZoneWindow) is new one, or already processed and skip creating new ZoneWindow objects and deleting old ones every time, even if nothing changed in it. We will keep map, where virtual desktop id is the key, and values are already processed monitors (virtual desktop exists across all monitors). Once we receive callback from EnumDisplayMonitors, indicating work area (defined by virtual desktop id and monitor) we can check if its new or not, and act accordingly (create new ZoneWindow for it or not). Deleting virtual desktop (which is also registered in 4.3), will trigger updates in this map, and also updates in our JSON storage.
As mentioned in 4.3 we already have tracker of virtual desktops implemented. Idea is to use this functionality and to extend it bit more, so we can track if work area (WorkArea) is new one, or already processed and skip creating new WorkArea objects and deleting old ones every time, even if nothing changed in it. We will keep map, where virtual desktop id is the key, and values are already processed monitors (virtual desktop exists across all monitors). Once we receive callback from EnumDisplayMonitors, indicating work area (defined by virtual desktop id and monitor) we can check if its new or not, and act accordingly (create new WorkArea for it or not). Deleting virtual desktop (which is also registered in 4.3), will trigger updates in this map, and also updates in our JSON storage.

View File

@ -61,7 +61,7 @@
<ClInclude Include="ZoneColors.h" />
<ClInclude Include="ZoneSet.h" />
<ClInclude Include="WorkArea.h" />
<ClInclude Include="ZoneWindowDrawing.h" />
<ClInclude Include="ZonesOverlay.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="FancyZones.cpp" />
@ -84,7 +84,7 @@
<ClCompile Include="Zone.cpp" />
<ClCompile Include="ZoneSet.cpp" />
<ClCompile Include="WorkArea.cpp" />
<ClCompile Include="ZoneWindowDrawing.cpp" />
<ClCompile Include="ZonesOverlay.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="fancyzones.base.rc" />

View File

@ -75,7 +75,7 @@
<ClInclude Include="KeyState.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZoneWindowDrawing.h">
<ClInclude Include="ZonesOverlay.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MonitorUtils.h">
@ -140,7 +140,7 @@
<ClCompile Include="FancyZonesDataTypes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneWindowDrawing.cpp">
<ClCompile Include="ZonesOverlay.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OnThreadExecutor.cpp">

View File

@ -101,12 +101,12 @@ void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const
{
for (auto [keyMonitor, workArea] : workAreaMap)
{
// Skip calling ShowZoneWindow for iter->second (m_draggedWindowWorkArea) since it
// Skip calling ShowZonesOverlay for iter->second (m_draggedWindowWorkArea) since it
// was already called in MoveSizeEnter
const bool moveSizeEnterCalled = workArea == m_draggedWindowWorkArea;
if (workArea && !moveSizeEnterCalled)
{
workArea->ShowZoneWindow();
workArea->ShowZonesOverlay();
}
}
}
@ -119,7 +119,7 @@ void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const
{
if (workArea)
{
workArea->HideZoneWindow();
workArea->HideZonesOverlay();
}
}
}
@ -159,7 +159,7 @@ void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen,
{
if (workArea)
{
workArea->HideZoneWindow();
workArea->HideZonesOverlay();
}
}
}
@ -174,7 +174,7 @@ void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen,
m_draggedWindowWorkArea->ClearSelectedZones();
if (!m_settings->GetSettings()->showZonesOnAllMonitors)
{
m_draggedWindowWorkArea->HideZoneWindow();
m_draggedWindowWorkArea->HideZonesOverlay();
}
m_draggedWindowWorkArea = iter->second;
@ -279,7 +279,7 @@ void WindowMoveHandler::MoveSizeEnd(HWND window, POINT const& ptScreen, const st
{
if (workArea)
{
workArea->HideZoneWindow();
workArea->HideZonesOverlay();
}
}
}

View File

@ -6,7 +6,7 @@
#include "FancyZonesData.h"
#include "FancyZonesDataTypes.h"
#include "ZoneWindowDrawing.h"
#include "ZonesOverlay.h"
#include "trace.h"
#include "util.h"
#include "on_thread_executor.h"
@ -21,7 +21,7 @@
// Non-Localizable strings
namespace NonLocalizable
{
const wchar_t ToolWindowClassName[] = L"SuperFancyZones_ZoneWindow";
const wchar_t ToolWindowClassName[] = L"FancyZones_ZonesOverlay";
}
using namespace FancyZonesUtils;
@ -57,13 +57,13 @@ namespace
public:
HWND NewZoneWindow(Rect position, HINSTANCE hinstance, WorkArea* owner)
HWND NewZonesOverlayWindow(Rect position, HINSTANCE hinstance, WorkArea* owner)
{
HWND windowFromPool = ExtractWindow();
if (windowFromPool == NULL)
{
HWND window = CreateWindowExW(WS_EX_TOOLWINDOW, NonLocalizable::ToolWindowClassName, L"", WS_POPUP, position.left(), position.top(), position.width(), position.height(), nullptr, nullptr, hinstance, owner);
Logger::info("Creating new zone window, hWnd = {}", (void*)window);
Logger::info("Creating new ZonesOverlay window, hWnd = {}", (void*)window);
MakeWindowTransparent(window);
// According to ShowWindow docs, we must call it with SW_SHOWNORMAL the first time
@ -73,17 +73,17 @@ namespace
}
else
{
Logger::info("Reusing zone window from pool, hWnd = {}", (void*)windowFromPool);
Logger::info("Reusing ZonesOverlay window from pool, hWnd = {}", (void*)windowFromPool);
SetWindowLongPtrW(windowFromPool, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(owner));
MoveWindow(windowFromPool, position.left(), position.top(), position.width(), position.height(), TRUE);
return windowFromPool;
}
}
void FreeZoneWindow(HWND window)
void FreeZonesOverlayWindow(HWND window)
{
_TRACER_;
Logger::info("Freeing zone window, hWnd = {}", (void*)window);
Logger::info("Freeing ZonesOverlay window into pool, hWnd = {}", (void*)window);
SetWindowLongPtrW(window, GWLP_USERDATA, 0);
ShowWindow(window, SW_HIDE);
@ -133,9 +133,9 @@ public:
IFACEMETHODIMP_(ZoneIndexSet)
GetWindowZoneIndexes(HWND window) const noexcept;
IFACEMETHODIMP_(void)
ShowZoneWindow() noexcept;
ShowZonesOverlay() noexcept;
IFACEMETHODIMP_(void)
HideZoneWindow() noexcept;
HideZonesOverlay() noexcept;
IFACEMETHODIMP_(void)
UpdateActiveZoneSet() noexcept;
IFACEMETHODIMP_(void)
@ -169,7 +169,7 @@ private:
ZoneIndexSet m_highlightZone;
WPARAM m_keyLast{};
size_t m_keyCycle{};
std::unique_ptr<ZoneWindowDrawing> m_zoneWindowDrawing;
std::unique_ptr<ZonesOverlay> m_zonesOverlay;
ZoneColors m_zoneColors;
OverlappingZonesAlgorithm m_overlappingAlgorithm;
};
@ -187,7 +187,7 @@ WorkArea::WorkArea(HINSTANCE hinstance)
WorkArea::~WorkArea()
{
windowPool.FreeZoneWindow(m_window);
windowPool.FreeZonesOverlayWindow(m_window);
}
bool WorkArea::Init(HINSTANCE hinstance, HMONITOR monitor, const FancyZonesDataTypes::DeviceIdData& uniqueId, const FancyZonesDataTypes::DeviceIdData& parentUniqueId, const ZoneColors& zoneColors, OverlappingZonesAlgorithm overlappingAlgorithm)
@ -215,14 +215,14 @@ bool WorkArea::Init(HINSTANCE hinstance, HMONITOR monitor, const FancyZonesDataT
m_uniqueId = uniqueId;
InitializeZoneSets(parentUniqueId);
m_window = windowPool.NewZoneWindow(workAreaRect, hinstance, this);
m_window = windowPool.NewZonesOverlayWindow(workAreaRect, hinstance, this);
if (!m_window)
{
return false;
}
m_zoneWindowDrawing = std::make_unique<ZoneWindowDrawing>(m_window);
m_zonesOverlay = std::make_unique<ZonesOverlay>(m_window);
return true;
}
@ -232,7 +232,7 @@ IFACEMETHODIMP WorkArea::MoveSizeEnter(HWND window) noexcept
m_windowMoveSize = window;
m_highlightZone = {};
m_initialHighlightZone = {};
ShowZoneWindow();
ShowZonesOverlay();
Trace::WorkArea::MoveOrResizeStarted(m_zoneSet);
return S_OK;
}
@ -275,7 +275,7 @@ IFACEMETHODIMP WorkArea::MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled,
if (redraw)
{
m_zoneWindowDrawing->DrawActiveZoneSet(m_zoneSet->GetZones(), m_highlightZone, m_zoneColors);
m_zonesOverlay->DrawActiveZoneSet(m_zoneSet->GetZones(), m_highlightZone, m_zoneColors);
}
return S_OK;
@ -301,7 +301,7 @@ IFACEMETHODIMP WorkArea::MoveSizeEnd(HWND window, POINT const& ptScreen) noexcep
}
Trace::WorkArea::MoveOrResizeEnd(m_zoneSet);
HideZoneWindow();
HideZonesOverlay();
m_windowMoveSize = nullptr;
return S_OK;
}
@ -400,22 +400,22 @@ WorkArea::GetWindowZoneIndexes(HWND window) const noexcept
}
IFACEMETHODIMP_(void)
WorkArea::ShowZoneWindow() noexcept
WorkArea::ShowZonesOverlay() noexcept
{
if (m_window)
{
SetAsTopmostWindow();
m_zoneWindowDrawing->DrawActiveZoneSet(m_zoneSet->GetZones(), m_highlightZone, m_zoneColors);
m_zoneWindowDrawing->Show();
m_zonesOverlay->DrawActiveZoneSet(m_zoneSet->GetZones(), m_highlightZone, m_zoneColors);
m_zonesOverlay->Show();
}
}
IFACEMETHODIMP_(void)
WorkArea::HideZoneWindow() noexcept
WorkArea::HideZonesOverlay() noexcept
{
if (m_window)
{
m_zoneWindowDrawing->Hide();
m_zonesOverlay->Hide();
m_keyLast = 0;
m_windowMoveSize = nullptr;
m_highlightZone = {};
@ -429,7 +429,7 @@ WorkArea::UpdateActiveZoneSet() noexcept
if (m_window)
{
m_highlightZone.clear();
m_zoneWindowDrawing->DrawActiveZoneSet(m_zoneSet->GetZones(), m_highlightZone, m_zoneColors);
m_zonesOverlay->DrawActiveZoneSet(m_zoneSet->GetZones(), m_highlightZone, m_zoneColors);
}
}
@ -448,7 +448,7 @@ WorkArea::ClearSelectedZones() noexcept
if (m_highlightZone.size())
{
m_highlightZone.clear();
m_zoneWindowDrawing->DrawActiveZoneSet(m_zoneSet->GetZones(), m_highlightZone, m_zoneColors);
m_zonesOverlay->DrawActiveZoneSet(m_zoneSet->GetZones(), m_highlightZone, m_zoneColors);
}
}
@ -458,8 +458,8 @@ WorkArea::FlashZones() noexcept
if (m_window)
{
SetAsTopmostWindow();
m_zoneWindowDrawing->DrawActiveZoneSet(m_zoneSet->GetZones(), {}, m_zoneColors);
m_zoneWindowDrawing->Flash();
m_zonesOverlay->DrawActiveZoneSet(m_zoneSet->GetZones(), {}, m_zoneColors);
m_zonesOverlay->Flash();
}
}

View File

@ -108,8 +108,14 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IWorkArea :
* @returns Zone index of the window
*/
IFACEMETHOD_(ZoneIndexSet, GetWindowZoneIndexes)(HWND window) const = 0;
IFACEMETHOD_(void, ShowZoneWindow)() = 0;
IFACEMETHOD_(void, HideZoneWindow)() = 0;
/**
* Show a drawing of the zones in the work area.
*/
IFACEMETHOD_(void, ShowZonesOverlay)() = 0;
/**
* Hide the drawing of the zones in the work area.
*/
IFACEMETHOD_(void, HideZonesOverlay)() = 0;
/**
* Update currently active zone layout for this work area.
*/

View File

@ -1,5 +1,5 @@
#include "pch.h"
#include "ZoneWindowDrawing.h"
#include "ZonesOverlay.h"
#include <algorithm>
#include <map>
@ -7,7 +7,6 @@
#include <vector>
#include <common/logger/call_tracer.h>
#include <common/logger/logger.h>
namespace
{
@ -20,7 +19,7 @@ namespace NonLocalizable
const wchar_t SegoeUiFont[] = L"Segoe ui";
}
float ZoneWindowDrawing::GetAnimationAlpha()
float ZonesOverlay::GetAnimationAlpha()
{
// Lock is held by the caller
@ -41,7 +40,7 @@ float ZoneWindowDrawing::GetAnimationAlpha()
return std::clamp(millis / FadeInDurationMillis, 0.001f, 1.f);
}
ID2D1Factory* ZoneWindowDrawing::GetD2DFactory()
ID2D1Factory* ZonesOverlay::GetD2DFactory()
{
static auto pD2DFactory = [] {
ID2D1Factory* res = nullptr;
@ -51,7 +50,7 @@ ID2D1Factory* ZoneWindowDrawing::GetD2DFactory()
return pD2DFactory;
}
IDWriteFactory* ZoneWindowDrawing::GetWriteFactory()
IDWriteFactory* ZonesOverlay::GetWriteFactory()
{
static auto pDWriteFactory = [] {
IUnknown* res = nullptr;
@ -61,7 +60,7 @@ IDWriteFactory* ZoneWindowDrawing::GetWriteFactory()
return pDWriteFactory;
}
D2D1_COLOR_F ZoneWindowDrawing::ConvertColor(COLORREF color)
D2D1_COLOR_F ZonesOverlay::ConvertColor(COLORREF color)
{
return D2D1::ColorF(GetRValue(color) / 255.f,
GetGValue(color) / 255.f,
@ -69,12 +68,12 @@ D2D1_COLOR_F ZoneWindowDrawing::ConvertColor(COLORREF color)
1.f);
}
D2D1_RECT_F ZoneWindowDrawing::ConvertRect(RECT rect)
D2D1_RECT_F ZonesOverlay::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)
ZonesOverlay::ZonesOverlay(HWND window)
{
HRESULT hr;
m_window = window;
@ -84,7 +83,7 @@ ZoneWindowDrawing::ZoneWindowDrawing(HWND window)
// Obtain the size of the drawing area.
if (!GetClientRect(window, &m_clientRect))
{
Logger::error("couldn't initialize ZoneWindowDrawing: GetClientRect failed");
Logger::error("couldn't initialize ZonesOverlay: GetClientRect failed");
return;
}
@ -103,14 +102,14 @@ ZoneWindowDrawing::ZoneWindowDrawing(HWND window)
if (!SUCCEEDED(hr))
{
Logger::error("couldn't initialize ZoneWindowDrawing: CreateHwndRenderTarget failed with {}", hr);
Logger::error("couldn't initialize ZonesOverlay: CreateHwndRenderTarget failed with {}", hr);
return;
}
m_renderThread = std::thread([this]() { RenderLoop(); });
}
ZoneWindowDrawing::RenderResult ZoneWindowDrawing::Render()
ZonesOverlay::RenderResult ZonesOverlay::Render()
{
std::unique_lock lock(m_mutex);
@ -193,7 +192,7 @@ ZoneWindowDrawing::RenderResult ZoneWindowDrawing::Render()
return RenderResult::Ok;
}
void ZoneWindowDrawing::RenderLoop()
void ZonesOverlay::RenderLoop()
{
while (!m_abortThread)
{
@ -212,7 +211,7 @@ void ZoneWindowDrawing::RenderLoop()
}
}
void ZoneWindowDrawing::Hide()
void ZonesOverlay::Hide()
{
_TRACER_;
bool shouldHideWindow = true;
@ -229,7 +228,7 @@ void ZoneWindowDrawing::Hide()
}
}
void ZoneWindowDrawing::Show()
void ZonesOverlay::Show()
{
_TRACER_;
bool shouldShowWindow = true;
@ -257,7 +256,7 @@ void ZoneWindowDrawing::Show()
m_cv.notify_all();
}
void ZoneWindowDrawing::Flash()
void ZonesOverlay::Flash()
{
_TRACER_;
bool shouldShowWindow = true;
@ -277,9 +276,9 @@ void ZoneWindowDrawing::Flash()
m_cv.notify_all();
}
void ZoneWindowDrawing::DrawActiveZoneSet(const IZoneSet::ZonesMap& zones,
const ZoneIndexSet& highlightZones,
const ZoneColors& colors)
void ZonesOverlay::DrawActiveZoneSet(const IZoneSet::ZonesMap& zones,
const ZoneIndexSet& highlightZones,
const ZoneColors& colors)
{
_TRACER_;
std::unique_lock lock(m_mutex);
@ -345,7 +344,7 @@ void ZoneWindowDrawing::DrawActiveZoneSet(const IZoneSet::ZonesMap& zones,
}
}
ZoneWindowDrawing::~ZoneWindowDrawing()
ZonesOverlay::~ZonesOverlay()
{
{
std::unique_lock lock(m_mutex);

View File

@ -13,7 +13,7 @@
#include "FancyZones.h"
#include "ZoneColors.h"
class ZoneWindowDrawing
class ZonesOverlay
{
struct DrawableRect
{
@ -60,8 +60,8 @@ class ZoneWindowDrawing
public:
~ZoneWindowDrawing();
ZoneWindowDrawing(HWND window);
~ZonesOverlay();
ZonesOverlay(HWND window);
void Hide();
void Show();
void Flash();

View File

@ -74,7 +74,7 @@ int GetHighlightedZoneIdx(const std::vector<RECT>& zones, const POINT& cursorPos
return -1;
}
void ShowZoneWindow()
void ShowZonesOverlay()
{
// InvalidateRect will essentially send WM_PAINT to main window.
UINT flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE;
@ -86,7 +86,7 @@ void ShowZoneWindow()
} }.detach();
}
void HideZoneWindow()
void HideZonesOverlay()
{
highlighted = std::vector<bool>(ZONE_COUNT, false);
ShowWindow(mainWindow, SW_HIDE);
@ -114,7 +114,7 @@ void RefreshMainWindow()
highlighted = std::vector<bool>(ZONE_COUNT, false);
highlighted[idx] = true;
ShowZoneWindow();
ShowZonesOverlay();
}
}
}
@ -138,11 +138,11 @@ LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
showZoneLayout = !showZoneLayout;
if (showZoneLayout)
{
ShowZoneWindow();
ShowZonesOverlay();
}
else
{
HideZoneWindow();
HideZonesOverlay();
}
return 1;
}