Skip to content

[Web/Embedded Mode] Support Document Picture-in-Picture API #181953

Description

@holzgeist

Use case

Document Picture-in-Picture is an extension of the standard Picture-in-Picture API to enable showing arbitrary HTML in "popped out" windows. This is currently used by Google Meet to allow users to switch to other tabs and even applications while keeping a small version of the call window in foreground all the time. See here for the announcement.

I'd like to implement a similar functionality in a flutter based call system. Most of it works already by just moving the hosting div element into the new window, but a few things are still missing:

  • cursor updates are still sent to the main window, i.e. on hovering a button, the body tag in the main window gets the style="cursor: pointer" attribute. I mentioned this in activateSystemCursor should set the cursor on all views #140226 already
  • more subtle: when the tab with the main application is put to background, flutter stops rendering. Actions on button clicks are still performed, but their effect is only visible after the main tab is brought back to foreground. My interpretation is that flutter still thinks that it is running on the (invisible) main window and is saving CPU/GPU cycles.

I will try to develop a minimal reproducible example as a test case.

Proposal

As a developer, I'd like a new function in the app object returned by engine.runApp(): app.moveView(viewId, newHostElement). Calling it would

  • move all content from the old to the new host element
  • start rendering the view in the new element
  • (if necessary) recreate listeners on the new window/document/body objects
  • (if necessary) redirect outgoing events to the new window/document/body objects

Activity

  1. holzgeist commented on Feb 9, 2026

    @holzgeist
    ContributorAuthor

    Here's a minimal repro: https://github.com/holzgeist/flutter-pip-minimal-repro

    It contains the standard example app adapted for web multi view.
    Clicking the button moves the app into pip, closing pip or clicking the button again moves it back.

    In addition to the above features, I sometimes have to click into the pip view to force a new render. Otherwise the screen stays black.

  2. added
    in triagePresently being triaged by the triage team
    c: proposalA detailed proposal for a change to Flutter
    f: scrollingViewports, list views, slivers, etc.
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    engineflutter/engine related. See also e: labels.
    platform-webWeb applications specifically
    team-webOwned by Web platform team
    and removed
    in triagePresently being triaged by the triage team
    f: scrollingViewports, list views, slivers, etc.
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    on Feb 12, 2026
  3. mdebbar commented on Feb 13, 2026

    @mdebbar
    Contributor

    This is already discussed in the other issue and I think it's relatively clear how to fix it. That said, this is not a priority for us at the moment, so I encourage you or anyone who needs this to send a PR 🙂

    • more subtle: when the tab with the main application is put to background, flutter stops rendering. Actions on button clicks are still performed, but their effect is only visible after the main tab is brought back to foreground. My interpretation is that flutter still thinks that it is running on the (invisible) main window and is saving CPU/GPU cycles.

    I bet that's because of the app lifecycle state. It gets updated here:

    domWindow.removeEventListener('focus', _focusListener);
    domWindow.removeEventListener('blur', _blurListener);
    domDocument.removeEventListener('visibilitychange', _visibilityChangeListener);

    Is there a better way to detect page visibility without breaking Document PIP?

    I'd like a new function in the app object returned by engine.runApp(): app.moveView(viewId, newHostElement)

    Could you clarify how this is related to the Document PIP feature?

  4. holzgeist commented on Feb 15, 2026

    @holzgeist
    ContributorAuthor

    Hi @mdebbar,

    thanks for taking a look.

    Yes, I included the cursor thing mainly for reference, I'll follow up there (and/or find the time for a PR)

    About the other point:

    It gets updated here

    Could you clarify how this is related

    If my mental model of the web engine is somehow correct, it's due to the domWindow/domDocument reference the code you linked above. The PiP window has a separate window instance, so the domWindow/domDocument instances themselves need to be updated when moving the flutter view to the pip window. After that, the listeners need to be updated as well.
    The app.moveView could do that (check if the hosting window of the new element changed and update the above references/listeners accordingly).

    If my mental model is way off, this is probably all wrong. However, the symptoms I'm seeing with the code sample I provided above would match my model well 😉

  5. mdebbar commented on Feb 18, 2026

    @mdebbar
    Contributor

    The PiP window has a separate window instance, so the domWindow/domDocument instances themselves need to be updated when moving the flutter view to the pip window. After that, the listeners need to be updated as well.

    Ugh this is unfortunate. It makes things slightly more complicated.

  6. added
    P2Important issues not at the top of the work list
    triaged-webTriaged by Web platform team
    on Feb 18, 2026
  7. holzgeist commented on Feb 23, 2026

    @holzgeist
    ContributorAuthor

    Do you have some pointers on where one would start working on this?

  8. added 2 commits that reference this issue on Sep 29, 2026
    5021a25
    984c188
  9. holzgeist commented on Sep 30, 2026

    @holzgeist
    ContributorAuthor

    I encourage you or anyone who needs this to send a PR

    @mdebbar first try: #193149

  10. added 2 commits that reference this issue on Oct 7, 2026
    83f7543
    68599b2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: proposalA detailed proposal for a change to Flutterengineflutter/engine related. See also e: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-webWeb applications specificallyteam-webOwned by Web platform teamtriaged-webTriaged by Web platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions