Skip to content
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

ScreenCaptureRequested draft #3587

Merged
merged 4 commits into from
Jul 20, 2023

Conversation

srwei
Copy link

@srwei srwei commented Jun 21, 2023

No description provided.

@srwei srwei requested a review from david-risney June 21, 2023 22:35
@srwei srwei added the API Proposal Review WebView2 API Proposal for review. label Jun 21, 2023
@@ -0,0 +1,394 @@
# Background

JavaScript's Screen Capture API `GetDisplayMedia` allows developers to get a video stream of a user's tabs, windows, or desktop. This API is available in WebView2, but the current default UI has some problems that we need to fix to make sure that hybrid apps using WebView2 have a more seamless web/native experience. This includes removing the tab column in the UI, replacing default strings and icons that do not match in WV2, and potentially having the ability to customize the UI itself.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please limit line lengths to 80 or 100 characters or less to make it easier to read in the PR.

[uuid(a1d309ee-c03f-11eb-8529-0242ac130003), object, pointer_default(unique)]
interface ICoreWebView2ScreenCaptureRequestedEventArgs : IUnknown {
/// The associated frame information that requests the screen capture
/// permission. This can be used to grab the frame source, name, frameId,
Copy link
Contributor

Choose a reason for hiding this comment

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

This also includes URI of the frame? I expect knowing the URI will be important to deciding to allow or disallow screen capture

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, FrameInfo.Source is the URI of the frame, which also is valid for the top level document.

[propput] HRESULT Handled([in] BOOL handled);
/// The host may set this flag to cancel the screen capture. If canceled,
/// the screen capture UI is not displayed regardless of the
/// `Handled` property.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please also document what happens in script. I guess that getDisplayMedia will asynchronously fail with the NotAllowedError error?

[uuid(12885cda-9caa-4793-9c38-f15827dbab1f), object, pointer_default(unique)]
interface ICoreWebView2Frame3 : IUnknown {
/// Add an event handler for the `ScreenCaptureRequested` event.
/// `ScreenCaptureRequested is raised when content in an iframe any of its
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// `ScreenCaptureRequested is raised when content in an iframe any of its
/// `ScreenCaptureRequested is raised when content in an iframe or any of its

/// be raised on the `CoreWebView2`, and its event handlers will not be
/// invoked.
///
/// In the case of nested iframes, the 'ScreenCaptureRequested' event will
Copy link
Contributor

Choose a reason for hiding this comment

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

You already say above that descendant iframes will raise the event. In the future we may support nested iframes. I don't think we need this sentence.

/// be raised from the top level iframe.
///
/// If a deferral is not taken on the event args, the subsequent scripts
/// re blocked until the event handler returns. If a deferral is taken,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// re blocked until the event handler returns. If a deferral is taken,
/// are blocked until the event handler returns. If a deferral is taken,

/// In the case of nested iframes, the 'ScreenCaptureRequested' event will
/// be raised from the top level iframe.
///
/// If a deferral is not taken on the event args, the subsequent scripts
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this right? Subsequent scripts aren't blocked are they? I would have thought all that is blocked is async completion of getDisplayMedia method?

wil::com_ptr<ICoreWebView2StagingFrameInfo> frameInfoStaging;
CHECK_FAILURE(frameInfo->QueryInterface(IID_PPV_ARGS(&frameInfoStaging)));
UINT32 frameId = 0;
frameInfoStaging->get_FrameId(&frameId);
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't do anything with the values you get. You don't need to get every property value but obtain some of them and show a real use of the properties to decide to cancel or not.

&m_FrameCreatedToken));
}

static void PutHandled(ICoreWebView2ScreenCaptureRequestedEventArgs* args)
Copy link
Contributor

Choose a reason for hiding this comment

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

It doesn't seem like you need a separate static function here. You check if args != null but when you call PutHandled just above it you do args->put_Cancel so args should be non null.

frameId = frameInfo.FrameId;

