diff --git a/README.md b/README.md
index 37c0cfc7..98b99a2d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Waybar [![Travis](https://travis-ci.org/Alexays/Waybar.svg?branch=master)](https://travis-ci.org/Alexays/Waybar) [![Licence](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Paypal Donate](https://img.shields.io/badge/Donate-Paypal-2244dd.svg)](https://paypal.me/ARouillard)
![Waybar](https://raw.githubusercontent.com/alexays/waybar/master/preview-2.png)
+# Waybar [![Licence](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Paypal Donate](https://img.shields.io/badge/Donate-Paypal-2244dd.svg)](https://paypal.me/ARouillard)
![Waybar](https://raw.githubusercontent.com/alexays/waybar/master/preview-2.png)
> Highly customizable Wayland bar for Sway and Wlroots based compositors.
> Available in Arch [community](https://www.archlinux.org/packages/community/x86_64/waybar/) or
diff --git a/include/modules/river/tags.hpp b/include/modules/river/tags.hpp
index f80b3c59..9b75fbd3 100644
--- a/include/modules/river/tags.hpp
+++ b/include/modules/river/tags.hpp
@@ -18,6 +18,7 @@ class Tags : public waybar::AModule {
// Handlers for wayland events
void handle_focused_tags(uint32_t tags);
void handle_view_tags(struct wl_array *tags);
+ void handle_urgent_tags(uint32_t tags);
struct zriver_status_manager_v1 *status_manager_;
diff --git a/include/modules/sni/host.hpp b/include/modules/sni/host.hpp
index f97900fd..8d321036 100644
--- a/include/modules/sni/host.hpp
+++ b/include/modules/sni/host.hpp
@@ -5,13 +5,15 @@
#include
#include
#include
+#include "bar.hpp"
#include "modules/sni/item.hpp"
namespace waybar::modules::SNI {
class Host {
public:
- Host(const std::size_t id, const Json::Value&, const std::function&)>&,
+ Host(const std::size_t id, const Json::Value&, const Bar&,
+ const std::function&)>&,
const std::function&)>&);
~Host();
@@ -36,6 +38,7 @@ class Host {
GCancellable* cancellable_ = nullptr;
SnWatcher* watcher_ = nullptr;
const Json::Value& config_;
+ const Bar& bar_;
const std::function&)> on_add_;
const std::function&)> on_remove_;
};
diff --git a/include/modules/sni/item.hpp b/include/modules/sni/item.hpp
index 1115145d..430c351c 100644
--- a/include/modules/sni/item.hpp
+++ b/include/modules/sni/item.hpp
@@ -14,6 +14,8 @@
#include
#include
+#include "bar.hpp"
+
namespace waybar::modules::SNI {
struct ToolTip {
@@ -23,7 +25,7 @@ struct ToolTip {
class Item : public sigc::trackable {
public:
- Item(const std::string&, const std::string&, const Json::Value&);
+ Item(const std::string&, const std::string&, const Json::Value&, const Bar&);
~Item() = default;
std::string bus_name;
@@ -56,6 +58,7 @@ class Item : public sigc::trackable {
bool item_is_menu = true;
private:
+ void onConfigure(GdkEventConfigure* ev);
void proxyReady(Glib::RefPtr& result);
void setProperty(const Glib::ustring& name, Glib::VariantBase& value);
void setStatus(const Glib::ustring& value);
diff --git a/include/modules/sway/language.hpp b/include/modules/sway/language.hpp
index b310b7f3..1faf52b3 100644
--- a/include/modules/sway/language.hpp
+++ b/include/modules/sway/language.hpp
@@ -21,10 +21,17 @@ class Language : public ALabel, public sigc::trackable {
auto update() -> void;
private:
+ enum class DispayedShortFlag {
+ None = 0,
+ ShortName = 1,
+ ShortDescription = 1 << 1
+ };
+
struct Layout {
std::string full_name;
std::string short_name;
std::string variant;
+ std::string short_description;
};
class XKBContext {
@@ -36,6 +43,7 @@ class Language : public ALabel, public sigc::trackable {
rxkb_context* context_ = nullptr;
rxkb_layout* xkb_layout_ = nullptr;
Layout* layout_ = nullptr;
+ std::map base_layouts_by_name_;
};
void onEvent(const struct Ipc::ipc_response&);
@@ -50,8 +58,8 @@ class Language : public ALabel, public sigc::trackable {
Layout layout_;
std::string tooltip_format_ = "";
std::map layouts_map_;
- XKBContext xkb_context_;
bool is_variant_displayed;
+ std::byte displayed_short_flag = static_cast(DispayedShortFlag::None);
util::JsonParser parser_;
std::mutex mutex_;
diff --git a/man/waybar-cpu.5.scd b/man/waybar-cpu.5.scd
index fbf6206f..679ca2ce 100644
--- a/man/waybar-cpu.5.scd
+++ b/man/waybar-cpu.5.scd
@@ -20,6 +20,11 @@ The *cpu* module displays the current cpu utilization.
default: {usage}% ++
The format, how information should be displayed. On {} data gets inserted.
+*format-icons*: ++
+ typeof: array/object ++
+ Based on the current usage, the corresponding icon gets selected. ++
+ The order is *low* to *high*. Or by the state if it is an object.
+
*max-length*: ++
typeof: integer ++
The maximum length in character the module should display.
diff --git a/man/waybar-memory.5.scd b/man/waybar-memory.5.scd
index 3ff4c35b..0639c07c 100644
--- a/man/waybar-memory.5.scd
+++ b/man/waybar-memory.5.scd
@@ -22,6 +22,11 @@ Addressed by *memory*
default: {percentage}% ++
The format, how information should be displayed.
+*format-icons*: ++
+ typeof: array/object ++
+ Based on the current percentage, the corresponding icon gets selected. ++
+ The order is *low* to *high*. Or by the state if it is an object.
+
*rotate*: ++
typeof: integer ++
Positive value to rotate the text label.
diff --git a/man/waybar-river-tags.5.scd b/man/waybar-river-tags.5.scd
index 0f027249..65b90332 100644
--- a/man/waybar-river-tags.5.scd
+++ b/man/waybar-river-tags.5.scd
@@ -15,7 +15,7 @@ Addressed by *river/tags*
*num-tags*: ++
typeof: uint ++
default: 9 ++
- The number of tags that should be displayed.
+ The number of tags that should be displayed. Max 32.
*tag-labels*: ++
typeof: array ++
@@ -34,8 +34,10 @@ Addressed by *river/tags*
- *#tags button*
- *#tags button.occupied*
- *#tags button.focused*
+- *#tags button.urgent*
-Note that a tag can be both occupied and focused at the same time.
+Note that occupied/focused/urgent status may overlap. That is, a tag may be
+both occupied and focused at the same time.
# SEE ALSO
diff --git a/man/waybar-sway-language.5.scd b/man/waybar-sway-language.5.scd
index 76bc7208..92a647e6 100644
--- a/man/waybar-sway-language.5.scd
+++ b/man/waybar-sway-language.5.scd
@@ -29,11 +29,13 @@ Addressed by *sway/language*
# FORMAT REPLACEMENTS
-*{short}*: Short name of layout (e.g. "en"). Equals to {}.
+*{short}*: Short name of layout (e.g. "us"). Equals to {}.
+
+*{shortDescription}*: Short description of layout (e.g. "en").
*{long}*: Long name of layout (e.g. "English (Dvorak)").
-*{variant}*: Variant of layout (e.g. "Dvorak").
+*{variant}*: Variant of layout (e.g. "dvorak").
# EXAMPLES
diff --git a/meson.build b/meson.build
index 1c065f7f..835b70e3 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
project(
'waybar', 'cpp', 'c',
- version: '0.9.7',
+ version: '0.9.8',
license: 'MIT',
meson_version: '>= 0.49.0',
default_options : [
diff --git a/protocol/river-status-unstable-v1.xml b/protocol/river-status-unstable-v1.xml
index a4d6f4e5..13affaa7 100644
--- a/protocol/river-status-unstable-v1.xml
+++ b/protocol/river-status-unstable-v1.xml
@@ -1,7 +1,7 @@
- Copyright 2020 Isaac Freund
+ Copyright 2020 The River Developers
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
+
A global factory for objects that receive status information specific
to river. It could be used to implement, for example, a status bar.
@@ -47,7 +47,7 @@
-
+
This interface allows clients to receive information about the current
windowing state of an output.
@@ -75,12 +75,21 @@
+
+
+
+ Sent once on binding the interface and again whenever the set of
+ tags with at least one urgent view changes.
+
+
+
This interface allows clients to receive information about the current
- focus of a seat.
+ focus of a seat. Note that (un)focused_output events will only be sent
+ if the client has bound the relevant wl_output globals.
diff --git a/src/modules/cpu/common.cpp b/src/modules/cpu/common.cpp
index 2ca74212..767cde92 100644
--- a/src/modules/cpu/common.cpp
+++ b/src/modules/cpu/common.cpp
@@ -26,9 +26,11 @@ auto waybar::modules::Cpu::update() -> void {
event_box_.hide();
} else {
event_box_.show();
+ auto icons = std::vector{state};
label_.set_markup(fmt::format(format,
fmt::arg("load", cpu_load),
fmt::arg("usage", cpu_usage),
+ fmt::arg("icon", getIcon(cpu_usage, icons)),
fmt::arg("max_frequency", max_frequency),
fmt::arg("min_frequency", min_frequency),
fmt::arg("avg_frequency", avg_frequency)));
diff --git a/src/modules/memory/common.cpp b/src/modules/memory/common.cpp
index 09ce8e83..31219ed6 100644
--- a/src/modules/memory/common.cpp
+++ b/src/modules/memory/common.cpp
@@ -38,8 +38,10 @@ auto waybar::modules::Memory::update() -> void {
event_box_.hide();
} else {
event_box_.show();
+ auto icons = std::vector{state};
label_.set_markup(fmt::format(format,
used_ram_percentage,
+ fmt::arg("icon", getIcon(used_ram_percentage, icons)),
fmt::arg("total", total_ram_gigabytes),
fmt::arg("percentage", used_ram_percentage),
fmt::arg("used", used_ram_gigabytes),
diff --git a/src/modules/river/tags.cpp b/src/modules/river/tags.cpp
index e96b2016..2628af2d 100644
--- a/src/modules/river/tags.cpp
+++ b/src/modules/river/tags.cpp
@@ -22,14 +22,24 @@ static void listen_view_tags(void *data, struct zriver_output_status_v1 *zriver_
static_cast(data)->handle_view_tags(tags);
}
+static void listen_urgent_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1,
+ uint32_t tags) {
+ static_cast(data)->handle_urgent_tags(tags);
+}
+
static const zriver_output_status_v1_listener output_status_listener_impl{
.focused_tags = listen_focused_tags,
.view_tags = listen_view_tags,
+ .urgent_tags = listen_urgent_tags,
};
static void handle_global(void *data, struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version) {
if (std::strcmp(interface, zriver_status_manager_v1_interface.name) == 0) {
+ version = std::min(version, 2);
+ if (version < ZRIVER_OUTPUT_STATUS_V1_URGENT_TAGS_SINCE_VERSION) {
+ spdlog::warn("river server does not support urgent tags");
+ }
static_cast(data)->status_manager_ = static_cast(
wl_registry_bind(registry, name, &zriver_status_manager_v1_interface, version));
}
@@ -64,8 +74,9 @@ Tags::Tags(const std::string &id, const waybar::Bar &bar, const Json::Value &con
}
event_box_.add(box_);
- // Default to 9 tags
- const uint32_t num_tags = config["num-tags"].isUInt() ? config_["num-tags"].asUInt() : 9;
+ // Default to 9 tags, cap at 32
+ const uint32_t num_tags =
+ config["num-tags"].isUInt() ? std::min(32, config_["num-tags"].asUInt()) : 9;
std::vector tag_labels(num_tags);
for (uint32_t tag = 0; tag < num_tags; ++tag) {
@@ -129,4 +140,16 @@ void Tags::handle_view_tags(struct wl_array *view_tags) {
}
}
+void Tags::handle_urgent_tags(uint32_t tags) {
+ uint32_t i = 0;
+ for (auto &button : buttons_) {
+ if ((1 << i) & tags) {
+ button.get_style_context()->add_class("urgent");
+ } else {
+ button.get_style_context()->remove_class("urgent");
+ }
+ ++i;
+ }
+}
+
} /* namespace waybar::modules::river */
diff --git a/src/modules/sni/host.cpp b/src/modules/sni/host.cpp
index 868fcd6e..414f1515 100644
--- a/src/modules/sni/host.cpp
+++ b/src/modules/sni/host.cpp
@@ -4,7 +4,7 @@
namespace waybar::modules::SNI {
-Host::Host(const std::size_t id, const Json::Value& config,
+Host::Host(const std::size_t id, const Json::Value& config, const Bar& bar,
const std::function&)>& on_add,
const std::function&)>& on_remove)
: bus_name_("org.kde.StatusNotifierHost-" + std::to_string(getpid()) + "-" +
@@ -13,6 +13,7 @@ Host::Host(const std::size_t id, const Json::Value& config,
bus_name_id_(Gio::DBus::own_name(Gio::DBus::BusType::BUS_TYPE_SESSION, bus_name_,
sigc::mem_fun(*this, &Host::busAcquired))),
config_(config),
+ bar_(bar),
on_add_(on_add),
on_remove_(on_remove) {}
@@ -136,7 +137,7 @@ void Host::addRegisteredItem(std::string service) {
return bus_name == item->bus_name && object_path == item->object_path;
});
if (it == items_.end()) {
- items_.emplace_back(new Item(bus_name, object_path, config_));
+ items_.emplace_back(new Item(bus_name, object_path, config_, bar_));
on_add_(items_.back());
}
}
diff --git a/src/modules/sni/item.cpp b/src/modules/sni/item.cpp
index d40f0ddf..991ccc4d 100644
--- a/src/modules/sni/item.cpp
+++ b/src/modules/sni/item.cpp
@@ -39,7 +39,7 @@ namespace waybar::modules::SNI {
static const Glib::ustring SNI_INTERFACE_NAME = sn_item_interface_info()->name;
static const unsigned UPDATE_DEBOUNCE_TIME = 10;
-Item::Item(const std::string& bn, const std::string& op, const Json::Value& config)
+Item::Item(const std::string& bn, const std::string& op, const Json::Value& config, const Bar& bar)
: bus_name(bn),
object_path(op),
icon_size(16),
@@ -54,6 +54,9 @@ Item::Item(const std::string& bn, const std::string& op, const Json::Value& conf
if (config["show-passive-items"].isBool()) {
show_passive_ = config["show-passive-items"].asBool();
}
+
+ auto &window = const_cast(bar).window;
+ window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Item::onConfigure));
event_box.add(image);
event_box.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
event_box.signal_button_press_event().connect(sigc::mem_fun(*this, &Item::handleClick));
@@ -73,6 +76,10 @@ Item::Item(const std::string& bn, const std::string& op, const Json::Value& conf
interface);
}
+void Item::onConfigure(GdkEventConfigure* ev) {
+ this->updateImage();
+}
+
void Item::proxyReady(Glib::RefPtr& result) {
try {
this->proxy_ = Gio::DBus::Proxy::create_for_bus_finish(result);
diff --git a/src/modules/sni/tray.cpp b/src/modules/sni/tray.cpp
index ae3702c2..e73c9eb4 100644
--- a/src/modules/sni/tray.cpp
+++ b/src/modules/sni/tray.cpp
@@ -7,7 +7,7 @@ Tray::Tray(const std::string& id, const Bar& bar, const Json::Value& config)
: AModule(config, "tray", id),
box_(bar.vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0),
watcher_(SNI::Watcher::getInstance()),
- host_(nb_hosts_, config, std::bind(&Tray::onAdd, this, std::placeholders::_1),
+ host_(nb_hosts_, config, bar, std::bind(&Tray::onAdd, this, std::placeholders::_1),
std::bind(&Tray::onRemove, this, std::placeholders::_1)) {
spdlog::warn(
"For a functional tray you must have libappindicator-* installed and export "
diff --git a/src/modules/sway/language.cpp b/src/modules/sway/language.cpp
index 5f3ce065..85dc769e 100644
--- a/src/modules/sway/language.cpp
+++ b/src/modules/sway/language.cpp
@@ -20,6 +20,12 @@ const std::string Language::XKB_ACTIVE_LAYOUT_NAME_KEY = "xkb_active_layout_name
Language::Language(const std::string& id, const Json::Value& config)
: ALabel(config, "language", id, "{}", 0, true) {
is_variant_displayed = format_.find("{variant}") != std::string::npos;
+ if (format_.find("{}") != std::string::npos || format_.find("{short}") != std::string::npos) {
+ displayed_short_flag |= static_cast(DispayedShortFlag::ShortName);
+ }
+ if (format_.find("{shortDescription}") != std::string::npos) {
+ displayed_short_flag |= static_cast(DispayedShortFlag::ShortDescription);
+ }
if (config.isMember("tooltip-format")) {
tooltip_format_ = config["tooltip-format"].asString();
}
@@ -88,8 +94,10 @@ void Language::onEvent(const struct Ipc::ipc_response& res) {
}
auto Language::update() -> void {
+ std::lock_guard lock(mutex_);
auto display_layout = trim(fmt::format(format_,
fmt::arg("short", layout_.short_name),
+ fmt::arg("shortDescription", layout_.short_description),
fmt::arg("long", layout_.full_name),
fmt::arg("variant", layout_.variant)));
label_.set_markup(display_layout);
@@ -97,10 +105,10 @@ auto Language::update() -> void {
if (tooltip_format_ != "") {
auto tooltip_display_layout = trim(fmt::format(tooltip_format_,
fmt::arg("short", layout_.short_name),
+ fmt::arg("shortDescription", layout_.short_description),
fmt::arg("long", layout_.full_name),
fmt::arg("variant", layout_.variant)));
label_.set_tooltip_markup(tooltip_display_layout);
-
} else {
label_.set_tooltip_markup(display_layout);
}
@@ -118,8 +126,9 @@ auto Language::set_current_layout(std::string current_layout) -> void {
auto Language::init_layouts_map(const std::vector& used_layouts) -> void {
std::map> found_by_short_names;
- auto layout = xkb_context_.next_layout();
- for (; layout != nullptr; layout = xkb_context_.next_layout()) {
+ XKBContext xkb_context;
+ auto layout = xkb_context.next_layout();
+ for (; layout != nullptr; layout = xkb_context.next_layout()) {
if (std::find(used_layouts.begin(), used_layouts.end(), layout->full_name) ==
used_layouts.end()) {
continue;
@@ -145,7 +154,6 @@ auto Language::init_layouts_map(const std::vector& used_layouts) ->
for (const auto& used_layout_name : used_layouts) {
auto used_layout = &layouts_map_.find(used_layout_name)->second;
auto layouts_with_same_name_list = found_by_short_names[used_layout->short_name];
- spdlog::info("SIZE: " + std::to_string(layouts_with_same_name_list.size()));
if (layouts_with_same_name_list.size() < 2) {
continue;
}
@@ -153,9 +161,15 @@ auto Language::init_layouts_map(const std::vector& used_layouts) ->
if (short_name_to_number_map.count(used_layout->short_name) == 0) {
short_name_to_number_map[used_layout->short_name] = 1;
}
-
- used_layout->short_name =
- used_layout->short_name + std::to_string(short_name_to_number_map[used_layout->short_name]++);
+
+ if (displayed_short_flag != static_cast(0)) {
+ int& number = short_name_to_number_map[used_layout->short_name];
+ used_layout->short_name =
+ used_layout->short_name + std::to_string(number);
+ used_layout->short_description =
+ used_layout->short_description + std::to_string(number);
+ ++number;
+ }
}
}
@@ -180,10 +194,22 @@ auto Language::XKBContext::next_layout() -> Layout* {
auto name = std::string(rxkb_layout_get_name(xkb_layout_));
auto variant_ = rxkb_layout_get_variant(xkb_layout_);
std::string variant = variant_ == nullptr ? "" : std::string(variant_);
-
- layout_ = new Layout{description, name, variant};
+ auto short_description_ = rxkb_layout_get_brief(xkb_layout_);
+ std::string short_description;
+ if (short_description_ != nullptr) {
+ short_description = std::string(short_description_);
+ base_layouts_by_name_.emplace(name, xkb_layout_);
+ } else {
+ auto base_layout = base_layouts_by_name_[name];
+ short_description = base_layout == nullptr ? "" : std::string(rxkb_layout_get_brief(base_layout));
+ }
+ delete layout_;
+ layout_ = new Layout{description, name, variant, short_description};
return layout_;
}
-Language::XKBContext::~XKBContext() { rxkb_context_unref(context_); }
+Language::XKBContext::~XKBContext() {
+ rxkb_context_unref(context_);
+ delete layout_;
+}
} // namespace waybar::modules::sway