Skip to content

Commit b6d0a4b

Browse files
committed
feat(bar): allow customization of bar modes
Allow changing existing modes and adding new ones via `modes` configuration key. `modes` accepts a JSON object roughly described by the following type ```typescript type BarMode = { layer: 'bottom' | 'top' | 'overlay'; exclusive: bool; passthrough: bool; visible: bool; }; type BarModeList = { [name: string]: BarMode; }; ``` and will be merged with the default modes defined in `bar.cpp`. Note that with absence of other ways to set mode, only those defined in the `sway-bar(5)`[1] documentation could be used right now. [1]: https://github.com/swaywm/sway/blob/master/sway/sway-bar.5.scd
1 parent cf5ddb2 commit b6d0a4b

File tree

1 file changed

+48
-14
lines changed

1 file changed

+48
-14
lines changed

src/bar.cpp

+48-14
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,48 @@ const std::string_view Bar::MODE_DEFAULT = "default";
6363
const std::string_view Bar::MODE_INVISIBLE = "invisible";
6464
const std::string_view DEFAULT_BAR_ID = "bar-0";
6565

66+
/* Deserializer for enum bar_layer */
67+
void from_json(const Json::Value& j, bar_layer& l) {
68+
if (j == "bottom") {
69+
l = bar_layer::BOTTOM;
70+
} else if (j == "top") {
71+
l = bar_layer::TOP;
72+
} else if (j == "overlay") {
73+
l = bar_layer::OVERLAY;
74+
}
75+
}
76+
77+
/* Deserializer for struct bar_mode */
78+
void from_json(const Json::Value& j, bar_mode& m) {
79+
if (j.isObject()) {
80+
if (auto v = j["layer"]; v.isString()) {
81+
from_json(v, m.layer);
82+
}
83+
if (auto v = j["exclusive"]; v.isBool()) {
84+
m.exclusive = v.asBool();
85+
}
86+
if (auto v = j["passthrough"]; v.isBool()) {
87+
m.passthrough = v.asBool();
88+
}
89+
if (auto v = j["visible"]; v.isBool()) {
90+
m.visible = v.asBool();
91+
}
92+
}
93+
}
94+
95+
/* Deserializer for JSON Object -> map<string compatible type, Value>
96+
* Assumes that all the values in the object are deserializable to the same type.
97+
*/
98+
template <typename Key, typename Value,
99+
typename = std::enable_if_t<std::is_convertible<std::string_view, Key>::value>>
100+
void from_json(const Json::Value& j, std::map<Key, Value>& m) {
101+
if (j.isObject()) {
102+
for (auto it = j.begin(); it != j.end(); ++it) {
103+
from_json(*it, m[it.key().asString()]);
104+
}
105+
}
106+
}
107+
66108
#ifdef HAVE_GTK_LAYER_SHELL
67109
struct GLSSurfaceImpl : public BarSurface, public sigc::trackable {
68110
GLSSurfaceImpl(Gtk::Window& window, struct waybar_output& output) : window_{window} {
@@ -527,23 +569,15 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
527569
surface_impl_->setPosition(position);
528570
surface_impl_->setSize(width, height);
529571

530-
/* Init "default" mode from globals */
531-
auto& default_mode = configured_modes[MODE_DEFAULT];
532-
if (config["layer"] == "top") {
533-
default_mode.layer = bar_layer::TOP;
534-
} else if (config["layer"] == "overlay") {
535-
default_mode.layer = bar_layer::OVERLAY;
536-
}
537-
538-
if (config["exclusive"].isBool()) {
539-
default_mode.exclusive = config["exclusive"].asBool();
572+
/* Read custom modes if available */
573+
if (auto modes = config.get("modes", {}); modes.isObject()) {
574+
from_json(modes, configured_modes);
540575
}
541576

542-
if (config["passthrough"].isBool()) {
543-
default_mode.passthrough = config["passthrough"].asBool();
544-
}
577+
/* Update "default" mode with the global bar options */
578+
from_json(config, configured_modes[MODE_DEFAULT]);
545579

546-
if (auto mode = config["mode"]; mode.isString()) {
580+
if (auto mode = config.get("mode", {}); mode.isString()) {
547581
setMode(config["mode"].asString());
548582
} else {
549583
setMode(MODE_DEFAULT);

0 commit comments

Comments
 (0)