Skip to content

Commit 9d4b0cb

Browse files
Update Linux template for headless mode (flutter#56618)
1 parent 06adde0 commit 9d4b0cb

File tree

2 files changed

+18
-24
lines changed

2 files changed

+18
-24
lines changed

packages/flutter_tools/templates/app/linux.tmpl/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ ALL_LIBS_OUT=$(FLUTTER_LIB_OUT) \
4949
# issues if they start with one or more '../'s.
5050
WRAPPER_ROOT=$(abspath $(FLUTTER_EPHEMERAL_DIR)/cpp_client_wrapper_glfw)
5151
WRAPPER_SOURCES= \
52+
$(WRAPPER_ROOT)/flutter_engine.cc \
5253
$(WRAPPER_ROOT)/flutter_window_controller.cc \
5354
$(WRAPPER_ROOT)/plugin_registrar.cc \
5455
$(WRAPPER_ROOT)/engine_method_result.cc
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <flutter/flutter_engine.h>
12
#include <flutter/flutter_window_controller.h>
23
#include <linux/limits.h>
34
#include <unistd.h>
@@ -12,34 +13,22 @@
1213

1314
namespace {
1415

15-
// Returns the path of the directory containing this executable, or an empty
16-
// string if the directory cannot be found.
17-
std::string GetExecutableDirectory() {
18-
char buffer[PATH_MAX + 1];
19-
ssize_t length = readlink("/proc/self/exe", buffer, sizeof(buffer));
20-
if (length > PATH_MAX) {
21-
std::cerr << "Couldn't locate executable" << std::endl;
22-
return "";
16+
// Runs the application in headless mode, without a window.
17+
void RunHeadless(const std::string& icu_data_path,
18+
const std::string& assets_path,
19+
const std::vector<std::string>& arguments) {
20+
flutter::FlutterEngine engine;
21+
engine.Start(icu_data_path, assets_path, arguments);
22+
RegisterPlugins(&engine);
23+
while (true) {
24+
engine.RunEventLoopWithTimeout();
2325
}
24-
std::string executable_path(buffer, length);
25-
size_t last_separator_position = executable_path.find_last_of('/');
26-
if (last_separator_position == std::string::npos) {
27-
std::cerr << "Unabled to find parent directory of " << executable_path
28-
<< std::endl;
29-
return "";
30-
}
31-
return executable_path.substr(0, last_separator_position);
3226
}
3327

3428
} // namespace
3529

3630
int main(int argc, char **argv) {
37-
// Resources are located relative to the executable.
38-
std::string base_directory = GetExecutableDirectory();
39-
if (base_directory.empty()) {
40-
base_directory = ".";
41-
}
42-
std::string data_directory = base_directory + "/data";
31+
std::string data_directory = "data";
4332
std::string assets_path = data_directory + "/flutter_assets";
4433
std::string icu_data_path = data_directory + "/icudtl.dat";
4534

@@ -55,13 +44,17 @@ int main(int argc, char **argv) {
5544
// Start the engine.
5645
if (!flutter_controller.CreateWindow(window_properties, assets_path,
5746
arguments)) {
47+
if (getenv("DISPLAY") == nullptr) {
48+
std::cout << "No DISPLAY; falling back to headless mode." << std::endl;
49+
RunHeadless(icu_data_path, assets_path, arguments);
50+
return EXIT_SUCCESS;
51+
}
5852
return EXIT_FAILURE;
5953
}
6054
RegisterPlugins(&flutter_controller);
6155

6256
// Run until the window is closed.
63-
while (flutter_controller.RunEventLoopWithTimeout(
64-
std::chrono::milliseconds::max())) {
57+
while (flutter_controller.RunEventLoopWithTimeout()) {
6558
}
6659
return EXIT_SUCCESS;
6760
}

0 commit comments

Comments
 (0)