[AlwaysOnTop] Corners scaling (#20352)

This commit is contained in:
Seraphima Zykova
2022-09-29 15:11:01 +02:00
committed by GitHub
parent 4e202e4523
commit 1ecaf039ca
9 changed files with 85 additions and 19 deletions

View File

@@ -131,6 +131,7 @@
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="ScalingUtils.cpp" />
<ClCompile Include="Settings.cpp" />
<ClCompile Include="trace.cpp" />
<ClCompile Include="VirtualDesktopUtils.cpp" />
@@ -144,6 +145,7 @@
<ClInclude Include="ModuleConstants.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="ScalingUtils.h" />
<ClInclude Include="Settings.h" />
<ClInclude Include="SettingsConstants.h" />
<ClInclude Include="SettingsObserver.h" />

View File

@@ -45,6 +45,9 @@
<ClCompile Include="WindowCornersUtil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ScalingUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@@ -92,6 +95,9 @@
<ClInclude Include="resource.h">
<Filter>Resource Files</Filter>
</ClInclude>
<ClInclude Include="ScalingUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="AlwaysOnTop.rc">

View File

@@ -3,6 +3,8 @@
#include <dwmapi.h>
#include <ScalingUtils.h>
namespace
{
size_t D2DRectUHash(D2D1_SIZE_U rect)
@@ -88,7 +90,7 @@ void FrameDrawer::Show()
Render();
}
void FrameDrawer::SetBorderRect(RECT windowRect, COLORREF color, int thickness, int radius)
void FrameDrawer::SetBorderRect(RECT windowRect, COLORREF color, int thickness, float radius)
{
auto newSceneRect = DrawableRect{
.borderColor = ConvertColor(color),
@@ -181,15 +183,27 @@ D2D1_COLOR_F FrameDrawer::ConvertColor(COLORREF color)
1.f);
}
D2D1_ROUNDED_RECT FrameDrawer::ConvertRect(RECT rect, int thickness, int radius)
D2D1_ROUNDED_RECT FrameDrawer::ConvertRect(RECT rect, int thickness, float radius)
{
auto d2d1Rect = D2D1::RectF((float)rect.left + thickness, (float)rect.top + thickness, (float)rect.right - thickness, (float)rect.bottom - thickness);
return D2D1::RoundedRect(d2d1Rect, (float)radius, (float)radius);
float halfThickness = thickness / 2.0f;
// 1 is needed to eliminate the gap between border and window
auto d2d1Rect = D2D1::RectF((float)rect.left + halfThickness + 1,
(float)rect.top + halfThickness + 1,
(float)rect.right - halfThickness - 1,
(float)rect.bottom - halfThickness - 1);
return D2D1::RoundedRect(d2d1Rect, radius, radius);
}
D2D1_RECT_F FrameDrawer::ConvertRect(RECT rect, int thickness)
{
return D2D1::RectF((float)rect.left + thickness, (float)rect.top + thickness, (float)rect.right - thickness, (float)rect.bottom - thickness);
float halfThickness = thickness / 2.0f;
// 1 is needed to eliminate the gap between border and window
return D2D1::RectF((float)rect.left + halfThickness + 1,
(float)rect.top + halfThickness + 1,
(float)rect.right - halfThickness - 1,
(float)rect.bottom - halfThickness - 1);
}
void FrameDrawer::Render()
@@ -207,11 +221,11 @@ void FrameDrawer::Render()
if (m_sceneRect.roundedRect)
{
m_renderTarget->DrawRoundedRectangle(m_sceneRect.roundedRect.value(), m_borderBrush.get(), static_cast<float>(m_sceneRect.thickness * 2));
m_renderTarget->DrawRoundedRectangle(m_sceneRect.roundedRect.value(), m_borderBrush.get(), static_cast<float>(m_sceneRect.thickness));
}
else if (m_sceneRect.rect)
{
m_renderTarget->DrawRectangle(m_sceneRect.rect.value(), m_borderBrush.get(), static_cast<float>(m_sceneRect.thickness * 2));
m_renderTarget->DrawRectangle(m_sceneRect.rect.value(), m_borderBrush.get(), static_cast<float>(m_sceneRect.thickness));
}
m_renderTarget->EndDraw();

View File

@@ -18,7 +18,7 @@ public:
void Show();
void Hide();
void SetBorderRect(RECT windowRect, COLORREF color, int thickness, int radius);
void SetBorderRect(RECT windowRect, COLORREF color, int thickness, float radius);
private:
bool CreateRenderTargets(const RECT& clientRect);
@@ -34,7 +34,7 @@ private:
static ID2D1Factory* GetD2DFactory();
static IDWriteFactory* GetWriteFactory();
static D2D1_COLOR_F ConvertColor(COLORREF color);
static D2D1_ROUNDED_RECT ConvertRect(RECT rect, int thickness, int radius);
static D2D1_ROUNDED_RECT ConvertRect(RECT rect, int thickness, float radius);
static D2D1_RECT_F ConvertRect(RECT rect, int thickness);
void Render();

View File

@@ -0,0 +1,19 @@
#include "pch.h"
#include "ScalingUtils.h"
#include <common/Display/dpi_aware.h>
#include <common/utils/winapi_error.h>
float ScalingUtils::ScalingFactor(HWND window) noexcept
{
UINT dpi = 96;
auto res = DPIAware::GetScreenDPIForWindow(window, dpi);
if (res != S_OK)
{
Logger::error(L"Failed to get DPI: {}", get_last_error_or_default(res));
return 1.0f;
}
return dpi / 96.0f;
}

View File

@@ -0,0 +1,6 @@
#pragma once
namespace ScalingUtils
{
float ScalingFactor(HWND window) noexcept;
};

View File

@@ -5,6 +5,7 @@
#include "winrt/Windows.Foundation.h"
#include <FrameDrawer.h>
#include <ScalingUtils.h>
#include <Settings.h>
#include <WindowCornersUtil.h>
@@ -192,13 +193,15 @@ void WindowBorder::UpdateBorderProperties() const
color = AlwaysOnTopSettings::settings().frameColor;
}
int cornerRadius = 0;
float scalingFactor = ScalingUtils::ScalingFactor(m_trackingWindow);
float thickness = AlwaysOnTopSettings::settings().frameThickness * scalingFactor;
float cornerRadius = 0.0;
if (AlwaysOnTopSettings::settings().roundCornersEnabled)
{
cornerRadius = WindowBordersUtils::AreCornersRounded(m_trackingWindow) ? 8 : 0;
cornerRadius = WindowCornerUtils::CornersRadius(m_trackingWindow) * scalingFactor;
}
m_frameDrawer->SetBorderRect(frameRect, color, AlwaysOnTopSettings::settings().frameThickness, cornerRadius);
m_frameDrawer->SetBorderRect(frameRect, color, static_cast<int>(thickness), cornerRadius);
}
LRESULT WindowBorder::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept

