Changes the interaction between the view controller and engine in both the C API and
the engine API, so that there's always an engine (as on other platforms) rather than
the engine APIs being specific to headless mode.
While adjusting the C API, this does a large cleanup:
- Renames all methods to follow a `FlutterDesktop` (prefix) + "class" name + method-style name.
E.g., `FlutterDestkopViewControllerCreate` rather than `FlutterDesktopCreateViewController`.
This makes it easier to see what functions operate on which conceptual "object" in the API.
- Reorders and groups them by the object they operate on.
Fixes https://github.com/flutter/flutter/issues/61966
Refactors the Windows embedding internals to make an engine object that
owns things associated with the engine rather than the view, and updates
the API surface to allow using the engine directly.
This is an incremental step toward both a cleaner, non-struct-based
internal structure and a finalized API surface.
Instead of a hand-rolled discriminated union (originally used to avoid a C++17
dependency, which is no longer an issue), implement EncodableValue as a
std::variant. Rather than simply changing the internals, this makes EncodableValue
a minimal std::variant subclass with only a handful of added methodS, replacing
the old IsFoo/FooValue APIs with the standard std::holds_alternative/std::get,
so that plugin code will use a standard-based API rather than a Flutter-specific
API for wrapped values.
This is a breaking change for Windows and GLFW plugins. In the short
term USE_LEGACY_ENCODABLE_VALUE can be set in builds to use the old
version, to separate rolling from updating.
Fixes https://github.com/flutter/flutter/issues/61970
The Windows, Linux, and GLFW embeddings (which all share a common code
ancestry) pass TextInput.setEditingState selection base and extents
straight through to the shared text model class. The model expects those
values to be valid, but the framework sends -1/-1 for "invalid"
selections, which happen for some empty text cases (e.g.,
TextFieldController.clear()).
This translates those invalid selection values to an empty selection at
the start of the string, as expected by the model.
Fixes https://github.com/flutter/flutter/issues/59140
For error messages in the Windows embedding, use stderr rather than
Windows debug logging, so that it will go to the console where, e.g.,
'flutter run' will display it.
The embedder.h API layer is an implementation detail of the desktop
embeddings, not part of the public API surface, so should not be part of
the public symbol list for those libraries.
- Adds a way to provide an AOT library to the C API.
- Adds app.so to the information provided by DartProject.
- Fixes the engine to only do static snapshot linking for Windows in
debug mode, not all modes, so that the provided library is used.
Engine side of https://github.com/flutter/flutter/issues/38477
This does some long-overdue refactoring of the spaghetti code that grew in the GLFW embedding to begin providing a clearer separation between the engine and the window. It is now possible to register plugins, and run the runloop, on a headless engine, which makes headless mode much more usable. This is useful in some automated testing environments.
There is more refactoring that should be done in the future, but this is a good incremental point to stop as the PR is already large, and it provides useful new functionality as-is.
When creating a console on Windows, stdout/stderr aren't wired up to it.
They need to be re-opened afeter the console is created, and that needs
to be done separately in the engine due to the use of static runtime
linking. This provides a helper method that the runner can call when
creating a console so that output will work as expected.
Part of https://github.com/flutter/flutter/issues/53169
The existing logic incorrectly factored out a check that there were arguments too early, applying it to any message not already handled (including unhandled methods, such as methods added after the initial implementation) and thus failing if any unhandled message had no arguments.
Fixes https://github.com/flutter/flutter/issues/55653
The C++ text input model used by Windows and Linux currently uses UTF-32. The intention was to facilitate handling of arrow keys, backspace/delete, etc., however since part of what is synchronized with the engine is cursor+selection offsets, and those offsets are defined in terms of UTF-16 code units, this causes very bad interactions with the framework-side model.
This converts to using UTF-16, rather than UTF-32, so that the offsets align with the framework. It also adds surrogate pair handling to the operations that adjust indexes, to avoid breaking surrogate pairs. (Arbitrary grapheme cluster handling is out of scope for this PR; while definitely desirable in the long term, surrogate pair handling is much more critical since improper handling yields invalid UTF-16, which breaks the text field).
This partially fixes https://github.com/flutter/flutter/issues/55014. A framework-side fix is also necessary (since currently both the engine and the framework attempt to handle arrow keys, which is another out-of-scope-for-this-PR issue), but even without the framework fix this dramatically improves the cursor behavior on Windows when there are surrogate pairs somewhere in the string since at least the two sides agree on what indexes mean.
Includes minor plumbing changes to the text input plumbing on Windows so that we're not pointlessly converting from UTF-16 to UTF-32 and then back to UTF-16.
Fixes a few issues with Windows text input:
- Filters out ASCII control characters
- Filters out lead surrogates, which aren't valid UTF-16 on their own so will cause assertion failures if sent to Flutter
- Adds a bandaid fix for a crash due to mismatches in indexing in the C++ and Dart text models. (A better fix would be to use UTF-16 and add surrogate pair handling to deletion and forward/back; that will be a later PR since it has a larger scope.)
Fixes https://github.com/flutter/flutter/issues/54879
Fixes several bugs in the clipboard code, and makes some structural
improvements:
- Adds scoped wrappers for clipboard open/close and global lock/unlock,
to prevent missing cleanup, fixing at least one case where the lock
was not released.
- Adds the relevant window handle to the clipboard calls, since the docs
suggest that some operations won't work without one.
- Adds a missing clear step to setting the clipboard data.
- Switches from TEXT to UNICODETEXT to handle non-ASCII text correctly.
- To enable that, adds UTF-16/-8 conversion utilities built on the
Win32 APIs (rather than the deprecated std::codecvt functions, as
have been previously used in the engine).
- Fixes handling of getting data when the clipboard is empty, correctly
returning null.
- Passes more errors back through the method channel, with details, for
easier debugging of future issues.
Fixes https://github.com/flutter/flutter/issues/54226
Relands #17489 with a fix for the unit test flake.
The previous unit test relied on the new instance not being created at the same memory address, which isn't guaranteed.
The transitive dependency on the embedder library brings in the right
runtime for the build mode, so directly depending on the JIT version
isn't necessary, and causes duplicate symbol issues in release builds.
Seems to have triggered flaky failures on the Windows bot since landing.
Example failure:
[ RUN ] PluginRegistrarTest.ManagerRemovesOnDestruction
c:\b\s\w\ir\cache\builder\src\flutter\shell\platform\common\cpp\client_wrapper\plugin_registrar_unittests.cc(149): error: Expected: (manager->GetRegistrar<PluginRegistrar>(dummy_registrar_handle)) != (first_wrapper), actual: 000002400A90E3D0 vs 000002400A90E3D0
This reverts commit 478a7855943d81a58dd9e9037fb338d3a18bb294.
This makes two changes:
- Adds a way to register a callback for when a FlutterDesktopPluginRegistrarRef is destroyed, and implements the logic to call it in the Windows and Linux embeddings.
- Adds a class to the C++ wrapper that handles making a singleton owning PluginRegistrar wrappers, and destroying them when the underlying reference goes away, to avoid needing that boilerplate code in every plugin's source.
Fixes https://github.com/flutter/flutter/issues/53496
The JSON codec is awkward to use in the wrapper (since the client has to build and link one of the JSON libraries to do so). Since it would be very cumbersome to wrap in a C API, and there's essentially no reason to use it instead of the standard codec, this removes it from the wrapper entirely.
Since some system channels (internal to the engine) still use it, it's moved into common/cpp instead of being eliminated entirely. Internally we always use RapidJSON though, so the jsoncpp implementation is removed. Also adds some unit test coverage, since there wasn't any.
Fixes#30669
This is a step toward aligning the API with macOS, and will make it easier to add the precompiled library later for release mode (since it can just be added to the project directory, without any code changes required for wrapper clients).
At the C API, uses a struct instead of individual arguments, mirroring a change that was already made on the Linux side to make the C API cleaner.
Functional changes in addition to the restructuring:
adds relative path support, as was recently added for GLFW
Uses wstring, rather than string, for paths; the conversion to UTF-8 is actually a potential problem on Windows, so pushing it into the embedding allows us the possibility of removing it later (if we can figure out a good solution at the embedder.h layer) without API breakage.
The old APIs used by the standard runner are left in place for now to avoid breaking the template on an engine roll. Once the framework template has been updated, the old API paths will be removed.
Clang has different warning settings, so catches different issues than
the VS compile. This fixes various minor issues caught by clang.
Part of https://github.com/flutter/flutter/issues/16256
This was only necessary when the Engine had to build in multiple buildroots
where the sources where checked out at different paths relative to the
buildroot. This is no longer the case and there are already cases GN rules
have been written that mix and match variable usage with the direct
specification of the path to the Flutter sources relative to the sole buildroot.
plugin_registrar_windows.h was never fully updated for the Win32 switch,
and didn't actually compile. This introduces FlutterView (parallel to
the GLFW wrapper's FlutterWindow) as a ways of holding view-specific
functionality to expose via the plugin registrar, and moves HWND access
from the FlutterViewController to the FlutterView so that it's
available to plugins. This allows the implementation of plugins that need
access to the native HWND (e.g., moving or resizing the top-level window).
Adds simple unit tests of the new wrapper functionality, ensuring that the
files actually compile, and that the passthroughs work as expected.
This is a breaking change for Windows runners due to moving
GetNativeWindow() in the wrapper. It's not being done as a multi-stage
change (addition + deprecation + later removal) since this API is explicitly
unstable.
Adds a task runner, and exposes API to allow application-level runloops to know when they need to next call the API to process engine events. Internally, sends null events to wake up the app runloop when new events are scheduled to ensure the wait time is updated accordingly.
Fixes#36420
Makes the plugin registration structure consistent with macOS. This will
be used in generated plugin registrant files rather than a specific
implemenation class, so this helps unblock the creation of generated
registrants on Windows and Linux.
Significantly improves the behavior of non-ASCII text input on Windows. Correctly
processes incoming character events as UTF-16, and for now uses UTF-32 for
the text model so that the existing index-based logic will work much more often.
Future work is still needed, but this will handle far more cases correctly.
* Begin API evolution to a more native win32 API
* Child-window based hosting
* Plumb through an initial size for child window to avoid reallocated surface on start
* Windows API cleanup part 1
* Fix wrapper tests
* Ensure flutter's HWND resources are destroyed
* Final API cleanup
* Fix dynamic DPI handling
* Cleanup
* Fix a bug that was causing engine to not be shutdown correctly
* CR feedback
* auto format
* CR feedback: combine FlutterView and FlutterViewController
* The one that clang-format seems to always get wrong
* expletive
* fix sources for licesnse file
* CR Feedback
* cleanup
* Update GetNativeWindow() to return an HWND rather than a long
* fix formatting