blob: 8067d6ed9a19b0be299562ca071eaa5e09558790 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#include "config.hpp"
#include <toml++/toml.hpp>
#include <cstdint>
#include <optional>
#include <string>
#include <string_view>
// Pure toml loader for the [window-field] policy. No wlroots, no kernel, no I/O
// (the glue reads the file and hands us the text). Mirrors ext-keybindings'
// config.cpp posture: per-key validation, defaults on absence/invalid, every
// problem recorded as a warning, never throws.
namespace unbox::ext_window_field::config {
namespace {
// Map a resize_mode string to the enum. nullopt for an unknown value (the caller
// warns + keeps the default).
auto parse_mode(std::string_view s) -> std::optional<ResizeMode> {
if (s == "off") {
return ResizeMode::off;
}
if (s == "settle") {
return ResizeMode::settle;
}
if (s == "continuous") {
return ResizeMode::continuous;
}
if (s == "debounced") {
return ResizeMode::debounced;
}
return std::nullopt;
}
} // namespace
auto load_from_string(std::string_view toml_text) -> LoadResult {
LoadResult result; // policy defaults already set
toml::table tbl;
try {
tbl = toml::parse(toml_text);
} catch (const toml::parse_error& e) {
result.parse_error = true;
result.warnings.emplace_back(std::string("[window-field] config parse error: ") +
std::string(e.description()));
return result; // defaults stand
}
const toml::node* section = tbl.get("window-field");
if (section == nullptr) {
return result; // no table => defaults, not an error
}
const toml::table* wf = section->as_table();
if (wf == nullptr) {
result.warnings.emplace_back("[window-field] is not a table; using defaults");
return result;
}
// resize_mode (string enum).
if (const toml::node* m = wf->get("resize_mode"); m != nullptr) {
if (const auto* s = m->as_string()) {
if (const auto parsed = parse_mode(s->get())) {
result.policy.mode = *parsed;
} else {
result.warnings.emplace_back(
"[window-field] resize_mode '" + s->get() +
"' is not one of off|settle|continuous|debounced; using 'settle'");
}
} else {
result.warnings.emplace_back(
"[window-field] resize_mode must be a string; using 'settle'");
}
}
// resize_debounce_ms (non-negative integer).
if (const toml::node* d = wf->get("resize_debounce_ms"); d != nullptr) {
if (const auto* v = d->as_integer()) {
const std::int64_t ms = v->get();
if (ms < 0) {
result.warnings.emplace_back(
"[window-field] resize_debounce_ms must be >= 0; using 100");
} else {
result.policy.debounce_ms = static_cast<int>(ms);
}
} else {
result.warnings.emplace_back(
"[window-field] resize_debounce_ms must be an integer; using 100");
}
}
return result;
}
} // namespace unbox::ext_window_field::config
|