-
Notifications
You must be signed in to change notification settings - Fork 6k
Add Platform View Manager to Windows shell #50598
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for sending this out! A few initial comments, mostly just on the docs side of things; I haven't given the implementation a pass other than one test.
|
||
namespace flutter { | ||
|
||
enum class FocusChangeDirection { kProgrammatic, kForward, kBackward }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add doc comments to document the enum and each value.
virtual ~PlatformViewManager(); | ||
|
||
virtual void QueuePlatformViewCreation(std::string_view type_name, | ||
int64_t id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider extracting a using PlatformViewId = int64_t;
for clarity in both the API and any local variable declarations.
@@ -203,6 +203,28 @@ FLUTTER_EXPORT void FlutterDesktopEngineSetNextFrameCallback( | |||
VoidCallback callback, | |||
void* user_data); | |||
|
|||
typedef struct { | |||
size_t cb_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and below, use struct_size
for consistency with existing code.
@@ -203,6 +203,28 @@ FLUTTER_EXPORT void FlutterDesktopEngineSetNextFrameCallback( | |||
VoidCallback callback, | |||
void* user_data); | |||
|
|||
typedef struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document this struct and its fields.
For the user_data field in particular, we always state that it's arbitrary user data that is opaque to the embedder, but it's often worth documenting what we typically expect the user to pass, where there is a reasonable "typical" value.
HWND parent_window; | ||
const char* platform_view_type; | ||
void* user_data; | ||
int64_t platform_view_id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we don't do it on other platforms (yet), but I think we should consider extracting a typedef for PlatformView IDs for the same reason as mentioned for our internal APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more minor notes.
shell/platform/windows/compositor.h
Outdated
@@ -32,6 +35,9 @@ class Compositor { | |||
|
|||
// Present Flutter content and platform views onto the view. | |||
virtual bool Present(const FlutterLayer** layers, size_t layers_count) = 0; | |||
|
|||
protected: | |||
PlatformViewManager* platform_view_manager_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider documenting that this is a weak pointer, and that the PlatformViewManager is owned by FlutterEngine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we make this be a std::shared_ptr
to avoid raw pointers? We're not creating tons of these objects so the performance impact should be acceptable.
FocusChangeDirection direction, | ||
bool focus); | ||
|
||
std::optional<HWND> GetNativeHandleForId(int64_t id) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are we gaining by using a std::optional
here over just returning nullptr
, since HWND
is already a pointer type? In both cases, the caller is left with:
auto platform_view = GetNativeHandleForId(pvid);
if (platform_view) {
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an indicator that this may return null when the id is bad. We can return just HWND
and state this in a comment instead.
private: | ||
std::unique_ptr<MethodChannel<EncodableValue>> channel_; | ||
|
||
std::map<std::string, FlutterPlatformViewTypeEntry> platform_view_types_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and below, unless ordering is required, prefer std::unordered_map
. I realise we're pretty inconsistent in existing code about this.
|
||
std::map<int64_t, std::function<HWND()>> pending_platform_views_; | ||
|
||
TaskRunner* task_runner_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment on ownership.
shell/platform/windows/compositor.h
Outdated
@@ -19,6 +21,7 @@ namespace flutter { | |||
// Platform views are not yet supported. | |||
class Compositor { | |||
public: | |||
Compositor(PlatformViewManager* manager) : platform_view_manager_(manager) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compositor
is just an interface that knows nothing about the implementation. I'd remove the platform_view_manager_
field from this type and move it to the software & opengl compositors.
... but since these compositors don't use this platform view manager yet, I wouldn't update them to accept this platform view manager yet.
// for the implementation of the encoding and magic number identifiers. | ||
final List<int> data = <int>[ | ||
// Method name | ||
7, 'create'.length, ...utf8.encode('create'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For readability, could we create constants for these? Something like:
const int valueNull = 0;
const int valueInt32 = 3;
const int valueString = 7;
const int valueMap = 13;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it. Even better:
enum class ValueType {
kNull = 0,
kInt32 = 3,
...
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cbracken I think this appears applicable only for C++ code. For the dart file, the const int
s may be the best we can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agh yes, not sure where my mind was at there. Dart enhanced enums do provide a mechanism for this, but it's entirely up to you.
Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
@@ -1169,5 +1170,30 @@ TEST_F(FlutterWindowsEngineTest, ChannelListenedTo) { | |||
} | |||
} | |||
|
|||
TEST_F(FlutterWindowsEngineTest, ReceivePlatformViewMessage) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my understanding, this file is more for engine unit tests. Since this launches & runs a full app, should we move this to the integration tests in flutter_windows_unittests.cc
?
I don't feel strongly about this, feel free to keep as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that this test is quite similar in most regards to the handful of unit tests immediately preceding it in this file. Would you disagree?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's probably fine to land as-is, but I do think we should probably do a followup evaluation of which tests belong where. We're definitely not super consistent and to be honest, I'm not sure we've ever drawn a really clear line (not just in the Windows embedder but also on macOS).
This is looking really close to landing! I left a few nitpicks, but the only one I really care about is this one: #50598 (comment). Let me know if you'd want to chat about that! |
Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent work!!! 🎉
@pragma('vm:entry-point') | ||
void sendCreatePlatformViewMethod() async { | ||
// The platform view method channel uses the standard method codec. | ||
// See https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/services/message_codecs.dart#L262 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use a permalink here. The line number will be wrong as the code continues to evolve
…144147) flutter/engine@7a573c2...34a8b9b 2024-02-26 109111084+yaakovschectman@users.noreply.github.com Add Platform View Manager to Windows shell (flutter/engine#50598) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jimgraham@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
_This is the same pull request as #50898. GitHub broke on the previous pull request so I re-created it_ This moves the logic to handle `flutter/accessibility` messages to a new type, `AccessibilityPlugin`. Notable changes: 1. Windows app no longer crashes if it receives accessibility events it does not support 2. Windows app no longer crashes if it receives accessibility events while in headless mode @yaakovschectman After playing around with this, I ended up using a different pattern than what what I suggested on #50598 (comment). This message handler is simple enough that splitting into a child/base types felt like unnecessary boilerplate. The key thing is separating messaging and implementation logic, which was achieved through the `SetUp` method. Let me know what you think, and sorry for all my flip-flopping on this topic! � This is preparation for: flutter/flutter#143765 Sample app for manual testing: flutter/flutter#113059 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Create a manager for platform views accessible to the compositor, handle the methods that the framework will send.
Addresses flutter/flutter#143375
Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.