diff --git a/CHANGELOG.md b/CHANGELOG.md index eb373f6..e400e15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- Windows platform support using webview_windows package + +### Changed + +- Updated platform support documentation in README + ## [0.2.0] - 2025-06-26 ### Added diff --git a/README.md b/README.md index eb5b8f7..01a00b0 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ This package supports the following platforms: | Platform | Supported | |----------|:---------:| -| Windows | ❌ | +| Windows | ✅ | | macOS | ✅ | | Linux | ❌ | | iOS | ✅ | diff --git a/pyproject.toml b/pyproject.toml index d2d9aad..66cd19d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ authors = [{ name = "Flet contributors", email = "hello@flet.dev" }] license = "Apache-2.0" requires-python = ">=3.10" dependencies = [ - "flet >=0.70.0.dev0", + "flet", ] [project.urls] diff --git a/src/flutter/flet_webview/lib/src/webview.dart b/src/flutter/flet_webview/lib/src/webview.dart index e6b9d63..700f70e 100644 --- a/src/flutter/flet_webview/lib/src/webview.dart +++ b/src/flutter/flet_webview/lib/src/webview.dart @@ -21,7 +21,7 @@ class WebViewControl extends StatelessWidget { } else if (isMobilePlatform() || isMacOSDesktop()) { view = WebviewMobileAndMac(control: control); } else if (isWindowsDesktop() || isLinuxDesktop()) { - view = const WebviewDesktop(); + view = WebviewDesktop(control: control); } return ConstrainedControl(control: control, child: view); diff --git a/src/flutter/flet_webview/lib/src/webview_windows_and_linux.dart b/src/flutter/flet_webview/lib/src/webview_windows_and_linux.dart index 8510a8e..4782542 100644 --- a/src/flutter/flet_webview/lib/src/webview_windows_and_linux.dart +++ b/src/flutter/flet_webview/lib/src/webview_windows_and_linux.dart @@ -1,11 +1,196 @@ +import 'dart:io' show Platform; import 'package:flet/flet.dart'; +import 'package:flet_webview/src/utils/webview.dart'; import 'package:flutter/material.dart'; +import 'package:webview_windows/webview_windows.dart' as windows_webview; -class WebviewDesktop extends StatelessWidget { - const WebviewDesktop({Key? key}) : super(key: key); +class WebviewDesktop extends StatefulWidget { + final Control control; + + const WebviewDesktop({Key? key, required this.control}) : super(key: key); + + @override + State createState() => _WebviewDesktopState(); +} + +class _WebviewDesktopState extends State { + final windows_webview.WebviewController _controller = + windows_webview.WebviewController(); + bool _isInitialized = false; + String? _errorMessage; + bool _canGoBack = false; + bool _canGoForward = false; + + @override + void initState() { + super.initState(); + widget.control.addInvokeMethodListener(_invokeMethod); + + // Only initialize on Windows + if (Platform.isWindows) { + _initializeWebView(); + } else { + // On Linux, just mark as initialized to show the error message + setState(() { + _isInitialized = true; + }); + } + } + + Future _initializeWebView() async { + try { + await _controller.initialize(); + + // Set up event listeners + _controller.url.listen((url) { + widget.control.triggerEvent("url_change", url); + }); + + _controller.loadingState.listen((state) { + if (state == windows_webview.LoadingState.loading) { + widget.control.triggerEvent( + "page_started", _controller.url.value); + } else if (state == windows_webview.LoadingState.navigationCompleted) { + widget.control.triggerEvent( + "page_ended", _controller.url.value); + } + }); + + _controller.historyChanged.listen((history) { + setState(() { + _canGoBack = history.canGoBack; + _canGoForward = history.canGoForward; + }); + }); + + // Load initial URL + final url = widget.control.getString("url", "https://flet.dev")!; + await _controller.loadUrl(url); + + // Set background color if specified + var bgcolor = widget.control.getColor("bgcolor", context); + if (bgcolor != null) { + await _controller.setBackgroundColor(bgcolor); + } + + setState(() { + _isInitialized = true; + }); + } catch (e) { + setState(() { + _errorMessage = "Failed to initialize WebView: $e"; + }); + } + } + + Future _invokeMethod(String name, dynamic args) async { + debugPrint("WebView.$name($args)"); + + if (!_isInitialized) { + debugPrint("WebView not initialized, ignoring method call: $name"); + return null; + } + + switch (name) { + case "reload": + await _controller.reload(); + break; + case "can_go_back": + return _canGoBack.toString(); + case "can_go_forward": + return _canGoForward.toString(); + case "go_back": + if (_canGoBack) { + await _controller.goBack(); + } + break; + case "go_forward": + if (_canGoForward) { + await _controller.goForward(); + } + break; + case "enable_zoom": + debugPrint("enable_zoom not explicitly supported on Windows WebView (use setZoomFactor)"); + break; + case "disable_zoom": + debugPrint("disable_zoom not explicitly supported on Windows WebView (use setZoomFactor)"); + break; + case "clear_cache": + await _controller.clearCache(); + break; + case "clear_cookies": + await _controller.clearCookies(); + break; + case "clear_local_storage": + debugPrint("clear_local_storage not supported on Windows WebView"); + break; + case "get_current_url": + return _controller.url.value; + case "get_title": + return _controller.title.value; + case "get_user_agent": + debugPrint("get_user_agent not supported on Windows WebView (can only set)"); + return null; + case "load_file": + debugPrint("load_file not supported on Windows WebView"); + break; + case "load_html": + await _controller.loadStringContent(args["value"]); + break; + case "load_request": + var url = args["url"]; + if (url != null) { + await _controller.loadUrl(url); + } + break; + case "run_javascript": + var javascript = args["value"]; + if (javascript != null) { + await _controller.executeScript(javascript); + } + break; + case "scroll_to": + debugPrint("scroll_to not supported on Windows WebView"); + break; + case "scroll_by": + debugPrint("scroll_by not supported on Windows WebView"); + break; + case "set_javascript_mode": + // webview_windows always has JavaScript enabled + debugPrint("JavaScript mode is always enabled on Windows"); + break; + default: + debugPrint("Unknown WebView method: $name"); + } + } + + @override + void dispose() { + debugPrint("WebViewControl dispose: ${widget.control.id}"); + widget.control.removeInvokeMethodListener(_invokeMethod); + _controller.dispose(); + super.dispose(); + } @override Widget build(BuildContext context) { - return const ErrorControl("Webview is not yet supported on this Platform."); + if (_errorMessage != null) { + return ErrorControl(_errorMessage!); + } + + if (!_isInitialized) { + return const Center(child: CircularProgressIndicator()); + } + + if (Platform.isWindows) { + return windows_webview.Webview(_controller); + } else { + return const ErrorControl( + "WebView is not yet supported on Linux. " + "Linux support requires additional system dependencies (webkit2gtk-4.1) " + "and there are no stable embeddable WebView packages available for Flutter on Linux yet. " + "For more information, see: https://github.com/flet-dev/flet-webview/issues/17" + ); + } } } diff --git a/src/flutter/flet_webview/lib/src/webview_windows_and_linux_vain.dart b/src/flutter/flet_webview/lib/src/webview_windows_and_linux_vain.dart index 2b03b80..211a87e 100644 --- a/src/flutter/flet_webview/lib/src/webview_windows_and_linux_vain.dart +++ b/src/flutter/flet_webview/lib/src/webview_windows_and_linux_vain.dart @@ -2,7 +2,9 @@ import 'package:flet/flet.dart'; import 'package:flutter/material.dart'; class WebviewDesktop extends StatefulWidget { - const WebviewDesktop({Key? key}) : super(key: key); + final Control control; + + const WebviewDesktop({Key? key, required this.control}) : super(key: key); @override State createState() => _WebviewDesktopState(); diff --git a/src/flutter/flet_webview/pubspec.yaml b/src/flutter/flet_webview/pubspec.yaml index c8f8959..0c64081 100644 --- a/src/flutter/flet_webview/pubspec.yaml +++ b/src/flutter/flet_webview/pubspec.yaml @@ -19,6 +19,7 @@ dependencies: sdk: flutter webview_flutter_web: ^0.2.3+4 webview_flutter_platform_interface: ^2.13.0 + webview_windows: ^0.4.0 # flet: 0.70.0 flet: