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 <windowsx.h>
9 
10 #include <memory>
11 #include <mutex>
12 #include <string>
13 #include <unordered_map>
14 #include <utility>
15 #include <vector>
16 
17 #include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h"
18 #include "flutter/shell/platform/common/geometry.h"
19 #include "flutter/shell/platform/embedder/embedder.h"
20 #include "flutter/shell/platform/windows/angle_surface_manager.h"
21 #include "flutter/shell/platform/windows/cursor_handler.h"
22 #include "flutter/shell/platform/windows/flutter_windows_engine.h"
23 #include "flutter/shell/platform/windows/keyboard_handler_base.h"
24 #include "flutter/shell/platform/windows/keyboard_key_embedder_handler.h"
25 #include "flutter/shell/platform/windows/keyboard_key_handler.h"
26 #include "flutter/shell/platform/windows/platform_handler.h"
27 #include "flutter/shell/platform/windows/public/flutter_windows.h"
28 #include "flutter/shell/platform/windows/text_input_plugin_delegate.h"
29 #include "flutter/shell/platform/windows/window_binding_handler.h"
30 #include "flutter/shell/platform/windows/window_binding_handler_delegate.h"
31 #include "flutter/shell/platform/windows/window_state.h"
32 
33 namespace flutter {
34 
35 // ID for the window frame buffer.
36 inline constexpr uint32_t kWindowFrameBufferID = 0;
37 
38 // An OS-windowing neutral abstration for flutter
39 // view that works with win32 hwnds and Windows::UI::Composition visuals.
42  public:
43  // Creates a FlutterWindowsView with the given implementor of
44  // WindowBindingHandler.
45  //
46  // In order for object to render Flutter content the SetEngine method must be
47  // called with a valid FlutterWindowsEngine instance.
48  FlutterWindowsView(std::unique_ptr<WindowBindingHandler> window_binding);
49 
50  virtual ~FlutterWindowsView();
51 
52  // Configures the window instance with an instance of a running Flutter
53  // engine.
54  void SetEngine(std::unique_ptr<FlutterWindowsEngine> engine);
55 
56  // Creates rendering surface for Flutter engine to draw into.
57  // Should be called before calling FlutterEngineRun using this view.
58  void CreateRenderSurface();
59 
60  // Destroys current rendering surface if one has been allocated.
61  void DestroyRenderSurface();
62 
63  // Return the currently configured WindowsRenderTarget.
65 
66  // Return the currently configured PlatformWindow.
68 
69  // Returns the engine backing this view.
71 
72  // Tells the engine to generate a new frame
73  void ForceRedraw();
74 
75  // Callbacks for clearing context, settings context and swapping buffers,
76  // these are typically called on an engine-controlled (non-platform) thread.
77  bool ClearContext();
78  bool MakeCurrent();
79  bool MakeResourceCurrent();
80  bool SwapBuffers();
81 
82  // Callback for presenting a software bitmap.
83  bool PresentSoftwareBitmap(const void* allocation,
84  size_t row_bytes,
85  size_t height);
86 
87  // Send initial bounds to embedder. Must occur after engine has initialized.
88  void SendInitialBounds();
89 
90  // Returns the frame buffer id for the engine to render to.
91  uint32_t GetFrameBufferId(size_t width, size_t height);
92 
93  // Called when the engine is restarted.
94  //
95  // This should reset necessary states to as if the view has just been
96  // created. This is typically caused by a hot restart (Shift-R in CLI.)
97  void OnPreEngineRestart();
98 
99  // |WindowBindingHandlerDelegate|
100  void OnWindowSizeChanged(size_t width, size_t height) override;
101 
102  // |WindowBindingHandlerDelegate|
103  void OnPointerMove(double x,
104  double y,
105  FlutterPointerDeviceKind device_kind,
106  int32_t device_id) override;
107 
108  // |WindowBindingHandlerDelegate|
109  void OnPointerDown(double x,
110  double y,
111  FlutterPointerDeviceKind device_kind,
112  int32_t device_id,
113  FlutterPointerMouseButtons button) override;
114 
115  // |WindowBindingHandlerDelegate|
116  void OnPointerUp(double x,
117  double y,
118  FlutterPointerDeviceKind device_kind,
119  int32_t device_id,
120  FlutterPointerMouseButtons button) override;
121 
122  // |WindowBindingHandlerDelegate|
123  void OnPointerLeave(FlutterPointerDeviceKind device_kind,
124  int32_t device_id = 0) override;
125 
126  // |WindowBindingHandlerDelegate|
127  void OnText(const std::u16string&) override;
128 
129  // |WindowBindingHandlerDelegate|
130  bool OnKey(int key,
131  int scancode,
132  int action,
133  char32_t character,
134  bool extended,
135  bool was_down) override;
136 
137  // |WindowBindingHandlerDelegate|
138  void OnComposeBegin() override;
139 
140  // |WindowBindingHandlerDelegate|
141  void OnComposeCommit() override;
142 
143  // |WindowBindingHandlerDelegate|
144  void OnComposeEnd() override;
145 
146  // |WindowBindingHandlerDelegate|
147  void OnComposeChange(const std::u16string& text, int cursor_pos) override;
148 
149  // |WindowBindingHandlerDelegate|
150  void OnScroll(double x,
151  double y,
152  double delta_x,
153  double delta_y,
154  int scroll_offset_multiplier,
155  FlutterPointerDeviceKind device_kind,
156  int32_t device_id) override;
157 
158  // |WindowBindingHandlerDelegate|
159  void OnPlatformBrightnessChanged() override;
160 
161  // |TextInputPluginDelegate|
162  void OnCursorRectUpdated(const Rect& rect) override;
163 
164  // |TextInputPluginDelegate|
165  void OnResetImeComposing() override;
166 
167  protected:
168  // Called to create the keyboard hook handlers.
169  //
170  // The provided |dispatch_event| is where to inject events into the system,
171  // while |get_key_state| is where to acquire keyboard states. They will be
172  // the system APIs in production classes, but might be replaced with mock
173  // functions in unit tests.
174  virtual void RegisterKeyboardHandlers(
175  flutter::BinaryMessenger* messenger,
178 
179  // Used by RegisterKeyboardHandlers to add a new keyboard hook handler.
180  void AddKeyboardHandler(
181  std::unique_ptr<flutter::KeyboardHandlerBase> handler);
182 
183  private:
184  // Struct holding the state of an individual pointer. The engine doesn't keep
185  // track of which buttons have been pressed, so it's the embedding's
186  // responsibility.
187  struct PointerState {
188  // The device kind.
190 
191  // A virtual pointer ID that is unique across all device kinds.
192  int32_t pointer_id = 0;
193 
194  // True if the last event sent to Flutter had at least one button pressed.
195  bool flutter_state_is_down = false;
196 
197  // True if kAdd has been sent to Flutter. Used to determine whether
198  // to send a kAdd event before sending an incoming pointer event, since
199  // Flutter expects pointers to be added before events are sent for them.
200  bool flutter_state_is_added = false;
201 
202  // The currently pressed buttons, as represented in FlutterPointerEvent.
203  uint64_t buttons = 0;
204  };
205 
206  // States a resize event can be in.
207  enum class ResizeState {
208  // When a resize event has started but is in progress.
209  kResizeStarted,
210  // After a resize event starts and the framework has been notified to
211  // generate a frame for the right size.
212  kFrameGenerated,
213  // Default state for when no resize is in progress. Also used to indicate
214  // that during a resize event, a frame with the right size has been rendered
215  // and the buffers have been swapped.
216  kDone,
217  };
218 
219  // Initialize states related to keyboard.
220  //
221  // This is called when the view is first created, or restarted.
222  void InitializeKeyboard();
223 
224  // Sends a window metrics update to the Flutter engine using current window
225  // dimensions in physical
226  void SendWindowMetrics(size_t width, size_t height, double dpiscale) const;
227 
228  // Reports a mouse movement to Flutter engine.
229  void SendPointerMove(double x, double y, PointerState* state);
230 
231  // Reports mouse press to Flutter engine.
232  void SendPointerDown(double x, double y, PointerState* state);
233 
234  // Reports mouse release to Flutter engine.
235  void SendPointerUp(double x, double y, PointerState* state);
236 
237  // Reports mouse left the window client area.
238  //
239  // Win32 api doesn't have "mouse enter" event. Therefore, there is no
240  // SendPointerEnter method. A mouse enter event is tracked then the "move"
241  // event is called.
242  void SendPointerLeave(PointerState* state);
243 
244  // Reports a keyboard character to Flutter engine.
245  void SendText(const std::u16string&);
246 
247  // Reports a raw keyboard message to Flutter engine.
248  bool SendKey(int key,
249  int scancode,
250  int action,
251  char32_t character,
252  bool extended,
253  bool was_down);
254 
255  // Reports an IME compose begin event.
256  //
257  // Triggered when the user begins editing composing text using a multi-step
258  // input method such as in CJK text input.
259  void SendComposeBegin();
260 
261  // Reports an IME compose commit event.
262  //
263  // Triggered when the user commits the current composing text while using a
264  // multi-step input method such as in CJK text input. Composing continues with
265  // the next keypress.
266  void SendComposeCommit();
267 
268  // Reports an IME compose end event.
269  //
270  // Triggered when the user commits the composing text while using a multi-step
271  // input method such as in CJK text input.
272  void SendComposeEnd();
273 
274  // Reports an IME composing region change event.
275  //
276  // Triggered when the user edits the composing text while using a multi-step
277  // input method such as in CJK text input.
278  void SendComposeChange(const std::u16string& text, int cursor_pos);
279 
280  // Reports scroll wheel events to Flutter engine.
281  void SendScroll(double x,
282  double y,
283  double delta_x,
284  double delta_y,
285  int scroll_offset_multiplier,
286  FlutterPointerDeviceKind device_kind,
287  int32_t device_id);
288 
289  // Creates a PointerState object unless it already exists.
290  PointerState* GetOrCreatePointerState(FlutterPointerDeviceKind device_kind,
291  int32_t device_id);
292 
293  // Sets |event_data|'s phase to either kMove or kHover depending on the
294  // current primary mouse button state.
295  void SetEventPhaseFromCursorButtonState(FlutterPointerEvent* event_data,
296  const PointerState* state) const;
297 
298  // Sends a pointer event to the Flutter engine based on given data. Since
299  // all input messages are passed in physical pixel values, no translation is
300  // needed before passing on to engine.
301  void SendPointerEventWithData(const FlutterPointerEvent& event_data,
302  PointerState* state);
303 
304  // Reports platform brightness change to Flutter engine.
305  void SendPlatformBrightnessChanged();
306 
307  // Currently configured WindowsRenderTarget for this view used by
308  // surface_manager for creation of render surfaces and bound to the physical
309  // os window.
310  std::unique_ptr<WindowsRenderTarget> render_target_;
311 
312  // The engine associated with this view.
313  std::unique_ptr<FlutterWindowsEngine> engine_;
314 
315  // Keeps track of pointer states in relation to the window.
316  std::map<int32_t, std::unique_ptr<PointerState>> pointer_states_;
317 
318  // The plugin registrar managing internal plugins.
319  std::unique_ptr<flutter::PluginRegistrar> internal_plugin_registrar_;
320 
321  // Handlers for keyboard events from Windows.
322  std::vector<std::unique_ptr<flutter::KeyboardHandlerBase>> keyboard_handlers_;
323 
324  // Handler for the flutter/platform channel.
325  std::unique_ptr<flutter::PlatformHandler> platform_handler_;
326 
327  // Handler for cursor events.
328  std::unique_ptr<flutter::CursorHandler> cursor_handler_;
329 
330  // Currently configured WindowBindingHandler for view.
331  std::unique_ptr<flutter::WindowBindingHandler> binding_handler_;
332 
333  // Resize events are synchronized using this mutex and the corresponding
334  // condition variable.
335  std::mutex resize_mutex_;
336  std::condition_variable resize_cv_;
337 
338  // Indicates the state of a window resize event. Platform thread will be
339  // blocked while this is not done. Guarded by resize_mutex_.
340  ResizeState resize_status_ = ResizeState::kDone;
341 
342  // Target for the window width. Valid when resize_pending_ is set. Guarded by
343  // resize_mutex_.
344  size_t resize_target_width_ = 0;
345 
346  // Target for the window width. Valid when resize_pending_ is set. Guarded by
347  // resize_mutex_.
348  size_t resize_target_height_ = 0;
349 };
350 
351 } // namespace flutter
352 
353 #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_VIEW_H_
FlutterPointerMouseButtons
Definition: embedder.h:631
void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button) override
FlutterWindowsView(std::unique_ptr< WindowBindingHandler > window_binding)
void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, FlutterPointerMouseButtons button) override
char32_t character
std::variant< HWND > WindowsRenderTarget
void OnCursorRectUpdated(const Rect &rect) override
constexpr uint32_t kWindowFrameBufferID
std::function< UINT(UINT cInputs, LPINPUT pInputs, int cbSize)> EventDispatcher
void OnComposeChange(const std::u16string &text, int cursor_pos) override
FlutterPointerDeviceKind
The device type that created a pointer event.
Definition: embedder.h:623
void SetEngine(std::unique_ptr< FlutterWindowsEngine > engine)
void OnText(const std::u16string &) override
void OnPointerLeave(FlutterPointerDeviceKind device_kind, int32_t device_id=0) override
SemanticsAction action
void AddKeyboardHandler(std::unique_ptr< flutter::KeyboardHandlerBase > handler)
void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id) override
int32_t width
bool PresentSoftwareBitmap(const void *allocation, size_t row_bytes, size_t height)
int32_t height
std::u16string text
uint32_t GetFrameBufferId(size_t width, size_t height)
bool OnKey(int key, int scancode, int action, char32_t character, bool extended, bool was_down) override
PlatformWindow GetPlatformWindow() const
WindowsRenderTarget * GetRenderTarget() const
virtual void RegisterKeyboardHandlers(flutter::BinaryMessenger *messenger, flutter::KeyboardKeyHandler::EventDispatcher dispatch_event, flutter::KeyboardKeyEmbedderHandler::GetKeyStateHandler get_key_state)
AtkStateType state
void OnScroll(double x, double y, double delta_x, double delta_y, int scroll_offset_multiplier, FlutterPointerDeviceKind device_kind, int32_t device_id) override
FlutterWindowsEngine * GetEngine()
void OnWindowSizeChanged(size_t width, size_t height) override