aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Simon Ser <contact@emersion.fr>2019-12-10 14:40:21 +0100
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2019-12-12 19:00:24 -0500
commit2f84d6e349d12f3293c44268bc5c8551340e5787 (patch)
treeb9ff4438269faef7dc3c44ba5237e709a324191b
parentAdd seat <seat> idle_{inhibit,wake} <sources...> (diff)
downloadsway-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
-rw-r--r--sway/config/output.c56
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. */
268static 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
284static 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
266bool apply_output_config(struct output_config *oc, struct sway_output *output) { 309bool 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;