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