Skip to content

Commit 1ecaf03

Browse files
[AlwaysOnTop] Corners scaling (#20352)
1 parent 4e202e4 commit 1ecaf03

9 files changed

+85
-19
lines changed

src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
<ClCompile Include="pch.cpp">
132132
<PrecompiledHeader>Create</PrecompiledHeader>
133133
</ClCompile>
134+
<ClCompile Include="ScalingUtils.cpp" />
134135
<ClCompile Include="Settings.cpp" />
135136
<ClCompile Include="trace.cpp" />
136137
<ClCompile Include="VirtualDesktopUtils.cpp" />
@@ -144,6 +145,7 @@
144145
<ClInclude Include="ModuleConstants.h" />
145146
<ClInclude Include="pch.h" />
146147
<ClInclude Include="resource.h" />
148+
<ClInclude Include="ScalingUtils.h" />
147149
<ClInclude Include="Settings.h" />
148150
<ClInclude Include="SettingsConstants.h" />
149151
<ClInclude Include="SettingsObserver.h" />

src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj.filters

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
<ClCompile Include="WindowCornersUtil.cpp">
4646
<Filter>Source Files</Filter>
4747
</ClCompile>
48+
<ClCompile Include="ScalingUtils.cpp">
49+
<Filter>Source Files</Filter>
50+
</ClCompile>
4851
</ItemGroup>
4952
<ItemGroup>
5053
<None Include="packages.config" />
@@ -92,6 +95,9 @@
9295
<ClInclude Include="resource.h">
9396
<Filter>Resource Files</Filter>
9497
</ClInclude>
98+
<ClInclude Include="ScalingUtils.h">
99+
<Filter>Header Files</Filter>
100+
</ClInclude>
95101
</ItemGroup>
96102
<ItemGroup>
97103
<ResourceCompile Include="AlwaysOnTop.rc">

src/modules/alwaysontop/AlwaysOnTop/FrameDrawer.cpp

+21-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <dwmapi.h>
55

6+
#include <ScalingUtils.h>
7+
68
namespace
79
{
810
size_t D2DRectUHash(D2D1_SIZE_U rect)
@@ -88,7 +90,7 @@ void FrameDrawer::Show()
8890
Render();
8991
}
9092

91-
void FrameDrawer::SetBorderRect(RECT windowRect, COLORREF color, int thickness, int radius)
93+
void FrameDrawer::SetBorderRect(RECT windowRect, COLORREF color, int thickness, float radius)
9294
{
9395
auto newSceneRect = DrawableRect{
9496
.borderColor = ConvertColor(color),
@@ -181,15 +183,27 @@ D2D1_COLOR_F FrameDrawer::ConvertColor(COLORREF color)
181183
1.f);
182184
}
183185

184-
D2D1_ROUNDED_RECT FrameDrawer::ConvertRect(RECT rect, int thickness, int radius)
186+
D2D1_ROUNDED_RECT FrameDrawer::ConvertRect(RECT rect, int thickness, float radius)
185187
{
186-
auto d2d1Rect = D2D1::RectF((float)rect.left + thickness, (float)rect.top + thickness, (float)rect.right - thickness, (float)rect.bottom - thickness);
187-
return D2D1::RoundedRect(d2d1Rect, (float)radius, (float)radius);
188+
float halfThickness = thickness / 2.0f;
189+
190+
// 1 is needed to eliminate the gap between border and window
191+
auto d2d1Rect = D2D1::RectF((float)rect.left + halfThickness + 1,
192+
(float)rect.top + halfThickness + 1,
193+
(float)rect.right - halfThickness - 1,
194+
(float)rect.bottom - halfThickness - 1);
195+
return D2D1::RoundedRect(d2d1Rect, radius, radius);
188196
}
189197

190198
D2D1_RECT_F FrameDrawer::ConvertRect(RECT rect, int thickness)
191199
{
192-
return D2D1::RectF((float)rect.left + thickness, (float)rect.top + thickness, (float)rect.right - thickness, (float)rect.bottom - thickness);
200+
float halfThickness = thickness / 2.0f;
201+
202+
// 1 is needed to eliminate the gap between border and window
203+
return D2D1::RectF((float)rect.left + halfThickness + 1,
204+
(float)rect.top + halfThickness + 1,
205+
(float)rect.right - halfThickness - 1,
206+
(float)rect.bottom - halfThickness - 1);
193207
}
194208

195209
void FrameDrawer::Render()
@@ -207,11 +221,11 @@ void FrameDrawer::Render()
207221

208222
if (m_sceneRect.roundedRect)
209223
{
210-
m_renderTarget->DrawRoundedRectangle(m_sceneRect.roundedRect.value(), m_borderBrush.get(), static_cast<float>(m_sceneRect.thickness * 2));
224+
m_renderTarget->DrawRoundedRectangle(m_sceneRect.roundedRect.value(), m_borderBrush.get(), static_cast<float>(m_sceneRect.thickness));
211225
}
212226
else if (m_sceneRect.rect)
213227
{
214-
m_renderTarget->DrawRectangle(m_sceneRect.rect.value(), m_borderBrush.get(), static_cast<float>(m_sceneRect.thickness * 2));
228+
m_renderTarget->DrawRectangle(m_sceneRect.rect.value(), m_borderBrush.get(), static_cast<float>(m_sceneRect.thickness));
215229
}
216230

217231
m_renderTarget->EndDraw();

src/modules/alwaysontop/AlwaysOnTop/FrameDrawer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class FrameDrawer
1818

1919
void Show();
2020
void Hide();
21-
void SetBorderRect(RECT windowRect, COLORREF color, int thickness, int radius);
21+
void SetBorderRect(RECT windowRect, COLORREF color, int thickness, float radius);
2222

2323
private:
2424
bool CreateRenderTargets(const RECT& clientRect);
@@ -34,7 +34,7 @@ class FrameDrawer
3434
static ID2D1Factory* GetD2DFactory();
3535
static IDWriteFactory* GetWriteFactory();
3636
static D2D1_COLOR_F ConvertColor(COLORREF color);
37-
static D2D1_ROUNDED_RECT ConvertRect(RECT rect, int thickness, int radius);
37+
static D2D1_ROUNDED_RECT ConvertRect(RECT rect, int thickness, float radius);
3838
static D2D1_RECT_F ConvertRect(RECT rect, int thickness);
3939
void Render();
4040

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "pch.h"
2+
#include "ScalingUtils.h"
3+
4+
#include <common/Display/dpi_aware.h>
5+
#include <common/utils/winapi_error.h>
6+
7+
float ScalingUtils::ScalingFactor(HWND window) noexcept
8+
{
9+
UINT dpi = 96;
10+
auto res = DPIAware::GetScreenDPIForWindow(window, dpi);
11+
12+
if (res != S_OK)
13+
{
14+
Logger::error(L"Failed to get DPI: {}", get_last_error_or_default(res));
15+
return 1.0f;
16+
}
17+
18+
return dpi / 96.0f;
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#pragma once
2+
3+
namespace ScalingUtils
4+
{
5+
float ScalingFactor(HWND window) noexcept;
6+
};

src/modules/alwaysontop/AlwaysOnTop/WindowBorder.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "winrt/Windows.Foundation.h"
66

77
#include <FrameDrawer.h>
8+
#include <ScalingUtils.h>
89
#include <Settings.h>
910
#include <WindowCornersUtil.h>
1011

@@ -192,13 +193,15 @@ void WindowBorder::UpdateBorderProperties() const
192193
color = AlwaysOnTopSettings::settings().frameColor;
193194
}
194195

195-
int cornerRadius = 0;
196+
float scalingFactor = ScalingUtils::ScalingFactor(m_trackingWindow);
197+
float thickness = AlwaysOnTopSettings::settings().frameThickness * scalingFactor;
198+
float cornerRadius = 0.0;
196199
if (AlwaysOnTopSettings::settings().roundCornersEnabled)
197200
{
198-
cornerRadius = WindowBordersUtils::AreCornersRounded(m_trackingWindow) ? 8 : 0;
201+
cornerRadius = WindowCornerUtils::CornersRadius(m_trackingWindow) * scalingFactor;
199202
}
200203

201-
m_frameDrawer->SetBorderRect(frameRect, color, AlwaysOnTopSettings::settings().frameThickness, cornerRadius);
204+
m_frameDrawer->SetBorderRect(frameRect, color, static_cast<int>(thickness), cornerRadius);
202205
}
203206

