diff --git a/src/core/output-layout.cpp b/src/core/output-layout.cpp index f25b1e9db..a7743b109 100644 --- a/src/core/output-layout.cpp +++ b/src/core/output-layout.cpp @@ -450,22 +450,76 @@ struct output_layout_output_t } } - wlr_output_mode select_default_mode() + wlr_output_mode select_default_mode(wf::output_config::mode_type_t default_heuristic) { wlr_output_mode *mode; - wl_list_for_each(mode, &handle->modes, link) + static wlr_output_mode __video_mode_all_zeroes{}; + + if (default_heuristic == output_config::MODE_AUTO) { - if (mode->preferred) + wl_list_for_each(mode, &handle->modes, link) { - return *mode; + if (mode->preferred) + { + return *mode; + } + } + } else + { + wlr_output_mode *biggest_mode = &__video_mode_all_zeroes; + + if (default_heuristic == output_config::MODE_HIGHRES) + { + /* Get the highest resolution compatible with the highest refresh rate. + * We measure it by calculating the area of each video mode. */ + + wl_list_for_each(mode, &handle->modes, link) + { + if ((mode->width * mode->height) > (biggest_mode->width * biggest_mode->height)) + { + biggest_mode = mode; + } + } + } else if (default_heuristic == output_config::MODE_HIGHRR) + { + int32_t max_refresh = 0; + + // Get the highest refresh rate out of all modes. + + wl_list_for_each(mode, &handle->modes, link) + { + if (mode->refresh > max_refresh) + { + max_refresh = mode->refresh; + } + } + + /* Get the highest resolution compatible with the highest refresh rate. + * We measure it by calculating the area of each video mode. */ + + wl_list_for_each(mode, &handle->modes, link) + { + if ((mode->refresh == max_refresh) && + ((mode->width * mode->height) > (biggest_mode->width * biggest_mode->height))) + { + biggest_mode = mode; + } + } + } + + // Don't return the dummy video mode. + if (biggest_mode != &__video_mode_all_zeroes) + { + return *biggest_mode; } } /* Couldn't find a preferred mode. Just return the last, which is * usually also the "largest" */ wl_list_for_each_reverse(mode, &handle->modes, link) - - return *mode; + { + return *mode; + } /* Finally, if there isn't any mode (for ex. wayland backend), * try the wlr_output resolution, falling back to 1200x720 @@ -552,10 +606,13 @@ struct output_layout_output_t wf::output_config::mode_t mode = mode_opt; wlr_output_mode tmp{}; - switch (mode.get_type()) + wf::output_config::mode_type_t mode_type = mode.get_type(); + switch (mode_type) { + case output_config::MODE_HIGHRES: + case output_config::MODE_HIGHRR: case output_config::MODE_AUTO: - state.mode = select_default_mode(); + state.mode = select_default_mode(mode_type); state.source = OUTPUT_IMAGE_SOURCE_SELF; break; @@ -564,7 +621,7 @@ struct output_layout_output_t tmp.width = mode.get_width(); tmp.height = mode.get_height(); tmp.refresh = mode.get_refresh(); - state.mode = (is_mode_supported(tmp) ? tmp : select_default_mode()); + state.mode = (is_mode_supported(tmp) ? tmp : select_default_mode(output_config::MODE_AUTO)); state.source = OUTPUT_IMAGE_SOURCE_SELF; break; @@ -574,7 +631,7 @@ struct output_layout_output_t case output_config::MODE_MIRROR: state.source = OUTPUT_IMAGE_SOURCE_MIRROR; - state.mode = select_default_mode(); + state.mode = select_default_mode(output_config::MODE_AUTO); state.mirror_from = mode.get_mirror_from(); break; } diff --git a/subprojects/wf-config b/subprojects/wf-config index d89d630ff..a2051f5d1 160000 --- a/subprojects/wf-config +++ b/subprojects/wf-config @@ -1 +1 @@ -Subproject commit d89d630ff3e3d8deb7813d6cd57b88e81ec059f9 +Subproject commit a2051f5d131a23acdcd96bfeb509d01cf57139ec