Skip to content

Commit d591691

Browse files
authored
Merge pull request #5 from google/master
Merge from google/flutter-desktop-embedding@master
2 parents c06222b + ff138f8 commit d591691

File tree

5 files changed

+98
-36
lines changed

5 files changed

+98
-36
lines changed

.travis.yaml renamed to .travis.yml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
matrix:
22
include:
33
- os: linux
4-
languge: cpp
4+
dist: xenial
5+
language: cpp
56
before_install:
67
- sudo apt-get update
78
install:
@@ -13,13 +14,13 @@ matrix:
1314
- make -C example/linux
1415

1516
- os: linux
16-
languge: cpp
17+
dist: xenial
18+
language: cpp
1719
before_install:
1820
- sudo apt-get update
1921
install:
2022
- build/travis/linux/install_dependencies
2123
- build/travis/install_flutter $TRAVIS_BUILD_DIR/..
22-
- sudo apt-get install -y ninja-build
2324
- build/travis/linux/install_gn bin
2425
before_script:
2526
- export PATH=$PATH:$TRAVIS_BUILD_DIR/bin
@@ -28,8 +29,14 @@ matrix:
2829

2930
- os: osx
3031
language: objective-c
31-
xcode_project: example/macos/ExmapleEmbedder.xcodeproj
32+
xcode_project: example/macos/ExampleEmbedder.xcodeproj
3233
xcode_scheme: ExampleEmbedder
3334
install:
3435
- build/travis/install_flutter $TRAVIS_BUILD_DIR/..
36+
# Override the build command to remove 'test'. The example embedder
37+
# doesn't have any unit tests, and while a UI test to ensure that it
38+
# launches would be useful, that's currently broken by:
39+
# https://travis-ci.community/t/issue-cant-run-macos-ui-tests-with-xcode10-1-image/1445
40+
script:
41+
- set -o pipefail && xcodebuild -project $TRAVIS_XCODE_PROJECT -scheme $TRAVIS_XCODE_SCHEME build | xcpretty
3542

build/travis/install_flutter

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,5 @@ if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
3636
tar xf "${TEMP_LOCATION}" -C "$1"
3737
else
3838
curl -o "${TEMP_LOCATION}" "${DOWNLOAD_URI}"
39-
unzip "${TEMP_LOCATION}" -d "$1"
39+
unzip -q "${TEMP_LOCATION}" -d "$1"
4040
fi

build/travis/linux/install_gn

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,18 @@
1616

1717
set -e
1818

19-
readonly DOWNLOAD_URI=https://chrome-infra-packages.appspot.com/dl/gn/gn/linux-amd64/+/latest
20-
readonly TEMP_LOCATION=/tmp/gn.zip
19+
readonly GN_URI=https://chrome-infra-packages.appspot.com/dl/gn/gn/linux-amd64/+/latest
20+
readonly NINJA_URI=https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-linux.zip
21+
readonly TEMP_LOCATION=/tmp/tool.zip
2122

22-
wget -O "${TEMP_LOCATION}" "${DOWNLOAD_URI}"
23+
# Download and install GN.
24+
wget -O "${TEMP_LOCATION}" "${GN_URI}"
2325
unzip -d "$1" "${TEMP_LOCATION}"
26+
rm "${TEMP_LOCATION}"
27+
28+
# Download and install ninja.
29+
# This is done directly, instead of via apt-get, because the version
30+
# available in apt-get may not be new enough for the latest GN.
31+
wget -O "${TEMP_LOCATION}" "${NINJA_URI}"
32+
unzip -d "$1" "${TEMP_LOCATION}"
33+
rm "${TEMP_LOCATION}"

example/macos/ExampleEmbedder.xcodeproj/xcshareddata/xcschemes/ExampleEmbedder.xcscheme

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
2929
shouldUseLaunchSchemeArgsEnv = "YES">
3030
<Testables>
31+
<TestableReference
32+
skipped = "NO">
33+
<BuildableReference
34+
BuildableIdentifier = "primary"
35+
BlueprintIdentifier = "00380F9121DF178D00097171"
36+
BuildableName = "ExampleEmbedderUITests.xctest"
37+
BlueprintName = "ExampleEmbedderUITests"
38+
ReferencedContainer = "container:ExampleEmbedder.xcodeproj">
39+
</BuildableReference>
40+
</TestableReference>
3141
</Testables>
3242
<MacroExpansion>
3343
<BuildableReference