View File

@@ -20,9 +20,9 @@ enum DWM_WINDOW_CORNER_PREFERENCE
DWMWCP_ROUNDSMALL = 3
};
bool WindowBordersUtils::AreCornersRounded(HWND window) noexcept
int WindowCornerUtils::CornerPreference(HWND window) noexcept
{
int cornerPreference = DWMWCP_DEFAULT;
int cornerPreference = -1;
auto res = DwmGetWindowAttribute(window, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPreference, sizeof(cornerPreference));
if (res != S_OK)
{
@@ -31,9 +31,24 @@ bool WindowBordersUtils::AreCornersRounded(HWND window) noexcept
{
Logger::error(L"Get corner preference error: {}", get_last_error_or_default(res));
}
return false;
}
return cornerPreference != DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_DONOTROUND;
return cornerPreference;
}
int WindowCornerUtils::CornersRadius(HWND window) noexcept
{
int cornerPreference = CornerPreference(window);
switch (cornerPreference)
{
case DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_ROUND:
return 8;
case DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_ROUNDSMALL:
return 4;
case DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_DEFAULT:
return 8;
default:
return 0;
}
}

View File

@@ -1,4 +1,5 @@
namespace WindowBordersUtils
namespace WindowCornerUtils
{
bool AreCornersRounded(HWND window) noexcept;
int CornerPreference(HWND window) noexcept;
int CornersRadius(HWND window) noexcept;
}