Flutter Windows Embedder
flutter_windows_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 
7 #include <chrono>
8 
9 #include "flutter/common/constants.h"
10 #include "flutter/fml/platform/win/wstring_conversion.h"
14 #include "flutter/third_party/accessibility/ax/platform/ax_platform_node_win.h"
15 
16 namespace flutter {
17 
18 namespace {
19 // The maximum duration to block the platform thread for while waiting
20 // for a window resize operation to complete.
21 constexpr std::chrono::milliseconds kWindowResizeTimeout{100};
22 
23 /// Returns true if the surface will be updated as part of the resize process.
24 ///
25 /// This is called on window resize to determine if the platform thread needs
26 /// to be blocked until the frame with the right size has been rendered. It
27 /// should be kept in-sync with how the engine deals with a new surface request
28 /// as seen in `CreateOrUpdateSurface` in `GPUSurfaceGL`.
29 bool SurfaceWillUpdate(size_t cur_width,
30  size_t cur_height,
31  size_t target_width,
32  size_t target_height) {
33  // TODO (https://github.com/flutter/flutter/issues/65061) : Avoid special
34  // handling for zero dimensions.
35  bool non_zero_target_dims = target_height > 0 && target_width > 0;
36  bool not_same_size =
37  (cur_height != target_height) || (cur_width != target_width);
38  return non_zero_target_dims && not_same_size;
39 }
40 
41 /// Update the surface's swap interval to block until the v-blank iff
42 /// the system compositor is disabled.
43 void UpdateVsync(const FlutterWindowsEngine& engine,
44  egl::WindowSurface* surface,
45  bool needs_vsync) {
46  egl::Manager* egl_manager = engine.egl_manager();
47  if (!egl_manager) {
48  return;
49  }
50 
51  auto update_vsync = [egl_manager, surface, needs_vsync]() {
52  if (!surface || !surface->IsValid()) {
53  return;
54  }
55 
56  if (!surface->MakeCurrent()) {
57  FML_LOG(ERROR) << "Unable to make the render surface current to update "
58  "the swap interval";
59  return;
60  }
61 
62  if (!surface->SetVSyncEnabled(needs_vsync)) {
63  FML_LOG(ERROR) << "Unable to update the render surface's swap interval";
64  }
65 
66  if (!egl_manager->render_context()->ClearCurrent()) {
67  FML_LOG(ERROR) << "Unable to clear current surface after updating "
68  "the swap interval";
69  }
70  };
71 
72  // Updating the vsync makes the EGL context and render surface current.
73  // If the engine is running, the render surface should only be made current on
74  // the raster thread. If the engine is initializing, the raster thread doesn't
75  // exist yet and the render surface can be made current on the platform
76  // thread.
77  if (engine.running()) {
78  engine.PostRasterThreadTask(update_vsync);
79  } else {
80  update_vsync();
81  }
82 }
83 
84 } // namespace
85 
87  FlutterViewId view_id,
88  FlutterWindowsEngine* engine,
89  std::unique_ptr<WindowBindingHandler> window_binding,
90  std::shared_ptr<WindowsProcTable> windows_proc_table)
91  : view_id_(view_id),
92  engine_(engine),
93  windows_proc_table_(std::move(windows_proc_table)) {
94  if (windows_proc_table_ == nullptr) {
95  windows_proc_table_ = std::make_shared<WindowsProcTable>();
96  }
97 
98  // Take the binding handler, and give it a pointer back to self.
99  binding_handler_ = std::move(window_binding);
100  binding_handler_->SetView(this);
101 }
102 
104  // The view owns the child window.
105  // Notify the engine the view's child window will no longer be visible.
107 
108  // The engine renders into the view's surface. The engine must be
109  // shutdown before the view's resources can be destroyed.
110  engine_->Stop();
111 
113 }
114 
116  // Called on the raster thread.
117  std::unique_lock<std::mutex> lock(resize_mutex_);
118 
119  if (surface_ == nullptr || !surface_->IsValid()) {
120  return false;
121  }
122 
123  if (resize_status_ != ResizeState::kResizeStarted) {
124  return true;
125  }
126 
127  if (!ResizeRenderSurface(resize_target_height_, resize_target_width_)) {
128  return false;
129  }
130 
131  // Platform thread is blocked for the entire duration until the
132  // resize_status_ is set to kDone by |OnFramePresented|.
133  resize_status_ = ResizeState::kFrameGenerated;
134  return true;
135 }
136 
137 bool FlutterWindowsView::OnFrameGenerated(size_t width, size_t height) {
138  // Called on the raster thread.
139  std::unique_lock<std::mutex> lock(resize_mutex_);
140 
141  if (surface_ == nullptr || !surface_->IsValid()) {
142  return false;
143  }
144 
145  if (resize_status_ != ResizeState::kResizeStarted) {
146  return true;
147  }
148 
149  if (resize_target_width_ != width || resize_target_height_ != height) {
150  return false;
151  }
152 
153  if (!ResizeRenderSurface(resize_target_width_, resize_target_height_)) {
154  return false;
155  }
156 
157  // Platform thread is blocked for the entire duration until the
158  // resize_status_ is set to kDone by |OnFramePresented|.
159  resize_status_ = ResizeState::kFrameGenerated;
160  return true;
161 }
162 
163 void FlutterWindowsView::UpdateFlutterCursor(const std::string& cursor_name) {
164  binding_handler_->UpdateFlutterCursor(cursor_name);
165 }
166 
168  binding_handler_->SetFlutterCursor(cursor);
169 }
170 
172  if (resize_status_ == ResizeState::kDone) {
173  // Request new frame.
174  engine_->ScheduleFrame();
175  }
176 }
177 
178 bool FlutterWindowsView::OnWindowSizeChanged(size_t width, size_t height) {
179  // Called on the platform thread.
180  std::unique_lock<std::mutex> lock(resize_mutex_);
181 
182  if (!engine_->egl_manager()) {
183  SendWindowMetrics(width, height, binding_handler_->GetDpiScale());
184  return true;
185  }
186 
187  if (!surface_ || !surface_->IsValid()) {
188  SendWindowMetrics(width, height, binding_handler_->GetDpiScale());
189  return true;
190  }
191 
192  // We're using OpenGL rendering. Resizing the surface must happen on the
193  // raster thread.
194  bool surface_will_update =
195  SurfaceWillUpdate(surface_->width(), surface_->height(), width, height);
196  if (!surface_will_update) {
197  SendWindowMetrics(width, height, binding_handler_->GetDpiScale());
198  return true;
199  }
200 
201  resize_status_ = ResizeState::kResizeStarted;
202  resize_target_width_ = width;
203  resize_target_height_ = height;
204 
205  SendWindowMetrics(width, height, binding_handler_->GetDpiScale());
206 
207  // Block the platform thread until a frame is presented with the target
208  // size. See |OnFrameGenerated|, |OnEmptyFrameGenerated|, and
209  // |OnFramePresented|.
210  return resize_cv_.wait_for(lock, kWindowResizeTimeout,
211  [&resize_status = resize_status_] {
212  return resize_status == ResizeState::kDone;
213  });
214 }
215 
217  ForceRedraw();
218 }
219 
221  double y,
222  FlutterPointerDeviceKind device_kind,
223  int32_t device_id,
224  int modifiers_state) {
225  engine_->keyboard_key_handler()->SyncModifiersIfNeeded(modifiers_state);
226  SendPointerMove(x, y, GetOrCreatePointerState(device_kind, device_id));
227 }
228 
230  double x,
231  double y,
232  FlutterPointerDeviceKind device_kind,
233  int32_t device_id,
234  FlutterPointerMouseButtons flutter_button) {
235  if (flutter_button != 0) {
236  auto state = GetOrCreatePointerState(device_kind, device_id);
237  state->buttons |= flutter_button;
238  SendPointerDown(x, y, state);
239  }
240 }
241 
243  double x,
244  double y,
245  FlutterPointerDeviceKind device_kind,
246  int32_t device_id,
247  FlutterPointerMouseButtons flutter_button) {
248  if (flutter_button != 0) {
249  auto state = GetOrCreatePointerState(device_kind, device_id);
250  state->buttons &= ~flutter_button;
251  SendPointerUp(x, y, state);
252  }
253 }
254 
256  double y,
257  FlutterPointerDeviceKind device_kind,
258  int32_t device_id) {
259  SendPointerLeave(x, y, GetOrCreatePointerState(device_kind, device_id));
260 }
261 
263  PointerLocation point = binding_handler_->GetPrimaryPointerLocation();
264  SendPointerPanZoomStart(device_id, point.x, point.y);
265 }
266 
268  double pan_x,
269  double pan_y,
270  double scale,
271  double rotation) {
272  SendPointerPanZoomUpdate(device_id, pan_x, pan_y, scale, rotation);
273 }
274 
276  SendPointerPanZoomEnd(device_id);
277 }
278 
279 void FlutterWindowsView::OnText(const std::u16string& text) {
280  SendText(text);
281 }
282 
284  int scancode,
285  int action,
286  char32_t character,
287  bool extended,
288  bool was_down,
291 }
292 
294  SendComposeBegin();
295 }
296 
298  SendComposeCommit();
299 }
300 
302  SendComposeEnd();
303 }
304 
305 void FlutterWindowsView::OnComposeChange(const std::u16string& text,
306  int cursor_pos) {
307  SendComposeChange(text, cursor_pos);
308 }
309 
311  double y,
312  double delta_x,
313  double delta_y,
314  int scroll_offset_multiplier,
315  FlutterPointerDeviceKind device_kind,
316  int32_t device_id) {
317  SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier, device_kind,
318  device_id);
319 }
320 
322  PointerLocation point = binding_handler_->GetPrimaryPointerLocation();
323  SendScrollInertiaCancel(device_id, point.x, point.y);
324 }
325 
327  engine_->UpdateSemanticsEnabled(enabled);
328 }
329 
330 gfx::NativeViewAccessible FlutterWindowsView::GetNativeViewAccessible() {
331  if (!accessibility_bridge_) {
332  return nullptr;
333  }
334 
335  return accessibility_bridge_->GetChildOfAXFragmentRoot();
336 }
337 
339  binding_handler_->OnCursorRectUpdated(rect);
340 }
341 
343  binding_handler_->OnResetImeComposing();
344 }
345 
346 // Sends new size information to FlutterEngine.
347 void FlutterWindowsView::SendWindowMetrics(size_t width,
348  size_t height,
349  double dpiScale) const {
350  FlutterWindowMetricsEvent event = {};
351  event.struct_size = sizeof(event);
352  event.width = width;
353  event.height = height;
354  event.pixel_ratio = dpiScale;
355  engine_->SendWindowMetricsEvent(event);
356 }
357 
359  PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
360 
361  SendWindowMetrics(bounds.width, bounds.height,
362  binding_handler_->GetDpiScale());
363 }
364 
365 FlutterWindowsView::PointerState* FlutterWindowsView::GetOrCreatePointerState(
366  FlutterPointerDeviceKind device_kind,
367  int32_t device_id) {
368  // Create a virtual pointer ID that is unique across all device types
369  // to prevent pointers from clashing in the engine's converter
370  // (lib/ui/window/pointer_data_packet_converter.cc)
371  int32_t pointer_id = (static_cast<int32_t>(device_kind) << 28) | device_id;
372 
373  auto [it, added] = pointer_states_.try_emplace(pointer_id, nullptr);
374  if (added) {
375  auto state = std::make_unique<PointerState>();
376  state->device_kind = device_kind;
377  state->pointer_id = pointer_id;
378  it->second = std::move(state);
379  }
380 
381  return it->second.get();
382 }
383 
384 // Set's |event_data|'s phase to either kMove or kHover depending on the current
385 // primary mouse button state.
386 void FlutterWindowsView::SetEventPhaseFromCursorButtonState(
387  FlutterPointerEvent* event_data,
388  const PointerState* state) const {
389  // For details about this logic, see FlutterPointerPhase in the embedder.h
390  // file.
391  if (state->buttons == 0) {
392  event_data->phase = state->flutter_state_is_down
393  ? FlutterPointerPhase::kUp
394  : FlutterPointerPhase::kHover;
395  } else {
396  event_data->phase = state->flutter_state_is_down
397  ? FlutterPointerPhase::kMove
398  : FlutterPointerPhase::kDown;
399  }
400 }
401 
402 void FlutterWindowsView::SendPointerMove(double x,
403  double y,
404  PointerState* state) {
405  FlutterPointerEvent event = {};
406  event.x = x;
407  event.y = y;
408 
409  SetEventPhaseFromCursorButtonState(&event, state);
410  SendPointerEventWithData(event, state);
411 }
412 
413 void FlutterWindowsView::SendPointerDown(double x,
414  double y,
415  PointerState* state) {
416  FlutterPointerEvent event = {};
417  event.x = x;
418  event.y = y;
419 
420  SetEventPhaseFromCursorButtonState(&event, state);
421  SendPointerEventWithData(event, state);
422 
423  state->flutter_state_is_down = true;
424 }
425 
426 void FlutterWindowsView::SendPointerUp(double x,
427  double y,
428  PointerState* state) {
429  FlutterPointerEvent event = {};
430  event.x = x;
431  event.y = y;
432 
433  SetEventPhaseFromCursorButtonState(&event, state);
434  SendPointerEventWithData(event, state);
435  if (event.phase == FlutterPointerPhase::kUp) {
436  state->flutter_state_is_down = false;
437  }
438 }
439 
440 void FlutterWindowsView::SendPointerLeave(double x,
441  double y,
442  PointerState* state) {
443  FlutterPointerEvent event = {};
444  event.x = x;
445  event.y = y;
446  event.phase = FlutterPointerPhase::kRemove;
447  SendPointerEventWithData(event, state);
448 }
449 
450 void FlutterWindowsView::SendPointerPanZoomStart(int32_t device_id,
451  double x,
452  double y) {
453  auto state =
454  GetOrCreatePointerState(kFlutterPointerDeviceKindTrackpad, device_id);
455  state->pan_zoom_start_x = x;
456  state->pan_zoom_start_y = y;
457  FlutterPointerEvent event = {};
458  event.x = x;
459  event.y = y;
460  event.phase = FlutterPointerPhase::kPanZoomStart;
461  SendPointerEventWithData(event, state);
462 }
463 
464 void FlutterWindowsView::SendPointerPanZoomUpdate(int32_t device_id,
465  double pan_x,
466  double pan_y,
467  double scale,
468  double rotation) {
469  auto state =
470  GetOrCreatePointerState(kFlutterPointerDeviceKindTrackpad, device_id);
471  FlutterPointerEvent event = {};
472  event.x = state->pan_zoom_start_x;
473  event.y = state->pan_zoom_start_y;
474  event.pan_x = pan_x;
475  event.pan_y = pan_y;
476  event.scale = scale;
477  event.rotation = rotation;
478  event.phase = FlutterPointerPhase::kPanZoomUpdate;
479  SendPointerEventWithData(event, state);
480 }
481 
482 void FlutterWindowsView::SendPointerPanZoomEnd(int32_t device_id) {
483  auto state =
484  GetOrCreatePointerState(kFlutterPointerDeviceKindTrackpad, device_id);
485  FlutterPointerEvent event = {};
486  event.x = state->pan_zoom_start_x;
487  event.y = state->pan_zoom_start_y;
488  event.phase = FlutterPointerPhase::kPanZoomEnd;
489  SendPointerEventWithData(event, state);
490 }
491 
492 void FlutterWindowsView::SendText(const std::u16string& text) {
493  engine_->text_input_plugin()->TextHook(text);
494 }
495 
496 void FlutterWindowsView::SendKey(int key,
497  int scancode,
498  int action,
499  char32_t character,
500  bool extended,
501  bool was_down,
502  KeyEventCallback callback) {
505  [=, callback = std::move(callback)](bool handled) {
506  if (!handled) {
507  engine_->text_input_plugin()->KeyboardHook(
509  }
510  callback(handled);
511  });
512 }
513 
514 void FlutterWindowsView::SendComposeBegin() {
515  engine_->text_input_plugin()->ComposeBeginHook();
516 }
517 
518 void FlutterWindowsView::SendComposeCommit() {
519  engine_->text_input_plugin()->ComposeCommitHook();
520 }
521 
522 void FlutterWindowsView::SendComposeEnd() {
523  engine_->text_input_plugin()->ComposeEndHook();
524 }
525 
526 void FlutterWindowsView::SendComposeChange(const std::u16string& text,
527  int cursor_pos) {
528  engine_->text_input_plugin()->ComposeChangeHook(text, cursor_pos);
529 }
530 
531 void FlutterWindowsView::SendScroll(double x,
532  double y,
533  double delta_x,
534  double delta_y,
535  int scroll_offset_multiplier,
536  FlutterPointerDeviceKind device_kind,
537  int32_t device_id) {
538  auto state = GetOrCreatePointerState(device_kind, device_id);
539 
540  FlutterPointerEvent event = {};
541  event.x = x;
542  event.y = y;
543  event.signal_kind = FlutterPointerSignalKind::kFlutterPointerSignalKindScroll;
544  event.scroll_delta_x = delta_x * scroll_offset_multiplier;
545  event.scroll_delta_y = delta_y * scroll_offset_multiplier;
546  SetEventPhaseFromCursorButtonState(&event, state);
547  SendPointerEventWithData(event, state);
548 }
549 
550 void FlutterWindowsView::SendScrollInertiaCancel(int32_t device_id,
551  double x,
552  double y) {
553  auto state =
554  GetOrCreatePointerState(kFlutterPointerDeviceKindTrackpad, device_id);
555 
556  FlutterPointerEvent event = {};
557  event.x = x;
558  event.y = y;
559  event.signal_kind =
560  FlutterPointerSignalKind::kFlutterPointerSignalKindScrollInertiaCancel;
561  SetEventPhaseFromCursorButtonState(&event, state);
562  SendPointerEventWithData(event, state);
563 }
564 
565 void FlutterWindowsView::SendPointerEventWithData(
566  const FlutterPointerEvent& event_data,
567  PointerState* state) {
568  // If sending anything other than an add, and the pointer isn't already added,
569  // synthesize an add to satisfy Flutter's expectations about events.
570  if (!state->flutter_state_is_added &&
571  event_data.phase != FlutterPointerPhase::kAdd) {
572  FlutterPointerEvent event = {};
573  event.phase = FlutterPointerPhase::kAdd;
574  event.x = event_data.x;
575  event.y = event_data.y;
576  event.buttons = 0;
577  SendPointerEventWithData(event, state);
578  }
579 
580  // Don't double-add (e.g., if events are delivered out of order, so an add has
581  // already been synthesized).
582  if (state->flutter_state_is_added &&
583  event_data.phase == FlutterPointerPhase::kAdd) {
584  return;
585  }
586 
587  FlutterPointerEvent event = event_data;
588  event.device_kind = state->device_kind;
589  event.device = state->pointer_id;
590  event.buttons = state->buttons;
591  // TODO(dkwingsmt): Use the correct view ID for pointer events once the
592  // Windows embedder supports multiple views.
593  // https://github.com/flutter/flutter/issues/138179
594  event.view_id = flutter::kFlutterImplicitViewId;
595 
596  // Set metadata that's always the same regardless of the event.
597  event.struct_size = sizeof(event);
598  event.timestamp =
599  std::chrono::duration_cast<std::chrono::microseconds>(
600  std::chrono::high_resolution_clock::now().time_since_epoch())
601  .count();
602 
603  engine_->SendPointerEvent(event);
604 
605  if (event_data.phase == FlutterPointerPhase::kAdd) {
606  state->flutter_state_is_added = true;
607  } else if (event_data.phase == FlutterPointerPhase::kRemove) {
608  auto it = pointer_states_.find(state->pointer_id);
609  if (it != pointer_states_.end()) {
610  pointer_states_.erase(it);
611  }
612  }
613 }
614 
616  // Called on the engine's raster thread.
617  std::unique_lock<std::mutex> lock(resize_mutex_);
618 
619  switch (resize_status_) {
620  case ResizeState::kResizeStarted:
621  // The caller must first call |OnFrameGenerated| or
622  // |OnEmptyFrameGenerated| before calling this method. This
623  // indicates one of the following:
624  //
625  // 1. The caller did not call these methods.
626  // 2. The caller ignored these methods' result.
627  // 3. The platform thread started a resize after the caller called these
628  // methods. We might have presented a frame of the wrong size to the
629  // view.
630  return;
631  case ResizeState::kFrameGenerated: {
632  // A frame was generated for a pending resize.
633  // Unblock the platform thread.
634  resize_status_ = ResizeState::kDone;
635  lock.unlock();
636  resize_cv_.notify_all();
637 
638  // Blocking the raster thread until DWM flushes alleviates glitches where
639  // previous size surface is stretched over current size view.
640  windows_proc_table_->DwmFlush();
641  }
642  case ResizeState::kDone:
643  return;
644  }
645 }
646 
648  return binding_handler_->OnBitmapSurfaceCleared();
649 }
650 
651 bool FlutterWindowsView::PresentSoftwareBitmap(const void* allocation,
652  size_t row_bytes,
653  size_t height) {
654  return binding_handler_->OnBitmapSurfaceUpdated(allocation, row_bytes,
655  height);
656 }
657 
659  return view_id_;
660 }
661 
663  FML_DCHECK(surface_ == nullptr);
664 
665  if (engine_->egl_manager()) {
666  PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
667  surface_ = engine_->egl_manager()->CreateWindowSurface(
668  GetWindowHandle(), bounds.width, bounds.height);
669 
670  UpdateVsync(*engine_, surface_.get(), NeedsVsync());
671 
672  resize_target_width_ = bounds.width;
673  resize_target_height_ = bounds.height;
674  }
675 }
676 
677 bool FlutterWindowsView::ResizeRenderSurface(size_t width, size_t height) {
678  FML_DCHECK(surface_ != nullptr);
679 
680  // No-op if the surface is already the desired size.
681  if (width == surface_->width() && height == surface_->height()) {
682  return true;
683  }
684 
685  auto const existing_vsync = surface_->vsync_enabled();
686 
687  // TODO: Destroying the surface and re-creating it is expensive.
688  // Ideally this would use ANGLE's automatic surface sizing instead.
689  // See: https://github.com/flutter/flutter/issues/79427
690  if (!surface_->Destroy()) {
691  FML_LOG(ERROR) << "View resize failed to destroy surface";
692  return false;
693  }
694 
695  std::unique_ptr<egl::WindowSurface> resized_surface =
696  engine_->egl_manager()->CreateWindowSurface(GetWindowHandle(), width,
697  height);
698  if (!resized_surface) {
699  FML_LOG(ERROR) << "View resize failed to create surface";
700  return false;
701  }
702 
703  if (!resized_surface->MakeCurrent() ||
704  !resized_surface->SetVSyncEnabled(existing_vsync)) {
705  // Surfaces block until the v-blank by default.
706  // Failing to update the vsync might result in unnecessary blocking.
707  // This regresses performance but not correctness.
708  FML_LOG(ERROR) << "View resize failed to set vsync";
709  }
710 
711  surface_ = std::move(resized_surface);
712  return true;
713 }
714 
716  if (surface_) {
717  surface_->Destroy();
718  }
719 }
720 
722  return surface_.get();
723 }
724 
726  engine_->UpdateHighContrastMode();
727 }
728 
730  return binding_handler_->GetWindowHandle();
731 }
732 
734  return engine_;
735 }
736 
737 void FlutterWindowsView::AnnounceAlert(const std::wstring& text) {
738  auto alert_delegate = binding_handler_->GetAlertDelegate();
739  if (!alert_delegate) {
740  return;
741  }
742  alert_delegate->SetText(fml::WideStringToUtf16(text));
743  ui::AXPlatformNodeWin* alert_node = binding_handler_->GetAlert();
744  NotifyWinEventWrapper(alert_node, ax::mojom::Event::kAlert);
745 }
746 
747 void FlutterWindowsView::NotifyWinEventWrapper(ui::AXPlatformNodeWin* node,
748  ax::mojom::Event event) {
749  if (node) {
750  node->NotifyAccessibilityEvent(event);
751  }
752 }
753 
754 ui::AXFragmentRootDelegateWin* FlutterWindowsView::GetAxFragmentRootDelegate() {
755  return accessibility_bridge_.get();
756 }
757 
758 ui::AXPlatformNodeWin* FlutterWindowsView::AlertNode() const {
759  return binding_handler_->GetAlert();
760 }
761 
762 std::shared_ptr<AccessibilityBridgeWindows>
764  return std::make_shared<AccessibilityBridgeWindows>(this);
765 }
766 
768  if (semantics_enabled_ != enabled) {
769  semantics_enabled_ = enabled;
770 
771  if (!semantics_enabled_ && accessibility_bridge_) {
772  accessibility_bridge_.reset();
773  } else if (semantics_enabled_ && !accessibility_bridge_) {
774  accessibility_bridge_ = CreateAccessibilityBridge();
775  }
776  }
777 }
778 
780  UpdateVsync(*engine_, surface_.get(), NeedsVsync());
781 }
782 
784  engine_->OnWindowStateEvent(hwnd, event);
785 }
786 
787 bool FlutterWindowsView::NeedsVsync() const {
788  // If the Desktop Window Manager composition is enabled,
789  // the system itself synchronizes with vsync.
790  // See: https://learn.microsoft.com/windows/win32/dwm/composition-ovw
791  return !windows_proc_table_->DwmIsCompositionEnabled();
792 }
793 
794 } // namespace flutter
flutter::FlutterWindowsView::OnPointerMove
void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, int modifiers_state) override
Definition: flutter_windows_view.cc:220
flutter::TextInputPlugin::ComposeBeginHook
virtual void ComposeBeginHook()
Definition: text_input_plugin.cc:125
flutter::TextInputPlugin::ComposeChangeHook
virtual void ComposeChangeHook(const std::u16string &text, int cursor_pos)
Definition: text_input_plugin.cc:192
flutter::FlutterWindowsView::OnPointerUp
void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button) override
Definition: flutter_windows_view.cc:242
flutter::WindowStateEvent
WindowStateEvent
An event representing a change in window state that may update the.
Definition: windows_lifecycle_manager.h:24
flutter::FlutterWindowsView::OnWindowStateEvent
void OnWindowStateEvent(HWND hwnd, WindowStateEvent event) override
Definition: flutter_windows_view.cc:783
flutter::FlutterWindowsView::CreateRenderSurface
void CreateRenderSurface()
Definition: flutter_windows_view.cc:662
flutter::FlutterWindowsView::OnUpdateSemanticsEnabled
virtual void OnUpdateSemanticsEnabled(bool enabled) override
Definition: flutter_windows_view.cc:326
flutter::WindowStateEvent::kHide
@ kHide
flutter::FlutterWindowsView::FlutterWindowsView
FlutterWindowsView(FlutterViewId view_id, FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > window_binding, std::shared_ptr< WindowsProcTable > windows_proc_table=nullptr)
Definition: flutter_windows_view.cc:86
flutter::FlutterWindowsView::OnComposeCommit
void OnComposeCommit() override
Definition: flutter_windows_view.cc:297
flutter::FlutterWindowsEngine::SendPointerEvent
void SendPointerEvent(const FlutterPointerEvent &event)
Definition: flutter_windows_engine.cc:560
scancode
int scancode
Definition: keyboard_key_handler_unittests.cc:115
flutter::FlutterWindowsView::~FlutterWindowsView
virtual ~FlutterWindowsView()
Definition: flutter_windows_view.cc:103
was_down
bool was_down
Definition: keyboard_key_handler_unittests.cc:119
text_input_plugin.h
flutter::FlutterWindowsView::surface
egl::WindowSurface * surface() const
Definition: flutter_windows_view.cc:721
extended
bool extended
Definition: keyboard_key_handler_unittests.cc:118
flutter::egl::WindowSurface
Definition: window_surface.h:19
flutter::FlutterWindowsView::OnPointerDown
void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button) override
Definition: flutter_windows_view.cc:229
flutter::FlutterWindowsEngine
Definition: flutter_windows_engine.h:89
character
char32_t character
Definition: keyboard_key_handler_unittests.cc:117
flutter::FlutterWindowsView::OnComposeChange
void OnComposeChange(const std::u16string &text, int cursor_pos) override
Definition: flutter_windows_view.cc:305
flutter::TextInputPlugin::ComposeEndHook
virtual void ComposeEndHook()
Definition: text_input_plugin.cc:175
flutter::FlutterWindowsView::OnScrollInertiaCancel
void OnScrollInertiaCancel(int32_t device_id) override
Definition: flutter_windows_view.cc:321
flutter::FlutterWindowsView::ForceRedraw
void ForceRedraw()
Definition: flutter_windows_view.cc:171
flutter::FlutterWindowsView::DestroyRenderSurface
void DestroyRenderSurface()
Definition: flutter_windows_view.cc:715
flutter::FlutterWindowsView::OnPointerPanZoomStart
virtual void OnPointerPanZoomStart(int32_t device_id) override
Definition: flutter_windows_view.cc:262
flutter::TextInputPlugin::ComposeCommitHook
virtual void ComposeCommitHook()
Definition: text_input_plugin.cc:140
flutter::Rect
Definition: geometry.h:56
flutter::PhysicalWindowBounds::width
size_t width
Definition: window_binding_handler.h:28
flutter::PhysicalWindowBounds
Definition: window_binding_handler.h:27
flutter::PointerLocation
Definition: window_binding_handler.h:34
flutter::FlutterWindowsView::AnnounceAlert
void AnnounceAlert(const std::wstring &text)
Definition: flutter_windows_view.cc:737
flutter::FlutterWindowsView::GetWindowHandle
virtual HWND GetWindowHandle() const
Definition: flutter_windows_view.cc:729
flutter::FlutterWindowsView::OnPointerPanZoomUpdate
virtual void OnPointerPanZoomUpdate(int32_t device_id, double pan_x, double pan_y, double scale, double rotation) override
Definition: flutter_windows_view.cc:267
flutter::FlutterWindowsView::OnWindowRepaint
void OnWindowRepaint() override
Definition: flutter_windows_view.cc:216
flutter::FlutterWindowsEngine::Stop
virtual bool Stop()
Definition: flutter_windows_engine.cc:479
flutter::WindowBindingHandlerDelegate::KeyEventCallback
std::function< void(bool)> KeyEventCallback
Definition: window_binding_handler_delegate.h:20
flutter::FlutterWindowsView::OnComposeEnd
void OnComposeEnd() override
Definition: flutter_windows_view.cc:301
flutter::PointerLocation::y
size_t y
Definition: window_binding_handler.h:36
flutter_windows_view.h
text
std::u16string text
Definition: keyboard_unittests.cc:332
flutter::FlutterWindowsEngine::SendWindowMetricsEvent
void SendWindowMetricsEvent(const FlutterWindowMetricsEvent &event)
Definition: flutter_windows_engine.cc:553
flutter::TextInputPlugin::TextHook
virtual void TextHook(const std::u16string &text)
Definition: text_input_plugin.cc:67
flutter::FlutterWindowsView::view_id
FlutterViewId view_id() const
Definition: flutter_windows_view.cc:658
flutter::KeyboardHandlerBase::SyncModifiersIfNeeded
virtual void SyncModifiersIfNeeded(int modifiers_state)=0
flutter::FlutterWindowsView::OnHighContrastChanged
void OnHighContrastChanged() override
Definition: flutter_windows_view.cc:725
flutter::FlutterWindowsView::OnWindowSizeChanged
bool OnWindowSizeChanged(size_t width, size_t height) override
Definition: flutter_windows_view.cc:178
flutter::FlutterViewId
int64_t FlutterViewId
Definition: flutter_view.h:13
flutter::FlutterWindowsView::OnFrameGenerated
bool OnFrameGenerated(size_t width, size_t height)
Definition: flutter_windows_view.cc:137
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::FlutterWindowsView::UpdateFlutterCursor
void UpdateFlutterCursor(const std::string &cursor_name)
Definition: flutter_windows_view.cc:163
flutter::FlutterWindowsView::SetFlutterCursor
void SetFlutterCursor(HCURSOR cursor)
Definition: flutter_windows_view.cc:167
flutter::FlutterWindowsView::OnPointerLeave
void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id=0) override
Definition: flutter_windows_view.cc:255
flutter::FlutterWindowsView::OnText
void OnText(const std::u16string &) override
Definition: flutter_windows_view.cc:279
flutter::FlutterWindowsEngine::keyboard_key_handler
KeyboardHandlerBase * keyboard_key_handler()
Definition: flutter_windows_engine.h:176
flutter::FlutterWindowsView::PresentSoftwareBitmap
virtual bool PresentSoftwareBitmap(const void *allocation, size_t row_bytes, size_t height)
Definition: flutter_windows_view.cc:651
flutter::FlutterWindowsView::OnCursorRectUpdated
virtual void OnCursorRectUpdated(const Rect &rect)
Definition: flutter_windows_view.cc:338
flutter::FlutterWindowsView::AlertNode
ui::AXPlatformNodeWin * AlertNode() const
Definition: flutter_windows_view.cc:758
flutter::FlutterWindowsView::GetEngine
FlutterWindowsEngine * GetEngine() const
Definition: flutter_windows_view.cc:733
flutter::FlutterWindowsEngine::text_input_plugin
TextInputPlugin * text_input_plugin()
Definition: flutter_windows_engine.h:179
flutter::FlutterWindowsView::OnPointerPanZoomEnd
virtual void OnPointerPanZoomEnd(int32_t device_id) override
Definition: flutter_windows_view.cc:275
flutter::FlutterWindowsView::OnDwmCompositionChanged
void OnDwmCompositionChanged()
Definition: flutter_windows_view.cc:779
flutter::FlutterWindowsView::NotifyWinEventWrapper
virtual void NotifyWinEventWrapper(ui::AXPlatformNodeWin *node, ax::mojom::Event event)
Definition: flutter_windows_view.cc:747
flutter::FlutterWindowsEngine::ScheduleFrame
void ScheduleFrame()
Definition: flutter_windows_engine.cc:633
flutter::FlutterWindowsEngine::UpdateHighContrastMode
void UpdateHighContrastMode()
Definition: flutter_windows_engine.cc:799
flutter::FlutterWindowsView::OnEmptyFrameGenerated
bool OnEmptyFrameGenerated()
Definition: flutter_windows_view.cc:115
flutter::FlutterWindowsView::ClearSoftwareBitmap
virtual bool ClearSoftwareBitmap()
Definition: flutter_windows_view.cc:647
flutter::PhysicalWindowBounds::height
size_t height
Definition: window_binding_handler.h:29
flutter::FlutterWindowsView::UpdateSemanticsEnabled
virtual void UpdateSemanticsEnabled(bool enabled)
Definition: flutter_windows_view.cc:767
flutter::FlutterWindowsView::OnComposeBegin
void OnComposeBegin() override
Definition: flutter_windows_view.cc:293
flutter::FlutterWindowsView::SendInitialBounds
void SendInitialBounds()
Definition: flutter_windows_view.cc:358
flutter::FlutterWindowsView::CreateAccessibilityBridge
virtual std::shared_ptr< AccessibilityBridgeWindows > CreateAccessibilityBridge()
Definition: flutter_windows_view.cc:763
action
int action
Definition: keyboard_key_handler_unittests.cc:116
flutter::FlutterWindowsView::OnScroll
void OnScroll(double x, double y, double delta_x, double delta_y, int scroll_offset_multiplier, FlutterPointerDeviceKind device_kind, int32_t device_id) override
Definition: flutter_windows_view.cc:310
flutter::FlutterWindowsEngine::UpdateSemanticsEnabled
void UpdateSemanticsEnabled(bool enabled)
Definition: flutter_windows_engine.cc:764
flutter::PointerLocation::x
size_t x
Definition: window_binding_handler.h:35
flutter::FlutterWindowsView::GetAxFragmentRootDelegate
virtual ui::AXFragmentRootDelegateWin * GetAxFragmentRootDelegate() override
Definition: flutter_windows_view.cc:754
flutter::FlutterWindowsEngine::egl_manager
egl::Manager * egl_manager() const
Definition: flutter_windows_engine.h:159
key
int key
Definition: keyboard_key_handler_unittests.cc:114
accessibility_bridge.h
flutter::FlutterWindowsEngine::OnWindowStateEvent
void OnWindowStateEvent(HWND hwnd, WindowStateEvent event)
Definition: flutter_windows_engine.cc:838
keyboard_key_channel_handler.h
flutter::FlutterWindowsView::OnKey
void OnKey(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback) override
Definition: flutter_windows_view.cc:283
flutter::KeyboardHandlerBase::KeyboardHook
virtual void KeyboardHook(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback)=0
flutter::FlutterWindowsView::GetNativeViewAccessible
virtual gfx::NativeViewAccessible GetNativeViewAccessible() override
Definition: flutter_windows_view.cc:330
flutter::FlutterWindowsView::OnResetImeComposing
virtual void OnResetImeComposing()
Definition: flutter_windows_view.cc:342
flutter::egl::Manager::CreateWindowSurface
virtual std::unique_ptr< WindowSurface > CreateWindowSurface(HWND hwnd, size_t width, size_t height)
Definition: manager.cc:266
flutter::FlutterWindowsView::OnFramePresented
virtual void OnFramePresented()
Definition: flutter_windows_view.cc:615
callback
FlutterDesktopBinaryReply callback
Definition: flutter_windows_view_unittests.cc:51