Skip to content

Add option to make the background transparent#2551

Open
RibShark wants to merge 2 commits into
LiveSplit:masterfrom
RibShark:transparency
Open

Add option to make the background transparent#2551
RibShark wants to merge 2 commits into
LiveSplit:masterfrom
RibShark:transparency

Conversation

@RibShark
Copy link
Copy Markdown
Contributor

This adds an option to make the background of LiveSplit transparent + blurred. This allows for the background to appear transparent without the opacity of the text being reduced alongside it. OBS can capture this (without blur) with the Windows 10 window capture method.

@RibShark RibShark mentioned this pull request Dec 11, 2024
@wooferzfg wooferzfg added the enhancement Suggests or implements new or improved features. label Dec 11, 2024
Comment thread src/LiveSplit.Core/UI/LayoutSavers/XMLLayoutSaver.cs Outdated
Comment thread src/LiveSplit.View/View/LayoutSettingsControl.Designer.cs Outdated
Comment thread src/LiveSplit.View/View/LayoutSettingsControl.cs Outdated
@wooferzfg
Copy link
Copy Markdown
Member

How does this new setting interact with setting the background color, background image, or opacity?

@RibShark
Copy link
Copy Markdown
Contributor Author

RibShark commented Dec 11, 2024

Here's a video demonstrating what it looks like. Works fine for the most part, though I just noticed doesn't seem to have an effect with images when the blur setting is off, will take a look and see what I can do to fix this. EDIT: Fixed with latest commit.

@wooferzfg
Copy link
Copy Markdown
Member

wooferzfg commented Dec 11, 2024

Do you need to check if the transparency setting changed here?

if (Layout.Settings.BackgroundImage != previousBackground
|| Layout.Settings.ImageOpacity != previousOpacity
|| Layout.Settings.ImageBlur != previousBlur)
{

@RibShark
Copy link
Copy Markdown
Contributor Author

Do you need to check if the transparency setting changed here?

if (Layout.Settings.BackgroundImage != previousBackground
|| Layout.Settings.ImageOpacity != previousOpacity
|| Layout.Settings.ImageBlur != previousBlur)
{

No, it seems to work without that, all that matters is that the background is a Bitmap, that conversion only needs to happen when the image is initially loaded.

Comment on lines +74 to +84
if (TransparentBackgroundState != value)
{
TransparentBackgroundState = value;
var attributeData = new WindowCompositionAttributeData()
{
Attribute = WCA_ACCENT_POLICY,
Data = value ? AccentPolicyBlurPtr : AccentPolicyDisabledPtr,
SizeOfData = Marshal.SizeOf(typeof(AccentPolicy))
};
SetWindowCompositionAttribute(Handle, attributeData);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use unsafe context and do the following:

if (value == _transparentBackground)
{
    return;
}

AccentPolicy policy = new()
{
    AccentState = value ? ACCENT_ENABLE_BLURBEHIND : ACCENT_DISABLED
};

WindowCompositionAttributeData data = new()
{
    Attribute = WCA_ACCENT_POLICY,
    Data = &policy,
    SizeOfData = sizeof(AccentPolicy)
};

SetWindowCompositionAttribute(Handle, data);
_transparentBackground = value;

private const int ACCENT_ENABLE_BLURBEHIND = 3;
private const int WCA_ACCENT_POLICY = 19;

[StructLayout(LayoutKind.Sequential)]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Structs are sequential in layout by default. Remove this.

internal struct WindowCompositionAttributeData
{
public int Attribute;
public IntPtr Data;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use public void* Data;.

Comment on lines +214 to +224
private AccentPolicy AccentPolicyBlur = new()
{
AccentState = ACCENT_ENABLE_BLURBEHIND,
};
private static readonly IntPtr AccentPolicyBlurPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(AccentPolicy)));

private AccentPolicy AccentPolicyDisabled = new()
{
AccentState = ACCENT_DISABLED,
};
private static readonly IntPtr AccentPolicyDisabledPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(AccentPolicy)));
Copy link
Copy Markdown
Contributor

@just-ero just-ero Dec 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not store these instances. It's not necessary. Please remove this and all code which accesses them.

}
}
}
private bool TransparentBackgroundState = false;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private bool TransparentBackgroundState = false;
private bool _transparentBackground;

Copy link
Copy Markdown
Contributor Author

