Flutter Windows Embedder
flutter_window.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_WINDOW_H_
6 #define FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOW_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "flutter/fml/macros.h"
14 #include "flutter/shell/platform/embedder/embedder.h"
24 #include "flutter/third_party/accessibility/ax/platform/ax_fragment_root_delegate_win.h"
25 #include "flutter/third_party/accessibility/ax/platform/ax_fragment_root_win.h"
26 #include "flutter/third_party/accessibility/ax/platform/ax_platform_node_win.h"
27 #include "flutter/third_party/accessibility/gfx/native_widget_types.h"
28 
29 namespace flutter {
30 
31 // A win32 flutter child window used as implementations for flutter view. In
32 // the future, there will likely be a CoreWindow-based FlutterWindow as well.
33 // At the point may make sense to dependency inject the native window rather
34 // than inherit.
36  public WindowBindingHandler {
37  public:
38  // Create flutter Window for use as child window
39  FlutterWindow(int width,
40  int height,
41  std::shared_ptr<WindowsProcTable> windows_proc_table = nullptr,
42  std::unique_ptr<TextInputManager> text_input_manager = nullptr);
43 
44  virtual ~FlutterWindow();
45 
46  // Initializes as a child window with size using |width| and |height| and
47  // |title| to identify the windowclass. Does not show window, window must be
48  // parented into window hierarchy by caller.
49  void InitializeChild(const char* title,
50  unsigned int width,
51  unsigned int height);
52 
53  // |KeyboardManager::WindowDelegate|
54  virtual BOOL Win32PeekMessage(LPMSG lpMsg,
55  UINT wMsgFilterMin,
56  UINT wMsgFilterMax,
57  UINT wRemoveMsg) override;
58 
59  // |KeyboardManager::WindowDelegate|
60  virtual uint32_t Win32MapVkToChar(uint32_t virtual_key) override;
61 
62  // |KeyboardManager::WindowDelegate|
63  virtual UINT Win32DispatchMessage(UINT Msg,
64  WPARAM wParam,
65  LPARAM lParam) override;
66 
67  // Called when the DPI changes either when a
68  // user drags the window between monitors of differing DPI or when the user
69  // manually changes the scale factor.
70  virtual void OnDpiScale(unsigned int dpi);
71 
72  // Called when a resize occurs.
73  virtual void OnResize(unsigned int width, unsigned int height);
74 
75  // Called when a paint is requested.
76  virtual void OnPaint();
77 
78  // Called when the pointer moves within the
79  // window bounds.
80  virtual void OnPointerMove(double x,
81  double y,
82  FlutterPointerDeviceKind device_kind,
83  int32_t device_id,
84  int modifiers_state);
85 
86  // Called when the a mouse button, determined by |button|, goes down.
87  virtual void OnPointerDown(double x,
88  double y,
89  FlutterPointerDeviceKind device_kind,
90  int32_t device_id,
91  UINT button);
92 
93  // Called when the a mouse button, determined by |button|, goes from
94  // down to up
95  virtual void OnPointerUp(double x,
96  double y,
97  FlutterPointerDeviceKind device_kind,
98  int32_t device_id,
99  UINT button);
100 
101  // Called when the mouse leaves the window.
102  virtual void OnPointerLeave(double x,
103  double y,
104  FlutterPointerDeviceKind device_kind,
105  int32_t device_id);
106 
107  // |WindowBindingHandlerDelegate|
108  virtual void OnText(const std::u16string& text) override;
109 
110  // |WindowBindingHandlerDelegate|
111  virtual void OnKey(int key,
112  int scancode,
113  int action,
114  char32_t character,
115  bool extended,
116  bool was_down,
117  KeyEventCallback callback) override;
118 
119  // Called when IME composing begins.
120  virtual void OnComposeBegin();
121 
122  // Called when IME composing text is committed.
123  virtual void OnComposeCommit();
124 
125  // Called when IME composing ends.
126  virtual void OnComposeEnd();
127 
128  // Called when IME composing text or cursor position changes.
129  virtual void OnComposeChange(const std::u16string& text, int cursor_pos);
130 
131  // |FlutterWindowBindingHandler|
132  virtual void OnCursorRectUpdated(const Rect& rect) override;
133 
134  // |FlutterWindowBindingHandler|
135  virtual void OnResetImeComposing() override;
136 
137  // Called when accessibility support is enabled or disabled.
138  virtual void OnUpdateSemanticsEnabled(bool enabled);
139 
140  // Called when mouse scrollwheel input occurs.
141  virtual void OnScroll(double delta_x,
142  double delta_y,
143  FlutterPointerDeviceKind device_kind,
144  int32_t device_id);
145 
146  // Returns the root view accessibility node, or nullptr if none.
147  virtual gfx::NativeViewAccessible GetNativeViewAccessible();
148 
149  // |FlutterWindowBindingHandler|
150  virtual void SetView(WindowBindingHandlerDelegate* view) override;
151 
152  // |FlutterWindowBindingHandler|
153  virtual HWND GetWindowHandle() override;
154 
155  // |FlutterWindowBindingHandler|
156  virtual float GetDpiScale() override;
157 
158  // |FlutterWindowBindingHandler|
160 
161  // |FlutterWindowBindingHandler|
162  virtual bool OnBitmapSurfaceCleared() override;
163 
164  // |FlutterWindowBindingHandler|
165  virtual bool OnBitmapSurfaceUpdated(const void* allocation,
166  size_t row_bytes,
167  size_t height) override;
168 
169  // |FlutterWindowBindingHandler|
170  virtual PointerLocation GetPrimaryPointerLocation() override;
171 
172  // Called when a theme change message is issued.
173  virtual void OnThemeChange();
174 
175  // |WindowBindingHandler|
176  virtual AlertPlatformNodeDelegate* GetAlertDelegate() override;
177 
178  // |WindowBindingHandler|
179  virtual ui::AXPlatformNodeWin* GetAlert() override;
180 
181  // [WindowBindingHandler]
182  virtual bool Focus() override;
183 
184  // Called to obtain a pointer to the fragment root delegate.
185  virtual ui::AXFragmentRootDelegateWin* GetAxFragmentRootDelegate();
186 
187  // Called on a resize or focus event.
188  virtual void OnWindowStateEvent(WindowStateEvent event);
189 
190  protected:
191  // Base constructor for mocks.
192  FlutterWindow();
193 
194  // Win32's DefWindowProc.
195  //
196  // Used as the fallback behavior of HandleMessage. Exposed for dependency
197  // injection.
198  virtual LRESULT Win32DefWindowProc(HWND hWnd,
199  UINT Msg,
200  WPARAM wParam,
201  LPARAM lParam);
202 
203  // Converts a c string to a wide unicode string.
204  std::wstring NarrowToWide(const char* source);
205 
206  // Processes and route salient window messages for mouse handling,
207  // size change and DPI. Delegates handling of these to member overloads that
208  // inheriting classes can handle.
209  LRESULT HandleMessage(UINT const message,
210  WPARAM const wparam,
211  LPARAM const lparam) noexcept;
212 
213  // Called when the OS requests a COM object.
214  //
215  // The primary use of this function is to supply Windows with wrapped
216  // semantics objects for use by Windows accessibility.
217  virtual LRESULT OnGetObject(UINT const message,
218  WPARAM const wparam,
219  LPARAM const lparam);
220 
221  // Called when a window is activated in order to configure IME support for
222  // multi-step text input.
223  virtual void OnImeSetContext(UINT const message,
224  WPARAM const wparam,
225  LPARAM const lparam);
226 
227  // Called when multi-step text input begins when using an IME.
228  virtual void OnImeStartComposition(UINT const message,
229  WPARAM const wparam,
230  LPARAM const lparam);
231 
232  // Called when edits/commit of multi-step text input occurs when using an IME.
233  virtual void OnImeComposition(UINT const message,
234  WPARAM const wparam,
235  LPARAM const lparam);
236 
237  // Called when multi-step text input ends when using an IME.
238  virtual void OnImeEndComposition(UINT const message,
239  WPARAM const wparam,
240  LPARAM const lparam);
241 
242  // Called when the user triggers an IME-specific request such as input
243  // reconversion, where an existing input sequence is returned to composing
244  // mode to select an alternative candidate conversion.
245  virtual void OnImeRequest(UINT const message,
246  WPARAM const wparam,
247  LPARAM const lparam);
248 
249  // Called when the app ends IME composing, such as when the text input client
250  // is cleared or changed.
251  virtual void AbortImeComposing();
252 
253  // Called when the cursor rect has been updated.
254  //
255  // |rect| is in Win32 window coordinates.
256  virtual void UpdateCursorRect(const Rect& rect);
257 
258  UINT GetCurrentDPI();
259 
260  UINT GetCurrentWidth();
261 
262  UINT GetCurrentHeight();
263 
264  // Returns the current pixel per scroll tick value.
265  virtual float GetScrollOffsetMultiplier();
266 
267  // Delegate to a alert_node_ used to set the announcement text.
268  std::unique_ptr<AlertPlatformNodeDelegate> alert_delegate_;
269 
270  // Accessibility node that represents an alert.
271  std::unique_ptr<ui::AXPlatformNodeWin> alert_node_;
272 
273  // Handles running DirectManipulation on the window to receive trackpad
274  // gestures.
275  std::unique_ptr<DirectManipulationOwner> direct_manipulation_owner_;
276 
277  private:
278  // OS callback called by message pump. Handles the WM_NCCREATE message which
279  // is passed when the non-client area is being created and enables automatic
280  // non-client DPI scaling so that the non-client area automatically
281  // responsponds to changes in DPI. All other messages are handled by
282  // MessageHandler.
283  static LRESULT CALLBACK WndProc(HWND const window,
284  UINT const message,
285  WPARAM const wparam,
286  LPARAM const lparam) noexcept;
287 
288  // WM_DPICHANGED_BEFOREPARENT defined in more recent Windows
289  // SDK
290  static const long kWmDpiChangedBeforeParent = 0x02E2;
291 
292  // Timer identifier for DirectManipulation gesture polling.
293  static const int kDirectManipulationTimer = 1;
294 
295  // Release OS resources associated with the window.
296  void Destroy();
297 
298  // Registers a window class with default style attributes, cursor and
299  // icon.
300  WNDCLASS RegisterWindowClass(std::wstring& title);
301 
302  // Retrieves a class instance pointer for |window|
303  static FlutterWindow* GetThisFromHandle(HWND const window) noexcept;
304 
305  // Activates tracking for a "mouse leave" event.
306  void TrackMouseLeaveEvent(HWND hwnd);
307 
308  // Stores new width and height and calls |OnResize| to notify inheritors
309  void HandleResize(UINT width, UINT height);
310 
311  // Updates the cached scroll_offset_multiplier_ value based off OS settings.
312  void UpdateScrollOffsetMultiplier();
313 
314  // Creates the ax_fragment_root_, alert_delegate_ and alert_node_ if they do
315  // not yet exist.
316  // Once set, they are not reset to nullptr.
317  void CreateAxFragmentRoot();
318 
319  // A pointer to a FlutterWindowsView that can be used to update engine
320  // windowing and input state.
321  WindowBindingHandlerDelegate* binding_handler_delegate_ = nullptr;
322 
323  // The cursor rect set by Flutter.
324  RECT cursor_rect_;
325 
326  // The window receives resize and focus messages before its view is set, so
327  // these values cache the state of the window in the meantime so that the
328  // proper application lifecycle state can be updated once the view is set.
329  bool restored_ = false;
330  bool focused_ = false;
331 
332  int current_dpi_ = 0;
333  int current_width_ = 0;
334  int current_height_ = 0;
335 
336  // Holds the conversion factor from lines scrolled to pixels scrolled.
337  float scroll_offset_multiplier_;
338 
339  // Member variable to hold window handle.
340  HWND window_handle_ = nullptr;
341 
342  // Member variable to hold the window title.
343  std::wstring window_class_name_;
344 
345  // Set to true to be notified when the mouse leaves the window.
346  bool tracking_mouse_leave_ = false;
347 
348  // Keeps track of the last key code produced by a WM_KEYDOWN or WM_SYSKEYDOWN
349  // message.
350  int keycode_for_char_message_ = 0;
351 
352  // Keeps track of the last mouse coordinates by a WM_MOUSEMOVE message.
353  double mouse_x_ = 0;
354  double mouse_y_ = 0;
355 
356  // Generates touch point IDs for touch events.
357  SequentialIdGenerator touch_id_generator_;
358 
359  // Abstracts Windows APIs that may not be available on all supported versions
360  // of Windows.
361  std::shared_ptr<WindowsProcTable> windows_proc_table_;
362 
363  // Manages IME state.
364  std::unique_ptr<TextInputManager> text_input_manager_;
365 
366  // Manages IME state.
367  std::unique_ptr<KeyboardManager> keyboard_manager_;
368 
369  // Used for temporarily storing the WM_TOUCH-provided touch points.
370  std::vector<TOUCHINPUT> touch_points_;
371 
372  // Implements IRawElementProviderFragmentRoot when UIA is enabled.
373  std::unique_ptr<ui::AXFragmentRootWin> ax_fragment_root_;
374 
375  // Allow WindowAXFragmentRootDelegate to access protected method.
377 
378  FML_DISALLOW_COPY_AND_ASSIGN(FlutterWindow);
379 };
380 
381 } // namespace flutter
382 
383 #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOW_H_
virtual void OnCursorRectUpdated(const Rect &rect) override
virtual void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id)
virtual float GetScrollOffsetMultiplier()
virtual bool Focus() override
virtual ui::AXPlatformNodeWin * GetAlert() override
virtual void OnText(const std::u16string &text) override
virtual UINT Win32DispatchMessage(UINT Msg, WPARAM wParam, LPARAM lParam) override
virtual BOOL Win32PeekMessage(LPMSG lpMsg, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) override
virtual void OnThemeChange()
std::unique_ptr< AlertPlatformNodeDelegate > alert_delegate_
virtual bool OnBitmapSurfaceUpdated(const void *allocation, size_t row_bytes, size_t height) override
virtual void OnImeRequest(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual LRESULT Win32DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
virtual void OnImeStartComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
std::wstring NarrowToWide(const char *source)
virtual ui::AXFragmentRootDelegateWin * GetAxFragmentRootDelegate()
virtual void OnScroll(double delta_x, double delta_y, FlutterPointerDeviceKind device_kind, int32_t device_id)
virtual void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, UINT button)
void InitializeChild(const char *title, unsigned int width, unsigned int height)
virtual AlertPlatformNodeDelegate * GetAlertDelegate() override
std::unique_ptr< DirectManipulationOwner > direct_manipulation_owner_
virtual HWND GetWindowHandle() override
friend class WindowAXFragmentRootDelegate
virtual void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, UINT button)
virtual void OnComposeCommit()
virtual void UpdateCursorRect(const Rect &rect)
virtual PhysicalWindowBounds GetPhysicalWindowBounds() override
virtual void OnImeSetContext(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual void OnWindowStateEvent(WindowStateEvent event)
virtual void OnKey(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback) override
virtual void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, int modifiers_state)
std::unique_ptr< ui::AXPlatformNodeWin > alert_node_
virtual PointerLocation GetPrimaryPointerLocation() override
virtual void OnComposeEnd()
virtual void SetView(WindowBindingHandlerDelegate *view) override
LRESULT HandleMessage(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept
virtual void OnComposeChange(const std::u16string &text, int cursor_pos)
virtual void OnResetImeComposing() override
virtual uint32_t Win32MapVkToChar(uint32_t virtual_key) override
virtual void OnImeComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual void OnDpiScale(unsigned int dpi)
virtual void AbortImeComposing()
virtual float GetDpiScale() override
virtual void OnUpdateSemanticsEnabled(bool enabled)
virtual LRESULT OnGetObject(UINT const message, WPARAM const wparam, LPARAM const lparam)
virtual gfx::NativeViewAccessible GetNativeViewAccessible()
virtual void OnComposeBegin()
virtual bool OnBitmapSurfaceCleared() override
virtual void OnResize(unsigned int width, unsigned int height)
virtual void OnImeEndComposition(UINT const message, WPARAM const wparam, LPARAM const lparam)
std::function< void(bool)> KeyEventCallback
FlutterDesktopBinaryReply callback
std::u16string text
Win32Message message
WindowStateEvent
An event representing a change in window state that may update the.