Flutter Engine
flutter_windows_view.cc
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 #include "flutter/shell/platform/windows/flutter_windows_view.h"
6 
7 #include <chrono>
8 
9 namespace flutter {
10 
12  std::unique_ptr<WindowBindingHandler> window_binding) {
13  surface_manager_ = std::make_unique<AngleSurfaceManager>();
14 
15  // Take the binding handler, and give it a pointer back to self.
16  binding_handler_ = std::move(window_binding);
17  binding_handler_->SetView(this);
18 
19  render_target_ = std::make_unique<WindowsRenderTarget>(
20  binding_handler_->GetRenderTarget());
21 }
22 
25 }
26 
28  std::unique_ptr<FlutterWindowsEngine> engine) {
29  engine_ = std::move(engine);
30 
31  engine_->SetView(this);
32 
33  internal_plugin_registrar_ =
34  std::make_unique<flutter::PluginRegistrar>(engine_->GetRegistrar());
35 
36  // Set up the system channel handlers.
37  auto internal_plugin_messenger = internal_plugin_registrar_->messenger();
38  keyboard_hook_handlers_.push_back(
39  std::make_unique<flutter::KeyEventHandler>(internal_plugin_messenger));
40  keyboard_hook_handlers_.push_back(
41  std::make_unique<flutter::TextInputPlugin>(internal_plugin_messenger));
42  platform_handler_ = std::make_unique<flutter::PlatformHandler>(
43  internal_plugin_messenger, this);
44  cursor_handler_ = std::make_unique<flutter::CursorHandler>(
45  internal_plugin_messenger, binding_handler_.get());
46 
47  PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
48 
49  SendWindowMetrics(bounds.width, bounds.height,
50  binding_handler_->GetDpiScale());
51 }
52 
54  size_t height) const {
55  surface_manager_->ResizeSurface(GetRenderTarget(), width, height);
56  SendWindowMetrics(width, height, binding_handler_->GetDpiScale());
57 }
58 
59 void FlutterWindowsView::OnPointerMove(double x, double y) {
60  SendPointerMove(x, y);
61 }
62 
64  double x,
65  double y,
66  FlutterPointerMouseButtons flutter_button) {
67  if (flutter_button != 0) {
68  uint64_t mouse_buttons = mouse_state_.buttons | flutter_button;
69  SetMouseButtons(mouse_buttons);
70  SendPointerDown(x, y);
71  }
72 }
73 
75  double x,
76  double y,
77  FlutterPointerMouseButtons flutter_button) {
78  if (flutter_button != 0) {
79  uint64_t mouse_buttons = mouse_state_.buttons & ~flutter_button;
80  SetMouseButtons(mouse_buttons);
81  SendPointerUp(x, y);
82  }
83 }
84 
86  SendPointerLeave();
87 }
88 
89 void FlutterWindowsView::OnText(const std::u16string& text) {
90  SendText(text);
91 }
92 
94  int scancode,
95  int action,
96  char32_t character) {
97  SendKey(key, scancode, action, character);
98 }
99 
101  double y,
102  double delta_x,
103  double delta_y,
104  int scroll_offset_multiplier) {
105  SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier);
106 }
107 
108 // Sends new size information to FlutterEngine.
109 void FlutterWindowsView::SendWindowMetrics(size_t width,
110  size_t height,
111  double dpiScale) const {
112  if (engine_->engine() == nullptr) {
113  return;
114  }
115 
116  FlutterWindowMetricsEvent event = {};
117  event.struct_size = sizeof(event);
118  event.width = width;
119  event.height = height;
120  event.pixel_ratio = dpiScale;
121  auto result = FlutterEngineSendWindowMetricsEvent(engine_->engine(), &event);
122 }
123 
125  PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
126 
127  SendWindowMetrics(bounds.width, bounds.height,
128  binding_handler_->GetDpiScale());
129 }
130 
131 // Set's |event_data|'s phase to either kMove or kHover depending on the current
132 // primary mouse button state.
133 void FlutterWindowsView::SetEventPhaseFromCursorButtonState(
134  FlutterPointerEvent* event_data) const {
135  // For details about this logic, see FlutterPointerPhase in the embedder.h
136  // file.
137  event_data->phase =
138  mouse_state_.buttons == 0
139  ? mouse_state_.flutter_state_is_down ? FlutterPointerPhase::kUp
141  : mouse_state_.flutter_state_is_down ? FlutterPointerPhase::kMove
143 }
144 
145 void FlutterWindowsView::SendPointerMove(double x, double y) {
146  FlutterPointerEvent event = {};
147  event.x = x;
148  event.y = y;
149  SetEventPhaseFromCursorButtonState(&event);
150  SendPointerEventWithData(event);
151 }
152 
153 void FlutterWindowsView::SendPointerDown(double x, double y) {
154  FlutterPointerEvent event = {};
155  SetEventPhaseFromCursorButtonState(&event);
156  event.x = x;
157  event.y = y;
158  SendPointerEventWithData(event);
159  SetMouseFlutterStateDown(true);
160 }
161 
162 void FlutterWindowsView::SendPointerUp(double x, double y) {
163  FlutterPointerEvent event = {};
164  SetEventPhaseFromCursorButtonState(&event);
165  event.x = x;
166  event.y = y;
167  SendPointerEventWithData(event);
168  if (event.phase == FlutterPointerPhase::kUp) {
169  SetMouseFlutterStateDown(false);
170  }
171 }
172 
173 void FlutterWindowsView::SendPointerLeave() {
174  FlutterPointerEvent event = {};
176  SendPointerEventWithData(event);
177 }
178 
179 void FlutterWindowsView::SendText(const std::u16string& text) {
180  for (const auto& handler : keyboard_hook_handlers_) {
181  handler->TextHook(this, text);
182  }
183 }
184 
185 void FlutterWindowsView::SendKey(int key,
186  int scancode,
187  int action,
188  char32_t character) {
189  for (const auto& handler : keyboard_hook_handlers_) {
190  handler->KeyboardHook(this, key, scancode, action, character);
191  }
192 }
193 
194 void FlutterWindowsView::SendScroll(double x,
195  double y,
196  double delta_x,
197  double delta_y,
198  int scroll_offset_multiplier) {
199  FlutterPointerEvent event = {};
200  SetEventPhaseFromCursorButtonState(&event);
202  event.x = x;
203  event.y = y;
204  event.scroll_delta_x = delta_x * scroll_offset_multiplier;
205  event.scroll_delta_y = delta_y * scroll_offset_multiplier;
206  SendPointerEventWithData(event);
207 }
208 
209 void FlutterWindowsView::SendPointerEventWithData(
210  const FlutterPointerEvent& event_data) {
211  // If sending anything other than an add, and the pointer isn't already added,
212  // synthesize an add to satisfy Flutter's expectations about events.
213  if (!mouse_state_.flutter_state_is_added &&
214  event_data.phase != FlutterPointerPhase::kAdd) {
215  FlutterPointerEvent event = {};
217  event.x = event_data.x;
218  event.y = event_data.y;
219  event.buttons = 0;
220  SendPointerEventWithData(event);
221  }
222  // Don't double-add (e.g., if events are delivered out of order, so an add has
223  // already been synthesized).
224  if (mouse_state_.flutter_state_is_added &&
225  event_data.phase == FlutterPointerPhase::kAdd) {
226  return;
227  }
228 
229  FlutterPointerEvent event = event_data;
231  event.buttons = mouse_state_.buttons;
232 
233  // Set metadata that's always the same regardless of the event.
234  event.struct_size = sizeof(event);
235  event.timestamp =
236  std::chrono::duration_cast<std::chrono::microseconds>(
237  std::chrono::high_resolution_clock::now().time_since_epoch())
238  .count();
239 
240  FlutterEngineSendPointerEvent(engine_->engine(), &event, 1);
241 
242  if (event_data.phase == FlutterPointerPhase::kAdd) {
243  SetMouseFlutterStateAdded(true);
244  } else if (event_data.phase == FlutterPointerPhase::kRemove) {
245  SetMouseFlutterStateAdded(false);
246  ResetMouseState();
247  }
248 }
249 
251  return surface_manager_->MakeCurrent();
252 }
253 
255  return surface_manager_->MakeResourceCurrent();
256 }
257 
259  return surface_manager_->ClearContext();
260 }
261 
263  return surface_manager_->SwapBuffers();
264 }
265 
267  PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
268  surface_manager_->CreateSurface(GetRenderTarget(), bounds.width,
269  bounds.height);
270 }
271 
273  if (surface_manager_) {
274  surface_manager_->DestroySurface();
275  }
276 }
277 
279  return render_target_.get();
280 }
281 
283  return engine_.get();
284 }
285 
286 } // namespace flutter
FlutterPointerMouseButtons
Definition: embedder.h:514
void OnScroll(double x, double y, double delta_x, double delta_y, int scroll_offset_multiplier) override
Definition: embedder.h:479
FlutterWindowsView(std::unique_ptr< WindowBindingHandler > window_binding)
void OnWindowSizeChanged(size_t width, size_t height) const override
std::variant< HWND > WindowsRenderTarget
double y
The y coordinate of the pointer event in physical pixels.
Definition: embedder.h:541
void OnPointerDown(double x, double y, FlutterPointerMouseButtons button) override
void OnPointerMove(double x, double y) override
void SetEngine(std::unique_ptr< FlutterWindowsEngine > engine)
void OnText(const std::u16string &) override
SemanticsAction action
The pointer moved while up.
Definition: embedder.h:503
int32_t height
int32_t width
size_t struct_size
The size of this struct. Must be sizeof(FlutterWindowMetricsEvent).
Definition: embedder.h:457
Definition: embedder.h:496
double x
The x coordinate of the pointer event in physical pixels.
Definition: embedder.h:539
GdkEventButton * event
Definition: fl_view.cc:62
void OnPointerUp(double x, double y, FlutterPointerMouseButtons button) override
FlutterEngineResult FlutterEngineSendPointerEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPointerEvent *pointers, size_t events_count)
Definition: embedder.cc:1323
FlutterPointerDeviceKind device_kind
Definition: embedder.h:555
WindowsRenderTarget * GetRenderTarget() const
void OnKey(int key, int scancode, int action, char32_t character) override
FlutterEngineResult FlutterEngineSendWindowMetricsEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterWindowMetricsEvent *flutter_metrics)
Definition: embedder.cc:1229
FlutterPointerPhase phase
Definition: embedder.h:533
FlutterWindowsEngine * GetEngine()