| 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
5 #include "flutter/shell/platform/windows/task_runner_window.h"
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
35 TaskRunnerWindow::~TaskRunnerWindow() {
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
54 void TaskRunnerWindow::WakeUp() {
55 if (!PostMessage(window_handle_, WM_NULL, 0, 0)) {
56 FML_LOG(ERROR) << "Failed to post message to main thread.";
57 }
58 }
59
60 void TaskRunnerWindow::AddDelegate(Delegate* delegate) {
61 delegates_.push_back(delegate);
62 SetTimer(std::chrono::nanoseconds::zero());
63 }
64
65 void TaskRunnerWindow::RemoveDelegate(Delegate* delegate) {
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