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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
--- /dev/null
+++ b/src/api/wayfire/output-transform.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <array>
+#include <optional>
+#include <string_view>
+#include <wayland-server-protocol.h>
+
+namespace wf
+{
+// Canonical configuration names, in wl_output_transform enum order. Keep the
+// earlier WCM spellings readable so saved profiles continue to work.
+inline constexpr std::array<std::string_view, 8> output_transform_names = {
+ "normal", "90", "180", "270", "flipped", "90_flipped", "180_flipped", "270_flipped",
+};
+
+inline std::optional<wl_output_transform> parse_output_transform(std::string_view name)
+{
+ for (size_t i = 0; i < output_transform_names.size(); ++i)
+ {
+ if (name == output_transform_names[i]) return static_cast<wl_output_transform>(i);
+ }
+
+ if (name == "flipped-90") return WL_OUTPUT_TRANSFORM_FLIPPED_90;
+ if (name == "flipped-180") return WL_OUTPUT_TRANSFORM_FLIPPED_180;
+ if (name == "flipped-270") return WL_OUTPUT_TRANSFORM_FLIPPED_270;
+ return std::nullopt;
+}
+}
--- a/src/core/output-layout.cpp
+++ b/src/core/output-layout.cpp
@@ -1,3 +1,4 @@
+#include <wayfire/output-transform.hpp>
#include <wayfire/window-scope.hpp>
#include <wayfire/workspace-set.hpp>
#include "wayfire/output.hpp"
@@ -92,25 +93,9 @@
};
}
-static std::map<std::string, wl_output_transform> output_transforms = {
- {"normal", WL_OUTPUT_TRANSFORM_NORMAL},
- {"90", WL_OUTPUT_TRANSFORM_90},
- {"180", WL_OUTPUT_TRANSFORM_180},
- {"270", WL_OUTPUT_TRANSFORM_270},
- {"flipped", WL_OUTPUT_TRANSFORM_FLIPPED},
- {"90_flipped", WL_OUTPUT_TRANSFORM_FLIPPED_90},
- {"180_flipped", WL_OUTPUT_TRANSFORM_FLIPPED_180},
- {"270_flipped", WL_OUTPUT_TRANSFORM_FLIPPED_270},
-};
-
wl_output_transform wf::layout_detail::get_transform_from_string(std::string_view transform)
{
- auto it = output_transforms.find(std::string{transform});
- if (it != output_transforms.end())
- {
- return it->second;
- }
-
+ if (auto parsed = wf::parse_output_transform(transform)) return *parsed;
LOGE("Bad output transform in config: ", transform);
return WL_OUTPUT_TRANSFORM_NORMAL;
}
@@ -127,13 +112,8 @@
std::string wf::layout_detail::wl_transform_to_string(wl_output_transform transform)
{
- for (auto& it : output_transforms)
- {
- if (it.second == transform)
- {
- return it.first;
- }
- }
+ if (static_cast<size_t>(transform) < wf::output_transform_names.size())
+ return std::string(wf::output_transform_names[transform]);
return "normal";
}
--- a/plugins/single_plugins/output-control.cpp
+++ b/plugins/single_plugins/output-control.cpp
@@ -1,3 +1,4 @@
+#include <wayfire/output-transform.hpp>
#include <wayfire/window-scope.hpp>
// Display settings transactions for WCM. The compositor owns the timeout;
// unconfirmed settings are never written to disk.
@@ -324,13 +325,9 @@
state.position = *wf::option_type::from_string<wf::output_config::position_t>(value(changes, pre + "position"));
state.scale = std::stod(value(changes, pre + "scale"));
if (!std::isfinite(state.scale) || state.scale < .25 || state.scale > 8) throw std::runtime_error("Scale must be between 0.25 and 8");
- const std::map<std::string, wl_output_transform> transforms = {{"normal", WL_OUTPUT_TRANSFORM_NORMAL},
- {"90", WL_OUTPUT_TRANSFORM_90}, {"180", WL_OUTPUT_TRANSFORM_180}, {"270", WL_OUTPUT_TRANSFORM_270},
- {"flipped", WL_OUTPUT_TRANSFORM_FLIPPED}, {"flipped-90", WL_OUTPUT_TRANSFORM_FLIPPED_90},
- {"flipped-180", WL_OUTPUT_TRANSFORM_FLIPPED_180}, {"flipped-270", WL_OUTPUT_TRANSFORM_FLIPPED_270}};
- auto t = transforms.find(value(changes, pre + "transform"));
- if (t == transforms.end()) throw std::runtime_error("Unknown transform for " + name);
- state.transform = t->second;
+ auto transform = wf::parse_output_transform(value(changes, pre + "transform"));
+ if (!transform) throw std::runtime_error("Unknown transform for " + name);
+ state.transform = *transform;
state.vrr = value(changes, pre + "vrr") == "true";
state.hdr = value(changes, pre + "hdr") == "true";
state.depth = std::stoi(value(changes, pre + "depth"));
@@ -432,6 +429,8 @@
if (!now.count(head) || (state.source != wf::OUTPUT_IMAGE_SOURCE_NONE &&
(head->width != state.mode.width || head->height != state.mode.height || std::abs(head->refresh - state.mode.refresh) > 500)))
throw std::runtime_error("A monitor did not accept the requested mode; reverted");
+ if (state.source != wf::OUTPUT_IMAGE_SOURCE_NONE && head->transform != state.transform)
+ throw std::runtime_error("A monitor did not accept the requested rotation; reverted");
}
auto wanted_members = members(requested);
auto virtual_output = wf::get_core().output_layout->find_output("VIRTUAL-1");
|