204207
LRESULT WindowBorder::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept

src/modules/alwaysontop/AlwaysOnTop/WindowCornersUtil.cpp

+20-5
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ enum DWM_WINDOW_CORNER_PREFERENCE
2020
DWMWCP_ROUNDSMALL = 3
2121
};
2222

23-
bool WindowBordersUtils::AreCornersRounded(HWND window) noexcept
23+
int WindowCornerUtils::CornerPreference(HWND window) noexcept
2424
{
25-
int cornerPreference = DWMWCP_DEFAULT;
25+
int cornerPreference = -1;
2626
auto res = DwmGetWindowAttribute(window, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPreference, sizeof(cornerPreference));
2727
if (res != S_OK)
2828
{
@@ -31,9 +31,24 @@ bool WindowBordersUtils::AreCornersRounded(HWND window) noexcept
3131
{
3232
Logger::error(L"Get corner preference error: {}", get_last_error_or_default(res));
3333
}
34-
35-
return false;
3634
}
3735

38-
return cornerPreference != DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_DONOTROUND;
36+
return cornerPreference;
37+
}
38+
39+
int WindowCornerUtils::CornersRadius(HWND window) noexcept
40+
{
41+
int cornerPreference = CornerPreference(window);
42+
43+
switch (cornerPreference)
44+
{
45+
case DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_ROUND:
46+
return 8;
47+
case DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_ROUNDSMALL:
48+
return 4;
49+
case DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_DEFAULT:
50+
return 8;
51+
default:
52+
return 0;
53+
}
3954
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
namespace WindowBordersUtils
1+
namespace WindowCornerUtils
22
{
3-
bool AreCornersRounded(HWND window) noexcept;
3+
int CornerPreference(HWND window) noexcept;
4+
int CornersRadius(HWND window) noexcept;
45
}

0 commit comments

Comments
 (0)