Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@

namespace flutter {

// A data type for window position and size.
struct WindowFrame {
int left;
int top;
int width;
int height;
};

// A window displaying Flutter content.
class FlutterWindow {
public:
Expand Down Expand Up @@ -48,6 +56,30 @@ class FlutterWindow {
FlutterDesktopWindowSetIcon(window_, pixel_data, width, height);
}

// Returns the frame of the window, including any decoration (e.g., title
// bar), in screen coordinates.
WindowFrame GetFrame() {
WindowFrame frame = {};
FlutterDesktopWindowGetFrame(window_, &frame.left, &frame.top, &frame.width,
&frame.height);
return frame;
}

// Set the frame of the window, including any decoration (e.g., title
// bar), in screen coordinates.
void SetFrame(const WindowFrame& frame) {
FlutterDesktopWindowSetFrame(window_, frame.left, frame.top, frame.width,
frame.height);
}

// Returns the number of pixels per screen coordinate for the window.
//
// Flutter uses pixel coordinates, so this is the ratio of positions and sizes
// seen by Flutter as compared to the screen.
double GetScaleFactor() {
return FlutterDesktopWindowGetScaleFactor(window_);
}

private:
// Handle for interacting with the C API's window.
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,34 @@ void FlutterDesktopWindowSetIcon(FlutterDesktopWindowRef flutter_window,
}
}

void FlutterDesktopWindowGetFrame(FlutterDesktopWindowRef flutter_window,
int* x,
int* y,
int* width,
int* height) {
if (s_stub_implementation) {
s_stub_implementation->GetWindowFrame(x, y, width, height);
}
}

void FlutterDesktopWindowSetFrame(FlutterDesktopWindowRef flutter_window,
int x,
int y,
int width,
int height) {
if (s_stub_implementation) {
s_stub_implementation->SetWindowFrame(x, y, width, height);
}
}

double FlutterDesktopWindowGetScaleFactor(
FlutterDesktopWindowRef flutter_window) {
if (s_stub_implementation) {
return s_stub_implementation->GetWindowScaleFactor();
}
return 1.0;
}

void FlutterDesktopRunWindowLoop(FlutterDesktopWindowControllerRef controller) {
if (s_stub_implementation) {
s_stub_implementation->RunWindowLoop();
Expand Down
11 changes: 11 additions & 0 deletions shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ class StubFlutterGlfwApi {
// Called for FlutterDesktopWindowSetIcon.
virtual void SetWindowIcon(uint8_t* pixel_data, int width, int height) {}

// Called for FlutterDesktopWindowGetFrame.
virtual void GetWindowFrame(int* x, int* y, int* width, int* height) {
x = y = width = height = 0;
}

// Called for FlutterDesktopWindowGetFrame.
virtual void SetWindowFrame(int x, int y, int width, int height) {}

// Called for FlutterDesktopWindowGetScaleFactor.
virtual double GetWindowScaleFactor() { return 1.0; }

// Called for FlutterDesktopRunWindowLoop.
virtual void RunWindowLoop() {}

Expand Down
68 changes: 58 additions & 10 deletions shell/platform/glfw/flutter_glfw.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ struct FlutterDesktopWindowControllerState {
// The screen coordinates per inch on the primary monitor. Defaults to a sane
// value based on pixel_ratio 1.0.
double monitor_screen_coordinates_per_inch = kDpPerInch;
// The ratio of pixels per screen coordinate for the window.
double window_pixels_per_screen_coordinate = 1.0;
};

// Opaque reference for the GLFW window itself. This is separate from the
Expand All @@ -82,6 +80,9 @@ struct FlutterDesktopWindow {

// Whether or not to track mouse movements to send kHover events.
bool hover_tracking_enabled = false;

// The ratio of pixels per screen coordinate for the window.
double pixels_per_screen_coordinate = 1.0;
};

// Struct for storing state of a Flutter engine instance.
Expand Down Expand Up @@ -152,9 +153,9 @@ static void GLFWFramebufferSizeCallback(GLFWwindow* window,
glfwGetWindowSize(window, &width, nullptr);

auto state = GetSavedWindowState(window);
state->window_pixels_per_screen_coordinate = width_px / width;
state->window_wrapper->pixels_per_screen_coordinate = width_px / width;

double dpi = state->window_pixels_per_screen_coordinate *
double dpi = state->window_wrapper->pixels_per_screen_coordinate *
state->monitor_screen_coordinates_per_inch;
// Limit the ratio to 1 to avoid rendering a smaller UI in standard resolution
// monitors.
Expand Down Expand Up @@ -200,10 +201,12 @@ static void SendPointerEventWithData(GLFWwindow* window,
std::chrono::high_resolution_clock::now().time_since_epoch())
.count();
// Convert all screen coordinates to pixel coordinates.
event.x *= state->window_pixels_per_screen_coordinate;
event.y *= state->window_pixels_per_screen_coordinate;
event.scroll_delta_x *= state->window_pixels_per_screen_coordinate;
event.scroll_delta_y *= state->window_pixels_per_screen_coordinate;
double pixels_per_coordinate =
state->window_wrapper->pixels_per_screen_coordinate;
event.x *= pixels_per_coordinate;
event.y *= pixels_per_coordinate;
event.scroll_delta_x *= pixels_per_coordinate;
event.scroll_delta_y *= pixels_per_coordinate;

FlutterEngineSendPointerEvent(state->engine, &event, 1);

Expand Down Expand Up @@ -579,9 +582,54 @@ void FlutterDesktopWindowSetIcon(FlutterDesktopWindowRef flutter_window,
uint8_t* pixel_data,
int width,
int height) {
GLFWwindow* window = flutter_window->window;
GLFWimage image = {width, height, static_cast<unsigned char*>(pixel_data)};
glfwSetWindowIcon(window, pixel_data ? 1 : 0, &image);
glfwSetWindowIcon(flutter_window->window, pixel_data ? 1 : 0, &image);
}

void FlutterDesktopWindowGetFrame(FlutterDesktopWindowRef flutter_window,
int* x,
int* y,
int* width,
int* height) {
glfwGetWindowPos(flutter_window->window, x, y);
glfwGetWindowSize(flutter_window->window, width, height);
// The above gives content area size and position; adjust for the window
// decoration to give actual window frame.
int frame_left, frame_top, frame_right, frame_bottom;
glfwGetWindowFrameSize(flutter_window->window, &frame_left, &frame_top,
&frame_right, &frame_bottom);
if (x) {
*x -= frame_left;
}
if (y) {
*y -= frame_top;
}
if (width) {
*width += frame_left + frame_right;
}
if (height) {
*height += frame_top + frame_bottom;
}
}

void FlutterDesktopWindowSetFrame(FlutterDesktopWindowRef flutter_window,
int x,
int y,
int width,
int height) {
// Get the window decoration sizes to adjust, since the GLFW setters take
// content position and size.
int frame_left, frame_top, frame_right, frame_bottom;
glfwGetWindowFrameSize(flutter_window->window, &frame_left, &frame_top,
&frame_right, &frame_bottom);
glfwSetWindowPos(flutter_window->window, x + frame_left, y + frame_top);
glfwSetWindowSize(flutter_window->window, width - frame_left - frame_right,
height - frame_top - frame_bottom);
}

double FlutterDesktopWindowGetScaleFactor(
FlutterDesktopWindowRef flutter_window) {
return flutter_window->pixels_per_screen_coordinate;
}

void FlutterDesktopRunWindowLoop(FlutterDesktopWindowControllerRef controller) {
Expand Down
21 changes: 21 additions & 0 deletions shell/platform/glfw/public/flutter_glfw.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,27 @@ FLUTTER_EXPORT void FlutterDesktopWindowSetIcon(
int width,
int height);

// Gets the position and size of |flutter_window| in screen coordinates.
FLUTTER_EXPORT void FlutterDesktopWindowGetFrame(
FlutterDesktopWindowRef flutter_window,
int* x,
int* y,
int* width,
int* height);

// Sets the position and size of |flutter_window| in screen coordinates.
FLUTTER_EXPORT void FlutterDesktopWindowSetFrame(
FlutterDesktopWindowRef flutter_window,
int x,
int y,
int width,
int height);

// Returns the scale factor--the number of pixels per screen coordinate--for
// |flutter_window|.
FLUTTER_EXPORT double FlutterDesktopWindowGetScaleFactor(
FlutterDesktopWindowRef flutter_window);

// Runs an instance of a headless Flutter engine.
//
// The |assets_path| is the path to the flutter_assets folder for the Flutter
Expand Down