Skip to content

Allow attaching overlay window to specified background element rather than the VideoView #393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 3.x
Choose a base branch
from

Conversation

Jdbye
Copy link

@Jdbye Jdbye commented Jul 18, 2025

Description of Change

Allow the foreground window to be "attached" to a specified background element (copying its position and size) rather than being constrained by the VideoView position and size.
This makes the position and size of the foreground window overlay much more predictable so that controls in the overlay are always in the same place relative to the main window even if the position and dimensions of the VideoView changes.
If VideoView.BackgroundElement is not specified, the behavior is as before, so this change should not break anything.
It's only a minor change to code but is a big improvement to usability in my humble opinion.
Take my case as an example. My application is a fancy image gallery with video playback functions. The image zoom and drag functions in my app also work for videos, but they affect the foreground window, which is undesired behavior. So for cases such as mine being able to attach the foreground window overlay to a different control rather than the VideoView is necessary.
This pull request concerns only LibVLCSharp.WPF since that is what I use but other platforms may benefit from similar changes.

Issues Resolved

Variability in location/size of foreground overlay which is sometimes undesirable.

API Changes

Added:
FrameworkElement? BackgroundElement { get; set; }

Platforms Affected

WPF

Behavioral/Visual Changes

There is no change in functionality or appearance unless VideoView.BackgroundElement is set to a control. If set, the position and size of the ForegroundWindow (and consequently the child controls of the VideoView) will follow that background element, rather than following the VideoView. The video is not affected, only the foreground window.

Before/After Screenshots

Screenshot 2025-07-18 20 40 59 Screenshot 2025-07-18 20 43 52

Testing Procedure

For this test, I used the following XAML, which resembles the layout in my actual application, but greatly simplified.
Fixed width and height of the VideoView is used here for demonstration purposes.

<Window x:Class="wpftestforvlc.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:wpftestforvlc"
        mc:Ignorable="d"
        xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
        Title="MainWindow" Height="1080" Width="1440" Loaded="Window_Loaded">
    <Grid Name="MainGrid" Background="Black">
        <Button x:Name="button" Content="Play Video" HorizontalAlignment="Center" VerticalAlignment="Center" Click="button_Click" Margin="0" Padding="24,12,24,12" FontSize="32"/>
        <Viewbox Stretch="Uniform">
        <vlc:VideoView Width="1920" Height="1080" x:Name="videoView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{x:Null}">
            <Grid Background="Transparent">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid Grid.Row="0">
                    <Label Foreground="White" Content="Top Left Text" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="32">
                        <Label.Effect>
                            <DropShadowEffect BlurRadius="4" ShadowDepth="4" Opacity="0.67" />
                        </Label.Effect>
                    </Label>
                    <Label Foreground="White" Content="Top Right Text" HorizontalAlignment="Right" VerticalAlignment="Top" FontSize="32">
                        <Label.Effect>
                            <DropShadowEffect BlurRadius="4" ShadowDepth="4" Opacity="0.67" />
                        </Label.Effect>
                    </Label>
                </Grid>
                <Grid Grid.Row="1">
                    <Label Foreground="White" Content="Bottom Left Text" HorizontalAlignment="Left" VerticalAlignment="Bottom" FontSize="32">
                        <Label.Effect>
                            <DropShadowEffect BlurRadius="4" ShadowDepth="4" Opacity="0.67" />
                        </Label.Effect>
                    </Label>
                    <Label Foreground="White" Content="Bottom Right Text" HorizontalAlignment="Right" VerticalAlignment="Bottom" FontSize="32">
                        <Label.Effect>
                            <DropShadowEffect BlurRadius="4" ShadowDepth="4" Opacity="0.67" />
                        </Label.Effect>
                    </Label>
                </Grid>
            </Grid>
        </vlc:VideoView>
        </Viewbox>
    </Grid>
</Window>

Without changing BackgroundElement, the window will look like the first screenshot (same behavior as current LibVLCSharp.WPF)
By setting BackgroundElement in the window's constructor (or in Window_Initialized), as such:

        public MainWindow()
        {
            InitializeComponent();
            videoView.BackgroundElement = MainGrid;
        }

The window becomes like the second screenshot.
It seems important that this is set in the constructor or in Window_Initialized, otherwise VideoView.Visibility must start out Collapsed and the property must be set before the VideoView is shown. Otherwise the change does not take. It seems that the ForegroundWindow is being created as soon as the VideoView is fully loaded. So that is one small but important caveat to keep in mind. Making it recreate (or modify) the ForegroundWindow whenever BackgroundElement is changed would be possible, but would require more extensive code changes. I've tried to keep my code changes to a minimum.
For the test it is not necessary to play any video or even initialize the core, the difference is apparent with just that one line of code.

