@@ -96,6 +96,10 @@ struct FlutterDesktopWindow {
9696
9797 // The ratio of pixels per screen coordinate for the window.
9898 double pixels_per_screen_coordinate = 1.0 ;
99+
100+ // Resizing triggers a window refresh, but the resize already updates Flutter.
101+ // To avoid double messages, the refresh after each resize is skipped.
102+ bool skip_next_window_refresh = false ;
99103};
100104
101105// Struct for storing state of a Flutter engine instance.
@@ -166,31 +170,53 @@ static double GetScreenCoordinatesPerInch() {
166170 return primary_monitor_mode->width / (primary_monitor_width_mm / 25.4 );
167171}
168172
173+ // Sends a window metrics update to the Flutter engine using the given
174+ // framebuffer size and the current window information in |state|.
175+ static void SendWindowMetrics (FlutterDesktopWindowControllerState* state,
176+ int width,
177+ int height) {
178+ double dpi = state->window_wrapper ->pixels_per_screen_coordinate *
179+ state->monitor_screen_coordinates_per_inch ;
180+
181+ FlutterWindowMetricsEvent event = {};
182+ event.struct_size = sizeof (event);
183+ event.width = width;
184+ event.height = height;
185+ // The Flutter pixel_ratio is defined as DPI/dp. Limit the ratio to a minimum
186+ // of 1 to avoid rendering a smaller UI on standard resolution monitors.
187+ event.pixel_ratio = std::max (dpi / kDpPerInch , 1.0 );
188+ FlutterEngineSendWindowMetricsEvent (state->engine , &event);
189+ }
190+
169191// When GLFW calls back to the window with a framebuffer size change, notify
170192// FlutterEngine about the new window metrics.
171- // The Flutter pixel_ratio is defined as DPI/dp.
172193static void GLFWFramebufferSizeCallback (GLFWwindow* window,
173194 int width_px,
174195 int height_px) {
175196 int width;
176197 glfwGetWindowSize (window, &width, nullptr );
177-
178- auto state = GetSavedWindowState (window);
198+ auto * state = GetSavedWindowState (window);
179199 state->window_wrapper ->pixels_per_screen_coordinate =
180200 width > 0 ? width_px / width : 1 ;
181201
182- double dpi = state->window_wrapper ->pixels_per_screen_coordinate *
183- state->monitor_screen_coordinates_per_inch ;
184- // Limit the ratio to 1 to avoid rendering a smaller UI in standard resolution
185- // monitors.
186- double pixel_ratio = std::max (dpi / kDpPerInch , 1.0 );
202+ SendWindowMetrics (state, width_px, height_px);
203+ state->window_wrapper ->skip_next_window_refresh = true ;
204+ }
187205
188- FlutterWindowMetricsEvent event = {};
189- event.struct_size = sizeof (event);
190- event.width = width_px;
191- event.height = height_px;
192- event.pixel_ratio = pixel_ratio;
193- FlutterEngineSendWindowMetricsEvent (state->engine , &event);
206+ // Indicates that the window needs to be redrawn.
207+ void GLFWWindowRefreshCallback (GLFWwindow* window) {
208+ auto * state = GetSavedWindowState (window);
209+ if (state->window_wrapper ->skip_next_window_refresh ) {
210+ state->window_wrapper ->skip_next_window_refresh = false ;
211+ return ;
212+ }
213+ // There's no engine API to request a redraw explicitly, so instead send a
214+ // window metrics event with the current size to trigger it.
215+ int width_px, height_px;
216+ glfwGetFramebufferSize (window, &width_px, &height_px);
217+ if (width_px > 0 && height_px > 0 ) {
218+ SendWindowMetrics (state, width_px, height_px);
219+ }
194220}
195221
196222// Sends a pointer event to the Flutter engine based on the given data.
@@ -589,6 +615,7 @@ FlutterDesktopWindowControllerRef FlutterDesktopCreateWindow(
589615
590616 // Set up GLFW callbacks for the window.
591617 glfwSetFramebufferSizeCallback (window, GLFWFramebufferSizeCallback);
618+ glfwSetWindowRefreshCallback (window, GLFWWindowRefreshCallback);
592619 GLFWAssignEventCallbacks (window);
593620
594621 return state.release ();
0 commit comments