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