PR Checklist

  • Rebased on top of the target branch at time of PR
  • Changes adhere to coding standard

@mfkl
Copy link
Member

mfkl commented Jul 21, 2025

Thanks for your contribution.

There is no change in functionality or appearance unless VideoView.BackgroundElement is set to a control.

I guess that's a breaking change for people who are doing this already, but it's probably niche and acceptable behavior change.

It seems important that this is set in the constructor or in Window_Initialized, otherwise VideoView.Visibility must start out Collapsed and the property must be set before the VideoView is shown. Otherwise the change does not take. It seems that the ForegroundWindow is being created as soon as the VideoView is fully loaded. So that is one small but important caveat to keep in mind.

Understood. This would be worth a note in https://code.videolan.org/videolan/LibVLCSharp/-/blob/3.x/src/LibVLCSharp.WPF/README.md, I believe, as well as how to use this feature otherwise it will likely remain unknown to users. Maybe I'll add a sample later.

@Jdbye
Copy link
Author

Jdbye commented Jul 22, 2025

Thanks for your contribution.

There is no change in functionality or appearance unless VideoView.BackgroundElement is set to a control.

I guess that's a breaking change for people who are doing this already, but it's probably niche and acceptable behavior change.

That won't be a problem since BackgroundElement is added by the commit, it didn't exist previously.

It seems important that this is set in the constructor or in Window_Initialized, otherwise VideoView.Visibility must start out Collapsed and the property must be set before the VideoView is shown. Otherwise the change does not take. It seems that the ForegroundWindow is being created as soon as the VideoView is fully loaded. So that is one small but important caveat to keep in mind.

Understood. This would be worth a note in https://code.videolan.org/videolan/LibVLCSharp/-/blob/3.x/src/LibVLCSharp.WPF/README.md, I believe, as well as how to use this feature otherwise it will likely remain unknown to users. Maybe I'll add a sample later.

That sounds like a good idea. If you have any questions feel free to let me know.

@videolan videolan deleted a comment from programClown Jul 28, 2025
Allow attaching overlay window to specified background element rather than it being constrained to the video dimensions.
This means the foreground window overlay is a predictable position and size and makes overlaying controls on top of the video much more intuitive.
@mfkl
Copy link
Member

mfkl commented Jul 29, 2025

Could you please add an Example3 here https://github.com/videolan/libvlcsharp/tree/3.x/samples/LibVLCSharp.WPF.Sample that demonstrates the use of your changes? This will be easier for me to test and maintain and for others to learn about.

I've tried modifying Example1 with your changes but no text is shown.

<Window x:Class="LibVLCSharp.WPF.Sample.Example1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:LibVLCSharp.WPF.Sample"
        xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
        mc:Ignorable="d"
        Title="Example1" Height="450" Width="800">
    <Grid Name="MainGrid" Background="Black">
        <Viewbox Stretch="Uniform">
            <vlc:VideoView Width="1920" Height="1080" x:Name="VideoView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{x:Null}">
                <Grid Background="Transparent">
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid Grid.Row="0">
                        <Label Foreground="White" Content="Top Left Text" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="32">
                            <Label.Effect>
                                <DropShadowEffect BlurRadius="4" ShadowDepth="4" Opacity="0.67" />
                            </Label.Effect>
                        </Label>
                        <Label Foreground="White" Content="Top Right Text" HorizontalAlignment="Right" VerticalAlignment="Top" FontSize="32">
                            <Label.Effect>
                                <DropShadowEffect BlurRadius="4" ShadowDepth="4" Opacity="0.67" />
                            </Label.Effect>
                        </Label>
                    </Grid>
                    <Grid Grid.Row="1">
                        <Label Foreground="White" Content="Bottom Left Text" HorizontalAlignment="Left" VerticalAlignment="Bottom" FontSize="32">
                            <Label.Effect>
                                <DropShadowEffect BlurRadius="4" ShadowDepth="4" Opacity="0.67" />
                            </Label.Effect>
                        </Label>
                        <Label Foreground="White" Content="Bottom Right Text" HorizontalAlignment="Right" VerticalAlignment="Bottom" FontSize="32">
                            <Label.Effect>
                                <DropShadowEffect BlurRadius="4" ShadowDepth="4" Opacity="0.67" />
                            </Label.Effect>
                        </Label>
                    </Grid>
                </Grid>
            </vlc:VideoView>
        </Viewbox>
    </Grid>
</Window>

@mfkl
Copy link
Member

mfkl commented Jul 29, 2025

I rebased your branch FYI (no merge commits allowed). I will rebase again 3.x when about to merge, you don't need to worry about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants