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
|
--- a/src/config-merge.hpp
+++ b/src/config-merge.hpp
@@ -28,6 +28,16 @@
for (size_t pos = 0; pos < source.size();)
{
auto end = source.find('\n', pos);
+ // A trailing unescaped backslash joins physical lines. Retain the
+ // original bytes so editing another key preserves these commands.
+ while (end != source.npos)
+ {
+ auto tail = end;
+ if (tail > pos && source[tail - 1] == '\r') --tail;
+ if (tail <= pos || source[tail - 1] != '\\' ||
+ (tail > pos + 1 && source[tail - 2] == '\\')) break;
+ end = source.find('\n', end + 1);
+ }
const size_t count = end == source.npos ? source.size() - pos : end - pos + 1;
const size_t index = lines.size(); lines.push_back(source.substr(pos, count)); pos += count;
const auto& raw = lines.back();
@@ -47,7 +57,7 @@
const auto key = section + "/" + raw.substr(first, name_end - first + 1);
size_t last = raw.size();
for (size_t i = equal + 1; i < raw.size(); ++i)
- if ((raw[i] == '#' || raw[i] == ';') && raw[i - 1] != '\\') { last = i; break; }
+ if (raw[i] == '#' && raw[i - 1] != '\\') { last = i; break; }
const auto start = raw.find_first_not_of(" \t", equal + 1);
const auto finish = raw.find_last_not_of(" \t\r\n", last ? last - 1 : 0);
const size_t a = start == raw.npos || start >= last ? equal + 1 : start;
@@ -91,6 +101,16 @@
auto previous = original.entries.find(key);
if (previous != original.entries.end() && previous->second.value == entry.value) continue;
Ini current(result); current.set(key, entry.value); result = current.bytes();
+ }
+ // Compound options (commands, bindings, rules) can remove individual keys.
+ // Only remove keys that this editor actually had in its previous snapshot.
+ for (const auto& [key, entry] : original.entries)
+ {
+ if (edited.entries.count(key)) continue;
+ Ini current(result);
+ if (auto found = current.entries.find(key); found != current.entries.end())
+ current.lines.erase(current.lines.begin() + found->second.line);
+ result = current.bytes();
}
return result;
}
--- a/src/displays.cpp
+++ b/src/displays.cpp
@@ -1,3 +1,4 @@
+#include <wayfire/output-transform.hpp>
#include "displays.hpp"
#include "backgrounds.hpp"
#include "ipc.hpp"
@@ -120,7 +121,7 @@
position.set_placeholder_text("auto or x,y"); field(monitor_grid, 2, "Desktop position", position);
scale.set_range(.25, 8); scale.set_increments(.25, 1); scale.set_digits(2); scale.set_value(1.0);
scale.get_accessible()->set_name("Physical monitor scale"); field(monitor_grid, 3, "Scale", scale);
- for (auto text : {"normal", "90", "180", "270", "flipped", "flipped-90", "flipped-180", "flipped-270"}) rotation.append(text, text);
+ for (auto text : wf::output_transform_names) rotation.append(std::string(text), std::string(text));
field(monitor_grid, 4, "Rotation", rotation);
local_gap.set_range(-1, 1000); local_gap.set_increments(1, 5);
local_gap.get_accessible()->set_name("Physical monitor zone gap");
@@ -303,7 +304,8 @@
if (added.insert(current).second) mode.append(current, mode_label(current));
mode.set_active_id(current);
position.set_text(get(pre + "position")); scale.set_value(std::stod(get(pre + "scale")));
- rotation.set_active_id(get(pre + "transform"));
+ auto transform = wf::parse_output_transform(get(pre + "transform"));
+ rotation.set_active_id(transform ? std::string(wf::output_transform_names.at(*transform)) : "");
local_gap.set_value(std::stoi(get(pre + "zone_gap")));
include.set_active(std::find(order.begin(), order.end(), selected) != order.end());
loading = false; update_controls(); diagram.queue_draw();
|