Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable range for auto scale #136

Merged
merged 5 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cfg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ SCALING: TRUE
# This may be disabled and scale 1 will be used, unless a SCALE has been specified.
AUTO_SCALE: TRUE

# Set an allowed range for auto scale.
AUTO_SCALE_MIN: 1.0
#AUTO_SCALE_MAX: 2.0

# Auto scale may be overridden for each display.
SCALE:
Expand Down
16 changes: 16 additions & 0 deletions doc/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,22 @@ This may be disabled and scale 1 will be used, unless a `SCALE` has been specifi
AUTO_SCALE: false
```

### AUTO_SCALE_MIN

Set minimum value for auto scaling. The default is 1.0.

```yaml
AUTO_SCALE_MIN: 1.0
```

### AUTO_SCALE_MAX

Set maximum value for auto scaling. Values below 1.0 are ignored.
dancek marked this conversation as resolved.
Show resolved Hide resolved

```yaml
AUTO_SCALE_MAX: 2.5
```

### SCALE

Auto scale may be overridden with custom scales for each display e.g.
Expand Down
8 changes: 8 additions & 0 deletions inc/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include <stdint.h>
#include "log.h"

#define AUTO_SCALE_MIN_DEFAULT 1.0f
#define AUTO_SCALE_MAX_DEFAULT -1.0f

struct UserScale {
char *name_desc;
float scale;
Expand Down Expand Up @@ -71,6 +74,9 @@ struct Cfg {
struct SList *disabled_name_desc;
struct SList *user_transforms;
enum LogThreshold log_threshold;

float auto_scale_min;
float auto_scale_max;
};

enum CfgElement {
Expand All @@ -88,6 +94,8 @@ enum CfgElement {
LOG_THRESHOLD,
DISABLED,
ARRANGE_ALIGN,
AUTO_SCALE_MIN,
AUTO_SCALE_MAX
};

void cfg_file_paths_init(const char *user_path);
Expand Down
2 changes: 1 addition & 1 deletion inc/head.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ bool head_matches_name_desc(const void *head, const void *name_desc);

bool head_name_desc_matches_head(const void *name_desc, const void *head);

wl_fixed_t head_auto_scale(struct Head *head);
wl_fixed_t head_auto_scale(struct Head *head, double min, double max);

void head_scaled_dimensions(struct Head *head);

Expand Down
12 changes: 12 additions & 0 deletions src/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ struct Cfg *clone_cfg(struct Cfg *from) {
// AUTO_SCALE
if (from->auto_scale) {
to->auto_scale = from->auto_scale;
to->auto_scale_min = from->auto_scale_min;
to->auto_scale_max = from->auto_scale_max;
}

// SCALE
Expand Down Expand Up @@ -316,6 +318,12 @@ bool cfg_equal(struct Cfg *a, struct Cfg *b) {
if (a->auto_scale != b->auto_scale) {
return false;
}
if (a->auto_scale_min != b->auto_scale_min) {
return false;
}
if (a->auto_scale_max != b->auto_scale_max) {
return false;
}

// SCALE
if (!slist_equal(a->user_scales, b->user_scales, cfg_equal_user_scale)) {
Expand Down Expand Up @@ -375,6 +383,8 @@ struct Cfg *cfg_default(void) {
def->align = ALIGN_DEFAULT;
def->scaling = SCALING_DEFAULT;
def->auto_scale = AUTO_SCALE_DEFAULT;
def->auto_scale_min = AUTO_SCALE_MIN_DEFAULT;
def->auto_scale_max = AUTO_SCALE_MIN_DEFAULT;

return def;
}
Expand Down Expand Up @@ -572,6 +582,8 @@ struct Cfg *merge_set(struct Cfg *to, struct Cfg *from) {
// AUTO_SCALE
if (from->auto_scale) {
merged->auto_scale = from->auto_scale;
merged->auto_scale_min = from->auto_scale_min;
merged->auto_scale_max = from->auto_scale_max;
}

// SCALE
Expand Down
18 changes: 16 additions & 2 deletions src/head.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ bool head_matches_name_desc_exact(const void *h, const void *n) {
(head->description && strcmp(head->description, name_desc) == 0);
}

wl_fixed_t head_auto_scale(struct Head *head) {
wl_fixed_t head_auto_scale(struct Head *head, double min, double max) {
if (!head || !head->desired.mode) {
return wl_fixed_from_int(1);
}
Expand All @@ -154,8 +154,22 @@ wl_fixed_t head_auto_scale(struct Head *head) {
// round the dpi to the nearest 12, so that we get a nice even wl_fixed_t
long dpi_quantized = (long)(dpi / 12 + 0.5) * 12;

// convert min and max to quantized dpi
long dpi_min = 12 * (long)(min * 8 + 0.9999f);
dancek marked this conversation as resolved.
Show resolved Hide resolved
long dpi_max = 12 * (long)(max * 8);
if (dpi_min < 12) {
dpi_min = 12;
}

// clamp dpi between min and max (if set)
if (dpi_quantized < dpi_min) {
dpi_quantized = dpi_min;
} else if (dpi_max >= 96 && dpi_quantized > dpi_max) {
dpi_quantized = dpi_max;
}

// 96dpi approximately correct for older monitors and became the convention for 1:1 scaling
return wl_fixed_from_double((double)dpi_quantized / 96);
return wl_fixed_from_double((double) dpi_quantized / 96);
}

void head_scaled_dimensions(struct Head *head) {
Expand Down
3 changes: 2 additions & 1 deletion src/layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ void desire_scale(struct Head *head) {

// auto or 1
if (cfg->auto_scale == ON) {
head->desired.scale = head_auto_scale(head);
head->desired.scale =
head_auto_scale(head, cfg->auto_scale_min, cfg->auto_scale_max);
} else {
head->desired.scale = wl_fixed_from_int(1);
}
Expand Down
17 changes: 17 additions & 0 deletions src/marshalling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ YAML::Emitter& operator << (YAML::Emitter& e, struct Cfg& cfg) {
if (cfg.auto_scale) {
e << YAML::Key << "AUTO_SCALE" << YAML::Value << (cfg.auto_scale == ON);
}
if (cfg.auto_scale_min) {
e << YAML::Key << "AUTO_SCALE_MIN" << YAML::Value << cfg.auto_scale_min;
}
if (cfg.auto_scale_max) {
e << YAML::Key << "AUTO_SCALE_MAX" << YAML::Value << cfg.auto_scale_max;
}

if (cfg.user_scales) {
e << YAML::Key << "SCALE" << YAML::BeginSeq; // SCALE
Expand Down Expand Up @@ -424,6 +430,14 @@ struct CfgValidated*& operator << (struct CfgValidated*& cfg_validated, const YA
}
}

if (node["AUTO_SCALE_MIN"]) {
parse_node_val_float(node, "AUTO_SCALE_MIN", &cfg->auto_scale_min, "AUTO_SCALE_MIN", "");
}

if (node["AUTO_SCALE_MAX"]) {
parse_node_val_float(node, "AUTO_SCALE_MAX", &cfg->auto_scale_max, "AUTO_SCALE_MAX", "");
}

if (node["SCALE"]) {
for (const auto &scale : node["SCALE"]) {
struct UserScale *user_scale = (struct UserScale*)calloc(1, sizeof(struct UserScale));
Expand Down Expand Up @@ -659,6 +673,9 @@ struct Cfg*& operator << (struct Cfg*& cfg, const YAML::Node& node) {

TI(cfg->auto_scale = node["AUTO_SCALE"].as<bool>() ? ON : OFF);

TI(cfg->auto_scale_min = node["AUTO_SCALE_MIN"].as<float>());
TI(cfg->auto_scale_max = node["AUTO_SCALE_MAX"].as<float>());

if (node["SCALE"] && node["SCALE"].IsSequence()) {
for (const auto &node_scale : node["SCALE"]) {
struct UserScale *scale = NULL;
Expand Down
2 changes: 2 additions & 0 deletions tst/marshalling/cfg-all.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ ORDER:
- "!two"
SCALING: FALSE
AUTO_SCALE: FALSE
AUTO_SCALE_MIN: 0.5
AUTO_SCALE_MAX: 2.5
SCALE:
- NAME_DESC: three
SCALE: 3
Expand Down
2 changes: 2 additions & 0 deletions tst/marshalling/ipc-request-cfg-set.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ CFG:
- "!two"
SCALING: FALSE
AUTO_SCALE: FALSE
AUTO_SCALE_MIN: 0.5
AUTO_SCALE_MAX: 2.5
SCALE:
- NAME_DESC: three
SCALE: 3
Expand Down
2 changes: 2 additions & 0 deletions tst/marshalling/ipc-responses-map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ CFG:
- "!two"
SCALING: FALSE
AUTO_SCALE: FALSE
AUTO_SCALE_MIN: 0.5
AUTO_SCALE_MAX: 2.5
SCALE:
- NAME_DESC: three
SCALE: 3
Expand Down
54 changes: 48 additions & 6 deletions tst/tst-head.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ void head_auto_scale__default(void **state) {
struct Head head = { 0 };

// no head
assert_wl_fixed_t_equal_double(head_auto_scale(NULL), 1);
assert_wl_fixed_t_equal_double(head_auto_scale(NULL, 1.0f, -1.0f), 1);

// no desired mode
assert_wl_fixed_t_equal_double(head_auto_scale(&head), 1);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 1.0f, -1.0f), 1);
}

void head_auto_scale__mode(void **state) {
Expand All @@ -72,22 +72,63 @@ void head_auto_scale__mode(void **state) {
// dpi 0 defaults to 96
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 0);
assert_wl_fixed_t_equal_double(head_auto_scale(&head), 1);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 1.0f, -1.0f), 1);

// even 144
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 144);
assert_wl_fixed_t_equal_double(head_auto_scale(&head), 144.0 / 96);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 1.0f, -1.0f), 144.0 / 96);

// rounded down to 156
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 161);
assert_wl_fixed_t_equal_double(head_auto_scale(&head), 156.0 / 96);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 1.0f, -1.0f), 156.0 / 96);

// rounded up to 168
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 162);
assert_wl_fixed_t_equal_double(head_auto_scale(&head), 168.0 / 96);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 1.0f, -1.0f), 168.0 / 96);
}

void head_auto_scale__range(void **state) {
struct Mode mode = { 0 };
struct Head head = { .desired.mode = &mode };

// scale under 1.0 is clamped to 1.0 with default settings
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 72);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 1.0f, -1.0f), 1);

// clamping to some other minimum value works too
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 12);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 0.125f, -1.0f), 0.125f);

// the minimum value is always positive (quantized to 1/8)
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 1);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, -1.0f, -1.0f), 0.125f);

// clamping to maximum value works
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 384);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 1.0f, 2.5f), 2.5f);

// maximum values under 1.0 are ignored
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 384);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 1.0f, 0.9f), 4.0f);

// the configured maximum is respected even with quantization
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 384);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 0.63f, 1.49f), 1.375f);

// the configured minimum is respected even with quantization
expect_value(__wrap_mode_dpi, mode, &mode);
will_return(__wrap_mode_dpi, 12);
assert_wl_fixed_t_equal_double(head_auto_scale(&head, 0.63f, -1.0f), 0.75f);

}

void head_scaled_dimensions__default(void **state) {
Expand Down Expand Up @@ -260,6 +301,7 @@ int main(void) {
const struct CMUnitTest tests[] = {
TEST(head_auto_scale__default),
TEST(head_auto_scale__mode),
TEST(head_auto_scale__range),

TEST(head_scaled_dimensions__default),
TEST(head_scaled_dimensions__calculated),
Expand Down
3 changes: 3 additions & 0 deletions tst/tst-marshalling.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ struct Cfg *cfg_all(void) {
cfg->auto_scale = OFF;
cfg->log_threshold = ERROR;

cfg->auto_scale_min = 0.5f;
cfg->auto_scale_max = 2.5f;

cfg->laptop_display_prefix = strdup("ldp");

slist_append(&cfg->order_name_desc, strdup("one"));
Expand Down