Condividi tramite


CompactOverlay mode - aka Picture-in-Picture

Note: The new feature(s) covered in this post are available to Windows Insiders running build 15021 or newer.

New in Creators Update: In the most recent Windows 10 Creators Update we introduce a new compact overlay mode for UWA app windows. When an app window enters compact overlay mode it’ll be shown above other windows so it won’t get blocked. This allows users to continue to keep an eye on your app's content even when they are working with something else. The canonical example of an app taking advantage of this feature is a media player or a video chat app.
CompactOverlay feature used to create a picture-in-picture media player experience

Quick Summary

The ViewMode APIs that powers the CompactOverlay mode described in this blogpost have three parts:

  • the ability to check if CompactOverlay mode is available to the app at all
  • the ability to transition an existing view in and out of CompactOverlay mode
  • the ability to show a standalone view in CompactOverlay mode.

If you're not familiar with multiple views, just skip that part of this blogpost for now or go explore the MultipleViews github sample then come back for that part.

The basics

For a single view app, which most UWP apps are, adding a compact overlay option to the app is easy and straight forward. First you put in some kind of UX affordance that lets the user switch modes (since this is a sample we go with a button), check if the view mode we want to enable is available (if so, make the button visible) and then change the view mode when the user taps on the UX affordance.

Is CompactOverlay supported?

Since the intent of the Compact Overlay view mode is a very specific type of user experience, it is not necessarily supported across all Windows devices and interaction modes. Best practice for the app developer is therefore to check whether it is supported before enabling the UX affordance in the app that lets users access this functionality.

 if (ApplicationView.GetForCurrentView().IsViewModeSupported(ApplicationViewMode.CompactOverlay))
{
    compactOverlayButton.Visibility = Visibility.Visible;
}

Switching the view into CompactOverlay mode

At its core the CompactOverlay API is really about this one function call:

 private async void compactOverlayButton_Click(object sender, RoutedEventArgs e)
{
    bool modeSwitched = await ApplicationView.GetForCurrentView().TryEnterViewModeAsync(ApplicationViewMode.CompactOverlay);
}

This API operates on the current ApplicationView of the app, transitioning it from one view mode into another, which in this case is from the default view mode into CompactOverlay mode. When this happens you will note some attributes changing for the window:

  1. it will most likely become smaller than your app window was prior to the call
  2. it will be moved to the top-right corner area of the screen
  3. if you move focus away from the CompactOverlay window the title bar will disappear

To get back to your normal app layout window just call the same API again, but this time with a ApplicationViewMode.Default:

 private async void standardModeButton_Click(object sender, RoutedEventArgs e)
{
    bool modeSwitched = await ApplicationView.GetForCurrentView().TryEnterViewModeAsync(ApplicationViewMode.Default);
}

This will restore your application view to the size and position it had before going into CompactOverlay mode and you can navigate the user back to the app's main layout again.

Providing options for the view

When going into CompactOverlay you probably have a very specific experience in mind for the user, such as providing a mini-view of a video chat, or a certain scaled down version of a video where you want to make sure it can maintains its aspect ratio in the new view configuration.

To enable this we give you the ability to provide a ViewModePreferences object when calling the API. At the time of this post the only preference you can set that will be considered by the system when displaying your view is the CustomSize property which allows you to set the size of the view as it switches into the new mode.

ViewModePreference works a little different then other preference objects that you may have worked with in the windowing space before in that you have to create a default version of it for the mode you want and then then modify the object you get back, instead of just calling 'new' and setting all the preferences to the correct values. The reason for this is that we want to make sure that future additions to the object gets set properly for the mode you are modifying and that vital preferences are not missed as the bells'n'whistles of this API are extended.

