output: add phys_scale to adjust EDID-reported size

Some monitors report an invalid size in their EDID.  While sway ignores these
sizes (see phys_size_is_aspect_ratio), some other applications do not.  Instead
of requiring a change to the monitor, allow specifying a scaling factor in the
configuration to bring the physical dimensions in line with reality.
This commit is contained in:
Daniel De Graaf 2020-11-09 21:00:59 -05:00
parent 5ae4f65045
commit 388fce5a1f
6 changed files with 37 additions and 0 deletions

View file

@ -282,6 +282,7 @@ sway_cmd output_cmd_dpms;
sway_cmd output_cmd_enable; sway_cmd output_cmd_enable;
sway_cmd output_cmd_max_render_time; sway_cmd output_cmd_max_render_time;
sway_cmd output_cmd_mode; sway_cmd output_cmd_mode;
sway_cmd output_cmd_phys_scale;
sway_cmd output_cmd_position; sway_cmd output_cmd_position;
sway_cmd output_cmd_scale; sway_cmd output_cmd_scale;
sway_cmd output_cmd_scale_filter; sway_cmd output_cmd_scale_filter;

View file

@ -259,6 +259,7 @@ struct output_config {
int custom_mode; int custom_mode;
int x, y; int x, y;
float scale; float scale;
float phys_scale;
enum scale_filter_mode scale_filter; enum scale_filter_mode scale_filter;
int32_t transform; int32_t transform;
enum wl_output_subpixel subpixel; enum wl_output_subpixel subpixel;

View file

@ -15,6 +15,7 @@ static struct cmd_handler output_handlers[] = {
{ "enable", output_cmd_enable }, { "enable", output_cmd_enable },
{ "max_render_time", output_cmd_max_render_time }, { "max_render_time", output_cmd_max_render_time },
{ "mode", output_cmd_mode }, { "mode", output_cmd_mode },
{ "phys_scale", output_cmd_phys_scale },
{ "pos", output_cmd_position }, { "pos", output_cmd_position },
{ "position", output_cmd_position }, { "position", output_cmd_position },
{ "res", output_cmd_mode }, { "res", output_cmd_mode },

View file

@ -0,0 +1,22 @@
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
struct cmd_results *output_cmd_phys_scale(int argc, char **argv) {
if (!config->handler_context.output_config) {
return cmd_results_new(CMD_FAILURE, "Missing output config");
}
if (!argc) {
return cmd_results_new(CMD_INVALID, "Missing phys_scale argument.");
}
char *end;
config->handler_context.output_config->phys_scale = strtof(*argv, &end);
if (*end) {
return cmd_results_new(CMD_INVALID, "Invalid scale.");
}
config->handler_context.leftovers.argc = argc - 1;
config->handler_context.leftovers.argv = argv + 1;
return NULL;
}

View file

@ -59,6 +59,7 @@ struct output_config *new_output_config(const char *name) {
oc->refresh_rate = -1; oc->refresh_rate = -1;
oc->custom_mode = -1; oc->custom_mode = -1;
oc->x = oc->y = -1; oc->x = oc->y = -1;
oc->phys_scale = -1;
oc->scale = -1; oc->scale = -1;
oc->scale_filter = SCALE_FILTER_DEFAULT; oc->scale_filter = SCALE_FILTER_DEFAULT;
oc->transform = -1; oc->transform = -1;
@ -84,6 +85,9 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
if (src->y != -1) { if (src->y != -1) {
dst->y = src->y; dst->y = src->y;
} }
if (src->phys_scale != -1) {
dst->phys_scale = src->phys_scale;
}
if (src->scale != -1) { if (src->scale != -1) {
dst->scale = src->scale; dst->scale = src->scale;
} }
@ -369,6 +373,13 @@ static void queue_output_config(struct output_config *oc,
wlr_output_set_transform(wlr_output, oc->transform); wlr_output_set_transform(wlr_output, oc->transform);
} }
if (oc && oc->phys_scale > 0) {
wlr_output->phys_width = wlr_output->phys_width * oc->phys_scale;
wlr_output->phys_height = wlr_output->phys_height * oc->phys_scale;
sway_log(SWAY_DEBUG, "Scaling %s physical sizes by %f to %dx%d mm", oc->name,
oc->phys_scale, wlr_output->phys_width, wlr_output->phys_height);
}
// Apply the scale last before the commit, because the scale auto-detection // Apply the scale last before the commit, because the scale auto-detection
// reads the pending output size // reads the pending output size
float scale; float scale;

View file

@ -186,6 +186,7 @@ sway_sources = files(
'commands/output/enable.c', 'commands/output/enable.c',
'commands/output/max_render_time.c', 'commands/output/max_render_time.c',
'commands/output/mode.c', 'commands/output/mode.c',
'commands/output/phys_scale.c',
'commands/output/position.c', 'commands/output/position.c',
'commands/output/scale.c', 'commands/output/scale.c',
'commands/output/scale_filter.c', 'commands/output/scale_filter.c',