webview_windows

repository·main·Indexed 42 days ago

https://github.com/jnschulze/flutter-webview-windows

A Flutter plugin that provides WebView capabilities for Windows applications by leveraging the Microsoft Edge WebView2 engine. It supports off-screen rendering for seamless composition with Flutter widgets, JavaScript interaction via WebviewController, and event streams for URL changes, loading states, and web messages. Requires Windows 10 1809+ and the WebView2 Runtime.

Tokens
1.9K
Snippets
7
Records
11
Agent score
54%

What's inside webview_windows

  1. Overview of webview_windows

    main
    webview_windows is a Flutter plugin designed for Windows that enables web content rendering using the Microsoft Edge WebView2 engine. It allows for the seamless composition of web-based content alongside other Flutter widgets by utilizing off-screen rendering techniques.
  2. Understand the limitations of off-screen rendering

    main

    Because Microsoft Edge WebView2 lacks an explicit API for off-screen rendering, webview_windows implements its own mechanism to obtain pixel buffers for frame rendering.

    Currently, the plugin relies on the Windows.Graphics.Capture API. This approach has the following implications:

    • Windows Version Support: It is optimized for newer Windows versions.
    • Legacy Support: Older Windows versions may require using BitBlt instead of the Windows.Graphics.Capture API.
  3. Development platform requirements for webview_windows

    main

    To develop with this plugin, ensure your environment meets these specifications:

    • Visual Studio: 2019 or higher.
    • Windows 11 SDK: Version 10.0.22000.194 or higher.
    • nuget.exe: It is recommended to have nuget.exe in your $PATH. While the build process attempts to download it as a fallback, this may fail in certain regions (e.g., China).
  4. Target platform requirements for webview_windows

    main

    To run applications using this plugin, the following requirements must be met:

    • Windows 10 1809+
    • WebView2 Runtime: This must be installed on the system.

    Checking for WebView2 Runtime: Before initializing the webview, you should call getWebViewVersion() to verify if the required runtime is present. If getWebViewVersion() returns null, the user must manually install the WebView2 Runtime.

    // Example logic for checking WebView2 Runtime
    final version = await webviewController.getWebViewVersion();
    if (version == null) {
      // Guide the user to install WebView2 Runtime
    }
  5. Initialize the WebView environment

    main

    Before creating any WebviewController, you must initialize the shared WebView environment. This can be done once per application lifecycle. You can optionally specify a user data path, a specific browser executable path, and additional Chromium command-line arguments.

    Note: This method throws a PlatformException if the environment has already been initialized.

    await WebviewController.initializeEnvironment(
      userDataPath: 'path/to/user/data',
      browserExePath: 'path/to/browser.exe',
      additionalArguments: ['--disable-web-security'],
    );
  6. Display the WebView using the Webview widget

    main

    The Webview widget renders the WebView content using a Texture widget. It requires a WebviewController.

    Key Parameters:

    • controller: The initialized WebviewController.
    • width / height: Optional dimensions. If not provided, the widget expands to fill available space.
    • scaleFactor: An optional scale factor. Defaults to window.devicePixelRatio. Setting this to 1.0 disables high-DPI support.
    • filterQuality: The FilterQuality used for scaling the texture. Defaults to FilterQuality.none (native resolution).
    Webview(
      controller,
      width: 800,
      height: 600,
      filterQuality: FilterQuality.medium,
    )
  7. Listen to WebView event streams

    main

    The WebviewController provides several streams to react to changes within the WebView:

    • url: Emits the current URL as a String when it changes.
    • loadingState: Emits the current LoadingState (e.g., loading, finished, error).
    • onLoadError: Emits a WebErrorStatus when navigation fails.
    • onDownloadEvent: Emits WebviewDownloadEvent objects for file downloads.
    • historyChanged: Emits HistoryChanged (contains canGoBack and canGoForward).
    • title: Emits the current document title.
    • webMessage: Emits decoded JSON messages sent from the web page via window.chrome.webview.postMessage.
    • containsFullScreenElementChanged: Emits a bool indicating if the document has full-screen elements.
    controller.url.listen((url) => print('New URL: $url'));
    
    controller.onLoadError.listen((error) => print('Error: $error'));
    
    controller.webMessage.listen((message) => print('Message from web: $message'));
  8. Use WebviewController to control the WebView

    main

    The WebviewController is the primary interface for interacting with the WebView. It must be initialized via controller.initialize() before use.

    Key capabilities include:

    • Navigation: loadUrl(url), loadStringContent(content), reload(), goBack(), goForward(), and stop().
    • JavaScript Interaction: executeScript(script) to run JS and get results, addScriptToExecuteOnDocumentCreated(script) for early execution, and postWebMessage(message) to send JSON messages to the document.
    • Browser Management: clearCookies(), clearCache(), setUserAgent(userAgent), setZoomFactor(factor), and openDevTools().
    • Lifecycle: suspend() and resume() to manage the web view state.
    final controller = WebviewController();
    await controller.initialize();
    
    await controller.loadUrl('https://flutter.dev');
    
    // Execute JS and get a decoded JSON result
    final result = await controller.executeScript('JSON.stringify({status: "ok"})');
    print(result); // {status: "ok"}
  9. Handle permission requests

    main

    You can intercept permission requests (like geolocation or camera) by providing a PermissionRequestedDelegate to the Webview widget. This delegate is a function that receives the URL, the WebviewPermissionKind, and whether the request was user-initiated. It must return a FutureOr<WebviewPermissionDecision> (either WebviewPermissionDecision.allow or WebviewPermissionDecision.deny).

    Webview(
      controller,
      permissionRequested: (url, permissionKind, isUserInitiated) async {
        if (permissionKind == WebviewPermissionKind.geolocation) {
          // Logic to show a dialog to the user
          return WebviewPermissionDecision.allow;
        }
        return WebviewPermissionDecision.deny;
      },
    );
  10. Get the WebView2 Runtime version

    main

    Use WebviewController.getWebViewVersion() to retrieve the browser version information, including the channel name (if it is not the standard WebView2 Runtime). Returns null if the WebView2 runtime is not installed on the system.

    String? version = await WebviewController.getWebViewVersion();
    if (version != null) {
      print('WebView version: $version');
    }