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