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

[webview] Add macOS support in implementation package #6221

Open
wants to merge 40 commits into
base: main
Choose a base branch
from

Conversation

stuartmorgan
Copy link
Contributor

@stuartmorgan stuartmorgan commented Feb 28, 2024

Adds initial support for macOS.

Known limitations:

  • Scroll APIs are not supported, and currently throw unimplemented. Longer term we could consider JS polyfills, but we'd probably want to make them opt-in since injecting JS into every page has some risks.
  • Setting the background color doesn't work since the view structure is different on macOS. We may be able to use a layer-backed view to support this in the future.

Since many use cases don't require these features, my preference is to land this without that support, rather than blocking on having full parity, and then the specific features can be added later based on community interest (demand and/or contributions).

This will not be landed until the next full stable release after 3.22, as 3.22 does not yet have gesture support for macOS platform views, and pushing this to users without gesture support would be very confusing.

Part of flutter/flutter#41725

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bparrishMines I'm curious what you think of this approach to handle the fact that WKWebView has a different base class on iOS vs macOS.

Copy link
Contributor

Choose a reason for hiding this comment

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

I like this approach for sharing code between the platforms. Especially the part of creating a platform agnostic WKWebView class. I can also see this working if we need to add the NSView class for macOS. Although I'm not sure how this translates for the Pigeon wrapper generator since the Dart classes would become completely generated.

const WebKitProxy({
this.createWebView = WKWebView.new,
WebKitProxy({
WebViewConstructor? createWebView,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bparrishMines Unfortunately I had to make this non-const because of the Platform switch. Better ideas welcome!

Copy link
Contributor

Choose a reason for hiding this comment

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

You should be able to set this with a constant Function. Either by putting (Platform.isIOS ? WKWebViewIOS.new : WKWebViewMacOS.new); in a static method or a top-level function.

I've also have been waiting for this feature! : dart-lang/language#1048

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the tip! I've re-added the consts I removed.

Unfortunately I had to duplicate all the arguments, because I couldn't make a static function that returned Platform.isIOS ? WKWebViewIOS.new : WKWebViewMacOS.new and then call that because it still didn't want me calling the function in the const constructor, so I had to instead make it a wrapper that calls the right constructor each time, passing all the args through. (If I missed a way to make that work please let me know!)

Future<String?> getCustomUserAgent() {
return _webViewApi.getCustomUserAgentForInstances(this);
/// The iOS version of a WKWebView.
class WKWebViewIOS extends WKWebView implements UIView {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bparrishMines This is the other half of how I'm handling the different parenting: the non-abstract classes are these subclasses which are different for the two platforms.

@stuartmorgan stuartmorgan added the waiting for stable update Can't be landed until functionality reaches the stable channel label May 21, 2024
@gvsakhil

This comment was marked as off-topic.

@stuartmorgan stuartmorgan marked this pull request as ready for review June 3, 2024 19:46
@stuartmorgan stuartmorgan changed the title [webview] Add macOS support [WIP] [webview] Add macOS support Jun 3, 2024
@stuartmorgan stuartmorgan changed the title [webview] Add macOS support [webview] Add macOS support in implementation package Jun 3, 2024
@stuartmorgan
Copy link
Contributor Author

@bparrishMines @hellohuanlin This is ready for review. As noted in the PR description it won't land until the next stable, but since the PR is in a good state now we can work through reviews now so it's ready to go when the next stable arrives.

@stuartmorgan stuartmorgan added triage-macos Should be looked at in macOS triage triage-ios Should be looked at in iOS triage labels Jun 3, 2024
},
// OGG playback is not supported on macOS, so the test data would need
// to be changed to support macOS.
skip: Platform.isMacOS);
Copy link
Member

Choose a reason for hiding this comment

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

nit: Is this indentation correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know why the formatter does this; it's something to do with having a comment inline. We hit this with skip frequently, unfortunately.

The only alternative I can get the formatter to do is by adding a comma after isMacOS, but then it indents the entire test more, which is annoying for consistency with other tests.

Copy link
Contributor

@hellohuanlin hellohuanlin left a comment

Choose a reason for hiding this comment

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

Only reviewed the objc part and looks very clean

}

- (BOOL)containsInstance:(nonnull NSObject *)instance {
BOOL __block containsInstance;
dispatch_sync(_lockQueue, ^{
containsInstance = [self.identifiers objectForKey:instance];
containsInstance = [self.identifiers objectForKey:instance] != nil;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: (probably unrelated to this pr so no need to change): can just use pthread or NSLock if __block feels tedious to write.

Using queues as mutex locks feels a bit overkill although many people are doing it so 🤷. iirc i ran a benchmark super long time ago and locks (even the slow NSLock) are A LOT faster than queues.

@cbenhagen
Copy link
Contributor

Can you add some information why setting a background is not supported on macOS? I guess most will want to make the background transparent. Is there a possibility to allow this special case?

@stuartmorgan
Copy link
Contributor Author

Can you add some information why setting a background is not supported on macOS?

Sorry, I'm not sure what you are asking exactly. The PR description and my issue comment about the limitations of the PR discuss this; if you are looking for details that aren't there you'll need to be more specific.

Is there a possibility to allow this special case?

As always, anyone is welcome to submit PRs adding functionality they need.

Copy link
Contributor

@bparrishMines bparrishMines left a comment

Choose a reason for hiding this comment

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

LGTM

This looks fine to land as is. I'll probably need to change the structure when the Swift ProxyApi generator is finished since I don't think it's compatible with this structure anymore. Mainly because the generated native file would reference the native class directly and the Dart class would be generated.

Co-authored-by: Maurice Parrish <[email protected]>
@LouiseHsu
Copy link
Contributor

@stuartmorgan is this okay to merge or are there still outstanding issues?

@stuartmorgan
Copy link
Contributor Author

This will not be landed until the next full stable release after 3.22, as 3.22 does not yet have gesture support for macOS platform views, and pushing this to users without gesture support would be very confusing.

Per the PR description:

This will not be landed until the next full stable release after 3.22, as 3.22 does not yet have gesture support for macOS platform views, and pushing this to users without gesture support would be very confusing.

@stuartmorgan stuartmorgan removed triage-ios Should be looked at in iOS triage triage-macos Should be looked at in macOS triage labels Jun 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p: webview_flutter platform-ios platform-macos waiting for stable update Can't be landed until functionality reaches the stable channel
Projects
None yet
9 participants