If we wanted to set the window size to 320x200 when switching into CompactOverlay the code looks like this:

 private async void compactOverlayButton_Click(object sender, RoutedEventArgs e)
{
    ViewModePreferences compactOptions = ViewModePreferences.CreateDefault(ApplicationViewMode.CompactOverlay);
    compactOptions.CustomSize = new Windows.Foundation.Size(320, 200);
    bool modeSwitched = await ApplicationView.GetForCurrentView().TryEnterViewModeAsync(ApplicationViewMode.Default, compactOptions);
}

Working with a separate view for CompactOverlay

As mentioned in the introduction you can also have new views show up as CompactOverlay views while your main app view remains untouched. The principle for this is the same as with multiview apps but we have added a new switcher API for transitioning the view directly into the specified mode as it is shown so that you avoid the flicker that would be the result of first showing the view as standalone (using TryShowAsStandaloneAsync) and then calling TryEnterViewMode on it.

The switcher API follows the same pattern as the API that acts on the current view, where you provide the mode you want to switch into and, if needed, the preferences for the view. In its most simple form the call would look like this:

 private async void ShowCompactView()
{
    await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        var frame = new Frame();
        compactViewId = ApplicationView.GetForCurrentView().Id;
        frame.Navigate(typeof(SecondaryCompactViewPage));
        Window.Current.Content = frame;
        Window.Current.Activate();
        ApplicationView.GetForCurrentView().Title = "CompactOverlay Window";
    });
    bool viewShown = await ApplicationViewSwitcher.TryShowAsViewModeAsync(compactViewId, ApplicationViewMode.CompactOverlay);
}

You can of course also set the preferred size of your pop-out window just as you did with the TryEnterViewMode, just add the ViewModePreferences to the TryShowAsViewModeAsync call and you're done!

For more details on how to work with CreateNewView, view switching APIs in general, and best practices for view lifetime control - please refer to the MultipleViews github sample.

Comments

  • Anonymous
    February 10, 2017
    IsViewModeSupported is not available on my Visual Studio 2015 during build time. Is VS2017 or a preview SDK version required?
  • Anonymous
    February 10, 2017
    Hi,Will this work in Windows 10 Mobile too?
    • Anonymous
      February 10, 2017
      At this time the functionality is not available on Windows 10 Mobile.
      • Anonymous
        February 14, 2017
        Although it's not part of the Windows PC Shell, is it already in the Xbox Shell? If not I will assume it is coming but as I don't have an Xbox setup in developer mode right now I can't just fire it up and try
        • Anonymous
          February 24, 2017
          At this time the functionality is not available on Xbox, it is however available on the Windows PC Shell as of build 15021.
  • Anonymous
    April 06, 2017
    Please Ask how to hide the TitleBar or make TitleBar Background Transparent
    • Anonymous
      April 06, 2017
      The TitleBar auto-hides when your window is in CompactOverlay mode. Move focus to another window, or the mouse pointer out of the CompactOverlay window to have it dismiss the TitleBar.
  • Anonymous
    April 18, 2017
    What symbol can I use?
  • Anonymous
    May 14, 2017
    Is it possible to have the comact view have some transparent (see-throught) parts?Would compact view show on top of Win32 windows?
    • Anonymous
      December 08, 2017
      Unfortunately at this time we do not support transparency for these windows. As for the z-order, yes this will be in a higher z-band than normal Win32 windows.
  • Anonymous
    May 24, 2017
    Keep getting System.InvalidCastException: 'Unable to cast object of type 'Windows.UI.ViewManagement.ApplicationView' to type 'Windows.UI.ViewManagement.IApplicationView4'.'on ApplicationView.GetForCurrentView().IsViewModeSupported(ApplicationViewMode.CompactOverlay)
    • Anonymous
      December 08, 2017
      This error message occurs when you try to access the API on an earlier version of Windows than the Windows Insiders build 15021. If your app targets multiple versions of Windows (especially if you supports versions older than the Creators Update), you should code to your app to not call this API if you're on a version where the feature is not present. This can be done by checking for the existence of the API through the ApiInformation Class.