Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 51d5267

Browse files
committed
Add an engine API that knows about screens.
1 parent 6d4a495 commit 51d5267

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1872
-326
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,10 @@ FILE: ../../../flutter/lib/ui/window/pointer_data_packet.h
410410
FILE: ../../../flutter/lib/ui/window/pointer_data_packet_converter.cc
411411
FILE: ../../../flutter/lib/ui/window/pointer_data_packet_converter.h
412412
FILE: ../../../flutter/lib/ui/window/pointer_data_packet_converter_unittests.cc
413+
FILE: ../../../flutter/lib/ui/window/screen.cc
414+
FILE: ../../../flutter/lib/ui/window/screen.h
415+
FILE: ../../../flutter/lib/ui/window/screen_metrics.cc
416+
FILE: ../../../flutter/lib/ui/window/screen_metrics.h
413417
FILE: ../../../flutter/lib/ui/window/viewport_metrics.cc
414418
FILE: ../../../flutter/lib/ui/window/viewport_metrics.h
415419
FILE: ../../../flutter/lib/ui/window/window.cc

examples/glfw/FlutterEmbedderGLFW.cc

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,43 @@ static void GLFWKeyCallback(GLFWwindow* window,
6868
}
6969

7070
void GLFWwindowSizeCallback(GLFWwindow* window, int width, int height) {
71+
int left, top;
72+
glfwGetWindowPos(window, &left, &top);
7173
FlutterWindowMetricsEvent event = {};
7274
event.struct_size = sizeof(event);
75+
event.window_id = 0;
76+
event.left = left * g_pixelRatio;
77+
event.top = top * g_pixelRatio;
7378
event.width = width * g_pixelRatio;
7479
event.height = height * g_pixelRatio;
7580
event.pixel_ratio = g_pixelRatio;
81+
82+
// TODO(gspencergoog): Currently, there is only one window. This will change
83+
// as multi-window support is added. See
84+
// https://github.com/flutter/flutter/issues/60131
85+
FlutterEngineSendWindowMetricsEvent(
86+
reinterpret_cast<FlutterEngine>(glfwGetWindowUserPointer(window)), &event,
87+
1);
88+
}
89+
90+
void GLFWwindowPosCallback(GLFWwindow* window, int left, int top) {
91+
int width, height;
92+
glfwGetWindowSize(window, &width, &height);
93+
FlutterWindowMetricsEvent event = {};
94+
event.struct_size = sizeof(event);
95+
event.window_id = 0;
96+
event.left = left * g_pixelRatio;
97+
event.top = top * g_pixelRatio;
98+
event.width = width * g_pixelRatio;
99+
event.height = height * g_pixelRatio;
100+
event.pixel_ratio = g_pixelRatio;
101+
102+
// TODO(gspencergoog): Currently, there is only one window. This will change
103+
// as multi-window support is added. See
104+
// https://github.com/flutter/flutter/issues/60131
76105
FlutterEngineSendWindowMetricsEvent(
77-
reinterpret_cast<FlutterEngine>(glfwGetWindowUserPointer(window)),
78-
&event);
106+
reinterpret_cast<FlutterEngine>(glfwGetWindowUserPointer(window)), &event,
107+
1);
79108
}
80109

