diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index cc2b18eb2..1a2338db9 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -496,8 +496,18 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager) meta_mode->name = g_strndup (mode->name, DRM_DISPLAY_MODE_LEN); meta_mode->width = mode->hdisplay; meta_mode->height = mode->vdisplay; - meta_mode->refresh_rate = (1000 * mode->clock / - ((float)mode->htotal * mode->vtotal)); + + /* Calculate refresh rate in milliHz first for extra precision. */ + meta_mode->refresh_rate = (mode->clock * 1000000LL) / mode->htotal; + meta_mode->refresh_rate += (mode->vtotal / 2); + meta_mode->refresh_rate /= mode->vtotal; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + meta_mode->refresh_rate *= 2; + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + meta_mode->refresh_rate /= 2; + if (mode->vscan > 1) + meta_mode->refresh_rate /= mode->vscan; + meta_mode->refresh_rate /= 1000.0; meta_mode->driver_private = g_slice_dup (drmModeModeInfo, mode); meta_mode->driver_notify = (GDestroyNotify)meta_monitor_mode_destroy_notify; diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c index 1a7d16efa..df199499f 100644 --- a/src/wayland/meta-wayland-outputs.c +++ b/src/wayland/meta-wayland-outputs.c @@ -99,7 +99,7 @@ bind_output (struct wl_client *client, mode_flags, (int)monitor_info->rect.width, (int)monitor_info->rect.height, - (int)monitor_info->refresh_rate); + (int)(monitor_info->refresh_rate * 1000)); if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) wl_output_send_scale (resource, output->scale); @@ -160,7 +160,7 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output, mode_flags, (int)monitor_info->rect.width, (int)monitor_info->rect.height, - (int)monitor_info->refresh_rate); + (int)(monitor_info->refresh_rate * 1000)); } /* It's very important that we change the output pointer here, as