@RibShark RibShark Dec 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote it like that to be consistent with MousePassThroughState later on in the file, which is used in a similar pattern. I can change the name, but the code will be less consistent that way.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file shouldn't really be cluttered up with Win32 definitions, those should go into separate files.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this because there were already a lot of Win32 definitions in TimerForm. I'll move the definitions to LiveSplit.View/Model/Win32.cs unless you have a better suggestion.

private static readonly IntPtr AccentPolicyDisabledPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(AccentPolicy)));

[DllImport("user32.dll")]
private static extern int SetWindowCompositionAttribute(IntPtr hWnd, in WindowCompositionAttributeData data);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static extern int SetWindowCompositionAttribute(IntPtr hWnd, in WindowCompositionAttributeData data);
private static extern int SetWindowCompositionAttribute(nint hWnd, WindowCompositionAttributeData* data);

@wooferzfg
Copy link
Copy Markdown
Member

wooferzfg commented Dec 13, 2024

No, it seems to work without that, all that matters is that the background is a Bitmap, that conversion only needs to happen when the image is initially loaded.

What if the conversion to Bitmap doesn't happen when you initially create the baked background image (because transparency is initially off), and then you enable the transparency setting? (Did you test every combination of settings changing?)

@RibShark
Copy link
Copy Markdown
Contributor Author

No, it seems to work without that, all that matters is that the background is a Bitmap, that conversion only needs to happen when the image is initially loaded.

What if the conversion to Bitmap doesn't happen when you initially create the baked background image (because transparency is initially off), and then you enable the transparency setting? (Did you test every combination of settings changing?)

Oops, forgot about that possibility, will add the check.

@ImAciidz
Copy link
Copy Markdown

OBS can capture this (without blur) with the Windows 10 window capture method

On Windows 10 (tested 22H2, OBS 31), the blur is still captured:
win10

On Windows 11 (tested 23H2 & 24H2, OBS 31), there's a noise of sorts in the capture, which results in a gray background:
win11

So unless I'm misunderstanding the purpose of this (or doing something wrong), it unfortunately doesn't seem very useful.

@Skajdrowski
Copy link
Copy Markdown

@ImAciidz The gray noise you're talking about is barely visible on a game that covers entire screen
It's a very nice feature for fonts with round edges. They don't get butchered by OBS Chroma keying anymore.

@ImAciidz
Copy link
Copy Markdown

It's worth noting that the feature doesn't work at all if transparency effects are disabled in the Windows accessibility settings.

@aesthet-ic
Copy link
Copy Markdown

aesthet-ic commented Apr 6, 2025

Added full transparency option: https://github.com/aesthet-ic/LiveSplit/releases

Edit: Fixed full transparency for Windows 11 22H2+

@siteod
Copy link
Copy Markdown

siteod commented Mar 8, 2026

Added full transparency option: https://github.com/aesthet-ic/LiveSplit/releases

Edit: Fixed full transparency for Windows 11 22H2+

Does your build still work? I found it via reddit post on google, but when I tried dropping the alpha to 0 on the background it did not become transparent. On Windows 11 23h, double checked Transparency Effects are enabled in both Personalization and Accessibility.

@aesthet-ic
Copy link
Copy Markdown

Added full transparency option: https://github.com/aesthet-ic/LiveSplit/releases
Edit: Fixed full transparency for Windows 11 22H2+

Does your build still work? I found it via reddit post on google, but when I tried dropping the alpha to 0 on the background it did not become transparent. On Windows 11 23h, double checked Transparency Effects are enabled in both Personalization and Accessibility.

Sorry about that, it should be fixed now.

Re-download and enable the now-visible transparency checkboxes in addition to setting a solid color background with 0 alpha.

Fixed layout settings UI: https://github.com/aesthet-ic/LiveSplit/releases

@siteod
Copy link
Copy Markdown

siteod commented Mar 8, 2026

Added full transparency option: https://github.com/aesthet-ic/LiveSplit/releases
Edit: Fixed full transparency for Windows 11 22H2+

Does your build still work? I found it via reddit post on google, but when I tried dropping the alpha to 0 on the background it did not become transparent. On Windows 11 23h, double checked Transparency Effects are enabled in both Personalization and Accessibility.

Sorry about that, it should be fixed now.

Re-download and enable the now-visible transparency checkboxes in addition to setting a solid color background with 0 alpha.

Fixed layout settings UI: https://github.com/aesthet-ic/LiveSplit/releases

Works great now, thanks. This is so helpful for running single monitor, wish it was built in and you didn't have to maintain a separate branch for it, but I'm glad you do. Much appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Suggests or implements new or improved features.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants