Skip to content

Conversation

@ne0rrmatrix
Copy link
Member

@ne0rrmatrix ne0rrmatrix commented Jul 19, 2024

  • Feature/Proposal

Add Support for Full Screen Events for Windows, Android, iOS and Mac Catalyst.

Description of Change

Add event handlers to notify developer when full screen status changes.

API:

/// <summary>
/// Backing store for the <see cref="FullScreenState"/> property.
/// </summary>
public static readonly BindableProperty FullScreenProperty =
	BindableProperty.Create(nameof(FullScreenState), typeof(MediaElementScreenState), typeof(MediaElement), 
		MediaElementScreenState.Default, propertyChanged: OnFullScreenPropertyChanged);
/// <summary>
/// Gets the full screen state of the media element.
/// </summary>
public MediaElementScreenState FullScreenState
{
	get => (MediaElementScreenState)GetValue(FullScreenProperty);
	private set => SetValue(FullScreenProperty, value);
}

XAML:

<toolkit:MediaElement
    x:Name="MediaElement"
    ShouldAutoPlay="True"
    Source="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
    MetadataArtworkUrl="https://lh3.googleusercontent.com/pw/AP1GczNRrebWCJvfdIau1EbsyyYiwAfwHS0JXjbioXvHqEwYIIdCzuLodQCZmA57GADIo5iB3yMMx3t_vsefbfoHwSg0jfUjIXaI83xpiih6d-oT7qD_slR0VgNtfAwJhDBU09kS5V2T5ZML-WWZn8IrjD4J-g=w1792-h1024-s-no-gm"
    MetadataTitle="Big Buck Bunny"
    MetadataArtist="Blender Foundation"
    MediaEnded="OnMediaEnded"
    MediaFailed="OnMediaFailed"
    MediaOpened="OnMediaOpened"
    PositionChanged="OnPositionChanged"
    StateChanged="OnStateChanged"
    SeekCompleted="OnSeekCompleted"
    FullScreenStateChanged="MediaElement_FullScreenStateChanged"/>

Code Behind:

void MediaElement_FullScreenStateChanged(object? sender, FullScreenStateChangedEventArgs e) =>
	logger.LogInformation("FullScreen State Changed. Old State: {PreviousState}, New State: {NewState}", e.PreviousState, e.NewState);

Linked Issues

PR Checklist

Additional information

This is a PR to implement a solution for adding support for developers to have an the choice to see when user goes into full full screen and back again.

Note for Maintainers: If you see a need for a name change please go ahead and edit. Names are important. I have no opinion on naming of classes/functions/variables. If you see a need for them to change feel free to make those edits.

This commit introduces full screen state management for media elements. The `CommunityToolkit.Maui.Primitives` namespace was added to several files to support this feature. A new `MediaElementScreenState` enum and `FullScreenStateChangedEventArgs` class were added to represent the full screen state and event data respectively. The `IMediaElement` and `MediaElement` interfaces were updated to include a `FullScreenState` property, a `FullScreenStateChanged` event, and a `FullScreenChanged` method. The `MediaElementPage` class now subscribes to the `FullScreenStateChanged` event and logs information when triggered. The `MauiMediaElement` classes for Android and Windows, and the `MediaManagerDelegate` class for MacOS, were updated to include a `WindowsChanged` event that triggers when the full screen state changes. The `MediaManager` classes for Android, MacOS, and Windows now subscribe to the `WindowsChanged` event and update the full screen state when triggered. The `MediaManager` class for MacOS sets the `Delegate` property of the `AVPlayerViewController` to a new instance of `MediaManagerDelegate`.
- Updated MediaElementPage.xaml to include a new event handler `FullScreenStateChanged` for better responsiveness to fullscreen changes.
- Removed subscription to `FullScreenStateChanged` in MediaElementPage.xaml.cs, indicating a shift in how fullscreen changes are managed.
- Improved Android fullscreen support in MauiMediaElement.android.cs by invoking `OnWindowsChanged` with `FullScreenStateChangedEventArgs` to accurately track fullscreen state changes.
Updated the comment for the `OnWindowsChanged` static event in the `MediaManager` class to more accurately describe its purpose related to changes in the full screen state of the media element. The previous, less descriptive comment was replaced with a clearer explanation.
This commit overhauls the handling of full-screen state changes across Android, Windows, and macOS within a Maui application. A new record, `FullScreenEvents`, has been introduced in the `MediaManager` class to centralize event handling, replacing platform-specific `WindowsChanged` events with a unified approach. This refactor includes the removal of redundant `using` directives, adjustments in event invocation to utilize the new centralized event, and general code cleanup for better readability and maintainability. Platform-specific code has been updated to align with this new mechanism, streamlining the full-screen state change process across different operating systems.
- Removed `OnWindowsChanged` from `MediaManager` in platform-specific files (Android, macOS, Windows) due to redundancy and centralized this logic by adding a new protected method `OnWindowsChanged` to the `FullScreenEvents` record in `MediaManager.shared.cs`. This change aims to reduce code duplication and improve the management of full-screen state changes across different platforms.
Centralized the subscription to FullScreenEvents.WindowsChanged in the MediaManager class to improve maintainability and readability. Removed redundant event unsubscriptions in platform-specific MediaManager files, streamlining event management.
- Renamed `OnWindowsChanged` to `OnFullScreenStatusChanged` in `MediaManager` and `FullScreenEvents` for clarity.
- Added `MediaElement` property to `FullScreenEvents` for better media element access.
In `MauiMediaElement.android.cs`, the visibility of `CurrentPlatformContext` has been changed from `readonly` to `public readonly`, enhancing its accessibility for external use. Additionally, in `MediaManager.shared.cs`, a comment has been added to acknowledge similarities with PR CommunityToolkit#1918 on the CommunityToolkit/Maui repository.
- Changed `CurrentPlatformContext` in `MauiMediaElement.android.cs` from `public` to `internal`, limiting its accessibility to within its assembly.
- Modified `FullScreenEvents` in `MediaManager.shared.cs`:
  1. Access modifier updated from `public` to `internal`.
  2. Converted from a `record` to a `readonly record struct`, making it a value type and immutable.
@ne0rrmatrix ne0rrmatrix added the needs discussion Discuss it on the next Monthly standup label Jul 30, 2024
@ne0rrmatrix ne0rrmatrix added the needs discussion Discuss it on the next Monthly standup label Jul 30, 2025
@dotnet-policy-service dotnet-policy-service bot added stale The author has not responded in over 30 days help wanted This proposal has been approved and is ready to be implemented labels Sep 4, 2025
@Neotrickster
Copy link

Hi @ne0rrmatrix , do you have any idea if this still need something to be in MedieElement ?

@ne0rrmatrix
Copy link
Member Author

Hi @ne0rrmatrix , do you have any idea if this still need something to be in MedieElement ?

I am unable to move forward at this time. I do not understand what I should use for a name as @VladislavAntonyuk requested. I hope someone can suggest something. So far I have heard nothing from anyone.

@ne0rrmatrix
Copy link
Member Author

@bijington ty for helping me figure out what I missed. I have updated the PR to address the naming issue.

@ne0rrmatrix
Copy link
Member Author

I have removed public static event handling and it now is much more compliant with our standards.

@TheCodeTraveler TheCodeTraveler marked this pull request as draft October 2, 2025 19:33
Copilot AI review requested due to automatic review settings November 20, 2025 12:21
Copilot finished reviewing on behalf of ne0rrmatrix November 20, 2025 12:24
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Comment on lines +6 to +17
public enum MediaElementScreenState
{
/// <summary>
/// Full screen.
/// </summary>
FullScreen,

/// <summary>
/// The default state.
/// </summary>
Default,
}
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

According to the coding guidelines, enums should have values assigned (0, 1, 2, 3) if not marked with a Flags attribute. Additionally, the enum ordering doesn't follow the guideline: for return types that may have an unknown value, use Unknown at index 0; for option types that can use the system default, use Default at index 0.

Since this represents a screen state where Default is the standard (non-fullscreen) state, it should be at index 0. Suggested fix:

public enum MediaElementScreenState
{
    /// <summary>
    /// The default state.
    /// </summary>
    Default = 0,

    /// <summary>
    /// Full screen.
    /// </summary>
    FullScreen = 1,
}

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +9 to +10
/// <param name="previousState"></param>
/// <param name="newState"></param>
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Missing documentation for the previousState and newState parameters. The parameter documentation should describe what these parameters represent. For example:

/// <param name="previousState">The previous full screen state.</param>
/// <param name="newState">The new full screen state.</param>
Suggested change
/// <param name="previousState"></param>
/// <param name="newState"></param>
/// <param name="previousState">The previous full screen state.</param>
/// <param name="newState">The new full screen state.</param>

Copilot uses AI. Check for mistakes.
/// <summary>
/// Triggers a <see cref="FullScreenState"/> change.
/// </summary>
/// <param name="newState"></param>
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Missing documentation for the newState parameter. It should describe what the parameter represents. For example:

/// <param name="newState">The new full screen state to update to.</param>
Suggested change
/// <param name="newState"></param>
/// <param name="newState">The new full screen state to update to.</param>

Copilot uses AI. Check for mistakes.
/// <param name="newState"></param>
public sealed class FullScreenStateChangedEventArgs(MediaElementScreenState previousState, MediaElementScreenState newState) : EventArgs
{

Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

[nitpick] There's an extra blank line here. According to coding style best practices, there should be consistent spacing. This blank line should be removed.

Suggested change

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings November 24, 2025 04:21
Copilot finished reviewing on behalf of ne0rrmatrix November 24, 2025 04:24
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

public override void WillBeginFullScreenPresentation(AVPlayerViewController playerViewController, IUIViewControllerTransitionCoordinator coordinator)
{
mediaManager.UpdateFullScreenState(MediaElementScreenState.FullScreen);
}
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

[nitpick] Missing blank line between methods. For consistency and readability, consider adding a blank line between the WillBeginFullScreenPresentation and WillEndFullScreenPresentation methods.

Suggested change
}
}

Copilot uses AI. Check for mistakes.
/// <param name="context">The application's <see cref="Context"/>.</param>
/// <param name="playerView">The <see cref="PlayerView"/> that acts as the platform media player.</param>
public MauiMediaElement(Context context, PlayerView playerView) : base(context)
/// <param name="mediaManager">The <see cref="mediaManager"/> that is managing the <see cref="MediaElement"/> instance.</param>
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The XML documentation has an incorrect <see cref> reference. It should reference MediaManager (the type) rather than just mediaManager (the parameter name).

Suggested fix:

/// <param name="mediaManager">The <see cref="MediaManager"/> that is managing the <see cref="MediaElement"/> instance.</param>
Suggested change
/// <param name="mediaManager">The <see cref="mediaManager"/> that is managing the <see cref="MediaElement"/> instance.</param>
/// <param name="mediaManager">The <see cref="MediaManager"/> that is managing the <see cref="MediaElement"/> instance.</param>

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

help wanted This proposal has been approved and is ready to be implemented 📽️ MediaElement Issue/PR that has to do with MediaElement needs discussion Discuss it on the next Monthly standup stale The author has not responded in over 30 days

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Proposal] API that allows developers to hook a media element event and know the full screen status.

7 participants