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