-
Notifications
You must be signed in to change notification settings - Fork 6k
Support platform messages in Linux shell #17995
Support platform messages in Linux shell #17995
Conversation
This is a first iteration on the platform message support and allows sending of messages in both directions. It is built on top of #17910. This is the MVP of this feature, submitting here for feedback. An example on these new APIs is: static FlView *view;
static void
message_cb (FlEngine *engine, const gchar *channel, GBytes *message, FlEnginePlatformMessageHandle *handle, gpointer user_data)
{
g_autoptr(GBytes) response = do_something_with_message (message);
g_autoptr(GError) error = NULL;
if (!fl_engine_send_platform_message_response (engine, handle, response, &error))
g_printerr ("Failed to send platform message response: %s\n", error->message);
}
static void
message_response_cb (GObject *object, GAsyncResult *result, gpointer user_data)
{
g_autoptr(GError) error = NULL;
g_autoptr(GBytes) response = fl_engine_send_platform_message_finish (fl_view_get_engine (view),
result,
&error);
if (response == NULL) {
g_printerr ("Failed to send platform message: %s\n", error->message);
return;
}
do_something_with_response (response);
}
static void
some_external_event ()
{
g_autoptr(GBytes) message = make_request ();
fl_engine_send_platform_message (fl_view_get_engine (view),
channel,
message,
NULL,
message_response_cb,
NULL);
}
int
main (int argc, char **argv)
{
view = set_up_gtk ();
g_autoptr(FlDartProject) project = fl_dart_project_new (".");
view = fl_view_new (project);
fl_engine_set_platform_message_handler (fl_view_get_engine (view),
"example.com/gtk-test-method",
message_cb,
NULL);
gtk_main ();
return 0;
} I've intentionally kept the APIs simple and as close to the GLib/GTK patterns. Do we then build the higher level codec/plugins on top of this or restructure it? Should we land this as working but refactor it later if the higher level code requires the API to change? |
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.
An example on these new APIs is
Thanks, that was super-helpful in understanding the code :)
I've intentionally kept the APIs simple and as close to the GLib/GTK patterns. Do we then build the higher level codec/plugins on top of this or restructure it? Should we land this as working but refactor it later if the higher level code requires the API to change?
Other than my comment inline about moving the APIs off of the engine's API surface, the APIs and the example look good to me. (I have some questions inline, but they are "how do I GLib/GTK?" questions, not things I think need to be changed.) The primitives here look basically the same as the primitives used in the Windows and GLFW embeddings as the foundation for the higher-level channel APIs, so I wouldn't expect it to need refactoring later. Even languages where we don't have the the requirement to expose them (as with the C/C++ split in Windows and GLFW), these primitives are still exposed as public API in addition to the higher-level APIs (see for example FlutterBinaryMessenger
on iOS/macOS).
FYI now that you have project permissions you can just add me as a reviewer directly. |
9907e35
to
2167bbd
Compare
@stuartmorgan I've added FlBinaryMessenger and tried to match the MacOS behaviour as much as possible. The only remaining issue is if we need to copy the message buffer. The example code using this new API is: static FlView *view;
static void
message_cb (FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *handle, gpointer user_data)
{
g_autoptr(GBytes) response = do_something_with_message (message);
g_autoptr(GError) error = NULL;
if (!fl_binary_messenger_send_response (messenger, handle, response, &error))
g_printerr ("Failed to send platform message response: %s\n", error->message);
}
static void
message_response_cb (GObject *object, GAsyncResult *result, gpointer user_data)
{
g_autoptr(GError) error = NULL;
g_autoptr(GBytes) response = fl_binary_messenger_send_on_channel_finish (FL_BINARY_MESSENGER(object),
result,
&error);
if (response == NULL) {
g_printerr ("Failed to send platform message: %s\n", error->message);
return;
}
do_something_with_response (response);
}
static void
some_external_event ()
{
g_autoptr(GBytes) message = make_request ();
fl_binary_messenger_send_on_channel (fl_engine_get_binary_messenger(fl_view_get_engine (view)),
channel,
message,
NULL,
message_response_cb,
NULL);
}
int
main (int argc, char **argv)
{
view = set_up_gtk ();
g_autoptr(FlDartProject) project = fl_dart_project_new (".");
view = fl_view_new (project);
fl_binary_messenger_set_message_handler_on_channel (fl_engine_get_binary_messenger(fl_view_get_engine (view)),
"example.com/gtk-test-method",
message_cb,
NULL);
gtk_main ();
return 0;
} |
727489c
to
09469d4
Compare
Updated to copy the message based on discussion on Discord. |
73bbcb2
to
aca72a0
Compare
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.
LGTM! (I'm having a harder time following the GLib constructions than usual today, so take that with a grain of salt. We can iterate if anything comes up during the higher-level messaging APIs though.)
That reminds me that we should talk about unit testing soon. The desktop embedding are woefully undertested right now, but at least the C++ wrapper has unit tests; as the code here approaches that abstraction level we should figure out tests sooner rather than later so we're not regressing even relative to the minimal testing we currently have with the GLFW embedding.
shell/platform/linux/public/flutter_linux/fl_binary_messenger.h
Outdated
Show resolved
Hide resolved
aca72a0
to
833cc7b
Compare
I've also been uneasy about the lack of tests - I've opened flutter/flutter#56261 to track this. |
No description provided.