config/output: Allow approximation of output refresh rate

Previous behavior was that only if resolution and refresh rate match
exactly, the mode was accepted. As fallback, the mode with the highest
refresh rate and the same resolution was chosen.

New behavior is that the mode with the closest match for the refresh
rate is used with a limit of up to 1Hz. The fallback behavior stays the same.

Additionally, the logging was made more verbose.
master
Tamino Bauknecht 1 year ago committed by Kenny Levinsen
parent f2425b5163
commit 0dfaf7ea63

@ -249,6 +249,8 @@ static void set_mode(struct wlr_output *output, struct wlr_output_state *pending
// as (int)(1000 * mHz / 1000.f) // as (int)(1000 * mHz / 1000.f)
// round() the result to avoid any error // round() the result to avoid any error
int mhz = (int)roundf(refresh_rate * 1000); int mhz = (int)roundf(refresh_rate * 1000);
// If no target refresh rate is given, match highest available
mhz = mhz <= 0 ? INT_MAX : mhz;
if (wl_list_empty(&output->modes) || custom) { if (wl_list_empty(&output->modes) || custom) {
sway_log(SWAY_DEBUG, "Assigning custom mode to %s", output->name); sway_log(SWAY_DEBUG, "Assigning custom mode to %s", output->name);
@ -258,23 +260,28 @@ static void set_mode(struct wlr_output *output, struct wlr_output_state *pending
} }
struct wlr_output_mode *mode, *best = NULL; struct wlr_output_mode *mode, *best = NULL;
int best_diff_mhz = INT_MAX;
wl_list_for_each(mode, &output->modes, link) { wl_list_for_each(mode, &output->modes, link) {
if (mode->width == width && mode->height == height) { if (mode->width == width && mode->height == height) {
if (mode->refresh == mhz) { int diff_mhz = abs(mode->refresh - mhz);
best = mode; if (diff_mhz < best_diff_mhz) {
break; best_diff_mhz = diff_mhz;
}
if (best == NULL || mode->refresh > best->refresh) {
best = mode; best = mode;
if (best_diff_mhz == 0) {
break;
}
} }
} }
} }
if (!best) { if (best) {
sway_log(SWAY_ERROR, "Configured mode for %s not available", output->name); sway_log(SWAY_INFO, "Assigning configured mode (%dx%d@%.3fHz) to %s",
sway_log(SWAY_INFO, "Picking preferred mode instead"); best->width, best->height, best->refresh / 1000.f, output->name);
best = wlr_output_preferred_mode(output);
} else { } else {
sway_log(SWAY_DEBUG, "Assigning configured mode to %s", output->name); best = wlr_output_preferred_mode(output);
sway_log(SWAY_INFO, "Configured mode (%dx%d@%.3fHz) not available, "
"applying preferred mode (%dx%d@%.3fHz)",
width, height, refresh_rate,
best->width, best->height, best->refresh / 1000.f);
} }
wlr_output_state_set_mode(pending, best); wlr_output_state_set_mode(pending, best);
} }

Loading…
Cancel
Save