mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 11:17:53 +01:00
[AlwaysOnTop] Corners scaling (#20352)
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
19
src/modules/alwaysontop/AlwaysOnTop/ScalingUtils.cpp
Normal file
19
src/modules/alwaysontop/AlwaysOnTop/ScalingUtils.cpp
Normal 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;
|
||||
}
|
||||
6
src/modules/alwaysontop/AlwaysOnTop/ScalingUtils.h
Normal file
6
src/modules/alwaysontop/AlwaysOnTop/ScalingUtils.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace ScalingUtils
|
||||
{
|
||||
float ScalingFactor(HWND window) noexcept;
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
namespace WindowBordersUtils
|
||||
namespace WindowCornerUtils
|
||||
{
|
||||
bool AreCornersRounded(HWND window) noexcept;
|
||||
int CornerPreference(HWND window) noexcept;
|
||||
int CornersRadius(HWND window) noexcept;
|
||||
}
|
||||
Reference in New Issue
Block a user