@@ -245,6 +245,7 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint {
245245 flutterArguments.command_line_argv = &arguments[0 ];
246246 flutterArguments.platform_message_callback = (FlutterPlatformMessageCallback)OnPlatformMessage;
247247 flutterArguments.custom_dart_entrypoint = entrypoint.UTF8String ;
248+ flutterArguments.display_refresh_rate = [self displayRefreshRate ];
248249 static size_t sTaskRunnerIdentifiers = 0 ;
249250 const FlutterTaskRunnerDescription cocoa_task_runner_description = {
250251 .struct_size = sizeof (FlutterTaskRunnerDescription),
@@ -317,6 +318,29 @@ - (NSOpenGLContext*)resourceContext {
317318 return _resourceContext;
318319}
319320
321+ - (float )displayRefreshRate {
322+ NSDictionary * description = [[NSScreen mainScreen ] deviceDescription ];
323+ CGDirectDisplayID displayId = [[description objectForKey: @" NSScreenNumber" ] unsignedIntValue ];
324+ CGDisplayModeRef displayModeRef = CGDisplayCopyDisplayMode (displayId);
325+ double refreshRate = CGDisplayModeGetRefreshRate (displayModeRef);
326+
327+ // The above can return zero always on some devices.
328+ // See: https://github.com/glfw/glfw/issues/137
329+ if (refreshRate == 0 .0f ) {
330+ CVDisplayLinkRef displayLinkRef;
331+ CVDisplayLinkCreateWithActiveCGDisplays (&displayLinkRef);
332+
333+ CVTime nominal = CVDisplayLinkGetNominalOutputVideoRefreshPeriod (displayLinkRef);
334+ if (!(nominal.flags & kCVTimeIsIndefinite )) {
335+ refreshRate = static_cast <double >(nominal.timeScale ) / nominal.timeValue ;
336+ }
337+
338+ CVDisplayLinkRelease (displayLinkRef);
339+ }
340+
341+ return static_cast <float >(refreshRate);
342+ }
343+
320344- (void )updateWindowMetrics {
321345 if (!_engine) {
322346 return ;
0 commit comments