mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 03:07:56 +01:00
[Always on top] Transparent border (#28127)
This commit is contained in:
@@ -90,10 +90,10 @@ void FrameDrawer::Show()
|
||||
Render();
|
||||
}
|
||||
|
||||
void FrameDrawer::SetBorderRect(RECT windowRect, COLORREF color, int thickness, float radius)
|
||||
void FrameDrawer::SetBorderRect(RECT windowRect, COLORREF rgb, float alpha, int thickness, float radius)
|
||||
{
|
||||
auto newSceneRect = DrawableRect{
|
||||
.borderColor = ConvertColor(color),
|
||||
.borderColor = ConvertColor(rgb, alpha),
|
||||
.thickness = thickness,
|
||||
};
|
||||
|
||||
@@ -175,12 +175,12 @@ IDWriteFactory* FrameDrawer::GetWriteFactory()
|
||||
return pDWriteFactory;
|
||||
}
|
||||
|
||||
D2D1_COLOR_F FrameDrawer::ConvertColor(COLORREF color)
|
||||
D2D1_COLOR_F FrameDrawer::ConvertColor(COLORREF color, float alpha)
|
||||
{
|
||||
return D2D1::ColorF(GetRValue(color) / 255.f,
|
||||
GetGValue(color) / 255.f,
|
||||
GetBValue(color) / 255.f,
|
||||
1.f);
|
||||
alpha);
|
||||
}
|
||||
|
||||
D2D1_ROUNDED_RECT FrameDrawer::ConvertRect(RECT rect, int thickness, float radius)
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
|
||||
void Show();
|
||||
void Hide();
|
||||
void SetBorderRect(RECT windowRect, COLORREF color, int thickness, float radius);
|
||||
void SetBorderRect(RECT windowRect, COLORREF rgb, float alpha, int thickness, float radius);
|
||||
|
||||
private:
|
||||
bool CreateRenderTargets(const RECT& clientRect);
|
||||
@@ -33,7 +33,7 @@ private:
|
||||
|
||||
static ID2D1Factory* GetD2DFactory();
|
||||
static IDWriteFactory* GetWriteFactory();
|
||||
static D2D1_COLOR_F ConvertColor(COLORREF color);
|
||||
static D2D1_COLOR_F ConvertColor(COLORREF color, float alpha);
|
||||
static D2D1_ROUNDED_RECT ConvertRect(RECT rect, int thickness, float radius);
|
||||
static D2D1_RECT_F ConvertRect(RECT rect, int thickness);
|
||||
void Render();
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace NonLocalizable
|
||||
const static wchar_t* FrameEnabledID = L"frame-enabled";
|
||||
const static wchar_t* FrameThicknessID = L"frame-thickness";
|
||||
const static wchar_t* FrameColorID = L"frame-color";
|
||||
const static wchar_t* FrameOpacityID = L"frame-opacity";
|
||||
const static wchar_t* BlockInGameModeID = L"do-not-activate-on-game-mode";
|
||||
const static wchar_t* ExcludedAppsID = L"excluded-apps";
|
||||
const static wchar_t* FrameAccentColor = L"frame-accent-color";
|
||||
@@ -134,6 +135,16 @@ void AlwaysOnTopSettings::LoadSettings()
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto jsonVal = values.get_int_value(NonLocalizable::FrameOpacityID))
|
||||
{
|
||||
auto val = *jsonVal;
|
||||
if (m_settings.frameOpacity != val)
|
||||
{
|
||||
m_settings.frameOpacity = val;
|
||||
NotifyObservers(SettingId::FrameOpacity);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto jsonVal = values.get_bool_value(NonLocalizable::FrameEnabledID))
|
||||
{
|
||||
auto val = *jsonVal;
|
||||
|
||||
@@ -21,6 +21,7 @@ struct Settings
|
||||
bool blockInGameMode = true;
|
||||
bool frameAccentColor = true;
|
||||
int frameThickness = 15;
|
||||
int frameOpacity = 100;
|
||||
COLORREF frameColor = RGB(0, 173, 239);
|
||||
std::vector<std::wstring> excludedApps{};
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ enum class SettingId
|
||||
FrameEnabled,
|
||||
FrameThickness,
|
||||
FrameColor,
|
||||
FrameOpacity,
|
||||
BlockInGameMode,
|
||||
ExcludeApps,
|
||||
FrameAccentColor,
|
||||
|
||||
@@ -33,7 +33,7 @@ std::optional<RECT> GetFrameRect(HWND window)
|
||||
}
|
||||
|
||||
WindowBorder::WindowBorder(HWND window) :
|
||||
SettingsObserver({ SettingId::FrameColor, SettingId::FrameThickness, SettingId::FrameAccentColor, SettingId::RoundCornersEnabled }),
|
||||
SettingsObserver({ SettingId::FrameColor, SettingId::FrameThickness, SettingId::FrameAccentColor, SettingId::FrameOpacity, SettingId::RoundCornersEnabled }),
|
||||
m_window(nullptr),
|
||||
m_trackingWindow(window),
|
||||
m_frameDrawer(nullptr)
|
||||
@@ -113,6 +113,14 @@ bool WindowBorder::Init(HINSTANCE hinstance)
|
||||
return false;
|
||||
}
|
||||
|
||||
// make window transparent
|
||||
int const pos = -GetSystemMetrics(SM_CXVIRTUALSCREEN) - 8;
|
||||
if (wil::unique_hrgn hrgn{ CreateRectRgn(pos, 0, (pos + 1), 1) })
|
||||
{
|
||||
DWM_BLURBEHIND bh = { DWM_BB_ENABLE | DWM_BB_BLURREGION, TRUE, hrgn.get(), FALSE };
|
||||
DwmEnableBlurBehindWindow(m_window, &bh);
|
||||
}
|
||||
|
||||
if (!SetLayeredWindowAttributes(m_window, RGB(0, 0, 0), 0, LWA_COLORKEY))
|
||||
{
|
||||
return false;
|
||||
@@ -193,6 +201,7 @@ void WindowBorder::UpdateBorderProperties() const
|
||||
color = AlwaysOnTopSettings::settings().frameColor;
|
||||
}
|
||||
|
||||
float opacity = AlwaysOnTopSettings::settings().frameOpacity / 100.0f;
|
||||
float scalingFactor = ScalingUtils::ScalingFactor(m_trackingWindow);
|
||||
float thickness = AlwaysOnTopSettings::settings().frameThickness * scalingFactor;
|
||||
float cornerRadius = 0.0;
|
||||
@@ -201,7 +210,7 @@ void WindowBorder::UpdateBorderProperties() const
|
||||
cornerRadius = WindowCornerUtils::CornersRadius(m_trackingWindow) * scalingFactor;
|
||||
}
|
||||
|
||||
m_frameDrawer->SetBorderRect(frameRect, color, static_cast<int>(thickness), cornerRadius);
|
||||
m_frameDrawer->SetBorderRect(frameRect, color, opacity, static_cast<int>(thickness), cornerRadius);
|
||||
}
|
||||
|
||||
LRESULT WindowBorder::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept
|
||||
@@ -267,22 +276,14 @@ void WindowBorder::SettingsUpdate(SettingId id)
|
||||
break;
|
||||
|
||||
case SettingId::FrameColor:
|
||||
{
|
||||
UpdateBorderProperties();
|
||||
}
|
||||
break;
|
||||
|
||||
case SettingId::FrameAccentColor:
|
||||
{
|
||||
UpdateBorderProperties();
|
||||
}
|
||||
break;
|
||||
|
||||
case SettingId::FrameOpacity:
|
||||
case SettingId::RoundCornersEnabled:
|
||||
{
|
||||
UpdateBorderProperties();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public const int DefaultFrameThickness = 15;
|
||||
public const string DefaultFrameColor = "#0099cc";
|
||||
public const bool DefaultFrameAccentColor = true;
|
||||
public const int DefaultFrameOpacity = 100;
|
||||
public const bool DefaultSoundEnabled = true;
|
||||
public const bool DefaultDoNotActivateOnGameMode = true;
|
||||
public const bool DefaultRoundCornersEnabled = true;
|
||||
@@ -26,6 +27,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
FrameThickness = new IntProperty(DefaultFrameThickness);
|
||||
FrameColor = new StringProperty(DefaultFrameColor);
|
||||
FrameAccentColor = new BoolProperty(DefaultFrameAccentColor);
|
||||
FrameOpacity = new IntProperty(DefaultFrameOpacity);
|
||||
SoundEnabled = new BoolProperty(DefaultSoundEnabled);
|
||||
DoNotActivateOnGameMode = new BoolProperty(DefaultDoNotActivateOnGameMode);
|
||||
RoundCornersEnabled = new BoolProperty(DefaultRoundCornersEnabled);
|
||||
@@ -44,6 +46,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonPropertyName("frame-color")]
|
||||
public StringProperty FrameColor { get; set; }
|
||||
|
||||
[JsonPropertyName("frame-opacity")]
|
||||
public IntProperty FrameOpacity { get; set; }
|
||||
|
||||
[JsonPropertyName("frame-accent-color")]
|
||||
public BoolProperty FrameAccentColor { get; set; }
|
||||
|
||||
|
||||
@@ -80,6 +80,15 @@
|
||||
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.FrameAccentColor, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
|
||||
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.FrameColor, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="AlwaysOnTop_FrameOpacity"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.FrameEnabled}">
|
||||
<Slider
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Value="{x:Bind Mode=TwoWay, Path=ViewModel.FrameOpacity}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="AlwaysOnTop_FrameThickness"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.FrameEnabled}">
|
||||
|
||||
@@ -3655,4 +3655,7 @@ Activate by holding the key for the character you want to add an accent to, then
|
||||
<data name="Run_PluginUseFindMorePlugins.Content" xml:space="preserve">
|
||||
<value>Find more plugins</value>
|
||||
</data>
|
||||
<data name="AlwaysOnTop_FrameOpacity.Header" xml:space="preserve">
|
||||
<value>Opacity (%)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -55,6 +55,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
_frameEnabled = Settings.Properties.FrameEnabled.Value;
|
||||
_frameThickness = Settings.Properties.FrameThickness.Value;
|
||||
_frameColor = Settings.Properties.FrameColor.Value;
|
||||
_frameOpacity = Settings.Properties.FrameOpacity.Value;
|
||||
_frameAccentColor = Settings.Properties.FrameAccentColor.Value;
|
||||
_soundEnabled = Settings.Properties.SoundEnabled.Value;
|
||||
_doNotActivateOnGameMode = Settings.Properties.DoNotActivateOnGameMode.Value;
|
||||
@@ -188,6 +189,21 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public int FrameOpacity
|
||||
{
|
||||
get => _frameOpacity;
|
||||
|
||||
set
|
||||
{
|
||||
if (value != _frameOpacity)
|
||||
{
|
||||
_frameOpacity = value;
|
||||
Settings.Properties.FrameOpacity.Value = value;
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool SoundEnabled
|
||||
{
|
||||
get => _soundEnabled;
|
||||
@@ -293,6 +309,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
private int _frameThickness;
|
||||
private string _frameColor;
|
||||
private bool _frameAccentColor;
|
||||
private int _frameOpacity;
|
||||
private bool _soundEnabled;
|
||||
private bool _doNotActivateOnGameMode;
|
||||
private bool _roundCornersEnabled;
|
||||
|
||||
Reference in New Issue
Block a user