81110
bool RunFlutter(GLFWwindow* window,
@@ -150,6 +179,7 @@ int main(int argc, const char* argv[]) {
150179

151180
glfwSetKeyCallback(window, GLFWKeyCallback);
152181
glfwSetWindowSizeCallback(window, GLFWwindowSizeCallback);
182+
glfwSetWindowPosCallback(window, GLFWwindowPosCallback);
153183
glfwSetMouseButtonCallback(window, GLFWmouseButtonCallback);
154184

155185
while (!glfwWindowShouldClose(window)) {

lib/ui/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ source_set_maybe_fuchsia_legacy("ui") {
103103
"window/pointer_data_packet.h",
104104
"window/pointer_data_packet_converter.cc",
105105
"window/pointer_data_packet_converter.h",
106+
"window/screen.cc",
107+
"window/screen.h",
108+
"window/screen_metrics.cc",
109+
"window/screen_metrics.h",
106110
"window/viewport_metrics.cc",
107111
"window/viewport_metrics.h",
108112
"window/window.cc",

lib/ui/compositing/scene.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ Scene::Scene(std::shared_ptr<flutter::Layer> rootLayer,
4242
uint32_t rasterizerTracingThreshold,
4343
bool checkerboardRasterCacheImages,
4444
bool checkerboardOffscreenLayers) {
45+
// TODO(gspencergoog): Currently, there is only one window. This will change
46+
// as multi-window support is added. See
47+
// https://github.com/flutter/flutter/issues/60131
4548
auto viewport_metrics = UIDartState::Current()
4649
->platform_configuration()
47-
->window()
48-
.viewport_metrics();
50+
->window(0)
51+
->viewport_metrics();
4952

5053
layer_tree_ = std::make_unique<LayerTree>(
5154
SkISize::Make(viewport_metrics.physical_width,

lib/ui/hooks.dart

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ part of dart.ui;
1111
@pragma('vm:entry-point')
1212
// ignore: unused_element
1313
void _updateWindowMetrics(
14+
Object windowId,
1415
double devicePixelRatio,
16+
double left,
17+
double top,
1518
double width,
1619
double height,
1720
double depth,
@@ -28,25 +31,6 @@ void _updateWindowMetrics(
2831
double systemGestureInsetBottom,
2932
double systemGestureInsetLeft,
3033
) {
31-
print('''
32-
Updated window metrics:
33-
devicePixelRatio: $devicePixelRatio
34-
width: $width
35-
height: $height
36-
depth: $depth
37-
viewPaddingTop: $viewPaddingTop
38-
viewPaddingRight: $viewPaddingRight
39-
viewPaddingBottom: $viewPaddingBottom
40-
viewPaddingLeft: $viewPaddingLeft
41-
viewInsetTop: $viewInsetTop
42-
viewInsetRight: $viewInsetRight
43-
viewInsetBottom: $viewInsetBottom
44-
viewInsetLeft: $viewInsetLeft
45-
systemGestureInsetTop: $systemGestureInsetTop
46-
systemGestureInsetRight: $systemGestureInsetRight
47-
systemGestureInsetBottom: $systemGestureInsetBottom
48-
systemGestureInsetLeft: $systemGestureInsetLeft
49-
''');
5034
window
5135
.._devicePixelRatio = devicePixelRatio
5236
.._physicalSize = Size(width, height)
@@ -74,6 +58,48 @@ Updated window metrics:
7458
_invoke(window.onMetricsChanged, window._onMetricsChangedZone);
7559
}
7660

61+
@pragma('vm:entry-point')
62+
// ignore: unused_element
63+
void _removeWindows(List<Object> removedIds) {
64+
// TODO(gspencergoog): Remove given IDs from screen metrics once dart::ui
65+
// understands screens. See https://github.com/flutter/flutter/issues/60131
66+
print('Removed windows: $removedIds');
67+
}
68+
69+
@pragma('vm:entry-point')
70+
// ignore: unused_element
71+
void _updateScreenMetrics(
72+
Object screenId,
73+
double left,
74+
double top,
75+
double width,
76+
double height,
77+
double devicePixelRatio,
78+
double viewPaddingTop,
79+
double viewPaddingRight,
80+
double viewPaddingBottom,
81+
double viewPaddingLeft,
82+
double viewInsetTop,
83+
double viewInsetRight,
84+
double viewInsetBottom,
85+
double viewInsetLeft,
86+
double systemGestureInsetTop,
87+
double systemGestureInsetRight,
88+
double systemGestureInsetBottom,
89+
double systemGestureInsetLeft,
90+
) {
91+
// TODO(gspencergoog): Once dart:ui understands screens, set their metrics
92+
// here. See https://github.com/flutter/flutter/issues/60131
93+
}
94+
95+
@pragma('vm:entry-point')
96+
// ignore: unused_element
97+
void _removeScreens(List<Object> removedIds) {
98+
// TODO(gspencergoog): Remove given IDs from screen metrics once dart::ui
99+
// understands screens. See https://github.com/flutter/flutter/issues/60131
100+
print('Removed screens: $removedIds');
101+
}
102+
77103
typedef _LocaleClosure = String? Function();
78104

79105
String? _localeClosure() {

lib/ui/painting/canvas.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,13 @@ void Canvas::drawShadow(const CanvasPath* path,
426426
Dart_ThrowException(
427427
ToDart("Canvas.drawShader called with non-genuine Path."));
428428
}
429+
// TODO(gspencergoog): Currently, there is only one window. This will change
430+
// as multi-window support is added. See
431+
// https://github.com/flutter/flutter/issues/60131
429432
SkScalar dpr = UIDartState::Current()
430433
->platform_configuration()
431-
->window()
432-
.viewport_metrics()
434+
->window(0)
435+
->viewport_metrics()
433436
.device_pixel_ratio;
434437
external_allocation_size_ += path->path().approximateBytesUsed();
435438
flutter::PhysicalShapeLayer::DrawShadow(canvas_, path->path(), color,

lib/ui/window/platform_configuration.cc

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
#include "flutter/lib/ui/compositing/scene.h"
88
#include "flutter/lib/ui/ui_dart_state.h"
99
#include "flutter/lib/ui/window/platform_message_response_dart.h"
10+
#include "flutter/lib/ui/window/screen.h"
1011
#include "flutter/lib/ui/window/window.h"
12+
#include "lib/ui/window/screen_metrics.h"
1113
#include "third_party/tonic/converter/dart_converter.h"
1214
#include "third_party/tonic/dart_args.h"
1315
#include "third_party/tonic/dart_library_natives.h"
@@ -188,7 +190,7 @@ PlatformConfigurationClient::~PlatformConfigurationClient() {}
188190

189191
PlatformConfiguration::PlatformConfiguration(
190192
PlatformConfigurationClient* client)
191-
: client_(client), window_(new Window({1.0, 0.0, 0.0})) {}
193+
: client_(client) {}
192194

193195
PlatformConfiguration::~PlatformConfiguration() {}
194196

@@ -197,11 +199,6 @@ void PlatformConfiguration::DidCreateIsolate() {
197199
Dart_LookupLibrary(tonic::ToDart("dart:ui")));
198200
}
199201

200-
void PlatformConfiguration::SetWindowMetrics(
201-
const ViewportMetrics& window_metrics) {
202-
window_->UpdateWindowMetrics(library_, window_metrics);
203-
}
204-
205202
void PlatformConfiguration::UpdateLocales(
206203
const std::vector<std::string>& locales) {
207204
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
@@ -439,4 +436,102 @@ void PlatformConfiguration::RegisterNatives(
439436
});
440437
}
441438

439+
void PlatformConfiguration::SetWindowMetrics(
440+
const std::vector<ViewportMetrics>& window_metrics) {
441+
WindowMap updated;
442+
for (const auto& metrics : window_metrics) {
443+
WindowMap::iterator found = windows_.find(metrics.view_id);
444+
if (found == windows_.end()) {
445+
// A new window that needs to be added
446+
std::shared_ptr<Window> new_window = std::make_shared<Window>(metrics);
447+
updated.insert(std::make_pair(metrics.view_id, new_window));
448+
new_window->UpdateWindowMetrics(library_, metrics);
449+
} else {
450+
// An existing window that needs to be updated, add it to the updated
451+
// list, and remove it from the existing screens.
452+
(*found).second->UpdateWindowMetrics(library_, metrics);
453+
updated.insert(*found);
454+
windows_.erase(found);
455+
}
456+
}
457+
458+
// Anything left in windows_ didn't exist in the window_metrics supplied, and
459+
// so will be removed.
460+
std::vector<int64_t> removed_ids;
461+
for (const auto& entry : windows_) {
462+
removed_ids.push_back(entry.first);
463+
}
464+
465+
windows_.swap(updated);
466+
467+
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
468+
if (!dart_state) {
469+
return;
470+
}
471+
tonic::DartState::Scope scope(dart_state);
472+
if (!removed_ids.empty()) {
473+
tonic::LogIfError(tonic::DartInvokeField(library_.value(), "_removeWindows",
474+
{
475+
tonic::ToDart(removed_ids),
476+
}));
477+
}
478+
}
479+
480+
void PlatformConfiguration::SetScreenMetrics(
481+
const std::vector<ScreenMetrics>& screen_metrics) {
482+
ScreenMap updated;
483+
for (const auto& metrics : screen_metrics) {
484+
ScreenMap::iterator found = screens_.find(metrics.screen_id);
485+
if (found == screens_.end()) {
486+
// A new screen that needs to be added
487+
std::shared_ptr<Screen> new_screen = std::make_shared<Screen>(metrics);
488+
updated.insert(std::make_pair(metrics.screen_id, new_screen));
489+
new_screen->UpdateScreenMetrics(library_, metrics);
490+
} else {
491+
// An existing screen that needs to be updated, add it to the updated
492+
// list, and remove it from the existing screens.
493+
(*found).second->UpdateScreenMetrics(library_, metrics);
494+
updated.insert(*found);
495+
screens_.erase(found);
496+
}
497+
}
498+
499+
// Anything left in screens_ didn't exist in the screen_metrics supplied, and
500+
// so will be removed.
501+
std::vector<int64_t> removed_ids;
502+
for (const auto& entry : screens_) {
503+
removed_ids.push_back(entry.first);
504+
}
505+
506+
screens_.swap(updated);
507+
508+
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
509+
if (!dart_state) {
510+
return;
511+
}
512+
tonic::DartState::Scope scope(dart_state);
513+
if (!removed_ids.empty()) {
514+
tonic::LogIfError(tonic::DartInvokeField(library_.value(), "_removeScreens",
515+
{
516+
tonic::ToDart(removed_ids),
517+
}));
518+
}
519+
}
520+
521+
std::shared_ptr<Window> PlatformConfiguration::window(int64_t window_id) {
522+
if (windows_.find(window_id) == windows_.end()) {
523+
FML_DLOG(WARNING) << "Unable to find window with id " << window_id;
524+
return nullptr;
525+
}
526+
return windows_.at(window_id);
527+
}
528+
529+
std::shared_ptr<Screen> PlatformConfiguration::screen(int64_t screen_id) {
530+
if (screens_.find(screen_id) == screens_.end()) {
531+
FML_DLOG(WARNING) << "Unable to find screen with id " << screen_id;
532+
return nullptr;
533+
}
534+
return screens_.at(screen_id);
535+
}
536+
442537
} // namespace flutter

0 commit comments

Comments
 (0)