diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index f30cbff4544..f97b5621e5d 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -1800,59 +1800,57 @@ Ref DisplayServerX11::screen_get_image(int p_screen) const { float DisplayServerX11::screen_get_refresh_rate(int p_screen) const { _THREAD_SAFE_METHOD_ + ERR_FAIL_COND_V_MSG(!xrandr_ext_ok || !xrr_get_monitors, SCREEN_REFRESH_RATE_FALLBACK, "XRandR extension is not available."); + p_screen = _get_screen_index(p_screen); int screen_count = get_screen_count(); ERR_FAIL_INDEX_V(p_screen, screen_count, SCREEN_REFRESH_RATE_FALLBACK); - //Use xrandr to get screen refresh rate. - if (xrandr_ext_ok) { - XRRScreenResources *screen_info = XRRGetScreenResourcesCurrent(x11_display, windows[MAIN_WINDOW_ID].x11_window); - if (screen_info) { - RRMode current_mode = 0; - xrr_monitor_info *monitors = nullptr; - - if (xrr_get_monitors) { - int count = 0; - monitors = xrr_get_monitors(x11_display, windows[MAIN_WINDOW_ID].x11_window, true, &count); - ERR_FAIL_INDEX_V(p_screen, count, SCREEN_REFRESH_RATE_FALLBACK); - } else { - ERR_PRINT("An error occurred while trying to get the screen refresh rate."); - return SCREEN_REFRESH_RATE_FALLBACK; - } - - bool found_active_mode = false; - for (int crtc = 0; crtc < screen_info->ncrtc; crtc++) { // Loop through outputs to find which one is currently outputting. - XRRCrtcInfo *monitor_info = XRRGetCrtcInfo(x11_display, screen_info, screen_info->crtcs[crtc]); - if (monitor_info->x != monitors[p_screen].x || monitor_info->y != monitors[p_screen].y) { // If X and Y aren't the same as the monitor we're looking for, this isn't the right monitor. Continue. - continue; - } - - if (monitor_info->mode != None) { - current_mode = monitor_info->mode; - found_active_mode = true; - break; - } - } - - if (found_active_mode) { - for (int mode = 0; mode < screen_info->nmode; mode++) { - XRRModeInfo m_info = screen_info->modes[mode]; - if (m_info.id == current_mode) { - // Snap to nearest 0.01 to stay consistent with other platforms. - return Math::snapped((float)m_info.dotClock / ((float)m_info.hTotal * (float)m_info.vTotal), 0.01); - } - } - } - - ERR_PRINT("An error occurred while trying to get the screen refresh rate."); // We should have returned the refresh rate by now. An error must have occurred. - return SCREEN_REFRESH_RATE_FALLBACK; - } else { - ERR_PRINT("An error occurred while trying to get the screen refresh rate."); - return SCREEN_REFRESH_RATE_FALLBACK; + int target_x; + int target_y; + { + int count = 0; + xrr_monitor_info *monitors = xrr_get_monitors(x11_display, windows[MAIN_WINDOW_ID].x11_window, true, &count); + ERR_FAIL_NULL_V(monitors, SCREEN_REFRESH_RATE_FALLBACK); + if (count <= p_screen) { + xrr_free_monitors(monitors); + ERR_FAIL_V_MSG(SCREEN_REFRESH_RATE_FALLBACK, vformat("Invalid screen index: %d (count: %d).", p_screen, count)); } + target_x = monitors[p_screen].x; + target_y = monitors[p_screen].y; + xrr_free_monitors(monitors); } - ERR_PRINT("An error occurred while trying to get the screen refresh rate."); - return SCREEN_REFRESH_RATE_FALLBACK; + + XRRScreenResources *screen_res = XRRGetScreenResourcesCurrent(x11_display, windows[MAIN_WINDOW_ID].x11_window); + ERR_FAIL_NULL_V(screen_res, SCREEN_REFRESH_RATE_FALLBACK); + + XRRModeInfo *mode_info = nullptr; + for (int crtc = 0; crtc < screen_res->ncrtc; crtc++) { // Loop through outputs to find which one is currently outputting. + XRRCrtcInfo *monitor_info = XRRGetCrtcInfo(x11_display, screen_res, screen_res->crtcs[crtc]); + if (monitor_info->x != target_x || monitor_info->y != target_y || monitor_info->mode == None) { + XRRFreeCrtcInfo(monitor_info); + continue; + } + for (int mode = 0; mode < screen_res->nmode; mode++) { + if (screen_res->modes[mode].id == monitor_info->mode) { + mode_info = &screen_res->modes[mode]; + } + } + XRRFreeCrtcInfo(monitor_info); + break; + } + + float result; + if (mode_info) { + // Snap to nearest 0.01 to stay consistent with other platforms. + result = Math::snapped((float)mode_info->dotClock / ((float)mode_info->hTotal * (float)mode_info->vTotal), 0.01); + } else { + ERR_PRINT("An error occurred while trying to get the screen refresh rate."); + result = SCREEN_REFRESH_RATE_FALLBACK; + } + + XRRFreeScreenResources(screen_res); + return result; } #ifdef DBUS_ENABLED