// If the host app wants to cancel the request from a specific frame
if ( frameId == 1 || frameSource == "https://developer.microsoft.com/en-us/microsoft-edge/webview2/"
Copy link
Contributor

Choose a reason for hiding this comment

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

Is frameId of 1 special? Or are you hardcoding as an example for this code sample? If so, a better and more realistic example would be just the URI check and not the frame name or frame ID and a good enough sample for the other cases of checking frame ID or frame name.

Copy link
Author

Choose a reason for hiding this comment

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

@david-risney Yes, it was just hard coded. That makes sense to just use the URI to cancel. What do you mean by "a good enough sample for the other cases of checking frame ID or frame name?"

Copy link
Contributor

Choose a reason for hiding this comment

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

I mean there may be cases where someone wants to check frame ID. If our sample only shows checking the frame URI it should be easy enough for the reader to figure out how to change that to instead check the frame ID. And if we check only the frame URI it should be easier to make a more realistic sample.

@srwei srwei requested a review from david-risney July 5, 2023 23:49
{
// ...
// ICoreWebView2Frame3 members
[doc_string("ScreenCaptureRequested is raised when content in an iframe or any of its descendant iframes requests permission to use screen capture.\nIf a deferral is not taken on the event args, the subsequent scripts are blocked until the event handler returns. If a deferral is taken, the scripts are blocked until the deferral is completed.")]
Copy link
Contributor

Choose a reason for hiding this comment

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

This line is longer than 80/100 chars, but also the only instance of documentation in the MIDL3. I'd recommend removing this and only having the docs in the COM IDL above to avoid differences between the two and so on.

@@ -0,0 +1,394 @@
# Background
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are there two documents? One is ScreenCaptureRequested and the other is ScreenCaptureRequested.md

Copy link
Author

Choose a reason for hiding this comment

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

Accidently created the first one without the markdown extension. Removing the old one. Thanks for catching that!


// Let CoreWebView2 handler know the event is already handled

// In the case of an iframe requesting permission to use Screen Capture, the default
Copy link
Contributor

Choose a reason for hiding this comment

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

This first part of the comment about the event going from frame to parent is good and should also appear in the Win32 sample code.

the WebView2 and/or iframe corresponding to the CoreWebView2Frame or any of its descendant iframes
requests permission to use the Screen Capture API before the UI is shown.

To maintain backwards compatibility, by default we plan to raise
Copy link
Contributor

Choose a reason for hiding this comment

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

We aren't doing this for compat. This is a new event. We're adding it on both frame and webview2 for convenience of end dev.

@srwei srwei requested a review from david-risney July 19, 2023 18:00
Copy link
Contributor

@david-risney david-risney left a comment

Choose a reason for hiding this comment

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

Looking good. Two changes and then please complete the PR, open a new PR to main, let me know, and I will schedule a review. Thanks

@@ -0,0 +1,357 @@
# Background

JavaScript's Screen Capture API `GetDisplayMedia` allows developers to get a video stream of a
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
JavaScript's Screen Capture API `GetDisplayMedia` allows developers to get a video stream of a
The HTML DOM's Screen Capture API `navigator.mediaDevices.getDisplayMedia` allows developers to get a video stream of a

/// The associated frame information that requests the screen capture
/// permission. This can be used to grab the frame source, name, frameId,
/// and parent frame information.
[propget] HRESULT FrameInfo([out, retval] ICoreWebView2FrameInfo**
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd like to use this same pattern in other events in the future. It will be good to put a prefix on this name to make it clear what this is the frame info for. Without a prefix it may be confused for the frame info of the frame on which the event was registered rather than the frame info of the original source of the event.

XAML calls this OriginalSource
HTML DOM events uses event.target for the original source of the event as opposed to event.currentTarget to refer to the current DOM node for bubbling.

I find the HTML DOM events one more confusing. How about OriginalSourceFrameInfo?

Copy link
Author

Choose a reason for hiding this comment

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

Good point. I think OriginalSourceFrameInfo makes sense.

@srwei srwei requested a review from david-risney July 20, 2023 23:44
@srwei srwei merged commit b0fce82 into ScreenCaptureRequested Jul 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Proposal Review WebView2 API Proposal for review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants