Flutter Linux Embedder
fl_view.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
8 
9 #include <atk/atk.h>
10 #include <gtk/gtk-a11y.h>
11 
12 #include <cstring>
13 
14 #include "flutter/common/constants.h"
34 
35 static constexpr int kMicrosecondsPerMillisecond = 1000;
36 
37 struct _FlView {
39 
40  // Engine this view is showing.
41  FlEngine* engine;
42 
43  // Handler for engine restart signal.
45 
46  // ID for this view.
47  FlutterViewId view_id;
48 
49  // Rendering output.
50  FlRendererGdk* renderer;
51 
52  // Background color.
53  GdkRGBA* background_color;
54 
55  // TRUE if have got the first frame to render.
56  gboolean have_first_frame;
57 
58  // Pointer button state recorded for sending status updates.
59  int64_t button_state;
60 
61  // Monitor to track window state.
62  FlWindowStateMonitor* window_state_monitor;
63 
64  FlScrollingManager* scrolling_manager;
65 
66  // Flutter system channel handlers.
67  FlKeyboardHandler* keyboard_handler;
68  FlTextInputHandler* text_input_handler;
69  FlMouseCursorHandler* mouse_cursor_handler;
70  FlPlatformHandler* platform_handler;
71 
72  GtkWidget* event_box;
73  GtkGLArea* gl_area;
74 
75  // Tracks whether mouse pointer is inside the view.
76  gboolean pointer_inside;
77 
78  /* FlKeyboardViewDelegate related properties */
80  GdkKeymap* keymap;
81  gulong keymap_keys_changed_cb_id; // Signal connection ID for
82  // keymap-keys-changed
83 
84  // Accessible tree from Flutter, exposed as an AtkPlug.
85  FlViewAccessible* view_accessible;
86 
87  GCancellable* cancellable;
88 };
89 
91 
93 
95  FlPluginRegistryInterface* iface);
96 
98  FlKeyboardViewDelegateInterface* iface);
99 
101  FlScrollingViewDelegateInterface* iface);
102 
104  FlTextInputViewDelegateInterface* iface);
105 
107  FlView,
108  fl_view,
109  GTK_TYPE_BOX,
110  G_IMPLEMENT_INTERFACE(fl_plugin_registry_get_type(),
112  G_IMPLEMENT_INTERFACE(fl_keyboard_view_delegate_get_type(),
114  G_IMPLEMENT_INTERFACE(fl_scrolling_view_delegate_get_type(),
116  G_IMPLEMENT_INTERFACE(fl_text_input_view_delegate_get_type(),
118 
119 // Emit the first frame signal in the main thread.
120 static gboolean first_frame_idle_cb(gpointer user_data) {
121  FlView* self = FL_VIEW(user_data);
122 
123  g_signal_emit(self, fl_view_signals[kSignalFirstFrame], 0);
124 
125  return FALSE;
126 }
127 
128 // Signal handler for GtkWidget::delete-event
129 static gboolean window_delete_event_cb(FlView* self) {
130  fl_platform_handler_request_app_exit(self->platform_handler);
131  // Stop the event from propagating.
132  return TRUE;
133 }
134 
135 // Initialize keyboard.
136 static void init_keyboard(FlView* self) {
137  FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(self->engine);
138 
139  GdkWindow* window =
140  gtk_widget_get_window(gtk_widget_get_toplevel(GTK_WIDGET(self)));
141  g_return_if_fail(GDK_IS_WINDOW(window));
142  g_autoptr(GtkIMContext) im_context = gtk_im_multicontext_new();
143  gtk_im_context_set_client_window(im_context, window);
144 
145  g_clear_object(&self->text_input_handler);
146  self->text_input_handler = fl_text_input_handler_new(
147  messenger, im_context, FL_TEXT_INPUT_VIEW_DELEGATE(self));
148  g_clear_object(&self->keyboard_handler);
149  self->keyboard_handler =
150  fl_keyboard_handler_new(messenger, FL_KEYBOARD_VIEW_DELEGATE(self));
151 }
152 
153 static void init_scrolling(FlView* self) {
154  g_clear_object(&self->scrolling_manager);
155  self->scrolling_manager =
156  fl_scrolling_manager_new(FL_SCROLLING_VIEW_DELEGATE(self));
157 }
158 
159 static FlutterPointerDeviceKind get_device_kind(GdkEvent* event) {
160  GdkDevice* device = gdk_event_get_source_device(event);
161  GdkInputSource source = gdk_device_get_source(device);
162  switch (source) {
163  case GDK_SOURCE_PEN:
164  case GDK_SOURCE_ERASER:
165  case GDK_SOURCE_CURSOR:
166  case GDK_SOURCE_TABLET_PAD:
167  return kFlutterPointerDeviceKindStylus;
168  case GDK_SOURCE_TOUCHSCREEN:
169  return kFlutterPointerDeviceKindTouch;
170  case GDK_SOURCE_TOUCHPAD: // trackpad device type is reserved for gestures
171  case GDK_SOURCE_TRACKPOINT:
172  case GDK_SOURCE_KEYBOARD:
173  case GDK_SOURCE_MOUSE:
174  return kFlutterPointerDeviceKindMouse;
175  }
176 }
177 
178 // Converts a GDK button event into a Flutter event and sends it to the engine.
179 static gboolean send_pointer_button_event(FlView* self, GdkEvent* event) {
180  guint event_time = gdk_event_get_time(event);
181  GdkEventType event_type = gdk_event_get_event_type(event);
182  GdkModifierType event_state = static_cast<GdkModifierType>(0);
183  gdk_event_get_state(event, &event_state);
184  guint event_button = 0;
185  gdk_event_get_button(event, &event_button);
186  gdouble event_x = 0.0, event_y = 0.0;
187  gdk_event_get_coords(event, &event_x, &event_y);
188 
189  int64_t button;
190  switch (event_button) {
191  case 1:
192  button = kFlutterPointerButtonMousePrimary;
193  break;
194  case 2:
195  button = kFlutterPointerButtonMouseMiddle;
196  break;
197  case 3:
198  button = kFlutterPointerButtonMouseSecondary;
199  break;
200  default:
201  return FALSE;
202  }
203  int old_button_state = self->button_state;
204  FlutterPointerPhase phase = kMove;
205  if (event_type == GDK_BUTTON_PRESS) {
206  // Drop the event if Flutter already thinks the button is down.
207  if ((self->button_state & button) != 0) {
208  return FALSE;
209  }
210  self->button_state ^= button;
211 
212  phase = old_button_state == 0 ? kDown : kMove;
213  } else if (event_type == GDK_BUTTON_RELEASE) {
214  // Drop the event if Flutter already thinks the button is up.
215  if ((self->button_state & button) == 0) {
216  return FALSE;
217  }
218  self->button_state ^= button;
219 
220  phase = self->button_state == 0 ? kUp : kMove;
221  }
222 
223  if (self->engine == nullptr) {
224  return FALSE;
225  }
226 
227  gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self));
229  self->scrolling_manager, event_x * scale_factor, event_y * scale_factor);
230  fl_keyboard_handler_sync_modifier_if_needed(self->keyboard_handler,
231  event_state, event_time);
233  self->engine, self->view_id, phase,
234  event_time * kMicrosecondsPerMillisecond, event_x * scale_factor,
235  event_y * scale_factor, get_device_kind((GdkEvent*)event), 0, 0,
236  self->button_state);
237 
238  return TRUE;
239 }
240 
241 // Generates a mouse pointer event if the pointer appears inside the window.
242 static void check_pointer_inside(FlView* self, GdkEvent* event) {
243  if (!self->pointer_inside) {
244  self->pointer_inside = TRUE;
245 
246  gdouble x, y;
247  if (gdk_event_get_coords(event, &x, &y)) {
248  gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self));
249 
251  self->engine, self->view_id, kAdd,
252  gdk_event_get_time(event) * kMicrosecondsPerMillisecond,
253  x * scale_factor, y * scale_factor, get_device_kind(event), 0, 0,
254  self->button_state);
255  }
256  }
257 }
258 
259 // Updates the engine with the current window metrics.
260 static void handle_geometry_changed(FlView* self) {
261  GtkAllocation allocation;
262  gtk_widget_get_allocation(GTK_WIDGET(self), &allocation);
263  gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self));
265  self->engine, self->view_id, allocation.width * scale_factor,
266  allocation.height * scale_factor, scale_factor);
267 
268  // Make sure the view has been realized and its size has been allocated before
269  // waiting for a frame. `fl_view_realize()` and `fl_view_size_allocate()` may
270  // be called in either order depending on the order in which the window is
271  // shown and the view is added to a container in the app runner.
272  //
273  // Note: `gtk_widget_init()` initializes the size allocation to 1x1.
274  if (allocation.width > 1 && allocation.height > 1 &&
275  gtk_widget_get_realized(GTK_WIDGET(self))) {
276  fl_renderer_wait_for_frame(FL_RENDERER(self->renderer),
277  allocation.width * scale_factor,
278  allocation.height * scale_factor);
279  }
280 }
281 
282 static void view_added_cb(GObject* object,
283  GAsyncResult* result,
284  gpointer user_data) {
285  FlView* self = FL_VIEW(user_data);
286 
287  g_autoptr(GError) error = nullptr;
288  if (!fl_engine_add_view_finish(FL_ENGINE(object), result, &error)) {
289  if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
290  return;
291  }
292 
293  g_warning("Failed to add view: %s", error->message);
294  // FIXME: Show on the GLArea
295  return;
296  }
297 
299 }
300 
301 // Called when the engine updates accessibility.
302 static void update_semantics_cb(FlEngine* engine,
303  const FlutterSemanticsUpdate2* update,
304  gpointer user_data) {
305  FlView* self = FL_VIEW(user_data);
306 
307  fl_view_accessible_handle_update_semantics(self->view_accessible, update);
308 }
309 
310 // Invoked by the engine right before the engine is restarted.
311 //
312 // This method should reset states to be as if the engine had just been started,
313 // which usually indicates the user has requested a hot restart (Shift-R in the
314 // Flutter CLI.)
315 static void on_pre_engine_restart_cb(FlView* self) {
316  init_keyboard(self);
317  init_scrolling(self);
318 }
319 
320 // Implements FlPluginRegistry::get_registrar_for_plugin.
321 static FlPluginRegistrar* fl_view_get_registrar_for_plugin(
322  FlPluginRegistry* registry,
323  const gchar* name) {
324  FlView* self = FL_VIEW(registry);
325 
326  return fl_plugin_registrar_new(self,
327  fl_engine_get_binary_messenger(self->engine),
328  fl_engine_get_texture_registrar(self->engine));
329 }
330 
332  FlPluginRegistryInterface* iface) {
333  iface->get_registrar_for_plugin = fl_view_get_registrar_for_plugin;
334 }
335 
337  FlKeyboardViewDelegateInterface* iface) {
338  iface->send_key_event =
339  [](FlKeyboardViewDelegate* view_delegate, const FlutterKeyEvent* event,
340  FlutterKeyEventCallback callback, void* user_data) {
341  FlView* self = FL_VIEW(view_delegate);
342  if (self->engine != nullptr) {
344  };
345  };
346 
347  iface->text_filter_key_press = [](FlKeyboardViewDelegate* view_delegate,
348  FlKeyEvent* event) {
349  FlView* self = FL_VIEW(view_delegate);
350  return fl_text_input_handler_filter_keypress(self->text_input_handler,
351  event);
352  };
353 
354  iface->get_messenger = [](FlKeyboardViewDelegate* view_delegate) {
355  FlView* self = FL_VIEW(view_delegate);
356  return fl_engine_get_binary_messenger(self->engine);
357  };
358 
359  iface->redispatch_event = [](FlKeyboardViewDelegate* view_delegate,
360  FlKeyEvent* event) {
361  GdkEventType event_type =
362  gdk_event_get_event_type(fl_key_event_get_origin(event));
363  g_return_if_fail(event_type == GDK_KEY_PRESS ||
364  event_type == GDK_KEY_RELEASE);
365  gdk_event_put(fl_key_event_get_origin(event));
366  };
367 
368  iface->subscribe_to_layout_change = [](FlKeyboardViewDelegate* view_delegate,
369  KeyboardLayoutNotifier notifier) {
370  FlView* self = FL_VIEW(view_delegate);
371  self->keyboard_layout_notifier = std::move(notifier);
372  };
373 
374  iface->lookup_key = [](FlKeyboardViewDelegate* view_delegate,
375  const GdkKeymapKey* key) -> guint {
376  FlView* self = FL_VIEW(view_delegate);
377  g_return_val_if_fail(self->keymap != nullptr, 0);
378  return gdk_keymap_lookup_key(self->keymap, key);
379  };
380 
381  iface->get_keyboard_state =
382  [](FlKeyboardViewDelegate* view_delegate) -> GHashTable* {
383  FlView* self = FL_VIEW(view_delegate);
384  return fl_view_get_keyboard_state(self);
385  };
386 }
387 
389  FlScrollingViewDelegateInterface* iface) {
390  iface->send_mouse_pointer_event =
391  [](FlScrollingViewDelegate* view_delegate, FlutterPointerPhase phase,
392  size_t timestamp, double x, double y,
393  FlutterPointerDeviceKind device_kind, double scroll_delta_x,
394  double scroll_delta_y, int64_t buttons) {
395  FlView* self = FL_VIEW(view_delegate);
396  if (self->engine != nullptr) {
398  self->engine, self->view_id, phase, timestamp, x, y, device_kind,
399  scroll_delta_x, scroll_delta_y, buttons);
400  }
401  };
402  iface->send_pointer_pan_zoom_event =
403  [](FlScrollingViewDelegate* view_delegate, size_t timestamp, double x,
404  double y, FlutterPointerPhase phase, double pan_x, double pan_y,
405  double scale, double rotation) {
406  FlView* self = FL_VIEW(view_delegate);
407  if (self->engine != nullptr) {
408  fl_engine_send_pointer_pan_zoom_event(self->engine, self->view_id,
409  timestamp, x, y, phase, pan_x,
410  pan_y, scale, rotation);
411  };
412  };
413 }
414 
416  FlTextInputViewDelegateInterface* iface) {
417  iface->translate_coordinates = [](FlTextInputViewDelegate* delegate,
418  gint view_x, gint view_y, gint* window_x,
419  gint* window_y) {
420  FlView* self = FL_VIEW(delegate);
421  gtk_widget_translate_coordinates(GTK_WIDGET(self),
422  gtk_widget_get_toplevel(GTK_WIDGET(self)),
423  view_x, view_y, window_x, window_y);
424  };
425 }
426 
427 // Signal handler for GtkWidget::button-press-event
428 static gboolean button_press_event_cb(FlView* self,
429  GdkEventButton* button_event) {
430  GdkEvent* event = reinterpret_cast<GdkEvent*>(button_event);
431 
432  // Flutter doesn't handle double and triple click events.
433  GdkEventType event_type = gdk_event_get_event_type(event);
434  if (event_type == GDK_DOUBLE_BUTTON_PRESS ||
435  event_type == GDK_TRIPLE_BUTTON_PRESS) {
436  return FALSE;
437  }
438 
440 
441  return send_pointer_button_event(self, event);
442 }
443 
444 // Signal handler for GtkWidget::button-release-event
445 static gboolean button_release_event_cb(FlView* self,
446  GdkEventButton* button_event) {
447  GdkEvent* event = reinterpret_cast<GdkEvent*>(button_event);
448  return send_pointer_button_event(self, event);
449 }
450 
451 // Signal handler for GtkWidget::scroll-event
452 static gboolean scroll_event_cb(FlView* self, GdkEventScroll* event) {
453  // TODO(robert-ancell): Update to use GtkEventControllerScroll when we can
454  // depend on GTK 3.24.
455 
457  self->scrolling_manager, event,
458  gtk_widget_get_scale_factor(GTK_WIDGET(self)));
459  return TRUE;
460 }
461 
462 // Signal handler for GtkWidget::motion-notify-event
463 static gboolean motion_notify_event_cb(FlView* self,
464  GdkEventMotion* motion_event) {
465  GdkEvent* event = reinterpret_cast<GdkEvent*>(motion_event);
466 
467  if (self->engine == nullptr) {
468  return FALSE;
469  }
470 
471  guint event_time = gdk_event_get_time(event);
472  GdkModifierType event_state = static_cast<GdkModifierType>(0);
473  gdk_event_get_state(event, &event_state);
474  gdouble event_x = 0.0, event_y = 0.0;
475  gdk_event_get_coords(event, &event_x, &event_y);
476 
478 
479  gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self));
480 
481  fl_keyboard_handler_sync_modifier_if_needed(self->keyboard_handler,
482  event_state, event_time);
484  self->engine, self->view_id, self->button_state != 0 ? kMove : kHover,
485  event_time * kMicrosecondsPerMillisecond, event_x * scale_factor,
486  event_y * scale_factor, get_device_kind((GdkEvent*)event), 0, 0,
487  self->button_state);
488 
489  return TRUE;
490 }
491 
492 // Signal handler for GtkWidget::enter-notify-event
493 static gboolean enter_notify_event_cb(FlView* self,
494  GdkEventCrossing* crossing_event) {
495  GdkEvent* event = reinterpret_cast<GdkEvent*>(crossing_event);
496 
497  if (self->engine == nullptr) {
498  return FALSE;
499  }
500 
502 
503  return TRUE;
504 }
505 
506 // Signal handler for GtkWidget::leave-notify-event
507 static gboolean leave_notify_event_cb(FlView* self,
508  GdkEventCrossing* crossing_event) {
509  GdkEvent* event = reinterpret_cast<GdkEvent*>(crossing_event);
510 
511  guint event_time = gdk_event_get_time(event);
512  gdouble event_x = 0.0, event_y = 0.0;
513  gdk_event_get_coords(event, &event_x, &event_y);
514 
515  if (crossing_event->mode != GDK_CROSSING_NORMAL) {
516  return FALSE;
517  }
518 
519  if (self->engine == nullptr) {
520  return FALSE;
521  }
522 
523  // Don't remove pointer while button is down; In case of dragging outside of
524  // window with mouse grab active Gtk will send another leave notify on
525  // release.
526  if (self->pointer_inside && self->button_state == 0) {
527  gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self));
529  self->engine, self->view_id, kRemove,
530  event_time * kMicrosecondsPerMillisecond, event_x * scale_factor,
531  event_y * scale_factor, get_device_kind((GdkEvent*)event), 0, 0,
532  self->button_state);
533  self->pointer_inside = FALSE;
534  }
535 
536  return TRUE;
537 }
538 
539 static void keymap_keys_changed_cb(FlView* self) {
540  if (self->keyboard_layout_notifier == nullptr) {
541  return;
542  }
543 
544  self->keyboard_layout_notifier();
545 }
546 
547 static void gesture_rotation_begin_cb(FlView* self) {
548  fl_scrolling_manager_handle_rotation_begin(self->scrolling_manager);
549 }
550 
551 static void gesture_rotation_update_cb(FlView* self,
552  gdouble rotation,
553  gdouble delta) {
554  fl_scrolling_manager_handle_rotation_update(self->scrolling_manager,
555  rotation);
556 }
557 
558 static void gesture_rotation_end_cb(FlView* self) {
559  fl_scrolling_manager_handle_rotation_end(self->scrolling_manager);
560 }
561 
562 static void gesture_zoom_begin_cb(FlView* self) {
563  fl_scrolling_manager_handle_zoom_begin(self->scrolling_manager);
564 }
565 
566 static void gesture_zoom_update_cb(FlView* self, gdouble scale) {
567  fl_scrolling_manager_handle_zoom_update(self->scrolling_manager, scale);
568 }
569 
570 static void gesture_zoom_end_cb(FlView* self) {
571  fl_scrolling_manager_handle_zoom_end(self->scrolling_manager);
572 }
573 
574 static GdkGLContext* create_context_cb(FlView* self) {
575  fl_renderer_gdk_set_window(self->renderer,
576  gtk_widget_get_parent_window(GTK_WIDGET(self)));
577 
578  // Must initialize the keymap before the keyboard.
579  self->keymap = gdk_keymap_get_for_display(gdk_display_get_default());
580  self->keymap_keys_changed_cb_id = g_signal_connect_swapped(
581  self->keymap, "keys-changed", G_CALLBACK(keymap_keys_changed_cb), self);
582 
583  // Create system channel handlers.
584  FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(self->engine);
585  init_scrolling(self);
586  self->mouse_cursor_handler = fl_mouse_cursor_handler_new(messenger, self);
587  self->platform_handler = fl_platform_handler_new(messenger);
588 
589  g_autoptr(GError) error = nullptr;
590  if (!fl_renderer_gdk_create_contexts(self->renderer, &error)) {
591  gtk_gl_area_set_error(self->gl_area, error);
592  return nullptr;
593  }
594 
595  return GDK_GL_CONTEXT(
596  g_object_ref(fl_renderer_gdk_get_context(self->renderer)));
597 }
598 
599 static void realize_cb(FlView* self) {
600  g_autoptr(GError) error = nullptr;
601 
602  fl_renderer_make_current(FL_RENDERER(self->renderer));
603 
604  GError* gl_error = gtk_gl_area_get_error(self->gl_area);
605  if (gl_error != NULL) {
606  g_warning("Failed to initialize GLArea: %s", gl_error->message);
607  return;
608  }
609 
610  fl_renderer_setup(FL_RENDERER(self->renderer));
611 
612  GtkWidget* toplevel_window = gtk_widget_get_toplevel(GTK_WIDGET(self));
613 
614  self->window_state_monitor =
616  GTK_WINDOW(toplevel_window));
617 
618  // Handle requests by the user to close the application.
619  g_signal_connect_swapped(toplevel_window, "delete-event",
620  G_CALLBACK(window_delete_event_cb), self);
621 
622  init_keyboard(self);
623 
624  fl_renderer_add_view(FL_RENDERER(self->renderer), self->view_id, self);
625 
626  if (!fl_engine_start(self->engine, &error)) {
627  g_warning("Failed to start Flutter engine: %s", error->message);
628  return;
629  }
630 
632 
633  self->view_accessible = fl_view_accessible_new(self->engine);
635  FL_SOCKET_ACCESSIBLE(gtk_widget_get_accessible(GTK_WIDGET(self))),
636  atk_plug_get_id(ATK_PLUG(self->view_accessible)));
637 }
638 
639 static gboolean render_cb(FlView* self, GdkGLContext* context) {
640  if (gtk_gl_area_get_error(self->gl_area) != NULL) {
641  return FALSE;
642  }
643 
644  int width = gtk_widget_get_allocated_width(GTK_WIDGET(self->gl_area));
645  int height = gtk_widget_get_allocated_height(GTK_WIDGET(self->gl_area));
646  gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self->gl_area));
647  fl_renderer_render(FL_RENDERER(self->renderer), self->view_id,
648  width * scale_factor, height * scale_factor,
649  self->background_color);
650 
651  return TRUE;
652 }
653 
654 static void unrealize_cb(FlView* self) {
655  g_autoptr(GError) error = nullptr;
656 
657  fl_renderer_make_current(FL_RENDERER(self->renderer));
658 
659  GError* gl_error = gtk_gl_area_get_error(self->gl_area);
660  if (gl_error != NULL) {
661  g_warning("Failed to uninitialize GLArea: %s", gl_error->message);
662  return;
663  }
664 
665  fl_renderer_cleanup(FL_RENDERER(self->renderer));
666 }
667 
668 static void size_allocate_cb(FlView* self) {
670 }
671 
672 static void fl_view_notify(GObject* object, GParamSpec* pspec) {
673  FlView* self = FL_VIEW(object);
674 
675  if (strcmp(pspec->name, "scale-factor") == 0) {
677  }
678 
679  if (G_OBJECT_CLASS(fl_view_parent_class)->notify != nullptr) {
680  G_OBJECT_CLASS(fl_view_parent_class)->notify(object, pspec);
681  }
682 }
683 
684 static void fl_view_dispose(GObject* object) {
685  FlView* self = FL_VIEW(object);
686 
687  g_cancellable_cancel(self->cancellable);
688 
689  if (self->engine != nullptr) {
690  fl_engine_set_update_semantics_handler(self->engine, nullptr, nullptr,
691  nullptr);
692 
693  // Stop rendering.
694  fl_renderer_remove_view(FL_RENDERER(self->renderer), self->view_id);
695 
696  // Release the view ID from the engine.
697  fl_engine_remove_view(self->engine, self->view_id, nullptr, nullptr,
698  nullptr);
699  }
700 
701  if (self->on_pre_engine_restart_handler != 0) {
702  g_signal_handler_disconnect(self->engine,
703  self->on_pre_engine_restart_handler);
704  self->on_pre_engine_restart_handler = 0;
705  }
706 
707  g_clear_object(&self->engine);
708  g_clear_object(&self->renderer);
709  g_clear_pointer(&self->background_color, gdk_rgba_free);
710  g_clear_object(&self->window_state_monitor);
711  g_clear_object(&self->scrolling_manager);
712  g_clear_object(&self->keyboard_handler);
713  if (self->keymap_keys_changed_cb_id != 0) {
714  g_signal_handler_disconnect(self->keymap, self->keymap_keys_changed_cb_id);
715  self->keymap_keys_changed_cb_id = 0;
716  }
717  g_clear_object(&self->mouse_cursor_handler);
718  g_clear_object(&self->platform_handler);
719  g_clear_object(&self->view_accessible);
720  g_clear_object(&self->cancellable);
721 
722  G_OBJECT_CLASS(fl_view_parent_class)->dispose(object);
723 }
724 
725 // Implements GtkWidget::realize.
726 static void fl_view_realize(GtkWidget* widget) {
727  FlView* self = FL_VIEW(widget);
728 
729  GTK_WIDGET_CLASS(fl_view_parent_class)->realize(widget);
730 
731  // Realize the child widgets.
732  gtk_widget_realize(GTK_WIDGET(self->gl_area));
733 }
734 
735 // Implements GtkWidget::key_press_event.
736 static gboolean fl_view_key_press_event(GtkWidget* widget, GdkEventKey* event) {
737  FlView* self = FL_VIEW(widget);
738 
740  self->keyboard_handler, fl_key_event_new_from_gdk_event(gdk_event_copy(
741  reinterpret_cast<GdkEvent*>(event))));
742 }
743 
744 // Implements GtkWidget::key_release_event.
745 static gboolean fl_view_key_release_event(GtkWidget* widget,
746  GdkEventKey* event) {
747  FlView* self = FL_VIEW(widget);
749  self->keyboard_handler, fl_key_event_new_from_gdk_event(gdk_event_copy(
750  reinterpret_cast<GdkEvent*>(event))));
751 }
752 
753 static void fl_view_class_init(FlViewClass* klass) {
754  GObjectClass* object_class = G_OBJECT_CLASS(klass);
755  object_class->notify = fl_view_notify;
756  object_class->dispose = fl_view_dispose;
757 
758  GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
759  widget_class->realize = fl_view_realize;
760  widget_class->key_press_event = fl_view_key_press_event;
761  widget_class->key_release_event = fl_view_key_release_event;
762 
764  g_signal_new("first-frame", fl_view_get_type(), G_SIGNAL_RUN_LAST, 0,
765  NULL, NULL, NULL, G_TYPE_NONE, 0);
766 
767  gtk_widget_class_set_accessible_type(GTK_WIDGET_CLASS(klass),
768  fl_socket_accessible_get_type());
769 }
770 
771 static void fl_view_init(FlView* self) {
772  self->cancellable = g_cancellable_new();
773 
774  gtk_widget_set_can_focus(GTK_WIDGET(self), TRUE);
775 
776  self->view_id = -1;
777 
778  GdkRGBA default_background = {
779  .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
780  self->background_color = gdk_rgba_copy(&default_background);
781 
782  self->event_box = gtk_event_box_new();
783  gtk_widget_set_hexpand(self->event_box, TRUE);
784  gtk_widget_set_vexpand(self->event_box, TRUE);
785  gtk_container_add(GTK_CONTAINER(self), self->event_box);
786  gtk_widget_show(self->event_box);
787  gtk_widget_add_events(self->event_box,
788  GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK |
789  GDK_BUTTON_RELEASE_MASK | GDK_SCROLL_MASK |
790  GDK_SMOOTH_SCROLL_MASK);
791 
792  g_signal_connect_swapped(self->event_box, "button-press-event",
793  G_CALLBACK(button_press_event_cb), self);
794  g_signal_connect_swapped(self->event_box, "button-release-event",
795  G_CALLBACK(button_release_event_cb), self);
796  g_signal_connect_swapped(self->event_box, "scroll-event",
797  G_CALLBACK(scroll_event_cb), self);
798  g_signal_connect_swapped(self->event_box, "motion-notify-event",
799  G_CALLBACK(motion_notify_event_cb), self);
800  g_signal_connect_swapped(self->event_box, "enter-notify-event",
801  G_CALLBACK(enter_notify_event_cb), self);
802  g_signal_connect_swapped(self->event_box, "leave-notify-event",
803  G_CALLBACK(leave_notify_event_cb), self);
804  GtkGesture* zoom = gtk_gesture_zoom_new(self->event_box);
805  g_signal_connect_swapped(zoom, "begin", G_CALLBACK(gesture_zoom_begin_cb),
806  self);
807  g_signal_connect_swapped(zoom, "scale-changed",
808  G_CALLBACK(gesture_zoom_update_cb), self);
809  g_signal_connect_swapped(zoom, "end", G_CALLBACK(gesture_zoom_end_cb), self);
810  GtkGesture* rotate = gtk_gesture_rotate_new(self->event_box);
811  g_signal_connect_swapped(rotate, "begin",
812  G_CALLBACK(gesture_rotation_begin_cb), self);
813  g_signal_connect_swapped(rotate, "angle-changed",
814  G_CALLBACK(gesture_rotation_update_cb), self);
815  g_signal_connect_swapped(rotate, "end", G_CALLBACK(gesture_rotation_end_cb),
816  self);
817 
818  self->gl_area = GTK_GL_AREA(gtk_gl_area_new());
819  gtk_gl_area_set_has_alpha(self->gl_area, TRUE);
820  gtk_widget_show(GTK_WIDGET(self->gl_area));
821  gtk_container_add(GTK_CONTAINER(self->event_box), GTK_WIDGET(self->gl_area));
822  g_signal_connect_swapped(self->gl_area, "render", G_CALLBACK(render_cb),
823  self);
824 
825  g_signal_connect_swapped(self, "size-allocate", G_CALLBACK(size_allocate_cb),
826  self);
827 }
828 
829 G_MODULE_EXPORT FlView* fl_view_new(FlDartProject* project) {
830  g_autoptr(FlEngine) engine = fl_engine_new(project);
831  FlView* self = FL_VIEW(g_object_new(fl_view_get_type(), nullptr));
832 
833  self->view_id = flutter::kFlutterImplicitViewId;
834  self->engine = FL_ENGINE(g_object_ref(engine));
835  FlRenderer* renderer = fl_engine_get_renderer(engine);
836  g_assert(FL_IS_RENDERER_GDK(renderer));
837  self->renderer = FL_RENDERER_GDK(g_object_ref(renderer));
838 
840  self, nullptr);
841  self->on_pre_engine_restart_handler =
842  g_signal_connect_swapped(engine, "on-pre-engine-restart",
843  G_CALLBACK(on_pre_engine_restart_cb), self);
844 
845  g_signal_connect_swapped(self->gl_area, "create-context",
846  G_CALLBACK(create_context_cb), self);
847  g_signal_connect_swapped(self->gl_area, "realize", G_CALLBACK(realize_cb),
848  self);
849  g_signal_connect_swapped(self->gl_area, "unrealize", G_CALLBACK(unrealize_cb),
850  self);
851 
852  return self;
853 }
854 
855 G_MODULE_EXPORT FlView* fl_view_new_for_engine(FlEngine* engine) {
856  FlView* self = FL_VIEW(g_object_new(fl_view_get_type(), nullptr));
857 
858  self->engine = FL_ENGINE(g_object_ref(engine));
859  FlRenderer* renderer = fl_engine_get_renderer(engine);
860  g_assert(FL_IS_RENDERER_GDK(renderer));
861  self->renderer = FL_RENDERER_GDK(g_object_ref(renderer));
862 
863  self->on_pre_engine_restart_handler =
864  g_signal_connect_swapped(engine, "on-pre-engine-restart",
865  G_CALLBACK(on_pre_engine_restart_cb), self);
866 
867  self->view_id = fl_engine_add_view(self->engine, 1, 1, 1.0, self->cancellable,
868  view_added_cb, self);
869  fl_renderer_add_view(FL_RENDERER(self->renderer), self->view_id, self);
870 
871  return self;
872 }
873 
874 G_MODULE_EXPORT FlEngine* fl_view_get_engine(FlView* self) {
875  g_return_val_if_fail(FL_IS_VIEW(self), nullptr);
876  return self->engine;
877 }
878 
879 G_MODULE_EXPORT
880 int64_t fl_view_get_id(FlView* self) {
881  g_return_val_if_fail(FL_IS_VIEW(self), -1);
882  return self->view_id;
883 }
884 
885 G_MODULE_EXPORT void fl_view_set_background_color(FlView* self,
886  const GdkRGBA* color) {
887  g_return_if_fail(FL_IS_VIEW(self));
888  gdk_rgba_free(self->background_color);
889  self->background_color = gdk_rgba_copy(color);
890 }
891 
892 void fl_view_redraw(FlView* self) {
893  g_return_if_fail(FL_IS_VIEW(self));
894 
895  gtk_widget_queue_draw(GTK_WIDGET(self->gl_area));
896 
897  if (!self->have_first_frame) {
898  self->have_first_frame = TRUE;
899  // This is not the main thread, so the signal needs to be done via an idle
900  // callback.
901  g_idle_add(first_frame_idle_cb, self);
902  }
903 }
904 
905 GHashTable* fl_view_get_keyboard_state(FlView* self) {
906  g_return_val_if_fail(FL_IS_VIEW(self), nullptr);
907  return fl_keyboard_handler_get_pressed_state(self->keyboard_handler);
908 }
fl_view_realize
static void fl_view_realize(GtkWidget *widget)
Definition: fl_view.cc:726
window_delete_event_cb
static gboolean window_delete_event_cb(FlView *self)
Definition: fl_view.cc:129
fl_keyboard_handler_handle_event
gboolean fl_keyboard_handler_handle_event(FlKeyboardHandler *self, FlKeyEvent *event)
Definition: fl_keyboard_handler.cc:541
_FlView::pointer_inside
gboolean pointer_inside
Definition: fl_view.cc:76
fl_renderer_remove_view
void fl_renderer_remove_view(FlRenderer *self, FlutterViewId view_id)
Definition: fl_renderer.cc:325
gesture_rotation_update_cb
static void gesture_rotation_update_cb(FlView *self, gdouble rotation, gdouble delta)
Definition: fl_view.cc:551
fl_renderer_wait_for_frame
void fl_renderer_wait_for_frame(FlRenderer *self, int target_width, int target_height)
Definition: fl_renderer.cc:409
fl_renderer_gdk_set_window
void fl_renderer_gdk_set_window(FlRendererGdk *self, GdkWindow *window)
Definition: fl_renderer_gdk.cc:88
fl_view_text_input_delegate_iface_init
static void fl_view_text_input_delegate_iface_init(FlTextInputViewDelegateInterface *iface)
Definition: fl_view.cc:415
G_DEFINE_TYPE_WITH_CODE
G_DEFINE_TYPE_WITH_CODE(FlView, fl_view, GTK_TYPE_BOX, G_IMPLEMENT_INTERFACE(fl_plugin_registry_get_type(), fl_view_plugin_registry_iface_init) G_IMPLEMENT_INTERFACE(fl_keyboard_view_delegate_get_type(), fl_view_keyboard_delegate_iface_init) G_IMPLEMENT_INTERFACE(fl_scrolling_view_delegate_get_type(), fl_view_scrolling_delegate_iface_init) G_IMPLEMENT_INTERFACE(fl_text_input_view_delegate_get_type(), fl_view_text_input_delegate_iface_init)) static gboolean first_frame_idle_cb(gpointer user_data)
Definition: fl_view.cc:106
enter_notify_event_cb
static gboolean enter_notify_event_cb(FlView *self, GdkEventCrossing *crossing_event)
Definition: fl_view.cc:493
event
FlKeyEvent * event
Definition: fl_key_channel_responder.cc:118
fl_view_accessible.h
leave_notify_event_cb
static gboolean leave_notify_event_cb(FlView *self, GdkEventCrossing *crossing_event)
Definition: fl_view.cc:507
fl_scrolling_manager_handle_zoom_end
void fl_scrolling_manager_handle_zoom_end(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:208
_FlView::text_input_handler
FlTextInputHandler * text_input_handler
Definition: fl_view.cc:68
_FlView::window_state_monitor
FlWindowStateMonitor * window_state_monitor
Definition: fl_view.cc:62
fl_engine_send_key_event
void fl_engine_send_key_event(FlEngine *self, const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *user_data)
Definition: fl_engine.cc:940
fl_key_event_new_from_gdk_event
FlKeyEvent * fl_key_event_new_from_gdk_event(GdkEvent *event)
Definition: fl_key_event.cc:53
fl_view_set_background_color
G_MODULE_EXPORT void fl_view_set_background_color(FlView *self, const GdkRGBA *color)
Definition: fl_view.cc:885
kMicrosecondsPerMillisecond
static constexpr int kMicrosecondsPerMillisecond
Definition: fl_view.cc:35
fl_scrolling_manager_handle_scroll_event
void fl_scrolling_manager_handle_scroll_event(FlScrollingManager *self, GdkEventScroll *scroll_event, gint scale_factor)
Definition: fl_scrolling_manager.cc:74
_FlView::background_color
GdkRGBA * background_color
Definition: fl_view.cc:53
fl_view_accessible_handle_update_semantics
void fl_view_accessible_handle_update_semantics(FlViewAccessible *self, const FlutterSemanticsUpdate2 *update)
Definition: fl_view_accessible.cc:142
fl_view_scrolling_delegate_iface_init
static void fl_view_scrolling_delegate_iface_init(FlScrollingViewDelegateInterface *iface)
Definition: fl_view.cc:388
fl_text_input_view_delegate.h
kSignalFirstFrame
@ kSignalFirstFrame
Definition: fl_view.cc:90
fl_scrolling_view_delegate.h
fl_view_class_init
static void fl_view_class_init(FlViewClass *klass)
Definition: fl_view.cc:753
fl_plugin_registrar_private.h
fl_view_get_id
G_MODULE_EXPORT int64_t fl_view_get_id(FlView *self)
Definition: fl_view.cc:880
_FlView::mouse_cursor_handler
FlMouseCursorHandler * mouse_cursor_handler
Definition: fl_view.cc:69
_FlView::parent_instance
GtkBox parent_instance
Definition: fl_view.cc:38
_FlView::have_first_frame
gboolean have_first_frame
Definition: fl_view.cc:56
_FlView::cancellable
GCancellable * cancellable
Definition: fl_view.cc:87
init_scrolling
static void init_scrolling(FlView *self)
Definition: fl_view.cc:153
fl_renderer_gdk_get_context
GdkGLContext * fl_renderer_gdk_get_context(FlRendererGdk *self)
Definition: fl_renderer_gdk.cc:125
create_context_cb
static GdkGLContext * create_context_cb(FlView *self)
Definition: fl_view.cc:574
fl_platform_handler_request_app_exit
void fl_platform_handler_request_app_exit(FlPlatformHandler *self)
Definition: fl_platform_handler.cc:421
get_device_kind
static FlutterPointerDeviceKind get_device_kind(GdkEvent *event)
Definition: fl_view.cc:159
fl_view_get_registrar_for_plugin
static FlPluginRegistrar * fl_view_get_registrar_for_plugin(FlPluginRegistry *registry, const gchar *name)
Definition: fl_view.cc:321
fl_keyboard_handler_get_pressed_state
GHashTable * fl_keyboard_handler_get_pressed_state(FlKeyboardHandler *self)
Definition: fl_keyboard_handler.cc:590
_FlView::platform_handler
FlPlatformHandler * platform_handler
Definition: fl_view.cc:70
on_pre_engine_restart_cb
static void on_pre_engine_restart_cb(FlView *self)
Definition: fl_view.cc:315
fl_engine_get_renderer
FlRenderer * fl_engine_get_renderer(FlEngine *self)
Definition: fl_engine.cc:504
fl_view_new_for_engine
G_MODULE_EXPORT FlView * fl_view_new_for_engine(FlEngine *engine)
Definition: fl_view.cc:855
size_allocate_cb
static void size_allocate_cb(FlView *self)
Definition: fl_view.cc:668
unrealize_cb
static void unrealize_cb(FlView *self)
Definition: fl_view.cc:654
_FlView::keymap
GdkKeymap * keymap
Definition: fl_view.cc:80
fl_text_input_handler.h
fl_engine_remove_view
void fl_engine_remove_view(FlEngine *self, FlutterViewId view_id, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:686
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
_FlView
Definition: fl_view.cc:37
_FlView::event_box
GtkWidget * event_box
Definition: fl_view.cc:72
keymap_keys_changed_cb
static void keymap_keys_changed_cb(FlView *self)
Definition: fl_view.cc:539
pspec
guint const GValue GParamSpec * pspec
Definition: fl_standard_method_codec.cc:33
fl_platform_handler_new
FlPlatformHandler * fl_platform_handler_new(FlBinaryMessenger *messenger)
Definition: fl_platform_handler.cc:405
fl_text_input_handler_new
FlTextInputHandler * fl_text_input_handler_new(FlBinaryMessenger *messenger, GtkIMContext *im_context, FlTextInputViewDelegate *view_delegate)
Definition: fl_text_input_handler.cc:747
realize_cb
static void realize_cb(FlView *self)
Definition: fl_view.cc:599
fl_engine_send_window_metrics_event
void fl_engine_send_window_metrics_event(FlEngine *self, FlutterViewId view_id, size_t width, size_t height, double pixel_ratio)
Definition: fl_engine.cc:854
scroll_event_cb
static gboolean scroll_event_cb(FlView *self, GdkEventScroll *event)
Definition: fl_view.cc:452
fl_engine_get_binary_messenger
G_MODULE_EXPORT FlBinaryMessenger * fl_engine_get_binary_messenger(FlEngine *self)
Definition: fl_engine.cc:995
_FlView::on_pre_engine_restart_handler
guint on_pre_engine_restart_handler
Definition: fl_view.cc:44
fl_view_private.h
view_added_cb
static void view_added_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_view.cc:282
fl_key_event_get_origin
GdkEvent * fl_key_event_get_origin(FlKeyEvent *self)
Definition: fl_key_event.cc:109
_FlView::keyboard_handler
FlKeyboardHandler * keyboard_handler
Definition: fl_view.cc:67
update_semantics_cb
static void update_semantics_cb(FlEngine *engine, const FlutterSemanticsUpdate2 *update, gpointer user_data)
Definition: fl_view.cc:302
_FlView::scrolling_manager
FlScrollingManager * scrolling_manager
Definition: fl_view.cc:64
fl_keyboard_handler.h
fl_view_new
G_MODULE_EXPORT FlView * fl_view_new(FlDartProject *project)
Definition: fl_view.cc:829
fl_framebuffer.h
render_cb
static gboolean render_cb(FlView *self, GdkGLContext *context)
Definition: fl_view.cc:639
_FlView::button_state
int64_t button_state
Definition: fl_view.cc:59
gesture_zoom_end_cb
static void gesture_zoom_end_cb(FlView *self)
Definition: fl_view.cc:570
button_release_event_cb
static gboolean button_release_event_cb(FlView *self, GdkEventButton *button_event)
Definition: fl_view.cc:445
KeyboardLayoutNotifier
std::function< void()> KeyboardLayoutNotifier
Definition: fl_keyboard_view_delegate.h:17
fl_socket_accessible.h
_FlView::view_id
FlutterViewId view_id
Definition: fl_view.cc:47
fl_engine_add_view_finish
gboolean fl_engine_add_view_finish(FlEngine *self, GAsyncResult *result, GError **error)
Definition: fl_engine.cc:679
fl_scrolling_manager_new
FlScrollingManager * fl_scrolling_manager_new(FlScrollingViewDelegate *view_delegate)
Definition: fl_scrolling_manager.cc:47
_FlView::keyboard_layout_notifier
KeyboardLayoutNotifier keyboard_layout_notifier
Definition: fl_view.cc:79
fl_view_key_press_event
static gboolean fl_view_key_press_event(GtkWidget *widget, GdkEventKey *event)
Definition: fl_view.cc:736
_FlView::engine
FlEngine * engine
Definition: fl_view.cc:41
fl_view_key_release_event
static gboolean fl_view_key_release_event(GtkWidget *widget, GdkEventKey *event)
Definition: fl_view.cc:745
fl_text_input_handler_filter_keypress
gboolean fl_text_input_handler_filter_keypress(FlTextInputHandler *self, FlKeyEvent *event)
Definition: fl_text_input_handler.cc:778
fl_view_plugin_registry_iface_init
static void fl_view_plugin_registry_iface_init(FlPluginRegistryInterface *iface)
Definition: fl_view.cc:331
fl_scrolling_manager_set_last_mouse_position
void fl_scrolling_manager_set_last_mouse_position(FlScrollingManager *self, gdouble x, gdouble y)
Definition: fl_scrolling_manager.cc:66
fl_view_dispose
static void fl_view_dispose(GObject *object)
Definition: fl_view.cc:684
fl_view_signals
static guint fl_view_signals[kSignalLastSignal]
Definition: fl_view.cc:92
fl_engine_private.h
fl_mouse_cursor_handler.h
fl_scrolling_manager.h
fl_renderer_gdk_create_contexts
gboolean fl_renderer_gdk_create_contexts(FlRendererGdk *self, GError **error)
Definition: fl_renderer_gdk.cc:95
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_scrolling_manager_handle_zoom_update
void fl_scrolling_manager_handle_zoom_update(FlScrollingManager *self, gdouble scale)
Definition: fl_scrolling_manager.cc:198
fl_view_get_engine
G_MODULE_EXPORT FlEngine * fl_view_get_engine(FlView *self)
Definition: fl_view.cc:874
check_pointer_inside
static void check_pointer_inside(FlView *self, GdkEvent *event)
Definition: fl_view.cc:242
fl_view_get_keyboard_state
GHashTable * fl_view_get_keyboard_state(FlView *self)
Definition: fl_view.cc:905
fl_window_state_monitor_new
FlWindowStateMonitor * fl_window_state_monitor_new(FlBinaryMessenger *messenger, GtkWindow *window)
Definition: fl_window_state_monitor.cc:104
fl_platform_handler.h
fl_scrolling_manager_handle_rotation_update
void fl_scrolling_manager_handle_rotation_update(FlScrollingManager *self, gdouble rotation)
Definition: fl_scrolling_manager.cc:164
gesture_rotation_begin_cb
static void gesture_rotation_begin_cb(FlView *self)
Definition: fl_view.cc:547
fl_accessible_node.h
fl_engine_add_view
FlutterViewId fl_engine_add_view(FlEngine *self, size_t width, size_t height, double pixel_ratio, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:641
fl_socket_accessible_embed
void fl_socket_accessible_embed(FlSocketAccessible *self, gchar *id)
Definition: fl_socket_accessible.cc:55
fl_view_redraw
void fl_view_redraw(FlView *self)
Definition: fl_view.cc:892
_FlView::keymap_keys_changed_cb_id
gulong keymap_keys_changed_cb_id
Definition: fl_view.cc:81
fl_view.h
fl_renderer_gdk.h
height
const uint8_t uint32_t uint32_t * height
Definition: fl_pixel_buffer_texture_test.cc:39
result
GAsyncResult * result
Definition: fl_text_input_handler.cc:106
handle_geometry_changed
static void handle_geometry_changed(FlView *self)
Definition: fl_view.cc:260
_FlView::renderer
FlRendererGdk * renderer
Definition: fl_view.cc:50
fl_renderer_cleanup
void fl_renderer_cleanup(FlRenderer *self)
Definition: fl_renderer.cc:528
gesture_rotation_end_cb
static void gesture_rotation_end_cb(FlView *self)
Definition: fl_view.cc:558
_FlView::gl_area
GtkGLArea * gl_area
Definition: fl_view.cc:73
gesture_zoom_update_cb
static void gesture_zoom_update_cb(FlView *self, gdouble scale)
Definition: fl_view.cc:566
send_pointer_button_event
static gboolean send_pointer_button_event(FlView *self, GdkEvent *event)
Definition: fl_view.cc:179
fl_engine_new
G_MODULE_EXPORT FlEngine * fl_engine_new(FlDartProject *project)
Definition: fl_engine.cc:494
fl_view_keyboard_delegate_iface_init
static void fl_view_keyboard_delegate_iface_init(FlKeyboardViewDelegateInterface *iface)
Definition: fl_view.cc:336
fl_renderer_add_view
void fl_renderer_add_view(FlRenderer *self, FlutterViewId view_id, FlView *view)
Definition: fl_renderer.cc:314
fl_key_event.h
gesture_zoom_begin_cb
static void gesture_zoom_begin_cb(FlView *self)
Definition: fl_view.cc:562
_FlView::view_accessible
FlViewAccessible * view_accessible
Definition: fl_view.cc:85
fl_engine.h
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
fl_renderer_make_current
void fl_renderer_make_current(FlRenderer *self)
Definition: fl_renderer.cc:340
fl_engine_set_update_semantics_handler
void fl_engine_set_update_semantics_handler(FlEngine *self, FlEngineUpdateSemanticsHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
Definition: fl_engine.cc:736
fl_engine_send_pointer_pan_zoom_event
void fl_engine_send_pointer_pan_zoom_event(FlEngine *self, FlutterViewId view_id, size_t timestamp, double x, double y, FlutterPointerPhase phase, double pan_x, double pan_y, double scale, double rotation)
Definition: fl_engine.cc:908
fl_keyboard_handler_sync_modifier_if_needed
void fl_keyboard_handler_sync_modifier_if_needed(FlKeyboardHandler *self, guint state, double event_time)
Definition: fl_keyboard_handler.cc:577
fl_view_init
static void fl_view_init(FlView *self)
Definition: fl_view.cc:771
fl_view_notify
static void fl_view_notify(GObject *object, GParamSpec *pspec)
Definition: fl_view.cc:672
fl_renderer_render
void fl_renderer_render(FlRenderer *self, FlutterViewId view_id, int width, int height, const GdkRGBA *background_color)
Definition: fl_renderer.cc:501
fl_scrolling_manager_handle_rotation_end
void fl_scrolling_manager_handle_rotation_end(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:174
fl_window_state_monitor.h
fl_engine_start
gboolean fl_engine_start(FlEngine *self, GError **error)
Definition: fl_engine.cc:509
fl_scrolling_manager_handle_rotation_begin
void fl_scrolling_manager_handle_rotation_begin(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:151
fl_plugin_registrar_new
FlPluginRegistrar * fl_plugin_registrar_new(FlView *view, FlBinaryMessenger *messenger, FlTextureRegistrar *texture_registrar)
Definition: fl_plugin_registrar.cc:87
fl_keyboard_view_delegate.h
fl_plugin_registry.h
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_channel_responder.cc:120
motion_notify_event_cb
static gboolean motion_notify_event_cb(FlView *self, GdkEventMotion *motion_event)
Definition: fl_view.cc:463
width
const uint8_t uint32_t * width
Definition: fl_pixel_buffer_texture_test.cc:38
fl_scrolling_manager_handle_zoom_begin
void fl_scrolling_manager_handle_zoom_begin(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:185
fl_engine_send_mouse_pointer_event
void fl_engine_send_mouse_pointer_event(FlEngine *self, FlutterViewId view_id, FlutterPointerPhase phase, size_t timestamp, double x, double y, FlutterPointerDeviceKind device_kind, double scroll_delta_x, double scroll_delta_y, int64_t buttons)
Definition: fl_engine.cc:874
fl_keyboard_handler_new
FlKeyboardHandler * fl_keyboard_handler_new(FlBinaryMessenger *messenger, FlKeyboardViewDelegate *view_delegate)
Definition: fl_keyboard_handler.cc:499
fl_view_accessible_new
FlViewAccessible * fl_view_accessible_new(FlEngine *engine)
Definition: fl_view_accessible.cc:133
init_keyboard
static void init_keyboard(FlView *self)
Definition: fl_view.cc:136
fl_engine_get_texture_registrar
G_MODULE_EXPORT FlTextureRegistrar * fl_engine_get_texture_registrar(FlEngine *self)
Definition: fl_engine.cc:1011
button_press_event_cb
static gboolean button_press_event_cb(FlView *self, GdkEventButton *button_event)
Definition: fl_view.cc:428
kSignalLastSignal
@ kSignalLastSignal
Definition: fl_view.cc:90
fl_mouse_cursor_handler_new
FlMouseCursorHandler * fl_mouse_cursor_handler_new(FlBinaryMessenger *messenger, FlView *view)
Definition: fl_mouse_cursor_handler.cc:164
fl_renderer_setup
void fl_renderer_setup(FlRenderer *self)
Definition: fl_renderer.cc:484