Skip to content

Commit

Permalink
[Always on top] Transparent border (#28127)
Browse files Browse the repository at this point in the history
  • Loading branch information
SeraphimaZykova committed Aug 25, 2023
1 parent 738072f commit b3532b8
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 18 deletions.
8 changes: 4 additions & 4 deletions src/modules/alwaysontop/AlwaysOnTop/FrameDrawer.cpp
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/modules/alwaysontop/AlwaysOnTop/FrameDrawer.h
Expand Up @@ -18,7 +18,7 @@ class FrameDrawer

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);
Expand All @@ -33,7 +33,7 @@ class FrameDrawer

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();
Expand Down
11 changes: 11 additions & 0 deletions src/modules/alwaysontop/AlwaysOnTop/Settings.cpp
Expand Up @@ -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";
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/modules/alwaysontop/AlwaysOnTop/Settings.h
Expand Up @@ -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{};
};
Expand Down
1 change: 1 addition & 0 deletions src/modules/alwaysontop/AlwaysOnTop/SettingsConstants.h
Expand Up @@ -7,6 +7,7 @@ enum class SettingId
FrameEnabled,
FrameThickness,
FrameColor,
FrameOpacity,
BlockInGameMode,
ExcludeApps,
FrameAccentColor,
Expand Down
25 changes: 13 additions & 12 deletions src/modules/alwaysontop/AlwaysOnTop/WindowBorder.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions src/settings-ui/Settings.UI.Library/AlwaysOnTopProperties.cs
Expand Up @@ -15,6 +15,7 @@ public class AlwaysOnTopProperties
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;
Expand All @@ -26,6 +27,7 @@ public AlwaysOnTopProperties()
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);
Expand All @@ -44,6 +46,9 @@ public AlwaysOnTopProperties()
[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; }

Expand Down
Expand Up @@ -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}">
Expand Down
3 changes: 3 additions & 0 deletions src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
Expand Up @@ -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>
17 changes: 17 additions & 0 deletions src/settings-ui/Settings.UI/ViewModels/AlwaysOnTopViewModel.cs
Expand Up @@ -55,6 +55,7 @@ public AlwaysOnTopViewModel(ISettingsUtils settingsUtils, ISettingsRepository<Ge
_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;
Expand Down Expand Up @@ -188,6 +189,21 @@ public string FrameColor
}
}

public int FrameOpacity
{
get => _frameOpacity;

set
{
if (value != _frameOpacity)
{
_frameOpacity = value;
Settings.Properties.FrameOpacity.Value = value;
NotifyPropertyChanged();
}
}
}

public bool SoundEnabled
{
get => _soundEnabled;
Expand Down Expand Up @@ -293,6 +309,7 @@ public void RefreshEnabledState()
private int _frameThickness;
private string _frameColor;
private bool _frameAccentColor;
private int _frameOpacity;
private bool _soundEnabled;
private bool _doNotActivateOnGameMode;
private bool _roundCornersEnabled;
Expand Down

0 comments on commit b3532b8

Please sign in to comment.