Flutter Windows Embedder
task_runner_window.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 
6 
7 #include <algorithm>
8 
9 #include "flutter/fml/logging.h"
10 
11 namespace flutter {
12 
13 TaskRunnerWindow::TaskRunnerWindow() {
14  WNDCLASS window_class = RegisterWindowClass();
15  window_handle_ =
16  CreateWindowEx(0, window_class.lpszClassName, L"", 0, 0, 0, 0, 0,
17  HWND_MESSAGE, nullptr, window_class.hInstance, nullptr);
18 
19  if (window_handle_) {
20  SetWindowLongPtr(window_handle_, GWLP_USERDATA,
21  reinterpret_cast<LONG_PTR>(this));
22  } else {
23  auto error = GetLastError();
24  LPWSTR message = nullptr;
25  size_t size = FormatMessageW(
26  FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
27  FORMAT_MESSAGE_IGNORE_INSERTS,
28  NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
29  reinterpret_cast<LPWSTR>(&message), 0, NULL);
30  OutputDebugString(message);
31  LocalFree(message);
32  }
33 }
34 
36  if (window_handle_) {
37  DestroyWindow(window_handle_);
38  window_handle_ = nullptr;
39  }
40  UnregisterClass(window_class_name_.c_str(), nullptr);
41 }
42 
43 std::shared_ptr<TaskRunnerWindow> TaskRunnerWindow::GetSharedInstance() {
44  static std::weak_ptr<TaskRunnerWindow> instance;
45  auto res = instance.lock();
46  if (!res) {
47  // can't use make_shared with private contructor
48  res.reset(new TaskRunnerWindow());
49  instance = res;
50  }
51  return res;
52 }
53 
55  if (!PostMessage(window_handle_, WM_NULL, 0, 0)) {
56  FML_LOG(ERROR) << "Failed to post message to main thread.";
57  }
58 }
59 
61  delegates_.push_back(delegate);
62  SetTimer(std::chrono::nanoseconds::zero());
63 }
64 
66  auto i = std::find(delegates_.begin(), delegates_.end(), delegate);
67  if (i != delegates_.end()) {
68  delegates_.erase(i);
69  }
70 }
71 
72 void TaskRunnerWindow::ProcessTasks() {
73  auto next = std::chrono::nanoseconds::max();
74  auto delegates_copy(delegates_);
75  for (auto delegate : delegates_copy) {
76  // if not removed in the meanwhile
77  if (std::find(delegates_.begin(), delegates_.end(), delegate) !=
78  delegates_.end()) {
79  next = std::min(next, delegate->ProcessTasks());
80  }
81  }
82  SetTimer(next);
83 }
84 
85 void TaskRunnerWindow::SetTimer(std::chrono::nanoseconds when) {
86  if (when == std::chrono::nanoseconds::max()) {
87  KillTimer(window_handle_, 0);
88  } else {
89  auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(when);
90  ::SetTimer(window_handle_, 0, millis.count() + 1, nullptr);
91  }
92 }
93 
94 WNDCLASS TaskRunnerWindow::RegisterWindowClass() {
95  window_class_name_ = L"FlutterTaskRunnerWindow";
96 
97  WNDCLASS window_class{};
98  window_class.hCursor = nullptr;
99  window_class.lpszClassName = window_class_name_.c_str();
100  window_class.style = 0;
101  window_class.cbClsExtra = 0;
102  window_class.cbWndExtra = 0;
103  window_class.hInstance = GetModuleHandle(nullptr);
104  window_class.hIcon = nullptr;
105  window_class.hbrBackground = 0;
106  window_class.lpszMenuName = nullptr;
107  window_class.lpfnWndProc = WndProc;
108  RegisterClass(&window_class);
109  return window_class;
110 }
111 
112 LRESULT
113 TaskRunnerWindow::HandleMessage(UINT const message,
114  WPARAM const wparam,
115  LPARAM const lparam) noexcept {
116  switch (message) {
117  case WM_TIMER:
118  case WM_NULL:
119  ProcessTasks();
120  return 0;
121  }
122  return DefWindowProcW(window_handle_, message, wparam, lparam);
123 }
124 
125 LRESULT TaskRunnerWindow::WndProc(HWND const window,
126  UINT const message,
127  WPARAM const wparam,
128  LPARAM const lparam) noexcept {
129  if (auto* that = reinterpret_cast<TaskRunnerWindow*>(
130  GetWindowLongPtr(window, GWLP_USERDATA))) {
131  return that->HandleMessage(message, wparam, lparam);
132  } else {
133  return DefWindowProc(window, message, wparam, lparam);
134  }
135 }
136 
137 } // namespace flutter
flutter::TaskRunnerWindow::GetSharedInstance
static std::shared_ptr< TaskRunnerWindow > GetSharedInstance()
Definition: task_runner_window.cc:43
flutter::TaskRunnerWindow::RemoveDelegate
void RemoveDelegate(Delegate *delegate)
Definition: task_runner_window.cc:65
flutter::TaskRunnerWindow::WakeUp
void WakeUp()
Definition: task_runner_window.cc:54
flutter::TaskRunnerWindow
Definition: task_runner_window.h:20
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::TaskRunnerWindow::AddDelegate
void AddDelegate(Delegate *delegate)
Definition: task_runner_window.cc:60
flutter::TaskRunnerWindow::Delegate
Definition: task_runner_window.h:22
message
Win32Message message
Definition: keyboard_unittests.cc:137
flutter::TaskRunnerWindow::~TaskRunnerWindow
~TaskRunnerWindow()
Definition: task_runner_window.cc:35
task_runner_window.h