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