library/common/glfw/embedder.cc

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444

4545
static_assert(FLUTTER_ENGINE_VERSION == 1, "");
4646

47+
static constexpr double kDpPerInch = 160.0;
48+
4749
// Struct for storing state within an instance of the GLFW Window.
4850
struct FlutterEmbedderState {
4951
FlutterEngine engine;
@@ -57,6 +59,12 @@ struct FlutterEmbedderState {
5759
// Handles raw key interactions from GLFW.
5860
// TODO: Revisit ownership model once Issue #102 is resolved.
5961
std::unique_ptr<flutter_desktop_embedding::KeyEventHandler> key_event_handler;
62+
63+
// The screen coordinates per inch on the primary monitor. Defaults to a sane
64+
// value based on pixel_ratio 1.0.
65+
double monitor_screen_coordinates_per_inch = kDpPerInch;
66+
// The ratio of pixels per screen coordinate for the window.
67+
double window_pixels_per_screen_coordinate = 1.0;
6068
};
6169

6270
static constexpr char kDefaultWindowTitle[] = "Flutter";
@@ -67,41 +75,78 @@ static FlutterEmbedderState *GetSavedEmbedderState(GLFWwindow *window) {
6775
glfwGetWindowUserPointer(window));
6876
}
6977

78+
// Returns the number of screen coordinates per inch for the main monitor.
79+
// If the information is unavailable, returns a default value that assumes
80+
// that a screen coordinate is one dp.
81+
static double GetScreenCoordinatesPerInch() {
82+
auto *primary_monitor = glfwGetPrimaryMonitor();
83+
auto *primary_monitor_mode = glfwGetVideoMode(primary_monitor);
84+
int primary_monitor_width_mm;
85+
glfwGetMonitorPhysicalSize(primary_monitor, &primary_monitor_width_mm,
86+
nullptr);
87+
if (primary_monitor_width_mm == 0) {
88+
return kDpPerInch;
89+
}
90+
return primary_monitor_mode->width / (primary_monitor_width_mm / 25.4);
91+
}
92+
93+
// When GLFW calls back to the window with a framebuffer size change, notify
94+
// FlutterEngine about the new window metrics.
95+
// The Flutter pixel_ratio is defined as DPI/dp.
96+
static void GLFWFramebufferSizeCallback(GLFWwindow *window, int width_px,
97+
int height_px) {
98+
int width;
99+
glfwGetWindowSize(window, &width, nullptr);
100+
101+
auto state = GetSavedEmbedderState(window);
102+
state->window_pixels_per_screen_coordinate = width_px / width;
103+
104+
double dpi = state->window_pixels_per_screen_coordinate *
105+
state->monitor_screen_coordinates_per_inch;
106+
107+
FlutterWindowMetricsEvent event = {};
108+
event.struct_size = sizeof(event);
109+
event.width = width_px;
110+
event.height = height_px;
111+
event.pixel_ratio = dpi / kDpPerInch;
112+
FlutterEngineSendWindowMetricsEvent(state->engine, &event);
113+
}
114+
70115
// When GLFW calls back to the window with a cursor position move, forwards to
71116
// FlutterEngine as a pointer event with appropriate phase.
72-
static void GLFWcursorPositionCallbackAtPhase(GLFWwindow *window,
117+
static void GLFWCursorPositionCallbackAtPhase(GLFWwindow *window,
73118
FlutterPointerPhase phase,
74119
double x, double y) {
120+
auto state = GetSavedEmbedderState(window);
75121
FlutterPointerEvent event = {};
76122
event.struct_size = sizeof(event);
77123
event.phase = phase;
78-
event.x = x;
79-
event.y = y;
124+
event.x = x * state->window_pixels_per_screen_coordinate;
125+
event.y = y * state->window_pixels_per_screen_coordinate;
80126
event.timestamp =
81127
std::chrono::duration_cast<std::chrono::microseconds>(
82128
std::chrono::high_resolution_clock::now().time_since_epoch())
83129
.count();
84-
FlutterEngineSendPointerEvent(GetSavedEmbedderState(window)->engine, &event,
85-
1);
130+
FlutterEngineSendPointerEvent(state->engine, &event, 1);
86131
}
87132

88133
// Reports cursor move to the Flutter engine.
89-
static void GLFWcursorPositionCallback(GLFWwindow *window, double x, double y) {
90-
GLFWcursorPositionCallbackAtPhase(window, FlutterPointerPhase::kMove, x, y);
134+
static void GLFWCursorPositionCallback(GLFWwindow *window, double x, double y) {
135+
GLFWCursorPositionCallbackAtPhase(window, FlutterPointerPhase::kMove, x, y);
91136
}
92137

93138
// Reports mouse button press to the Flutter engine.
94-
static void GLFWmouseButtonCallback(GLFWwindow *window, int key, int action,
139+
static void GLFWMouseButtonCallback(GLFWwindow *window, int key, int action,
95140
int mods) {
96141
double x, y;
97142
if (key == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS) {
98143
glfwGetCursorPos(window, &x, &y);
99-
GLFWcursorPositionCallbackAtPhase(window, FlutterPointerPhase::kDown, x, y);
100-
glfwSetCursorPosCallback(window, GLFWcursorPositionCallback);
144+
GLFWCursorPositionCallbackAtPhase(window, FlutterPointerPhase::kDown, x, y);
145+
glfwSetCursorPosCallback(window, GLFWCursorPositionCallback);
101146
}
102147
if (key == GLFW_MOUSE_BUTTON_1 && action == GLFW_RELEASE) {
103148
glfwGetCursorPos(window, &x, &y);
104-
GLFWcursorPositionCallbackAtPhase(window, FlutterPointerPhase::kUp, x, y);
149+
GLFWCursorPositionCallbackAtPhase(window, FlutterPointerPhase::kUp, x, y);
105150
glfwSetCursorPosCallback(window, nullptr);
106151
}
107152
}
@@ -123,24 +168,12 @@ static void GLFWKeyCallback(GLFWwindow *window, int key, int scancode,
123168
}
124169
}
125170

126-
// Reports window size changes to the Flutter engine.
127-
static void GLFWwindowSizeCallback(GLFWwindow *window, int width, int height) {
128-
FlutterWindowMetricsEvent event = {};
129-
event.struct_size = sizeof(event);
130-
event.width = width;
131-
event.height = height;
132-
// TODO: Handle pixel ratio for different DPI monitors.
133-
event.pixel_ratio = 1.0;
134-
FlutterEngineSendWindowMetricsEvent(GetSavedEmbedderState(window)->engine,
135-
&event);
136-
}
137-
138171
// Flushes event queue and then assigns default window callbacks.
139172
static void GLFWAssignEventCallbacks(GLFWwindow *window) {
140173
glfwPollEvents();
141174
glfwSetKeyCallback(window, GLFWKeyCallback);
142175
glfwSetCharCallback(window, GLFWCharCallback);
143-
glfwSetMouseButtonCallback(window, GLFWmouseButtonCallback);
176+
glfwSetMouseButtonCallback(window, GLFWMouseButtonCallback);
144177
}
145178

146179
// Clears default window events.
@@ -311,10 +344,12 @@ GLFWwindow *CreateFlutterWindow(size_t initial_width, size_t initial_height,
311344

312345
AddPlugin(window, std::move(input_plugin));
313346

314-
int width, height;
315-
glfwGetWindowSize(window, &width, &height);
316-
GLFWwindowSizeCallback(window, width, height);
317-
glfwSetWindowSizeCallback(window, GLFWwindowSizeCallback);
347+
state->monitor_screen_coordinates_per_inch = GetScreenCoordinatesPerInch();
348+
int width_px, height_px;
349+
glfwGetFramebufferSize(window, &width_px, &height_px);
350+
glfwSetFramebufferSizeCallback(window, GLFWFramebufferSizeCallback);
351+
GLFWFramebufferSizeCallback(window, width_px, height_px);
352+
318353
GLFWAssignEventCallbacks(window);
319354
return window;
320355
}

0 commit comments

Comments
 (0)