Add resize functions to GLFW shell (flutter/engine#8864)

Adds methods to get and set the window size, as well as to query the
window's scale factor. This is useful both for custom clients, and for
building a window resize plugin to prototype what will eventually likely
be a system channel.
This commit is contained in:
stuartmorgan 2019-05-06 16:22:40 -04:00 committed by GitHub
parent 71903838b8
commit fe6ed0bd72
5 changed files with 150 additions and 10 deletions

View File

@ -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:
@ -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.
//

View File

@ -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();

View File

@ -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() {}

View File

@ -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
@ -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.
@ -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.
@ -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);
@ -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) {

View File

@ -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