| 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
5 #include "flutter/shell/platform/windows/flutter_windows_view.h"
6
7 #include <chrono>
8
9 #include "flutter/common/constants.h"
10 #include "flutter/fml/platform/win/wstring_conversion.h"
11 #include "flutter/shell/platform/common/accessibility_bridge.h"
12 #include "flutter/shell/platform/windows/keyboard_key_channel_handler.h"
13 #include "flutter/shell/platform/windows/text_input_plugin.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, bool needs_vsync) {
44 AngleSurfaceManager* surface_manager = engine.surface_manager();
45 if (!surface_manager) {
46 return;
47 }
48
49 // Updating the vsync makes the EGL context and render surface current.
50 // If the engine is running, the render surface should only be made current on
51 // the raster thread. If the engine is initializing, the raster thread doesn't
52 // exist yet and the render surface can be made current on the platform
53 // thread.
54 if (engine.running()) {
55 engine.PostRasterThreadTask([surface_manager, needs_vsync]() {
56 surface_manager->SetVSyncEnabled(needs_vsync);
57 });
58 } else {
59 surface_manager->SetVSyncEnabled(needs_vsync);
60
61 // Release the EGL context so that the raster thread can use it.
62 if (!surface_manager->ClearCurrent()) {
63 FML_LOG(ERROR)
64 << "Unable to clear current surface after updating the swap interval";
65 return;
66 }
67 }
68 }
69
70 } // namespace
71
72 FlutterWindowsView::FlutterWindowsView(
73 std::unique_ptr<WindowBindingHandler> window_binding,
74 std::shared_ptr<WindowsProcTable> windows_proc_table)
75 : windows_proc_table_(std::move(windows_proc_table)) {
76 if (windows_proc_table_ == nullptr) {
77 windows_proc_table_ = std::make_shared<WindowsProcTable>();
78 }
79
80 // Take the binding handler, and give it a pointer back to self.
81 binding_handler_ = std::move(window_binding);
82 binding_handler_->SetView(this);
83 }
84
85 FlutterWindowsView::~FlutterWindowsView() {
86 // The engine renders into the view's surface. The engine must be
87 // shutdown before the view's resources can be destroyed.
88 if (engine_) {
89 engine_->Stop();
90 }
91
92 DestroyRenderSurface();
93 }
94
95 void FlutterWindowsView::SetEngine(FlutterWindowsEngine* engine) {
96 FML_DCHECK(engine_ == nullptr);
97 FML_DCHECK(engine != nullptr);
98
99 engine_ = engine;
100
101 engine_->SetView(this);
102
103 PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
104
105 SendWindowMetrics(bounds.width, bounds.height,
106 binding_handler_->GetDpiScale());
107 }
108
109 uint32_t FlutterWindowsView::GetFrameBufferId(size_t width, size_t height) {
110 // Called on an engine-controlled (non-platform) thread.
111 std::unique_lock<std::mutex> lock(resize_mutex_);
112
113 if (resize_status_ != ResizeState::kResizeStarted) {
114 return kWindowFrameBufferID;
115 }
116
117 if (resize_target_width_ == width && resize_target_height_ == height) {
118 // Platform thread is blocked for the entire duration until the
119 // resize_status_ is set to kDone.
120 engine_->surface_manager()->ResizeSurface(GetWindowHandle(), width, height,
121 NeedsVsync());
122 resize_status_ = ResizeState::kFrameGenerated;
123 }
124
125 return kWindowFrameBufferID;
126 }
127
128 void FlutterWindowsView::UpdateFlutterCursor(const std::string& cursor_name) {
129 binding_handler_->UpdateFlutterCursor(cursor_name);
130 }
131
132 void FlutterWindowsView::SetFlutterCursor(HCURSOR cursor) {
133 binding_handler_->SetFlutterCursor(cursor);
134 }
135
136 void FlutterWindowsView::ForceRedraw() {
137 if (resize_status_ == ResizeState::kDone) {
138 // Request new frame.
139 engine_->ScheduleFrame();
140 }
141 }
142
143 void FlutterWindowsView::OnWindowSizeChanged(size_t width, size_t height) {
144 // Called on the platform thread.
145 std::unique_lock<std::mutex> lock(resize_mutex_);
146
147 if (!engine_->surface_manager()) {
148 SendWindowMetrics(width, height, binding_handler_->GetDpiScale());
149 return;
150 }
151
152 EGLint surface_width, surface_height;
153 engine_->surface_manager()->GetSurfaceDimensions(&surface_width,
154 &surface_height);
155
156 bool surface_will_update =
157 SurfaceWillUpdate(surface_width, surface_height, width, height);
158 if (surface_will_update) {
159 resize_status_ = ResizeState::kResizeStarted;
160 resize_target_width_ = width;
161 resize_target_height_ = height;
162 }
163
164 SendWindowMetrics(width, height, binding_handler_->GetDpiScale());
165
166 if (surface_will_update) {
167 // Block the platform thread until:
168 // 1. GetFrameBufferId is called with the right frame size.
169 // 2. Any pending SwapBuffers calls have been invoked.
170 resize_cv_.wait_for(lock, kWindowResizeTimeout,
171 [&resize_status = resize_status_] {
172 return resize_status == ResizeState::kDone;
173 });
174 }
175 }
176
177 void FlutterWindowsView::OnWindowRepaint() {
178 ForceRedraw();
179 }
180
181 void FlutterWindowsView::OnPointerMove(double x,
182 double y,
183 FlutterPointerDeviceKind device_kind,
184 int32_t device_id,
185 int modifiers_state) {
186 engine_->keyboard_key_handler()->SyncModifiersIfNeeded(modifiers_state);
187 SendPointerMove(x, y, GetOrCreatePointerState(device_kind, device_id));
188 }
189
190 void FlutterWindowsView::OnPointerDown(
191 double x,
192 double y,
193 FlutterPointerDeviceKind device_kind,
194 int32_t device_id,
195 FlutterPointerMouseButtons flutter_button) {
196 if (flutter_button != 0) {
197 auto state = GetOrCreatePointerState(device_kind, device_id);
198 state->buttons |= flutter_button;
199 SendPointerDown(x, y, state);
200 }
201 }
202
203 void FlutterWindowsView::OnPointerUp(
204 double x,
205 double y,
206 FlutterPointerDeviceKind device_kind,
207 int32_t device_id,
208 FlutterPointerMouseButtons flutter_button) {
209 if (flutter_button != 0) {
210 auto state = GetOrCreatePointerState(device_kind, device_id);
211 state->buttons &= ~flutter_button;
212 SendPointerUp(x, y, state);
213 }
214 }
215
216 void FlutterWindowsView::OnPointerLeave(double x,
217 double y,
218 FlutterPointerDeviceKind device_kind,
219 int32_t device_id) {
220 SendPointerLeave(x, y, GetOrCreatePointerState(device_kind, device_id));
221 }
222
223 void FlutterWindowsView::OnPointerPanZoomStart(int32_t device_id) {
224 PointerLocation point = binding_handler_->GetPrimaryPointerLocation();
225 SendPointerPanZoomStart(device_id, point.x, point.y);
226 }
227
228 void FlutterWindowsView::OnPointerPanZoomUpdate(int32_t device_id,
229 double pan_x,
230 double pan_y,
231 double scale,
232 double rotation) {
233 SendPointerPanZoomUpdate(device_id, pan_x, pan_y, scale, rotation);
234 }
235
236 void FlutterWindowsView::OnPointerPanZoomEnd(int32_t device_id) {
237 SendPointerPanZoomEnd(device_id);
238 }
239
240 void FlutterWindowsView::OnText(const std::u16string& text) {
241 SendText(text);
242 }
243
244 void FlutterWindowsView::OnKey(int key,
245 int scancode,
246 int action,
247 char32_t character,
248 bool extended,
249 bool was_down,
250 KeyEventCallback callback) {
251 SendKey(key, scancode, action, character, extended, was_down, callback);
252 }
253
254 void FlutterWindowsView::OnComposeBegin() {
255 SendComposeBegin();
256 }
257
258 void FlutterWindowsView::OnComposeCommit() {
259 SendComposeCommit();
260 }
261
262 void FlutterWindowsView::OnComposeEnd() {
263 SendComposeEnd();
264 }
265
266 void FlutterWindowsView::OnComposeChange(const std::u16string& text,
267 int cursor_pos) {
268 SendComposeChange(text, cursor_pos);
269 }
270
271 void FlutterWindowsView::OnScroll(double x,
272 double y,
273 double delta_x,
274 double delta_y,
275 int scroll_offset_multiplier,
276 FlutterPointerDeviceKind device_kind,
277 int32_t device_id) {
278 SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier, device_kind,
279 device_id);
280 }
281
282 void FlutterWindowsView::OnScrollInertiaCancel(int32_t device_id) {
283 PointerLocation point = binding_handler_->GetPrimaryPointerLocation();
284 SendScrollInertiaCancel(device_id, point.x, point.y);
285 }
286
287 void FlutterWindowsView::OnUpdateSemanticsEnabled(bool enabled) {
288 engine_->UpdateSemanticsEnabled(enabled);
289 }
290
291 gfx::NativeViewAccessible FlutterWindowsView::GetNativeViewAccessible() {
292 if (!accessibility_bridge_) {
293 return nullptr;
294 }
295
296 return accessibility_bridge_->GetChildOfAXFragmentRoot();
297 }
298
299 void FlutterWindowsView::OnCursorRectUpdated(const Rect& rect) {
300 binding_handler_->OnCursorRectUpdated(rect);
301 }
302
303 void FlutterWindowsView::OnResetImeComposing() {
304 binding_handler_->OnResetImeComposing();
305 }
306
307 // Sends new size information to FlutterEngine.
308 void FlutterWindowsView::SendWindowMetrics(size_t width,
309 size_t height,
310 double dpiScale) const {
311 FlutterWindowMetricsEvent event = {};
312 event.struct_size = sizeof(event);
313 event.width = width;
314 event.height = height;
315 event.pixel_ratio = dpiScale;
316 engine_->SendWindowMetricsEvent(event);
317 }
318
319 void FlutterWindowsView::SendInitialBounds() {
320 PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
321
322 SendWindowMetrics(bounds.width, bounds.height,
323 binding_handler_->GetDpiScale());
324 }
325
326 FlutterWindowsView::PointerState* FlutterWindowsView::GetOrCreatePointerState(
327 FlutterPointerDeviceKind device_kind,
328 int32_t device_id) {
329 // Create a virtual pointer ID that is unique across all device types
330 // to prevent pointers from clashing in the engine's converter
331 // (lib/ui/window/pointer_data_packet_converter.cc)
332 int32_t pointer_id = (static_cast<int32_t>(device_kind) << 28) | device_id;
333
334 auto [it, added] = pointer_states_.try_emplace(pointer_id, nullptr);
335 if (added) {
336 auto state = std::make_unique<PointerState>();
337 state->device_kind = device_kind;
338 state->pointer_id = pointer_id;
339 it->second = std::move(state);
340 }
341
342 return it->second.get();
343 }
344
345 // Set's |event_data|'s phase to either kMove or kHover depending on the current
346 // primary mouse button state.
347 void FlutterWindowsView::SetEventPhaseFromCursorButtonState(
348 FlutterPointerEvent* event_data,
349 const PointerState* state) const {
350 // For details about this logic, see FlutterPointerPhase in the embedder.h
351 // file.
352 if (state->buttons == 0) {
353 event_data->phase = state->flutter_state_is_down
354 ? FlutterPointerPhase::kUp
355 : FlutterPointerPhase::kHover;
356 } else {
357 event_data->phase = state->flutter_state_is_down
358 ? FlutterPointerPhase::kMove
359 : FlutterPointerPhase::kDown;
360 }
361 }
362
363 void FlutterWindowsView::SendPointerMove(double x,
364 double y,
365 PointerState* state) {
366 FlutterPointerEvent event = {};
367 event.x = x;
368 event.y = y;
369
370 SetEventPhaseFromCursorButtonState(&event, state);
371 SendPointerEventWithData(event, state);
372 }
373
374 void FlutterWindowsView::SendPointerDown(double x,
375 double y,
376 PointerState* state) {
377 FlutterPointerEvent event = {};
378 event.x = x;
379 event.y = y;
380
381 SetEventPhaseFromCursorButtonState(&event, state);
382 SendPointerEventWithData(event, state);
383
384 state->flutter_state_is_down = true;
385 }
386
387 void FlutterWindowsView::SendPointerUp(double x,
388 double y,
389 PointerState* state) {
390 FlutterPointerEvent event = {};
391 event.x = x;
392 event.y = y;
393
394 SetEventPhaseFromCursorButtonState(&event, state);
395 SendPointerEventWithData(event, state);
396 if (event.phase == FlutterPointerPhase::kUp) {
397 state->flutter_state_is_down = false;
398 }
399 }
400
401 void FlutterWindowsView::SendPointerLeave(double x,
402 double y,
403 PointerState* state) {
404 FlutterPointerEvent event = {};
405 event.x = x;
406 event.y = y;
407 event.phase = FlutterPointerPhase::kRemove;
408 SendPointerEventWithData(event, state);
409 }
410
411 void FlutterWindowsView::SendPointerPanZoomStart(int32_t device_id,
412 double x,
413 double y) {
414 auto state =
415 GetOrCreatePointerState(kFlutterPointerDeviceKindTrackpad, device_id);
416 state->pan_zoom_start_x = x;
417 state->pan_zoom_start_y = y;
418 FlutterPointerEvent event = {};
419 event.x = x;
420 event.y = y;
421 event.phase = FlutterPointerPhase::kPanZoomStart;
422 SendPointerEventWithData(event, state);
423 }
424
425 void FlutterWindowsView::SendPointerPanZoomUpdate(int32_t device_id,
426 double pan_x,
427 double pan_y,
428 double scale,
429 double rotation) {
430 auto state =
431 GetOrCreatePointerState(kFlutterPointerDeviceKindTrackpad, device_id);
432 FlutterPointerEvent event = {};
433 event.x = state->pan_zoom_start_x;
434 event.y = state->pan_zoom_start_y;
435 event.pan_x = pan_x;
436 event.pan_y = pan_y;
437 event.scale = scale;
438 event.rotation = rotation;
439 event.phase = FlutterPointerPhase::kPanZoomUpdate;
440 SendPointerEventWithData(event, state);
441 }
442
443 void FlutterWindowsView::SendPointerPanZoomEnd(int32_t device_id) {
444 auto state =
445 GetOrCreatePointerState(kFlutterPointerDeviceKindTrackpad, device_id);
446 FlutterPointerEvent event = {};
447 event.x = state->pan_zoom_start_x;
448 event.y = state->pan_zoom_start_y;
449 event.phase = FlutterPointerPhase::kPanZoomEnd;
450 SendPointerEventWithData(event, state);
451 }
452
453 void FlutterWindowsView::SendText(const std::u16string& text) {
454 engine_->text_input_plugin()->TextHook(text);
455 }
456
457 void FlutterWindowsView::SendKey(int key,
458 int scancode,
459 int action,
460 char32_t character,
461 bool extended,
462 bool was_down,
463 KeyEventCallback callback) {
464 engine_->keyboard_key_handler()->KeyboardHook(
465 key, scancode, action, character, extended, was_down,
466 [=, callback = std::move(callback)](bool handled) {
467 if (!handled) {
468 engine_->text_input_plugin()->KeyboardHook(
469 key, scancode, action, character, extended, was_down);
470 }
471 callback(handled);
472 });
473 }
474
475 void FlutterWindowsView::SendComposeBegin() {
476 engine_->text_input_plugin()->ComposeBeginHook();
477 }
478
479 void FlutterWindowsView::SendComposeCommit() {
480 engine_->text_input_plugin()->ComposeCommitHook();
481 }
482
483 void FlutterWindowsView::SendComposeEnd() {
484 engine_->text_input_plugin()->ComposeEndHook();
485 }
486
487 void FlutterWindowsView::SendComposeChange(const std::u16string& text,
488 int cursor_pos) {
489 engine_->text_input_plugin()->ComposeChangeHook(text, cursor_pos);
490 }
491
492 void FlutterWindowsView::SendScroll(double x,
493 double y,
494 double delta_x,
495 double delta_y,
496 int scroll_offset_multiplier,
497 FlutterPointerDeviceKind device_kind,
498 int32_t device_id) {
499 auto state = GetOrCreatePointerState(device_kind, device_id);
500
501 FlutterPointerEvent event = {};
502 event.x = x;
503 event.y = y;
504 event.signal_kind = FlutterPointerSignalKind::kFlutterPointerSignalKindScroll;
505 event.scroll_delta_x = delta_x * scroll_offset_multiplier;
506 event.scroll_delta_y = delta_y * scroll_offset_multiplier;
507 SetEventPhaseFromCursorButtonState(&event, state);
508 SendPointerEventWithData(event, state);
509 }
510
511 void FlutterWindowsView::SendScrollInertiaCancel(int32_t device_id,
512 double x,
513 double y) {
514 auto state =
515 GetOrCreatePointerState(kFlutterPointerDeviceKindTrackpad, device_id);
516
517 FlutterPointerEvent event = {};
518 event.x = x;
519 event.y = y;
520 event.signal_kind =
521 FlutterPointerSignalKind::kFlutterPointerSignalKindScrollInertiaCancel;
522 SetEventPhaseFromCursorButtonState(&event, state);
523 SendPointerEventWithData(event, state);
524 }
525
526 void FlutterWindowsView::SendPointerEventWithData(
527 const FlutterPointerEvent& event_data,
528 PointerState* state) {
529 // If sending anything other than an add, and the pointer isn't already added,
530 // synthesize an add to satisfy Flutter's expectations about events.
531 if (!state->flutter_state_is_added &&
532 event_data.phase != FlutterPointerPhase::kAdd) {
533 FlutterPointerEvent event = {};
534 event.phase = FlutterPointerPhase::kAdd;
535 event.x = event_data.x;
536 event.y = event_data.y;
537 event.buttons = 0;
538 SendPointerEventWithData(event, state);
539 }
540
541 // Don't double-add (e.g., if events are delivered out of order, so an add has
542 // already been synthesized).
543 if (state->flutter_state_is_added &&
544 event_data.phase == FlutterPointerPhase::kAdd) {
545 return;
546 }
547
548 FlutterPointerEvent event = event_data;
549 event.device_kind = state->device_kind;
550 event.device = state->pointer_id;
551 event.buttons = state->buttons;
552 // TODO(dkwingsmt): Use the correct view ID for pointer events once the
553 // Windows embedder supports multiple views.
554 // https://github.com/flutter/flutter/issues/138179
555 event.view_id = flutter::kFlutterImplicitViewId;
556
557 // Set metadata that's always the same regardless of the event.
558 event.struct_size = sizeof(event);
559 event.timestamp =
560 std::chrono::duration_cast<std::chrono::microseconds>(
561 std::chrono::high_resolution_clock::now().time_since_epoch())
562 .count();
563
564 engine_->SendPointerEvent(event);
565
566 if (event_data.phase == FlutterPointerPhase::kAdd) {
567 state->flutter_state_is_added = true;
568 } else if (event_data.phase == FlutterPointerPhase::kRemove) {
569 auto it = pointer_states_.find(state->pointer_id);
570 if (it != pointer_states_.end()) {
571 pointer_states_.erase(it);
572 }
573 }
574 }
575
576 bool FlutterWindowsView::SwapBuffers() {
577 // Called on an engine-controlled (non-platform) thread.
578 std::unique_lock<std::mutex> lock(resize_mutex_);
579
580 switch (resize_status_) {
581 // SwapBuffer requests during resize are ignored until the frame with the
582 // right dimensions has been generated. This is marked with
583 // kFrameGenerated resize status.
584 case ResizeState::kResizeStarted:
585 return false;
586 case ResizeState::kFrameGenerated: {
587 bool visible = binding_handler_->IsVisible();
588 bool swap_buffers_result;
589 // For visible windows swap the buffers while resize handler is waiting.
590 // For invisible windows unblock the handler first and then swap buffers.
591 // SwapBuffers waits for vsync and there's no point doing that for
592 // invisible windows.
593 if (visible) {
594 swap_buffers_result = engine_->surface_manager()->SwapBuffers();
595 }
596 resize_status_ = ResizeState::kDone;
597 lock.unlock();
598 resize_cv_.notify_all();
599
600 // Blocking the raster thread until DWM flushes alleviates glitches where
601 // previous size surface is stretched over current size view.
602 windows_proc_table_->DwmFlush();
603
604 if (!visible) {
605 swap_buffers_result = engine_->surface_manager()->SwapBuffers();
606 }
607 return swap_buffers_result;
608 }
609 case ResizeState::kDone:
610 default:
611 return engine_->surface_manager()->SwapBuffers();
612 }
613 }
614
615 bool FlutterWindowsView::PresentSoftwareBitmap(const void* allocation,
616 size_t row_bytes,
617 size_t height) {
618 return binding_handler_->OnBitmapSurfaceUpdated(allocation, row_bytes,
619 height);
620 }
621
622 void FlutterWindowsView::CreateRenderSurface() {
623 if (engine_ && engine_->surface_manager()) {
624 PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
625 engine_->surface_manager()->CreateSurface(GetWindowHandle(), bounds.width,
626 bounds.height);
627
628 UpdateVsync(*engine_, NeedsVsync());
629
630 resize_target_width_ = bounds.width;
631 resize_target_height_ = bounds.height;
632 }
633 }
634
635 void FlutterWindowsView::DestroyRenderSurface() {
636 if (engine_ && engine_->surface_manager()) {
637 engine_->surface_manager()->DestroySurface();
638 }
639 }
640
641 void FlutterWindowsView::OnHighContrastChanged() {
642 engine_->UpdateHighContrastMode();
643 }
644
645 HWND FlutterWindowsView::GetWindowHandle() const {
646 return binding_handler_->GetWindowHandle();
647 }
648
649 FlutterWindowsEngine* FlutterWindowsView::GetEngine() {
650 return engine_;
651 }
652
653 void FlutterWindowsView::AnnounceAlert(const std::wstring& text) {
654 auto alert_delegate = binding_handler_->GetAlertDelegate();
655 if (!alert_delegate) {
656 return;
657 }
658 alert_delegate->SetText(fml::WideStringToUtf16(text));
659 ui::AXPlatformNodeWin* alert_node = binding_handler_->GetAlert();
660 NotifyWinEventWrapper(alert_node, ax::mojom::Event::kAlert);
661 }
662
663 void FlutterWindowsView::NotifyWinEventWrapper(ui::AXPlatformNodeWin* node,
664 ax::mojom::Event event) {
665 if (node) {
666 node->NotifyAccessibilityEvent(event);
667 }
668 }
669
670 ui::AXFragmentRootDelegateWin* FlutterWindowsView::GetAxFragmentRootDelegate() {
671 return accessibility_bridge_.get();
672 }
673
674 ui::AXPlatformNodeWin* FlutterWindowsView::AlertNode() const {
675 return binding_handler_->GetAlert();
676 }
677
678 std::shared_ptr<AccessibilityBridgeWindows>
679 FlutterWindowsView::CreateAccessibilityBridge() {
680 return std::make_shared<AccessibilityBridgeWindows>(this);
681 }
682
683 void FlutterWindowsView::UpdateSemanticsEnabled(bool enabled) {
684 if (semantics_enabled_ != enabled) {
685 semantics_enabled_ = enabled;
686
687 if (!semantics_enabled_ && accessibility_bridge_) {
688 accessibility_bridge_.reset();
689 } else if (semantics_enabled_ && !accessibility_bridge_) {
690 accessibility_bridge_ = CreateAccessibilityBridge();
691 }
692 }
693 }
694
695 void FlutterWindowsView::OnDwmCompositionChanged() {
696 UpdateVsync(*engine_, NeedsVsync());
697 }
698
699 void FlutterWindowsView::OnWindowStateEvent(HWND hwnd, WindowStateEvent event) {
700 if (engine_) {
701 engine_->OnWindowStateEvent(hwnd, event);
702 }
703 }
704
705 bool FlutterWindowsView::NeedsVsync() const {
706 // If the Desktop Window Manager composition is enabled,
707 // the system itself synchronizes with vsync.
708 // See: https://learn.microsoft.com/windows/win32/dwm/composition-ovw
709 return !windows_proc_table_->DwmIsCompositionEnabled();
710 }
711
712 } // 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:181
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:203
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:699
flutter::FlutterWindowsView::CreateRenderSurface
void CreateRenderSurface()
Definition: flutter_windows_view.cc:622
flutter::FlutterWindowsView::OnWindowSizeChanged
void OnWindowSizeChanged(size_t width, size_t height) override
Definition: flutter_windows_view.cc:143
flutter::FlutterWindowsView::OnUpdateSemanticsEnabled
virtual void OnUpdateSemanticsEnabled(bool enabled) override
Definition: flutter_windows_view.cc:287
flutter::FlutterWindowsView::OnComposeCommit
void OnComposeCommit() override
Definition: flutter_windows_view.cc:258
flutter::FlutterWindowsEngine::SendPointerEvent
void SendPointerEvent(const FlutterPointerEvent &event)
Definition: flutter_windows_engine.cc:514
scancode
int scancode
Definition: keyboard_key_handler_unittests.cc:115
flutter::FlutterWindowsView::~FlutterWindowsView
virtual ~FlutterWindowsView()
Definition: flutter_windows_view.cc:85
was_down
bool was_down
Definition: keyboard_key_handler_unittests.cc:119
text_input_plugin.h
extended
bool extended
Definition: keyboard_key_handler_unittests.cc:118
flutter::AngleSurfaceManager::CreateSurface
virtual bool CreateSurface(HWND hwnd, EGLint width, EGLint height)
Definition: angle_surface_manager.cc:232
flutter::FlutterWindowsView::OnPointerDown
void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button) override
Definition: flutter_windows_view.cc:190
flutter::FlutterWindowsEngine
Definition: flutter_windows_engine.h:78
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:266
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:282
flutter::FlutterWindowsView::ForceRedraw
void ForceRedraw()
Definition: flutter_windows_view.cc:136
flutter::FlutterWindowsView::DestroyRenderSurface
void DestroyRenderSurface()
Definition: flutter_windows_view.cc:635
flutter::FlutterWindowsView::OnPointerPanZoomStart
virtual void OnPointerPanZoomStart(int32_t device_id) override
Definition: flutter_windows_view.cc:223
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:653
flutter::kWindowFrameBufferID
constexpr uint32_t kWindowFrameBufferID
Definition: flutter_windows_view.h:31
flutter::FlutterWindowsView::GetWindowHandle
virtual HWND GetWindowHandle() const
Definition: flutter_windows_view.cc:645
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:228
flutter::FlutterWindowsView::OnWindowRepaint
void OnWindowRepaint() override
Definition: flutter_windows_view.cc:177
flutter::FlutterWindowsEngine::Stop
virtual bool Stop()
Definition: flutter_windows_engine.cc:450
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:262
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:507
flutter::TextInputPlugin::TextHook
virtual void TextHook(const std::u16string &text)
Definition: text_input_plugin.cc:67
flutter::FlutterWindowsView::SwapBuffers
bool SwapBuffers()
Definition: flutter_windows_view.cc:576
flutter::KeyboardHandlerBase::SyncModifiersIfNeeded
virtual void SyncModifiersIfNeeded(int modifiers_state)=0
flutter::AngleSurfaceManager::DestroySurface
virtual void DestroySurface()
Definition: angle_surface_manager.cc:301
flutter::FlutterWindowsView::OnHighContrastChanged
void OnHighContrastChanged() override
Definition: flutter_windows_view.cc:641
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::FlutterWindowsView::UpdateFlutterCursor
void UpdateFlutterCursor(const std::string &cursor_name)
Definition: flutter_windows_view.cc:128
flutter::FlutterWindowsView::SetFlutterCursor
void SetFlutterCursor(HCURSOR cursor)
Definition: flutter_windows_view.cc:132
flutter::FlutterWindowsView::OnPointerLeave
void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id=0) override
Definition: flutter_windows_view.cc:216
flutter::FlutterWindowsView::OnText
void OnText(const std::u16string &) override
Definition: flutter_windows_view.cc:240
flutter::FlutterWindowsEngine::keyboard_key_handler
KeyboardHandlerBase * keyboard_key_handler()
Definition: flutter_windows_engine.h:163
flutter::FlutterWindowsView::PresentSoftwareBitmap
bool PresentSoftwareBitmap(const void *allocation, size_t row_bytes, size_t height)
Definition: flutter_windows_view.cc:615
flutter::FlutterWindowsView::OnCursorRectUpdated
virtual void OnCursorRectUpdated(const Rect &rect)
Definition: flutter_windows_view.cc:299
flutter::FlutterWindowsEngine::surface_manager
AngleSurfaceManager * surface_manager() const
Definition: flutter_windows_engine.h:144
flutter::FlutterWindowsView::AlertNode
ui::AXPlatformNodeWin * AlertNode() const
Definition: flutter_windows_view.cc:674
flutter::FlutterWindowsView::SetEngine
void SetEngine(FlutterWindowsEngine *engine)
Definition: flutter_windows_view.cc:95
flutter::FlutterWindowsEngine::text_input_plugin
TextInputPlugin * text_input_plugin()
Definition: flutter_windows_engine.h:166
flutter::FlutterWindowsView::OnPointerPanZoomEnd
virtual void OnPointerPanZoomEnd(int32_t device_id) override
Definition: flutter_windows_view.cc:236
flutter::FlutterWindowsView::OnDwmCompositionChanged
void OnDwmCompositionChanged()
Definition: flutter_windows_view.cc:695
flutter::FlutterWindowsView::NotifyWinEventWrapper
virtual void NotifyWinEventWrapper(ui::AXPlatformNodeWin *node, ax::mojom::Event event)
Definition: flutter_windows_view.cc:663
flutter::FlutterWindowsEngine::ScheduleFrame
void ScheduleFrame()
Definition: flutter_windows_engine.cc:587
flutter::FlutterWindowsEngine::UpdateHighContrastMode
void UpdateHighContrastMode()
Definition: flutter_windows_engine.cc:751
flutter::AngleSurfaceManager::SwapBuffers
EGLBoolean SwapBuffers()
Definition: angle_surface_manager.cc:332
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:683
flutter::FlutterWindowsView::OnComposeBegin
void OnComposeBegin() override
Definition: flutter_windows_view.cc:254
flutter::FlutterWindowsView::SendInitialBounds
void SendInitialBounds()
Definition: flutter_windows_view.cc:319
flutter::FlutterWindowsView::CreateAccessibilityBridge
virtual std::shared_ptr< AccessibilityBridgeWindows > CreateAccessibilityBridge()
Definition: flutter_windows_view.cc:679
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:271
flutter::FlutterWindowsEngine::UpdateSemanticsEnabled
void UpdateSemanticsEnabled(bool enabled)
Definition: flutter_windows_engine.cc:718
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:670
flutter::AngleSurfaceManager::GetSurfaceDimensions
void GetSurfaceDimensions(EGLint *width, EGLint *height)
Definition: angle_surface_manager.cc:286
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:809
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:244
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:291
flutter::FlutterWindowsView::OnResetImeComposing
virtual void OnResetImeComposing()
Definition: flutter_windows_view.cc:303
flutter::FlutterWindowsView::GetEngine
FlutterWindowsEngine * GetEngine()
Definition: flutter_windows_view.cc:649
flutter::AngleSurfaceManager::ResizeSurface
virtual void ResizeSurface(HWND hwnd, EGLint width, EGLint height, bool enable_vsync)
Definition: angle_surface_manager.cc:262
flutter::FlutterWindowsView::GetFrameBufferId
uint32_t GetFrameBufferId(size_t width, size_t height)
Definition: flutter_windows_view.cc:109
flutter::FlutterWindowsEngine::SetView
void SetView(FlutterWindowsView *view)
Definition: flutter_windows_engine.cc:463
flutter::FlutterWindowsView::FlutterWindowsView
FlutterWindowsView(std::unique_ptr< WindowBindingHandler > window_binding, std::shared_ptr< WindowsProcTable > windows_proc_table=nullptr)
Definition: flutter_windows_view.cc:72
callback
FlutterDesktopBinaryReply callback
Definition: flutter_windows_view_unittests.cc:48