diff options
author | Simon Ser <contact@emersion.fr> | 2019-12-10 14:40:21 +0100 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2019-12-12 19:00:24 -0500 |
commit | 2f84d6e349d12f3293c44268bc5c8551340e5787 (patch) | |
tree | b9ff4438269faef7dc3c44ba5237e709a324191b /sway | |
parent | Add seat <seat> idle_{inhibit,wake} <sources...> (diff) | |
download | sway-2f84d6e349d12f3293c44268bc5c8551340e5787.tar.gz sway-2f84d6e349d12f3293c44268bc5c8551340e5787.tar.zst sway-2f84d6e349d12f3293c44268bc5c8551340e5787.zip |
Auto-detect output scale
If the screen DPI is high enough, auto-enable scale=2 (if the user
hasn't set the scale).
Uses heuristics based on [1].
[1]: https://gitlab.gnome.org/GNOME/mutter/blob/05217066171992b0bc50882869aad6385285c878/src/backends/meta-monitor.c#L1590
Closes: https://github.com/swaywm/sway/issues/1800
Diffstat (limited to 'sway')
-rw-r--r-- | sway/config/output.c | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/sway/config/output.c b/sway/config/output.c index 21a12b8f..0bb375c1 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -263,6 +263,49 @@ static bool set_mode(struct wlr_output *output, int width, int height, | |||
263 | return wlr_output_set_mode(output, best); | 263 | return wlr_output_set_mode(output, best); |
264 | } | 264 | } |
265 | 265 | ||
266 | /* Some manufacturers hardcode the aspect-ratio of the output in the physical | ||
267 | * size field. */ | ||
268 | static bool phys_size_is_aspect_ratio(struct wlr_output *output) { | ||
269 | return (output->phys_width == 1600 && output->phys_height == 900) || | ||
270 | (output->phys_width == 1600 && output->phys_height == 1000) || | ||
271 | (output->phys_width == 160 && output->phys_height == 90) || | ||
272 | (output->phys_width == 160 && output->phys_height == 100) || | ||
273 | (output->phys_width == 16 && output->phys_height == 9) || | ||
274 | (output->phys_width == 16 && output->phys_height == 10); | ||
275 | } | ||
276 | |||
277 | // The minimum DPI at which we turn on a scale of 2 | ||
278 | #define HIDPI_DPI_LIMIT (2 * 96) | ||
279 | // The minimum screen height at which we turn on a scale of 2 | ||
280 | #define HIDPI_MIN_HEIGHT 1200 | ||
281 | // 1 inch = 25.4 mm | ||
282 | #define MM_PER_INCH 25.4 | ||
283 | |||
284 | static int compute_default_scale(struct wlr_output *output) { | ||
285 | int width, height; | ||
286 | wlr_output_transformed_resolution(output, &width, &height); | ||
287 | if (height < HIDPI_MIN_HEIGHT) { | ||
288 | return 1; | ||
289 | } | ||
290 | |||
291 | if (output->phys_width == 0 || output->phys_height == 0) { | ||
292 | return 1; | ||
293 | } | ||
294 | |||
295 | if (phys_size_is_aspect_ratio(output)) { | ||
296 | return 1; | ||
297 | } | ||
298 | |||
299 | double dpi_x = (double) width / (output->phys_width / MM_PER_INCH); | ||
300 | double dpi_y = (double) height / (output->phys_height / MM_PER_INCH); | ||
301 | sway_log(SWAY_DEBUG, "Output DPI: %fx%f", dpi_x, dpi_y); | ||
302 | if (dpi_x <= HIDPI_DPI_LIMIT || dpi_y <= HIDPI_DPI_LIMIT) { | ||
303 | return 1; | ||
304 | } | ||
305 | |||
306 | return 2; | ||
307 | } | ||
308 | |||
266 | bool apply_output_config(struct output_config *oc, struct sway_output *output) { | 309 | bool apply_output_config(struct output_config *oc, struct sway_output *output) { |
267 | if (output == root->noop_output) { | 310 | if (output == root->noop_output) { |
268 | return false; | 311 | return false; |
@@ -313,9 +356,16 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { | |||
313 | } | 356 | } |
314 | output->current_mode = wlr_output->current_mode; | 357 | output->current_mode = wlr_output->current_mode; |
315 | 358 | ||
359 | float scale; | ||
316 | if (oc && oc->scale > 0) { | 360 | if (oc && oc->scale > 0) { |
317 | sway_log(SWAY_DEBUG, "Set %s scale to %f", oc->name, oc->scale); | 361 | scale = oc->scale; |
318 | wlr_output_set_scale(wlr_output, oc->scale); | 362 | } else { |
363 | scale = compute_default_scale(wlr_output); | ||
364 | sway_log(SWAY_DEBUG, "Auto-detected output scale: %f", scale); | ||
365 | } | ||
366 | if (scale != wlr_output->scale) { | ||
367 | sway_log(SWAY_DEBUG, "Set %s scale to %f", oc->name, scale); | ||
368 | wlr_output_set_scale(wlr_output, scale); | ||
319 | 369 | ||
320 | enum scale_filter_mode scale_filter_old = output->scale_filter; | 370 | enum scale_filter_mode scale_filter_old = output->scale_filter; |
321 | switch (oc->scale_filter) { | 371 | switch (oc->scale_filter) { |
@@ -388,7 +438,7 @@ static void default_output_config(struct output_config *oc, | |||
388 | oc->refresh_rate = mode->refresh / 1000.f; | 438 | oc->refresh_rate = mode->refresh / 1000.f; |
389 | } | 439 | } |
390 | oc->x = oc->y = -1; | 440 | oc->x = oc->y = -1; |
391 | oc->scale = 1; | 441 | oc->scale = 0; // auto |
392 | oc->scale_filter = SCALE_FILTER_DEFAULT; | 442 | oc->scale_filter = SCALE_FILTER_DEFAULT; |
393 | struct sway_output *output = wlr_output->data; | 443 | struct sway_output *output = wlr_output->data; |
394 | oc->subpixel = output->detected_subpixel; | 444 | oc->subpixel = output->detected_subpixel; |