@@ -21,6 +21,7 @@ namespace {
2121// Z-fighting.
2222constexpr float kScenicZElevationBetweenLayers = 0 .0001f ;
2323constexpr float kScenicZElevationForPlatformView = 100 .f;
24+ constexpr float kScenicElevationForInputInterceptor = 500 .f;
2425
2526} // namespace
2627
@@ -39,18 +40,24 @@ FuchsiaExternalViewEmbedder::FuchsiaExternalViewEmbedder(
3940 std::move(view_ref_pair.view_ref),
4041 debug_label),
4142 metrics_node_(session_.get()),
42- root_node_(session_.get()),
43- intercept_all_input_(intercept_all_input) {
44- root_view_.AddChild (metrics_node_);
45- metrics_node_.SetEventMask (fuchsia::ui::gfx::kMetricsEventMask );
43+ layer_tree_node_(session_.get()) {
44+ layer_tree_node_.SetLabel (" Flutter::LayerTree" );
4645 metrics_node_.SetLabel (" Flutter::MetricsWatcher" );
47- metrics_node_.AddChild (root_node_);
48- root_node_.SetLabel (" Flutter::LayerTree" );
46+ metrics_node_.SetEventMask (fuchsia::ui::gfx::kMetricsEventMask );
47+ metrics_node_.AddChild (layer_tree_node_);
48+ root_view_.AddChild (metrics_node_);
4949
50- // Set up the input interceptor at the top of the scene, if applicable.
51- if (intercept_all_input_) {
52- input_interceptor_.emplace (session_.get ());
53- metrics_node_.AddChild (input_interceptor_->node ());
50+ // Set up the input interceptor at the top of the scene, if applicable. It
51+ // will capture all input, and any unwanted input will be reinjected into
52+ // embedded views.
53+ if (intercept_all_input) {
54+ input_interceptor_node_.emplace (session_.get ());
55+ input_interceptor_node_->SetLabel (" Flutter::InputInterceptor" );
56+ input_interceptor_node_->SetHitTestBehavior (
57+ fuchsia::ui::gfx::HitTestBehavior::kDefault );
58+ input_interceptor_node_->SetSemanticVisibility (false );
59+
60+ metrics_node_.AddChild (input_interceptor_node_.value ());
5461 }
5562
5663 session_.Present ();
@@ -124,12 +131,28 @@ void FuchsiaExternalViewEmbedder::BeginFrame(
124131 frame_composition_order_.push_back (kRootLayerId );
125132
126133 // Set up the input interceptor at the top of the scene, if applicable.
127- if (input_interceptor_.has_value ()) {
128- // TODO: Don't hardcode elevation.
129- const float kMaximumElevation = -100 .f ;
130- input_interceptor_->UpdateDimensions (session_.get (), frame_size.width (),
131- frame_size.height (),
132- kMaximumElevation );
134+ if (input_interceptor_node_.has_value ()) {
135+ const uint64_t rect_hash =
136+ (static_cast <uint64_t >(frame_size_.width ()) << 32 ) +
137+ frame_size_.height ();
138+
139+ // Create a new rect if needed for the interceptor.
140+ auto found_rect = scenic_interceptor_rects_.find (rect_hash);
141+ if (found_rect == scenic_interceptor_rects_.end ()) {
142+ auto [emplaced_rect, success] =
143+ scenic_interceptor_rects_.emplace (std::make_pair (
144+ rect_hash, scenic::Rectangle (session_.get (), frame_size_.width (),
145+ frame_size_.height ())));
146+ FML_DCHECK (success);
147+
148+ found_rect = std::move (emplaced_rect);
149+ }
150+
151+ // TODO(fxb/): Don't hardcode elevation.
152+ input_interceptor_node_->SetTranslation (
153+ frame_size.width () * 0 .5f , frame_size.height () * 0 .5f ,
154+ -kScenicElevationForInputInterceptor );
155+ input_interceptor_node_->SetShape (found_rect->second );
133156 }
134157}
135158
@@ -179,7 +202,7 @@ void FuchsiaExternalViewEmbedder::SubmitFrame(
179202
180203 // First re-scale everything according to the DPR.
181204 const float inv_dpr = 1 .0f / frame_dpr_;
182- root_node_ .SetScale (inv_dpr, inv_dpr, 1 .0f );
205+ layer_tree_node_ .SetScale (inv_dpr, inv_dpr, 1 .0f );
183206
184207 bool first_layer = true ;
185208 for (const auto & layer_id : frame_composition_order_) {
@@ -267,7 +290,7 @@ void FuchsiaExternalViewEmbedder::SubmitFrame(
267290 }
268291
269292 // Attach the ScenicView to the main scene graph.
270- root_node_ .AddChild (view_holder.opacity_node );
293+ layer_tree_node_ .AddChild (view_holder.opacity_node );
271294
272295 // Account for the ScenicView's height when positioning the next layer.
273296 embedded_views_height += kScenicZElevationForPlatformView ;
@@ -355,7 +378,7 @@ void FuchsiaExternalViewEmbedder::SubmitFrame(
355378 first_layer = false ;
356379
357380 // Attach the ScenicLayer to the main scene graph.
358- root_node_ .AddChild (scenic_layer.shape_node );
381+ layer_tree_node_ .AddChild (scenic_layer.shape_node );
359382
360383 // Account for the ScenicLayer's height when positioning the next layer.
361384 scenic_layer_index++;
@@ -461,14 +484,12 @@ void FuchsiaExternalViewEmbedder::Reset() {
461484 frame_dpr_ = 1 .f ;
462485
463486 // Detach the root node to prepare for the next frame.
464- session_. get ()-> Enqueue ( scenic::NewDetachChildrenCmd (root_node_. id ()) );
487+ layer_tree_node_. DetachChildren ( );
465488
466489 // Clear images on all layers so they aren't cached unnecesarily.
467490 for (auto & layer : scenic_layers_) {
468491 layer.material .SetTexture (0 );
469492 }
470-
471- input_interceptor_.reset ();
472493}
473494
474495} // namespace flutter_runner
0 commit comments