Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
flutter_windows_view.h
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#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_VIEW_H_
6#define FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_VIEW_H_
7
8#include <atomic>
9#include <memory>
10#include <mutex>
11#include <string>
12#include <unordered_map>
13#include <utility>
14#include <vector>
15
16#include "flutter/fml/closure.h"
17#include "flutter/fml/macros.h"
28
29namespace flutter {
30
31// A unique identifier for a view.
32using FlutterViewId = int64_t;
33
34// Optional delegate for views that are sized to contents.
36 public:
37 // This method is called from the raster thread
38 // after the view's surface has been resized but
39 // before the frame has been presented on the view.
40 virtual void DidUpdateViewSize(int32_t width, int32_t height) = 0;
41
42 // Return the work area that the view can be laid out within.
43 virtual WindowRect GetWorkArea() const = 0;
44};
45
46// An OS-windowing neutral abstration for a Flutter view that works
47// with win32 HWNDs.
49 public:
50 // Creates a FlutterWindowsView with the given implementor of
51 // WindowBindingHandler.
55 std::unique_ptr<WindowBindingHandler> window_binding,
56 bool is_sized_to_content,
57 const BoxConstraints& box_constraints,
58 FlutterWindowsViewSizingDelegate* sizing_delegate = nullptr,
59 std::shared_ptr<WindowsProcTable> windows_proc_table = nullptr);
60
61 virtual ~FlutterWindowsView();
62
63 // Get the view's unique identifier.
64 FlutterViewId view_id() const;
65
66 // Whether this view is the implicit view.
67 //
68 // The implicit view is a special view for backwards compatibility.
69 // The engine assumes it can always render to this view, even if the app has
70 // destroyed the window for this view.
71 //
72 // Today, the implicit view is the first view that is created. It is the only
73 // view that can be created before the engine is launched.
74 //
75 // The embedder must ignore presents to this view before it is created and
76 // after it is destroyed.
77 //
78 // See:
79 // https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/implicitView.html
80 bool IsImplicitView() const;
81
82 // Create a rendering surface for Flutter engine to draw into.
83 //
84 // This is a no-op if using software rasterization.
86
87 // Get the EGL surface that backs the Flutter view.
88 //
89 // This might be nullptr or an invalid surface.
91
92 // Return the currently configured HWND.
93 virtual HWND GetWindowHandle() const;
94
95 // Returns the engine backing this view.
97
98 // Tells the engine to generate a new frame
99 void ForceRedraw();
100
101 // Callback to clear a previously presented software bitmap.
102 virtual bool ClearSoftwareBitmap();
103
104 // Callback for presenting a software bitmap.
105 virtual bool PresentSoftwareBitmap(const void* allocation,
106 size_t row_bytes,
107 size_t height);
108
109 // Creates a window metric for this view.
110 //
111 // Used to notify the engine of a view's current size and device pixel ratio.
113
114 // Send initial bounds to embedder. Must occur after engine has initialized.
115 //
116 // This is a no-op if this is not the implicit view. Non-implicit views'
117 // initial window metrics are sent when the view is added to the engine.
118 void SendInitialBounds();
119
120 // Set the text of the alert, and create it if it does not yet exist.
121 virtual void AnnounceAlert(const std::wstring& text);
122
123 // |WindowBindingHandlerDelegate|
124 void OnHighContrastChanged() override;
125
126 // Called on the raster thread when |CompositorOpenGL| receives an empty
127 // frame. Returns true if the frame can be presented.
128 //
129 // This destroys and then re-creates the view's surface if a resize is
130 // pending.
132
133 // Called on the raster thread when |CompositorOpenGL| receives a frame.
134 // Returns true if the frame can be presented.
135 //
136 // This destroys and then re-creates the view's surface if a resize is pending
137 // and |width| and |height| match the target size.
138 bool OnFrameGenerated(size_t width, size_t height);
139
140 // Called on the raster thread after |CompositorOpenGL| presents a frame.
141 //
142 // This completes a view resize if one is pending.
143 virtual void OnFramePresented();
144
145 // Set a callback that is invoked on the platform thread after the first
146 // frame is presented for this view. The callback is called exactly once
147 // and then cleared. This can be used to defer showing the host window
148 // until the first frame is rendered, avoiding a blank window flash.
150
151 // |WindowBindingHandlerDelegate|
152 bool OnWindowSizeChanged(size_t width, size_t height) override;
153
154 // Enables or disables content-based sizing for this view.
155 //
156 // When enabled, the view ignores externally-driven resizes and instead
157 // sizes itself to the rendered content after each frame. When disabled,
158 // the view follows the normal platform-driven resize flow.
159 //
160 // This may be called on any thread.
161 void SetSizedToContent(bool sized_to_content);
162
163 // Returns true if the view is currently sized to its rendered content.
164 //
165 // This may be called from the platform or raster threads.
166 bool IsSizedToContent() const;
167
168 // |WindowBindingHandlerDelegate|
169 void OnWindowRepaint() override;
170
171 // |WindowBindingHandlerDelegate|
172 void OnPointerMove(double x,
173 double y,
174 FlutterPointerDeviceKind device_kind,
175 int32_t device_id,
176 uint64_t buttons,
177 uint32_t rotation,
178 uint32_t pressure,
179 int modifiers_state) override;
180
181 // |WindowBindingHandlerDelegate|
182 void OnPointerDown(double x,
183 double y,
184 FlutterPointerDeviceKind device_kind,
185 int32_t device_id,
186 uint64_t buttons,
187 uint32_t rotation,
188 uint32_t pressure) override;
189
190 // |WindowBindingHandlerDelegate|
191 void OnPointerUp(double x,
192 double y,
193 FlutterPointerDeviceKind device_kind,
194 int32_t device_id,
195 uint64_t buttons) override;
196
197 // |WindowBindingHandlerDelegate|
198 void OnPointerLeave(double x,
199 double y,
200 FlutterPointerDeviceKind device_kind,
201 int32_t device_id = 0) override;
202
203 // |WindowBindingHandlerDelegate|
204 virtual void OnPointerPanZoomStart(int32_t device_id) override;
205
206 // |WindowBindingHandlerDelegate|
207 virtual void OnPointerPanZoomUpdate(int32_t device_id,
208 double pan_x,
209 double pan_y,
210 double scale,
211 double rotation) override;
212
213 // |WindowBindingHandlerDelegate|
214 virtual void OnPointerPanZoomEnd(int32_t device_id) override;
215
216 // |WindowBindingHandlerDelegate|
217 void OnText(const std::u16string&) override;
218
219 // |WindowBindingHandlerDelegate|
220 void OnKey(int key,
221 int scancode,
222 int action,
223 char32_t character,
224 bool extended,
225 bool was_down,
226 KeyEventCallback callback) override;
227
228 // |WindowBindingHandlerDelegate|
229 void OnFocus(FlutterViewFocusState focus_state,
230 FlutterViewFocusDirection direction) override;
231
232 // |WindowBindingHandlerDelegate|
233 void OnComposeBegin() override;
234
235 // |WindowBindingHandlerDelegate|
236 void OnComposeCommit() override;
237
238 // |WindowBindingHandlerDelegate|
239 void OnComposeEnd() override;
240
241 // |WindowBindingHandlerDelegate|
242 void OnComposeChange(const std::u16string& text, int cursor_pos) override;
243
244 // |WindowBindingHandlerDelegate|
245 void OnScroll(double x,
246 double y,
247 double delta_x,
248 double delta_y,
249 int scroll_offset_multiplier,
250 FlutterPointerDeviceKind device_kind,
251 int32_t device_id) override;
252
253 // |WindowBindingHandlerDelegate|
254 void OnScrollInertiaCancel(int32_t device_id) override;
255
256 // |WindowBindingHandlerDelegate|
257 virtual void OnUpdateSemanticsEnabled(bool enabled) override;
258
259 // |WindowBindingHandlerDelegate|
261
262 // Notifies the delegate of the updated the cursor rect in Flutter root view
263 // coordinates.
264 virtual void OnCursorRectUpdated(const Rect& rect);
265
266 // Notifies the delegate that the system IME composing state should be reset.
267 virtual void OnResetImeComposing();
268
269 // Called when a WM_ONCOMPOSITIONCHANGED message is received.
271
272 // Get a pointer to the alert node for this view.
273 ui::AXPlatformNodeWin* AlertNode() const;
274
275 // |WindowBindingHandlerDelegate|
277
278 // Called to re/set the accessibility bridge pointer.
279 virtual void UpdateSemanticsEnabled(bool enabled);
280
281 std::weak_ptr<AccessibilityBridgeWindows> accessibility_bridge() {
282 return accessibility_bridge_;
283 }
284
285 // |WindowBindingHandlerDelegate|
286 void OnWindowStateEvent(HWND hwnd, WindowStateEvent event) override;
287
288 // Focus the view.
289 // Returns true if the view was focused.
290 virtual bool Focus();
291
292 protected:
293 virtual void NotifyWinEventWrapper(ui::AXPlatformNodeWin* node,
294 ax::mojom::Event event);
295
296 // Create an AccessibilityBridgeWindows using this view.
297 virtual std::shared_ptr<AccessibilityBridgeWindows>
299
300 private:
301 // Allows setting the surface in tests.
302 friend class ViewModifier;
303
304 // Struct holding the state of an individual pointer. The engine doesn't keep
305 // track of which buttons have been pressed, so it's the embedding's
306 // responsibility.
307 struct PointerState {
308 // The device kind.
310
311 // A virtual pointer ID that is unique across all device kinds.
312 int32_t pointer_id = 0;
313
314 // True if the last event sent to Flutter had at least one button pressed.
315 bool flutter_state_is_down = false;
316
317 // True if kAdd has been sent to Flutter. Used to determine whether
318 // to send a kAdd event before sending an incoming pointer event, since
319 // Flutter expects pointers to be added before events are sent for them.
320 bool flutter_state_is_added = false;
321
322 // The currently pressed buttons, as represented in FlutterPointerEvent.
323 uint64_t buttons = 0;
324
325 // The x position where the last pan/zoom started.
326 double pan_zoom_start_x = 0;
327
328 // The y position where the last pan/zoom started.
329 double pan_zoom_start_y = 0;
330
331 // The clockwise rotation of the current pointer, from 0-359.
332 uint32_t rotation = 0;
333
334 // The pressure of the current pointer from 0-1024.
335 uint32_t pressure = 0;
336 };
337
338 // States a resize event can be in.
339 enum class ResizeState {
340 // When a resize event has started but is in progress.
341 kResizeStarted,
342 // After a resize event starts and the framework has been notified to
343 // generate a frame for the right size.
344 kFrameGenerated,
345 // Default state for when no resize is in progress. Also used to indicate
346 // that during a resize event, a frame with the right size has been rendered
347 // and the buffers have been swapped.
348 kDone,
349 };
350
351 // Resize the surface to the desired size.
352 //
353 // If the dimensions have changed, this destroys the original surface and
354 // creates a new one.
355 //
356 // This must be run on the raster thread. This binds the surface to the
357 // current thread.
358 //
359 // Width and height are the surface's desired physical pixel dimensions.
360 bool ResizeRenderSurface(size_t width, size_t height);
361
362 // Sends a window metrics update to the Flutter engine using current window
363 // dimensions in physical pixels.
364 void SendWindowMetrics(size_t width, size_t height, double pixel_ratio) const;
365
366 // Reports a mouse movement to Flutter engine.
367 void SendPointerMove(double x, double y, PointerState* state);
368
369 // Reports mouse press to Flutter engine.
370 void SendPointerDown(double x, double y, PointerState* state);
371
372 // Reports mouse release to Flutter engine.
373 void SendPointerUp(double x, double y, PointerState* state);
374
375 // Reports mouse left the window client area.
376 //
377 // Win32 api doesn't have "mouse enter" event. Therefore, there is no
378 // SendPointerEnter method. A mouse enter event is tracked then the "move"
379 // event is called.
380 void SendPointerLeave(double x, double y, PointerState* state);
381
382 void SendPointerPanZoomStart(int32_t device_id, double x, double y);
383
384 void SendPointerPanZoomUpdate(int32_t device_id,
385 double pan_x,
386 double pan_y,
387 double scale,
388 double rotation);
389
390 void SendPointerPanZoomEnd(int32_t device_id);
391
392 // Reports a keyboard character to Flutter engine.
393 void SendText(const std::u16string&);
394
395 // Reports a raw keyboard message to Flutter engine.
396 void SendKey(int key,
397 int scancode,
398 int action,
399 char32_t character,
400 bool extended,
401 bool was_down,
403
404 // Reports a focus event to Flutter engine.
405 void SendFocus(FlutterViewFocusState focus_state,
406 FlutterViewFocusDirection direction);
407
408 // Reports an IME compose begin event.
409 //
410 // Triggered when the user begins editing composing text using a multi-step
411 // input method such as in CJK text input.
412 void SendComposeBegin();
413
414 // Reports an IME compose commit event.
415 //
416 // Triggered when the user commits the current composing text while using a
417 // multi-step input method such as in CJK text input. Composing continues with
418 // the next keypress.
419 void SendComposeCommit();
420
421 // Reports an IME compose end event.
422 //
423 // Triggered when the user commits the composing text while using a multi-step
424 // input method such as in CJK text input.
425 void SendComposeEnd();
426
427 // Reports an IME composing region change event.
428 //
429 // Triggered when the user edits the composing text while using a multi-step
430 // input method such as in CJK text input.
431 void SendComposeChange(const std::u16string& text, int cursor_pos);
432
433 // Reports scroll wheel events to Flutter engine.
434 void SendScroll(double x,
435 double y,
436 double delta_x,
437 double delta_y,
438 int scroll_offset_multiplier,
439 FlutterPointerDeviceKind device_kind,
440 int32_t device_id);
441
442 // Reports scroll inertia cancel events to Flutter engine.
443 void SendScrollInertiaCancel(int32_t device_id, double x, double y);
444
445 // Creates a PointerState object unless it already exists.
446 PointerState* GetOrCreatePointerState(FlutterPointerDeviceKind device_kind,
447 int32_t device_id);
448
449 // Sets |event_data|'s phase to either kMove or kHover depending on the
450 // current primary mouse button state.
451 void SetEventPhaseFromCursorButtonState(FlutterPointerEvent* event_data,
452 const PointerState* state) const;
453
454 // Sends a pointer event to the Flutter engine based on given data. Since
455 // all input messages are passed in physical pixel values, no translation is
456 // needed before passing on to engine.
457 void SendPointerEventWithData(const FlutterPointerEvent& event_data,
458 PointerState* state);
459
460 // Fires |first_frame_callback_| on the platform thread if set, then clears
461 // it. Called from the raster thread after a frame is presented.
462 void FireFirstFrameCallbackIfSet();
463
464 // If true, rendering to the window should synchronize with the vsync
465 // to prevent screen tearing.
466 bool NeedsVsync() const;
467
468 // Gets the constraints for this view.
469 BoxConstraints GetConstraints() const;
470
471 // The view's unique identifier.
472 FlutterViewId view_id_;
473
474 // The engine associated with this view.
475 FlutterWindowsEngine* engine_ = nullptr;
476
477 // Mocks win32 APIs.
478 std::shared_ptr<WindowsProcTable> windows_proc_table_;
479
480 // The EGL surface backing the view.
481 //
482 // Null if using software rasterization, the surface hasn't been created yet,
483 // or if surface creation failed.
484 std::unique_ptr<egl::WindowSurface> surface_ = nullptr;
485
486 // Keeps track of pointer states in relation to the window.
487 std::unordered_map<int32_t, std::unique_ptr<PointerState>> pointer_states_;
488
489 // Currently configured WindowBindingHandler for view.
490 std::unique_ptr<WindowBindingHandler> binding_handler_;
491
492 // Protects resize_status_, resize_target_width_ and resize_target_height_.
493 std::mutex resize_mutex_;
494
495 // Indicates the state of a window resize event. Platform thread will be
496 // blocked while this is not done. Guarded by resize_mutex_.
497 ResizeState resize_status_ = ResizeState::kDone;
498
499 // Target for the window width. Valid when resize_pending_ is set. Guarded by
500 // resize_mutex_.
501 size_t resize_target_width_ = 0;
502
503 // Target for the window width. Valid when resize_pending_ is set. Guarded by
504 // resize_mutex_.
505 size_t resize_target_height_ = 0;
506
507 // True when flutter's semantics tree is enabled.
508 bool semantics_enabled_ = false;
509
510 // The accessibility bridge associated with this view.
511 std::shared_ptr<AccessibilityBridgeWindows> accessibility_bridge_;
512
513 // If `true`, the view is sized to its content via a sizing delegate.
514 // If `false`, the view is sized by its parent HWND.
515 std::atomic<bool> is_sized_to_content_{false};
516
517 // The constraints for this view.
518 BoxConstraints box_constraints_;
519
520 // Optional sizing delegate for views that are sized to content.
521 FlutterWindowsViewSizingDelegate* sizing_delegate_ = nullptr;
522
523 // Mutex protecting |first_frame_callback_|.
524 std::mutex first_frame_callback_mutex_;
525
526 // Callback invoked on the platform thread after the first frame is
527 // presented. Set via |SetFirstFrameCallback| and cleared after invocation.
528 fml::closure first_frame_callback_;
529
530 FML_DISALLOW_COPY_AND_ASSIGN(FlutterWindowsView);
531};
532
533} // namespace flutter
534
535#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_VIEW_H_
virtual void OnPointerPanZoomStart(int32_t device_id) override
virtual void UpdateSemanticsEnabled(bool enabled)
virtual ui::AXFragmentRootDelegateWin * GetAxFragmentRootDelegate() override
void OnScrollInertiaCancel(int32_t device_id) override
virtual std::shared_ptr< AccessibilityBridgeWindows > CreateAccessibilityBridge()
void SetSizedToContent(bool sized_to_content)
ui::AXPlatformNodeWin * AlertNode() const
void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, uint64_t buttons, uint32_t rotation, uint32_t pressure) override
virtual void OnUpdateSemanticsEnabled(bool enabled) override
void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id=0) override
virtual void NotifyWinEventWrapper(ui::AXPlatformNodeWin *node, ax::mojom::Event event)
void SetFirstFrameCallback(fml::closure callback)
FlutterWindowsEngine * GetEngine() const
void OnScroll(double x, double y, double delta_x, double delta_y, int scroll_offset_multiplier, FlutterPointerDeviceKind device_kind, int32_t device_id) override
void OnWindowStateEvent(HWND hwnd, WindowStateEvent event) override
virtual void OnPointerPanZoomEnd(int32_t device_id) override
void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, uint64_t buttons, uint32_t rotation, uint32_t pressure, int modifiers_state) override
FlutterWindowMetricsEvent CreateWindowMetricsEvent() const
virtual void AnnounceAlert(const std::wstring &text)
void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, uint64_t buttons) override
std::weak_ptr< AccessibilityBridgeWindows > accessibility_bridge()
virtual bool PresentSoftwareBitmap(const void *allocation, size_t row_bytes, size_t height)
void OnFocus(FlutterViewFocusState focus_state, FlutterViewFocusDirection direction) override
egl::WindowSurface * surface() const
bool OnWindowSizeChanged(size_t width, size_t height) override
void OnText(const std::u16string &) override
virtual void OnPointerPanZoomUpdate(int32_t device_id, double pan_x, double pan_y, double scale, double rotation) override
void OnComposeChange(const std::u16string &text, int cursor_pos) override
virtual gfx::NativeViewAccessible GetNativeViewAccessible() override
virtual void OnCursorRectUpdated(const Rect &rect)
void OnKey(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback) override
bool OnFrameGenerated(size_t width, size_t height)
virtual WindowRect GetWorkArea() const =0
virtual void DidUpdateViewSize(int32_t width, int32_t height)=0
int32_t x
FlutterViewFocusState
Represents the focus state of a given [FlutterView].
Definition embedder.h:1219
FlutterViewFocusDirection
Definition embedder.h:1200
int64_t FlutterViewId
Definition embedder.h:393
FlutterPointerDeviceKind
The device type that created a pointer event.
Definition embedder.h:1309
@ kFlutterPointerDeviceKindMouse
Definition embedder.h:1310
FlutterEngine engine
Definition main.cc:84
FlutterDesktopBinaryReply callback
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
std::u16string text
double y
WindowStateEvent
An event representing a change in window state that may update the.
int64_t FlutterViewId
std::function< void()> closure
Definition closure.h:14
UnimplementedNativeViewAccessible * NativeViewAccessible
int32_t height
int32_t width