From e343cf4b0004c51ba9bc3c14d1e8284127731a30 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 10 May 2019 12:07:17 -0400 Subject: [PATCH 01/44] fix(btformat): fixes an issue where btformat was not being correctly detected --- include/modules/pulseaudio.hpp | 1 + src/modules/pulseaudio.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/modules/pulseaudio.hpp b/include/modules/pulseaudio.hpp index b16118cd..92c8c06b 100644 --- a/include/modules/pulseaudio.hpp +++ b/include/modules/pulseaudio.hpp @@ -33,6 +33,7 @@ class Pulseaudio : public ALabel { bool muted_; std::string port_name_; std::string desc_; + std::string monitor_; bool scrolling_; }; diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index 3c768445..9d0fe52c 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -148,6 +148,7 @@ void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, const pa_ pa->volume_ = std::round(volume * 100.0F); pa->muted_ = i->mute != 0; pa->desc_ = i->description; + pa->monitor_ = i->monitor_source_name; pa->port_name_ = i->active_port != nullptr ? i->active_port->name : "Unknown"; pa->dp.emit(); } @@ -192,7 +193,7 @@ auto waybar::modules::Pulseaudio::update() -> void { label_.get_style_context()->add_class("muted"); } else { label_.get_style_context()->remove_class("muted"); - if (port_name_.find("a2dp_sink") != std::string::npos) { + if (monitor_.find("a2dp_sink") != std::string::npos) { format = config_["format-bluetooth"].isString() ? config_["format-bluetooth"].asString() : format; label_.get_style_context()->add_class("bluetooth"); From 7cdde05568fb3a750de254afa996ea60cf5c22ae Mon Sep 17 00:00:00 2001 From: Adam Pioterek Date: Sat, 11 May 2019 20:36:10 +0200 Subject: [PATCH 02/44] remove empty and solo classes when they do not apply --- src/modules/sway/window.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/sway/window.cpp b/src/modules/sway/window.cpp index 2f0287fd..2bccb60f 100644 --- a/src/modules/sway/window.cpp +++ b/src/modules/sway/window.cpp @@ -31,8 +31,10 @@ void Window::onCmd(const struct Ipc::ipc_response& res) { bar_.window.get_style_context()->remove_class(app_id_); } if (nb == 0) { + bar_.window.get_style_context()->remove_class("solo"); bar_.window.get_style_context()->add_class("empty"); } else if (nb == 1) { + bar_.window.get_style_context()->remove_class("empty"); bar_.window.get_style_context()->add_class("solo"); if (!app_id.empty()) { bar_.window.get_style_context()->add_class(app_id); @@ -99,4 +101,4 @@ void Window::getTree() { } } -} // namespace waybar::modules::sway \ No newline at end of file +} // namespace waybar::modules::sway From 80e9ea746bc0d744cd60a7916fa3bdd2e39c8f3e Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 12 May 2019 19:53:14 +0200 Subject: [PATCH 03/44] fix(battery): use path for the / operator --- include/factory.hpp | 4 +++- include/modules/temperature.hpp | 5 ----- meson.build | 9 +++++++-- meson_options.txt | 1 + src/factory.cpp | 4 +++- src/modules/battery.cpp | 12 ++++++------ src/modules/temperature.cpp | 7 ++----- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/include/factory.hpp b/include/factory.hpp index fa41ef4b..65d7e3ce 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -7,11 +7,13 @@ #include "modules/sway/window.hpp" #include "modules/sway/workspaces.hpp" #endif +#ifndef NO_FILESYSTEM #include "modules/battery.hpp" +#endif #include "modules/cpu.hpp" #include "modules/idle_inhibitor.hpp" #include "modules/memory.hpp" -#ifdef HAVE_DBUSMENU +#if defined(HAVE_DBUSMENU) && !defined(NO_FILESYSTEM) #include "modules/sni/tray.hpp" #endif #ifdef HAVE_LIBNL diff --git a/include/modules/temperature.hpp b/include/modules/temperature.hpp index 49410036..22bc21c2 100644 --- a/include/modules/temperature.hpp +++ b/include/modules/temperature.hpp @@ -4,11 +4,6 @@ #include #include "ALabel.hpp" #include "util/sleeper_thread.hpp" -#ifdef FILESYSTEM_EXPERIMENTAL -#include -#else -#include -#endif namespace waybar::modules { diff --git a/meson.build b/meson.build index dc7778b2..89f5ff38 100644 --- a/meson.build +++ b/meson.build @@ -12,7 +12,7 @@ project( cpp_args = [] cpp_link_args = [] -if false # libc++ +if get_option('libcxx') cpp_args += ['-stdlib=libc++'] cpp_link_args += ['-stdlib=libc++', '-lc++abi'] @@ -34,7 +34,12 @@ else endif if not compiler.has_header('filesystem') - add_project_arguments('-DFILESYSTEM_EXPERIMENTAL', language: 'cpp') + if compiler.has_header('experimental/filesystem') + add_project_arguments('-DFILESYSTEM_EXPERIMENTAL', language: 'cpp') + else + add_project_arguments('-DNO_FILESYSTEM', language: 'cpp') + warning('No filesystem header found, some modules may not work') + endif endif add_global_arguments(cpp_args, language : 'cpp') diff --git a/meson_options.txt b/meson_options.txt index f49d9c14..d84bd22c 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,3 +1,4 @@ +option('libcxx', type : 'boolean', value : false, description : 'Build with Clang\'s libc++ instead of libstdc++ on Linux.') option('libnl', type: 'feature', value: 'auto', description: 'Enable libnl support for network related features') option('libudev', type: 'feature', value: 'auto', description: 'Enable libudev support for udev related features') option('pulseaudio', type: 'feature', value: 'auto', description: 'Enable support for pulseaudio') diff --git a/src/factory.cpp b/src/factory.cpp index a2e8839e..100ca146 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -7,9 +7,11 @@ waybar::IModule* waybar::Factory::makeModule(const std::string& name) const { auto hash_pos = name.find('#'); auto ref = name.substr(0, hash_pos); auto id = hash_pos != std::string::npos ? name.substr(hash_pos + 1) : ""; +#ifndef NO_FILESYSTEM if (ref == "battery") { return new waybar::modules::Battery(id, config_[name]); } +#endif #ifdef HAVE_SWAY if (ref == "sway/mode") { return new waybar::modules::sway::Mode(id, config_[name]); @@ -33,7 +35,7 @@ waybar::IModule* waybar::Factory::makeModule(const std::string& name) const { if (ref == "clock") { return new waybar::modules::Clock(id, config_[name]); } -#ifdef HAVE_DBUSMENU +#if defined(HAVE_DBUSMENU) && !defined(NO_FILESYSTEM) if (ref == "tray") { return new waybar::modules::SNI::Tray(id, bar_, config_[name]); } diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index 607efdd4..5024964a 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -47,21 +47,21 @@ void waybar::modules::Battery::worker() { void waybar::modules::Battery::getBatteries() { try { - for (auto const& node : fs::directory_iterator(data_dir_)) { + for (auto& node : fs::directory_iterator(data_dir_)) { if (!fs::is_directory(node)) { continue; } auto dir_name = node.path().filename(); auto bat_defined = config_["bat"].isString(); if (((bat_defined && dir_name == config_["bat"].asString()) || !bat_defined) && - fs::exists(node / "capacity") && fs::exists(node / "uevent") && - fs::exists(node / "status")) { - batteries_.push_back(node); + fs::exists(node.path() / "capacity") && fs::exists(node.path() / "uevent") && + fs::exists(node.path() / "status")) { + batteries_.push_back(node.path()); } auto adap_defined = config_["adapter"].isString(); if (((adap_defined && dir_name == config_["adapter"].asString()) || !adap_defined) && - fs::exists(node / "online")) { - adapter_ = node; + fs::exists(node.path() / "online")) { + adapter_ = node.path(); } } } catch (fs::filesystem_error& e) { diff --git a/src/modules/temperature.cpp b/src/modules/temperature.cpp index 72c2880c..c41a498f 100644 --- a/src/modules/temperature.cpp +++ b/src/modules/temperature.cpp @@ -8,11 +8,8 @@ waybar::modules::Temperature::Temperature(const std::string& id, const Json::Val auto zone = config_["thermal-zone"].isInt() ? config_["thermal-zone"].asInt() : 0; file_path_ = fmt::format("/sys/class/thermal/thermal_zone{}/temp", zone); } -#ifdef FILESYSTEM_EXPERIMENTAL - if (!std::experimental::filesystem::exists(file_path_)) { -#else - if (!std::filesystem::exists(file_path_)) { -#endif + std::ifstream temp(file_path_); + if (!temp.is_open()) { throw std::runtime_error("Can't open " + file_path_); } label_.set_name("temperature"); From d5a9eccb7b5bb5bcddcfbab778f4cf482df8b7ca Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 12 May 2019 20:02:53 +0200 Subject: [PATCH 04/44] chore: v0.6.3 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 89f5ff38..5514e118 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project( 'waybar', 'cpp', 'c', - version: '0.6.2', + version: '0.6.3', license: 'MIT', default_options : [ 'cpp_std=c++17', From 62f8af8a39134326bb41c4923e9e1fe7aafbd4c6 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 May 2019 10:56:48 +0200 Subject: [PATCH 05/44] fix(Window): avoid multiple same classes --- resources/style.css | 3 +-- src/modules/sway/window.cpp | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/resources/style.css b/resources/style.css index ea881313..c008bfb9 100644 --- a/resources/style.css +++ b/resources/style.css @@ -32,8 +32,7 @@ window#waybar.termite { } window#waybar.chromium { - background-color: #DEE1E6; - color: #000000; + background-color: #000000; border: none; } diff --git a/src/modules/sway/window.cpp b/src/modules/sway/window.cpp index 2bccb60f..6caa16c2 100644 --- a/src/modules/sway/window.cpp +++ b/src/modules/sway/window.cpp @@ -32,11 +32,15 @@ void Window::onCmd(const struct Ipc::ipc_response& res) { } if (nb == 0) { bar_.window.get_style_context()->remove_class("solo"); - bar_.window.get_style_context()->add_class("empty"); + if (!bar_.window.get_style_context()->has_class("empty")) { + bar_.window.get_style_context()->add_class("empty"); + } } else if (nb == 1) { bar_.window.get_style_context()->remove_class("empty"); - bar_.window.get_style_context()->add_class("solo"); - if (!app_id.empty()) { + if (!bar_.window.get_style_context()->has_class("solo")) { + bar_.window.get_style_context()->add_class("solo"); + } + if (!app_id.empty() && !bar_.window.get_style_context()->has_class(app_id)) { bar_.window.get_style_context()->add_class(app_id); } } else { From fcb23d3104d2f36edecdf0866d202fb2110c64f3 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 May 2019 11:31:05 +0200 Subject: [PATCH 06/44] feat(temperature): format-icons --- include/ALabel.hpp | 2 +- resources/config | 5 +++-- src/ALabel.cpp | 7 +++++-- src/modules/temperature.cpp | 7 +++++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/ALabel.hpp b/include/ALabel.hpp index d4d10878..728bbc49 100644 --- a/include/ALabel.hpp +++ b/include/ALabel.hpp @@ -13,7 +13,7 @@ class ALabel : public IModule { ALabel(const Json::Value &, const std::string &format, uint16_t interval = 0); virtual ~ALabel(); virtual auto update() -> void; - virtual std::string getIcon(uint16_t, const std::string &alt = ""); + virtual std::string getIcon(uint16_t, const std::string &alt = "", uint16_t max = 0); virtual operator Gtk::Widget &(); protected: diff --git a/resources/config b/resources/config index 2c1f69c3..d3f5fbae 100644 --- a/resources/config +++ b/resources/config @@ -78,8 +78,9 @@ // "thermal-zone": 2, // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input", "critical-threshold": 80, - // "format-critical": "{temperatureC}°C ", - "format": "{temperatureC}°C " + // "format-critical": "{temperatureC}°C {icon}", + "format": "{temperatureC}°C {icon}", + "format-icons": ["", "", ""] }, "backlight": { // "device": "acpi_video1", diff --git a/src/ALabel.cpp b/src/ALabel.cpp index 9435e03b..ffe06bf3 100644 --- a/src/ALabel.cpp +++ b/src/ALabel.cpp @@ -109,7 +109,7 @@ bool waybar::ALabel::handleScroll(GdkEventScroll* e) { return true; } -std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt) { +std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_t max) { auto format_icons = config_["format-icons"]; if (format_icons.isObject()) { if (!alt.empty() && (format_icons[alt].isString() || format_icons[alt].isArray())) { @@ -120,7 +120,7 @@ std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt) } if (format_icons.isArray()) { auto size = format_icons.size(); - auto idx = std::clamp(percentage / (100 / size), 0U, size - 1); + auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1); format_icons = format_icons[idx]; } if (format_icons.isString()) { @@ -130,6 +130,9 @@ std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt) } std::string waybar::ALabel::getState(uint8_t value) { + if (!config_["states"].isObject()) { + return ""; + } // Get current state std::vector> states; if (config_["states"].isObject()) { diff --git a/src/modules/temperature.cpp b/src/modules/temperature.cpp index c41a498f..9e6bff79 100644 --- a/src/modules/temperature.cpp +++ b/src/modules/temperature.cpp @@ -32,8 +32,11 @@ auto waybar::modules::Temperature::update() -> void { } else { label_.get_style_context()->remove_class("critical"); } - label_.set_markup(fmt::format( - format, fmt::arg("temperatureC", temperature_c), fmt::arg("temperatureF", temperature_f))); + auto max_temp = config_["critical-threshold"].isInt() ? config_["critical-threshold"].asInt() : 0; + label_.set_markup(fmt::format(format, + fmt::arg("temperatureC", temperature_c), + fmt::arg("temperatureF", temperature_f), + fmt::arg("icon", getIcon(temperature_c, "", max_temp)))); } std::tuple waybar::modules::Temperature::getTemperature() { From 92967c7c06e994528306c99e78d224203b8d1f88 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 May 2019 11:36:34 +0200 Subject: [PATCH 07/44] fix(Label): reverse only battery states --- include/ALabel.hpp | 2 +- src/ALabel.cpp | 6 ++++-- src/modules/battery.cpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/ALabel.hpp b/include/ALabel.hpp index 728bbc49..e1c8e0f6 100644 --- a/include/ALabel.hpp +++ b/include/ALabel.hpp @@ -31,7 +31,7 @@ class ALabel : public IModule { virtual bool handleToggle(GdkEventButton *const &ev); virtual bool handleScroll(GdkEventScroll *); - virtual std::string getState(uint8_t value); + virtual std::string getState(uint8_t value, bool reverse = false); private: std::vector pid_; diff --git a/src/ALabel.cpp b/src/ALabel.cpp index ffe06bf3..70e502a7 100644 --- a/src/ALabel.cpp +++ b/src/ALabel.cpp @@ -129,7 +129,7 @@ std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt, return ""; } -std::string waybar::ALabel::getState(uint8_t value) { +std::string waybar::ALabel::getState(uint8_t value, bool reverse) { if (!config_["states"].isObject()) { return ""; } @@ -143,7 +143,9 @@ std::string waybar::ALabel::getState(uint8_t value) { } } // Sort states - std::sort(states.begin(), states.end(), [](auto& a, auto& b) { return a.second < b.second; }); + std::sort(states.begin(), states.end(), [&reverse](auto& a, auto& b) { + return reverse ? a.second < b.second : a.second > b.second; + }); std::string valid_state; for (auto const& state : states) { if (value <= state.second && valid_state.empty()) { diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index 5024964a..5f97bb26 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -119,7 +119,7 @@ auto waybar::modules::Battery::update() -> void { } std::transform(status.begin(), status.end(), status.begin(), ::tolower); auto format = format_; - auto state = getState(capacity); + auto state = getState(capacity, true); label_.get_style_context()->remove_class(old_status_); label_.get_style_context()->add_class(status); old_status_ = status; From 4f1defe6d5b119cc07b5cb081c2d7d450f61faac Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 May 2019 11:46:12 +0200 Subject: [PATCH 08/44] fix(Pulseaudio): avoid handleScroll override --- include/modules/pulseaudio.hpp | 2 +- src/modules/pulseaudio.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/modules/pulseaudio.hpp b/include/modules/pulseaudio.hpp index 92c8c06b..7d4b6290 100644 --- a/include/modules/pulseaudio.hpp +++ b/include/modules/pulseaudio.hpp @@ -20,7 +20,7 @@ class Pulseaudio : public ALabel { static void sinkInfoCb(pa_context*, const pa_sink_info*, int, void*); static void serverInfoCb(pa_context*, const pa_server_info*, void*); static void volumeModifyCb(pa_context*, int, void*); - bool handleScroll(GdkEventScroll* e); + bool handleVolume(GdkEventScroll* e); const std::string getPortIcon() const; diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index 9d0fe52c..712a2a92 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -39,7 +39,7 @@ waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value // events are configured if (!config["on-scroll-up"].isString() && !config["on-scroll-down"].isString()) { event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); - event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &Pulseaudio::handleScroll)); + event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &Pulseaudio::handleVolume)); } } @@ -71,7 +71,7 @@ void waybar::modules::Pulseaudio::contextStateCb(pa_context *c, void *data) { } } -bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) { +bool waybar::modules::Pulseaudio::handleVolume(GdkEventScroll *e) { // Avoid concurrent scroll event bool direction_up = false; uint16_t change = config_["scroll-step"].isUInt() ? config_["scroll-step"].asUInt() * 100 : 100; From db14fac0380fca3f215b6b3f1bfbde31ca6cffe9 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 May 2019 13:23:32 +0200 Subject: [PATCH 09/44] style: remove chromium style --- resources/style.css | 8 -------- 1 file changed, 8 deletions(-) diff --git a/resources/style.css b/resources/style.css index c008bfb9..3e61bf0b 100644 --- a/resources/style.css +++ b/resources/style.css @@ -44,19 +44,11 @@ window#waybar.chromium { border-bottom: 3px solid transparent; } -window#waybar.chromium #workspaces button { - color: #3F3F3F; -} - #workspaces button.focused { background: #64727D; border-bottom: 3px solid #ffffff; } -window#waybar.chromium #workspaces button.focused { - color: #ffffff; -} - #workspaces button.urgent { background-color: #eb4d4b; } From b54160e02f4391427004d44e0452e57fc0529afa Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 May 2019 14:27:01 +0200 Subject: [PATCH 10/44] fix(Tray): add item if not exist --- src/modules/sni/host.cpp | 11 ++++++++--- src/modules/sni/watcher.cpp | 4 +++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/modules/sni/host.cpp b/src/modules/sni/host.cpp index b9204bcc..62a68a2e 100644 --- a/src/modules/sni/host.cpp +++ b/src/modules/sni/host.cpp @@ -130,8 +130,13 @@ std::tuple Host::getBusNameAndObjectPath(const std::st void Host::addRegisteredItem(std::string service) { auto [bus_name, object_path] = getBusNameAndObjectPath(service); - items_.emplace_back(new Item(bus_name, object_path, config_)); - on_add_(items_.back()); + auto it = std::find_if(items_.begin(), items_.end(), [&bus_name, &object_path](const auto& item) { + 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_)); + on_add_(items_.back()); + } } -} \ No newline at end of file +} // namespace waybar::modules::SNI \ No newline at end of file diff --git a/src/modules/sni/watcher.cpp b/src/modules/sni/watcher.cpp index 3937d15a..42cfe2a3 100644 --- a/src/modules/sni/watcher.cpp +++ b/src/modules/sni/watcher.cpp @@ -28,7 +28,9 @@ Watcher::~Watcher() { g_slist_free_full(items_, gfWatchFree); items_ = nullptr; } - g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(watcher_)); + auto iface = G_DBUS_INTERFACE_SKELETON(watcher_); + auto conn = g_dbus_interface_skeleton_get_connection(iface); + g_dbus_interface_skeleton_unexport_from_connection(iface, conn); } void Watcher::busAcquired(const Glib::RefPtr& conn, Glib::ustring name) { From 0c3c548bc0aff71175346af72d2a2919a51991a5 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 May 2019 14:35:45 +0200 Subject: [PATCH 11/44] fix(Window): avoid concurrency --- include/modules/sway/window.hpp | 5 +++-- src/modules/mpd.cpp | 2 +- src/modules/sway/window.cpp | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/modules/sway/window.hpp b/include/modules/sway/window.hpp index f8f33b00..20638cb5 100644 --- a/include/modules/sway/window.hpp +++ b/include/modules/sway/window.hpp @@ -6,8 +6,8 @@ #include "bar.hpp" #include "client.hpp" #include "modules/sway/ipc/client.hpp" -#include "util/sleeper_thread.hpp" #include "util/json.hpp" +#include "util/sleeper_thread.hpp" namespace waybar::modules::sway { @@ -27,10 +27,11 @@ class Window : public ALabel { const Bar& bar_; waybar::util::SleeperThread thread_; Ipc ipc_; + std::mutex mutex_; std::string window_; int windowId_; std::string app_id_; - util::JsonParser parser_; + util::JsonParser parser_; }; } // namespace waybar::modules::sway diff --git a/src/modules/mpd.cpp b/src/modules/mpd.cpp index c019d366..b94eea91 100644 --- a/src/modules/mpd.cpp +++ b/src/modules/mpd.cpp @@ -65,7 +65,7 @@ std::thread waybar::modules::MPD::event_listener() { try { if (connection_ == nullptr) { // Retry periodically if no connection - update(); + dp.emit(); std::this_thread::sleep_for(interval_); } else { waitForEvent(); diff --git a/src/modules/sway/window.cpp b/src/modules/sway/window.cpp index 6caa16c2..c17f5fea 100644 --- a/src/modules/sway/window.cpp +++ b/src/modules/sway/window.cpp @@ -25,6 +25,7 @@ void Window::onEvent(const struct Ipc::ipc_response& res) { getTree(); } void Window::onCmd(const struct Ipc::ipc_response& res) { try { + std::lock_guard lock(mutex_); auto payload = parser_.parse(res.payload); auto [nb, id, name, app_id] = getFocusedNode(payload); if (!app_id_.empty()) { From 362c393b1d503c708a1c6ae1b1b133c1789e1725 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 May 2019 15:15:50 +0200 Subject: [PATCH 12/44] refactor: try/catch, sigc trackable --- include/modules/sni/item.hpp | 2 +- include/modules/sway/mode.hpp | 2 +- include/modules/sway/window.hpp | 2 +- include/modules/sway/workspaces.hpp | 2 +- include/util/json.hpp | 10 +++++----- src/modules/sni/watcher.cpp | 5 ----- src/modules/sway/workspaces.cpp | 14 ++++++++++++-- 7 files changed, 21 insertions(+), 16 deletions(-) diff --git a/include/modules/sni/item.hpp b/include/modules/sni/item.hpp index ee209956..6706e32b 100644 --- a/include/modules/sni/item.hpp +++ b/include/modules/sni/item.hpp @@ -63,8 +63,8 @@ class Item : public sigc::trackable { bool makeMenu(GdkEventButton* const& ev); bool handleClick(GdkEventButton* const& /*ev*/); - Glib::RefPtr cancellable_; Glib::RefPtr proxy_; + Glib::RefPtr cancellable_; bool update_pending_; }; diff --git a/include/modules/sway/mode.hpp b/include/modules/sway/mode.hpp index 36f53e14..e2c4e116 100644 --- a/include/modules/sway/mode.hpp +++ b/include/modules/sway/mode.hpp @@ -10,7 +10,7 @@ namespace waybar::modules::sway { -class Mode : public ALabel { +class Mode : public ALabel, public sigc::trackable { public: Mode(const std::string&, const Json::Value&); ~Mode() = default; diff --git a/include/modules/sway/window.hpp b/include/modules/sway/window.hpp index 20638cb5..3715eb2f 100644 --- a/include/modules/sway/window.hpp +++ b/include/modules/sway/window.hpp @@ -11,7 +11,7 @@ namespace waybar::modules::sway { -class Window : public ALabel { +class Window : public ALabel, public sigc::trackable { public: Window(const std::string&, const waybar::Bar&, const Json::Value&); ~Window() = default; diff --git a/include/modules/sway/workspaces.hpp b/include/modules/sway/workspaces.hpp index 1e0e8107..84c2eb0e 100644 --- a/include/modules/sway/workspaces.hpp +++ b/include/modules/sway/workspaces.hpp @@ -12,7 +12,7 @@ namespace waybar::modules::sway { -class Workspaces : public IModule { +class Workspaces : public IModule, public sigc::trackable { public: Workspaces(const std::string&, const waybar::Bar&, const Json::Value&); ~Workspaces() = default; diff --git a/include/util/json.hpp b/include/util/json.hpp index 3f83172f..581ad9b4 100644 --- a/include/util/json.hpp +++ b/include/util/json.hpp @@ -5,15 +5,16 @@ namespace waybar::util { struct JsonParser { - JsonParser() : reader_(builder_.newCharReader()) {} + JsonParser() {} const Json::Value parse(const std::string& data) const { Json::Value root(Json::objectValue); if (data.empty()) { return root; } - std::string err; - bool res = reader_->parse(data.c_str(), data.c_str() + data.size(), &root, &err); + std::unique_ptr const reader(builder_.newCharReader()); + std::string err; + bool res = reader->parse(data.c_str(), data.c_str() + data.size(), &root, &err); if (!res) throw std::runtime_error(err); return root; } @@ -21,8 +22,7 @@ struct JsonParser { ~JsonParser() = default; private: - Json::CharReaderBuilder builder_; - std::unique_ptr const reader_; + Json::CharReaderBuilder builder_; }; } // namespace waybar::util diff --git a/src/modules/sni/watcher.cpp b/src/modules/sni/watcher.cpp index 42cfe2a3..1ba1324f 100644 --- a/src/modules/sni/watcher.cpp +++ b/src/modules/sni/watcher.cpp @@ -14,11 +14,6 @@ Watcher::Watcher() watcher_(sn_watcher_skeleton_new()) {} Watcher::~Watcher() { - if (bus_name_id_ != 0) { - Gio::DBus::unown_name(bus_name_id_); - bus_name_id_ = 0; - } - if (hosts_ != nullptr) { g_slist_free_full(hosts_, gfWatchFree); hosts_ = nullptr; diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 50be8d94..f379c9aa 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -19,7 +19,13 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value worker(); } -void Workspaces::onEvent(const struct Ipc::ipc_response &res) { ipc_.sendCmd(IPC_GET_WORKSPACES); } +void Workspaces::onEvent(const struct Ipc::ipc_response &res) { + try { + ipc_.sendCmd(IPC_GET_WORKSPACES); + } catch (const std::exception &e) { + std::cerr << "Workspaces: " << e.what() << std::endl; + } +} void Workspaces::onCmd(const struct Ipc::ipc_response &res) { if (res.type == IPC_GET_WORKSPACES) { @@ -194,7 +200,11 @@ bool Workspaces::handleScroll(GdkEventScroll *e) { return false; } } - ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"", name)); + try { + ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"", name)); + } catch (const std::exception &e) { + std::cerr << "Workspaces: " << e.what() << std::endl; + } return true; } From 0968170074b5b71a6a5358464c89263c24269d5b Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 May 2019 15:40:02 +0200 Subject: [PATCH 13/44] style(media): min-width --- resources/style.css | 1 + src/modules/pulseaudio.cpp | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/style.css b/resources/style.css index 3e61bf0b..f8e68df3 100644 --- a/resources/style.css +++ b/resources/style.css @@ -133,6 +133,7 @@ label:focus { #custom-media { background: #66cc99; color: #2a5c45; + min-width: 150px; } .custom-spotify { diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index 712a2a92..099b1dc4 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -73,13 +73,12 @@ void waybar::modules::Pulseaudio::contextStateCb(pa_context *c, void *data) { bool waybar::modules::Pulseaudio::handleVolume(GdkEventScroll *e) { // Avoid concurrent scroll event - bool direction_up = false; - uint16_t change = config_["scroll-step"].isUInt() ? config_["scroll-step"].asUInt() * 100 : 100; - pa_cvolume pa_volume = pa_volume_; - if (scrolling_) { return false; } + bool direction_up = false; + uint16_t change = config_["scroll-step"].isUInt() ? config_["scroll-step"].asUInt() * 100 : 100; + pa_cvolume pa_volume = pa_volume_; scrolling_ = true; if (e->direction == GDK_SCROLL_UP) { direction_up = true; From d209d350feaa3f65baa2d69ceb36f9adacf7d2f3 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 May 2019 15:48:18 +0200 Subject: [PATCH 14/44] style(media): reduce min-width --- resources/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/style.css b/resources/style.css index f8e68df3..b2c96269 100644 --- a/resources/style.css +++ b/resources/style.css @@ -133,7 +133,7 @@ label:focus { #custom-media { background: #66cc99; color: #2a5c45; - min-width: 150px; + min-width: 100px; } .custom-spotify { From 5b3402e110eca2bb3f99c6c81fa78106f7a51d29 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 14 May 2019 15:43:57 +0200 Subject: [PATCH 15/44] feat(Battery): plugged status --- include/modules/battery.hpp | 8 ++++---- resources/config | 8 +++++--- src/modules/battery.cpp | 29 +++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/include/modules/battery.hpp b/include/modules/battery.hpp index 9787a8dc..5f2290ee 100644 --- a/include/modules/battery.hpp +++ b/include/modules/battery.hpp @@ -30,10 +30,10 @@ class Battery : public ALabel { private: static inline const fs::path data_dir_ = "/sys/class/power_supply/"; - void getBatteries(); - void worker(); - const std::string getAdapterStatus(uint8_t capacity) const; - const std::tuple getInfos() const; + void getBatteries(); + void worker(); + const std::string getAdapterStatus(uint8_t capacity, uint32_t current_now) const; + const std::tuple getInfos() const; util::SleeperThread thread_; util::SleeperThread thread_timer_; diff --git a/resources/config b/resources/config index d3f5fbae..430535fa 100644 --- a/resources/config +++ b/resources/config @@ -94,6 +94,8 @@ "critical": 15 }, "format": "{capacity}% {icon}", + "format-charging": "{capacity}% ", + "format-plugged": "{capacity}% ", // "format-good": "", // An empty format will hide the module // "format-full": "", "format-icons": ["", "", "", "", ""] @@ -104,14 +106,14 @@ "network": { // "interface": "wlp2s0", // (Optional) To force the use of this interface "format-wifi": "{essid} ({signalStrength}%) ", - "format-ethernet": "{ifname}: {ipaddr}/{cidr} ", + "format-ethernet": "{ifname}: {ipaddr}/{cidr} ", "format-disconnected": "Disconnected ⚠" }, "pulseaudio": { //"scroll-step": 1, "format": "{volume}% {icon}", "format-bluetooth": "{volume}% {icon}", - "format-muted": "", + "format-muted": "", "format-icons": { "headphones": "", "handsfree": "", @@ -119,7 +121,7 @@ "phone": "", "portable": "", "car": "", - "default": ["", ""] + "default": ["", "", ""] }, "on-click": "pavucontrol" }, diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index 5f97bb26..c0610c31 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -75,44 +75,55 @@ void waybar::modules::Battery::getBatteries() { } } -const std::tuple waybar::modules::Battery::getInfos() const { +const std::tuple waybar::modules::Battery::getInfos() const { try { uint16_t total = 0; + uint32_t total_current = 0; std::string status = "Unknown"; for (auto const& bat : batteries_) { uint16_t capacity; + uint32_t current_now; std::string _status; std::ifstream(bat / "capacity") >> capacity; std::ifstream(bat / "status") >> _status; + std::ifstream(bat / "current_now") >> current_now; if (_status != "Unknown") { status = _status; } total += capacity; + total_current += current_now; } uint16_t capacity = total / batteries_.size(); - return {capacity, status}; + if (status == "Charging" && total_current != 0) { + status == "Plugged"; + } + return {capacity, total_current, status}; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; - return {0, "Unknown"}; + return {0, 0, "Unknown"}; } } -const std::string waybar::modules::Battery::getAdapterStatus(uint8_t capacity) const { +const std::string waybar::modules::Battery::getAdapterStatus(uint8_t capacity, + uint32_t current_now) const { if (!adapter_.empty()) { bool online; std::ifstream(adapter_ / "online") >> online; if (capacity == 100) { return "Full"; } - return online ? "Charging" : "Discharging"; + if (online) { + return current_now == 0 ? "Charging" : "Plugged"; + } + return "Discharging"; } return "Unknown"; } auto waybar::modules::Battery::update() -> void { - auto [capacity, status] = getInfos(); + auto [capacity, current_now, status] = getInfos(); if (status == "Unknown") { - status = getAdapterStatus(capacity); + status = getAdapterStatus(capacity, current_now); } if (tooltipEnabled()) { label_.set_tooltip_text(status); @@ -120,7 +131,9 @@ auto waybar::modules::Battery::update() -> void { std::transform(status.begin(), status.end(), status.begin(), ::tolower); auto format = format_; auto state = getState(capacity, true); - label_.get_style_context()->remove_class(old_status_); + if (!old_status_.empty()) { + label_.get_style_context()->remove_class(old_status_); + } label_.get_style_context()->add_class(status); old_status_ = status; if (!state.empty() && config_["format-" + status + "-" + state].isString()) { From 22bf0b161a39aa5cfe6fb494f343d99b0a4804b6 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 15 May 2019 10:24:35 +0200 Subject: [PATCH 16/44] fix(Network): do not stop thread --- src/modules/network.cpp | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 94f34cd0..ff29fcce 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -66,7 +66,6 @@ void waybar::modules::Network::createInfoSocket() { throw std::runtime_error("Can't add membership"); } nl_socket_disable_seq_check(info_sock_); - nl_socket_set_nonblocking(info_sock_); nl_socket_modify_cb(info_sock_, NL_CB_VALID, NL_CB_CUSTOM, handleEvents, this); efd_ = epoll_create1(EPOLL_CLOEXEC); if (efd_ < 0) { @@ -126,8 +125,6 @@ void waybar::modules::Network::worker() { break; } } - } else if (ec == -1) { - thread_.stop(); } }; } @@ -388,25 +385,23 @@ int waybar::modules::Network::netlinkResponse(void *resp, uint32_t resplen, uint } int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { - int ret = 0; auto net = static_cast(data); bool need_update = false; - for (nlmsghdr *nh = nlmsg_hdr(msg); NLMSG_OK(nh, ret); nh = NLMSG_NEXT(nh, ret)) { - if (nh->nlmsg_type == RTM_NEWADDR) { + struct nlmsghdr *nh = nlmsg_hdr(msg); + + if (nh->nlmsg_type == RTM_NEWADDR) { + need_update = true; + } + if (nh->nlmsg_type < RTM_NEWADDR) { + auto rtif = static_cast(NLMSG_DATA(nh)); + if (rtif->ifi_index == static_cast(net->ifid_)) { need_update = true; - } - if (nh->nlmsg_type < RTM_NEWADDR) { - auto rtif = static_cast(NLMSG_DATA(nh)); - if (rtif->ifi_index == static_cast(net->ifid_)) { - need_update = true; - if (!(rtif->ifi_flags & IFF_RUNNING)) { - net->disconnected(); - net->dp.emit(); - return NL_SKIP; - } + if (!(rtif->ifi_flags & IFF_RUNNING)) { + net->disconnected(); + net->dp.emit(); + return NL_SKIP; } } - if (need_update) break; } if (net->ifid_ <= 0 && !net->config_["interface"].isString()) { for (uint8_t i = 0; i < MAX_RETRY; i += 1) { From 380fc58f3c5622c1a7a783d5984d8df395644664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Bele=20Reinfjell?= Date: Wed, 15 May 2019 19:14:29 +0200 Subject: [PATCH 17/44] fix(battery): change comparison expr. to assignment --- src/modules/battery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index c0610c31..b51ed496 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -95,7 +95,7 @@ const std::tuple waybar::modules::Battery::getIn } uint16_t capacity = total / batteries_.size(); if (status == "Charging" && total_current != 0) { - status == "Plugged"; + status = "Plugged"; } return {capacity, total_current, status}; } catch (const std::exception& e) { From 7e8eee0571146c41d6d85f3b20cadb707dd40167 Mon Sep 17 00:00:00 2001 From: unresolvedsymbol <48220091+unresolvedsymbol@users.noreply.github.com> Date: Wed, 15 May 2019 22:14:51 -0500 Subject: [PATCH 18/44] fix state behavior --- include/ALabel.hpp | 2 +- src/ALabel.cpp | 4 ++-- src/modules/battery.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/ALabel.hpp b/include/ALabel.hpp index e1c8e0f6..078e577c 100644 --- a/include/ALabel.hpp +++ b/include/ALabel.hpp @@ -31,7 +31,7 @@ class ALabel : public IModule { virtual bool handleToggle(GdkEventButton *const &ev); virtual bool handleScroll(GdkEventScroll *); - virtual std::string getState(uint8_t value, bool reverse = false); + virtual std::string getState(uint8_t value, bool lesser = false, bool reverse = false); private: std::vector pid_; diff --git a/src/ALabel.cpp b/src/ALabel.cpp index 70e502a7..6ebbc827 100644 --- a/src/ALabel.cpp +++ b/src/ALabel.cpp @@ -129,7 +129,7 @@ std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt, return ""; } -std::string waybar::ALabel::getState(uint8_t value, bool reverse) { +std::string waybar::ALabel::getState(uint8_t value, bool lesser, bool reverse) { if (!config_["states"].isObject()) { return ""; } @@ -148,7 +148,7 @@ std::string waybar::ALabel::getState(uint8_t value, bool reverse) { }); std::string valid_state; for (auto const& state : states) { - if (value <= state.second && valid_state.empty()) { + if ((lesser ? value <= state.second : value >= state.second) && valid_state.empty()) { label_.get_style_context()->add_class(state.first); valid_state = state.first; } else { diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index b51ed496..1aaa6489 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -130,7 +130,7 @@ auto waybar::modules::Battery::update() -> void { } std::transform(status.begin(), status.end(), status.begin(), ::tolower); auto format = format_; - auto state = getState(capacity, true); + auto state = getState(capacity, true, true); if (!old_status_.empty()) { label_.get_style_context()->remove_class(old_status_); } From 963d4f68e4197731cac5fa52a11fa9770a177b6f Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 09:39:06 +0200 Subject: [PATCH 19/44] refactor: remove useless param --- include/ALabel.hpp | 2 +- src/ALabel.cpp | 6 +++--- src/modules/battery.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/ALabel.hpp b/include/ALabel.hpp index 078e577c..cf2cc286 100644 --- a/include/ALabel.hpp +++ b/include/ALabel.hpp @@ -31,7 +31,7 @@ class ALabel : public IModule { virtual bool handleToggle(GdkEventButton *const &ev); virtual bool handleScroll(GdkEventScroll *); - virtual std::string getState(uint8_t value, bool lesser = false, bool reverse = false); + virtual std::string getState(uint8_t value, bool lesser = false); private: std::vector pid_; diff --git a/src/ALabel.cpp b/src/ALabel.cpp index 6ebbc827..e1fa212d 100644 --- a/src/ALabel.cpp +++ b/src/ALabel.cpp @@ -129,7 +129,7 @@ std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt, return ""; } -std::string waybar::ALabel::getState(uint8_t value, bool lesser, bool reverse) { +std::string waybar::ALabel::getState(uint8_t value, bool lesser) { if (!config_["states"].isObject()) { return ""; } @@ -143,8 +143,8 @@ std::string waybar::ALabel::getState(uint8_t value, bool lesser, bool reverse) { } } // Sort states - std::sort(states.begin(), states.end(), [&reverse](auto& a, auto& b) { - return reverse ? a.second < b.second : a.second > b.second; + std::sort(states.begin(), states.end(), [&lesser](auto& a, auto& b) { + return lesser ? a.second < b.second : a.second > b.second; }); std::string valid_state; for (auto const& state : states) { diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index 1aaa6489..b51ed496 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -130,7 +130,7 @@ auto waybar::modules::Battery::update() -> void { } std::transform(status.begin(), status.end(), status.begin(), ::tolower); auto format = format_; - auto state = getState(capacity, true, true); + auto state = getState(capacity, true); if (!old_status_.empty()) { label_.get_style_context()->remove_class(old_status_); } From 841576497aa128cbefafe4d8b63143565b909199 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 11:22:22 +0200 Subject: [PATCH 20/44] refactor: cleaner events --- include/modules/network.hpp | 11 +- resources/config | 5 +- src/modules/network.cpp | 289 ++++++++++++++++++++++++------------ 3 files changed, 204 insertions(+), 101 deletions(-) diff --git a/include/modules/network.hpp b/include/modules/network.hpp index ade3bb2c..cbea4e48 100644 --- a/include/modules/network.hpp +++ b/include/modules/network.hpp @@ -28,7 +28,6 @@ class Network : public ALabel { static int handleScan(struct nl_msg*, void*); void worker(); - void disconnected(); void createInfoSocket(); void createEventSocket(); int getExternalInterface(); @@ -38,24 +37,30 @@ class Network : public ALabel { void parseEssid(struct nlattr**); void parseSignal(struct nlattr**); bool associatedOrJoined(struct nlattr**); + bool checkInterface(int if_index, std::string name); + int getPreferredIface(); auto getInfo() -> void; + bool wildcardMatch(const std::string& pattern, const std::string& text); waybar::util::SleeperThread thread_; waybar::util::SleeperThread thread_timer_; int ifid_; + int last_ext_iface_; sa_family_t family_; struct sockaddr_nl nladdr_ = {0}; - struct nl_sock* sk_ = nullptr; - struct nl_sock* info_sock_ = nullptr; + struct nl_sock* sock_ = nullptr; + struct nl_sock* ev_sock_ = nullptr; int efd_; int ev_fd_; int nl80211_id_; + std::mutex mutex_; std::string essid_; std::string ifname_; std::string ipaddr_; std::string netmask_; int cidr_; + bool linked_; int32_t signal_strength_dbm_; uint8_t signal_strength_; }; diff --git a/resources/config b/resources/config index 430535fa..4d9a96d6 100644 --- a/resources/config +++ b/resources/config @@ -104,9 +104,10 @@ "bat": "BAT2" }, "network": { - // "interface": "wlp2s0", // (Optional) To force the use of this interface - "format-wifi": "{essid} ({signalStrength}%) ", + // "interface": "wlp2*", // (Optional) To force the use of this interface + "format-wifi": "{ifname}: {ipaddr}/{cidr} {essid} ({signalStrength}%) ", "format-ethernet": "{ifname}: {ipaddr}/{cidr} ", + "format-linked": "{ifname} (No IP) ", "format-disconnected": "Disconnected ⚠" }, "pulseaudio": { diff --git a/src/modules/network.cpp b/src/modules/network.cpp index ff29fcce..bdab3a8d 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -1,8 +1,13 @@ #include "modules/network.hpp" #include +#include + +#include waybar::modules::Network::Network(const std::string &id, const Json::Value &config) : ALabel(config, "{ifname}", 60), + ifid_(-1), + last_ext_iface_(-1), family_(AF_INET), efd_(-1), ev_fd_(-1), @@ -15,19 +20,12 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf } createInfoSocket(); createEventSocket(); - if (config_["interface"].isString()) { - ifid_ = if_nametoindex(config_["interface"].asCString()); - ifname_ = config_["interface"].asString(); - if (ifid_ <= 0) { - throw std::runtime_error("Can't found network interface"); - } - } else { - ifid_ = getExternalInterface(); - if (ifid_ > 0) { - char ifname[IF_NAMESIZE]; - if_indextoname(ifid_, ifname); - ifname_ = ifname; - } + auto default_iface = getPreferredIface(); + if (default_iface != -1) { + char ifname[IF_NAMESIZE]; + if_indextoname(default_iface, ifname); + ifname_ = ifname; + getInterfaceAddress(); } dp.emit(); worker(); @@ -42,38 +40,40 @@ waybar::modules::Network::~Network() { if (efd_ > -1) { close(efd_); } - if (info_sock_ != nullptr) { - nl_socket_drop_membership(info_sock_, RTMGRP_LINK); - nl_socket_drop_membership(info_sock_, RTMGRP_IPV4_IFADDR); - nl_close(info_sock_); - nl_socket_free(info_sock_); + if (ev_sock_ != nullptr) { + nl_socket_drop_membership(ev_sock_, RTNLGRP_LINK); + nl_socket_drop_membership(ev_sock_, RTMGRP_IPV4_IFADDR); + nl_socket_drop_membership(ev_sock_, RTMGRP_IPV6_IFADDR); + nl_close(ev_sock_); + nl_socket_free(ev_sock_); } - if (sk_ != nullptr) { - nl_close(sk_); - nl_socket_free(sk_); + if (sock_ != nullptr) { + nl_close(sock_); + nl_socket_free(sock_); } } void waybar::modules::Network::createInfoSocket() { - info_sock_ = nl_socket_alloc(); - if (nl_connect(info_sock_, NETLINK_ROUTE) != 0) { + ev_sock_ = nl_socket_alloc(); + nl_socket_disable_seq_check(ev_sock_); + nl_socket_modify_cb(ev_sock_, NL_CB_VALID, NL_CB_CUSTOM, handleEvents, this); + nl_join_groups(ev_sock_, RTMGRP_LINK); + if (nl_connect(ev_sock_, NETLINK_ROUTE) != 0) { throw std::runtime_error("Can't connect network socket"); } - if (nl_socket_add_membership(info_sock_, RTMGRP_LINK) != 0) { - throw std::runtime_error("Can't add membership"); - } - if (nl_socket_add_membership(info_sock_, RTMGRP_IPV4_IFADDR) != 0) { - throw std::runtime_error("Can't add membership"); - } - nl_socket_disable_seq_check(info_sock_); - nl_socket_modify_cb(info_sock_, NL_CB_VALID, NL_CB_CUSTOM, handleEvents, this); + nl_socket_add_membership(ev_sock_, RTNLGRP_LINK); + nl_socket_add_membership(ev_sock_, RTNLGRP_IPV4_IFADDR); + nl_socket_add_membership(ev_sock_, RTNLGRP_IPV6_IFADDR); + nl_socket_add_membership(ev_sock_, RTNLGRP_IPV4_ROUTE); + nl_socket_add_membership(ev_sock_, RTNLGRP_IPV6_ROUTE); efd_ = epoll_create1(EPOLL_CLOEXEC); if (efd_ < 0) { throw std::runtime_error("Can't create epoll"); } { ev_fd_ = eventfd(0, EFD_NONBLOCK); - struct epoll_event event = {0}; + struct epoll_event event; + memset(&event, 0, sizeof(event)); event.events = EPOLLIN | EPOLLET; event.data.fd = ev_fd_; if (epoll_ctl(efd_, EPOLL_CTL_ADD, ev_fd_, &event) == -1) { @@ -81,8 +81,9 @@ void waybar::modules::Network::createInfoSocket() { } } { - auto fd = nl_socket_get_fd(info_sock_); - struct epoll_event event = {0}; + auto fd = nl_socket_get_fd(ev_sock_); + struct epoll_event event; + memset(&event, 0, sizeof(event)); event.events = EPOLLIN | EPOLLET | EPOLLRDHUP; event.data.fd = fd; if (epoll_ctl(efd_, EPOLL_CTL_ADD, fd, &event) == -1) { @@ -92,14 +93,14 @@ void waybar::modules::Network::createInfoSocket() { } void waybar::modules::Network::createEventSocket() { - sk_ = nl_socket_alloc(); - if (genl_connect(sk_) != 0) { + sock_ = nl_socket_alloc(); + if (genl_connect(sock_) != 0) { throw std::runtime_error("Can't connect to netlink socket"); } - if (nl_socket_modify_cb(sk_, NL_CB_VALID, NL_CB_CUSTOM, handleScan, this) < 0) { + if (nl_socket_modify_cb(sock_, NL_CB_VALID, NL_CB_CUSTOM, handleScan, this) < 0) { throw std::runtime_error("Can't set callback"); } - nl80211_id_ = genl_ctrl_resolve(sk_, "nl80211"); + nl80211_id_ = genl_ctrl_resolve(sock_, "nl80211"); if (nl80211_id_ < 0) { throw std::runtime_error("Can't resolve nl80211 interface"); } @@ -118,11 +119,8 @@ void waybar::modules::Network::worker() { int ec = epoll_wait(efd_, events.data(), EPOLL_MAX, -1); if (ec > 0) { for (auto i = 0; i < ec; i++) { - if (events[i].data.fd == nl_socket_get_fd(info_sock_)) { - nl_recvmsgs_default(info_sock_); - } else { - thread_.stop(); - break; + if (events[i].data.fd == nl_socket_get_fd(ev_sock_)) { + nl_recvmsgs_default(ev_sock_); } } } @@ -135,7 +133,7 @@ auto waybar::modules::Network::update() -> void { if (config_["tooltip-format"].isString()) { tooltip_format = config_["tooltip-format"].asString(); } - if (ifid_ <= 0 || ipaddr_.empty()) { + if (ifid_ <= 0 || !linked_) { if (config_["format-disconnected"].isString()) { default_format_ = config_["format-disconnected"].asString(); } @@ -153,6 +151,14 @@ auto waybar::modules::Network::update() -> void { tooltip_format = config_["tooltip-format-ethernet"].asString(); } connectiontype = "ethernet"; + } else if (ipaddr_.empty()) { + if (config_["format-linked"].isString()) { + default_format_ = config_["format-linked"].asString(); + } + if (config_["tooltip-format-linked"].isString()) { + tooltip_format = config_["tooltip-format-linked"].asString(); + } + connectiontype = "linked"; } else { if (config_["format-wifi"].isString()) { default_format_ = config_["format-wifi"].asString(); @@ -196,21 +202,6 @@ auto waybar::modules::Network::update() -> void { } } -void waybar::modules::Network::disconnected() { - essid_.clear(); - signal_strength_dbm_ = 0; - signal_strength_ = 0; - ipaddr_.clear(); - netmask_.clear(); - cidr_ = 0; - if (!config_["interface"].isString()) { - ifname_.clear(); - ifid_ = -1; - } - // Need to wait otherwise we'll have the same information - thread_.sleep_for(std::chrono::seconds(1)); -} - // Based on https://gist.github.com/Yawning/c70d804d4b8ae78cc698 int waybar::modules::Network::getExternalInterface() { static const uint32_t route_buffer_size = 8192; @@ -330,6 +321,7 @@ int waybar::modules::Network::getExternalInterface() { } while (true); out: + last_ext_iface_ = ifidx; return ifidx; } @@ -348,6 +340,7 @@ void waybar::modules::Network::getInterfaceAddress() { ipaddr_ = inet_ntoa(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr); netmask_ = inet_ntoa(((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr); cidrRaw = ((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr.s_addr; + linked_ = ifa->ifa_flags & IFF_RUNNING; unsigned int cidr = 0; while (cidrRaw) { cidr += cidrRaw & 1; @@ -368,7 +361,7 @@ int waybar::modules::Network::netlinkRequest(void *req, uint32_t reqlen, uint32_ sa.nl_groups = groups; struct iovec iov = {req, reqlen}; struct msghdr msg = {&sa, sizeof(sa), &iov, 1, nullptr, 0, 0}; - return sendmsg(nl_socket_get_fd(info_sock_), &msg, 0); + return sendmsg(nl_socket_get_fd(ev_sock_), &msg, 0); } int waybar::modules::Network::netlinkResponse(void *resp, uint32_t resplen, uint32_t groups) { @@ -377,53 +370,119 @@ int waybar::modules::Network::netlinkResponse(void *resp, uint32_t resplen, uint sa.nl_groups = groups; struct iovec iov = {resp, resplen}; struct msghdr msg = {&sa, sizeof(sa), &iov, 1, nullptr, 0, 0}; - auto ret = recvmsg(nl_socket_get_fd(info_sock_), &msg, 0); + auto ret = recvmsg(nl_socket_get_fd(ev_sock_), &msg, 0); if (msg.msg_flags & MSG_TRUNC) { return -1; } return ret; } +bool waybar::modules::Network::checkInterface(int if_index, std::string name) { + if (config_["interface"].isString()) { + return config_["interface"].asString() == name || + wildcardMatch(config_["interface"].asString(), name); + } + auto external_iface = getExternalInterface(); + if (external_iface == -1) { + // Try with lastest working external iface + return last_ext_iface_ == if_index; + } + return external_iface == if_index; +} + +int waybar::modules::Network::getPreferredIface() { + if (config_["interface"].isString()) { + ifid_ = if_nametoindex(config_["interface"].asCString()); + if (ifid_ > 0) { + ifname_ = config_["interface"].asString(); + return ifid_; + } else { + // Try with regex + struct ifaddrs *ifaddr, *ifa; + int success = getifaddrs(&ifaddr); + if (success != 0) { + return -1; + } + ifa = ifaddr; + ifid_ = -1; + while (ifa != nullptr && ipaddr_.empty() && netmask_.empty()) { + if (wildcardMatch(config_["interface"].asString(), ifa->ifa_name)) { + ifid_ = if_nametoindex(ifa->ifa_name); + break; + } + ifa = ifa->ifa_next; + } + freeifaddrs(ifaddr); + return ifid_; + } + } + ifid_ = getExternalInterface(); + if (ifid_ > 0) { + char ifname[IF_NAMESIZE]; + if_indextoname(ifid_, ifname); + ifname_ = ifname; + return ifid_; + } + return -1; +} + int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { - auto net = static_cast(data); - bool need_update = false; - struct nlmsghdr *nh = nlmsg_hdr(msg); + auto net = static_cast(data); + auto nh = nlmsg_hdr(msg); + std::lock_guard lock(net->mutex_); if (nh->nlmsg_type == RTM_NEWADDR) { - need_update = true; - } - if (nh->nlmsg_type < RTM_NEWADDR) { auto rtif = static_cast(NLMSG_DATA(nh)); - if (rtif->ifi_index == static_cast(net->ifid_)) { - need_update = true; - if (!(rtif->ifi_flags & IFF_RUNNING)) { - net->disconnected(); - net->dp.emit(); - return NL_SKIP; - } - } - } - if (net->ifid_ <= 0 && !net->config_["interface"].isString()) { - for (uint8_t i = 0; i < MAX_RETRY; i += 1) { - net->ifid_ = net->getExternalInterface(); - if (net->ifid_ > 0) { - break; - } - // Need to wait before get external interface - net->thread_.sleep_for(std::chrono::seconds(1)); - } - if (net->ifid_ > 0) { - char ifname[IF_NAMESIZE]; - if_indextoname(net->ifid_, ifname); + char ifname[IF_NAMESIZE]; + if_indextoname(rtif->ifi_index, ifname); + // Auto detected network must be assigned here + if (net->checkInterface(rtif->ifi_index, ifname) && net->ifid_ == -1) { + net->linked_ = true; net->ifname_ = ifname; - need_update = true; + net->ifid_ = rtif->ifi_index; + net->dp.emit(); } - } - if (need_update) { - if (net->ifid_ > 0) { - net->getInfo(); + // Check for valid interface + if (rtif->ifi_index == static_cast(net->ifid_)) { + // Get Iface and WIFI info + net->thread_timer_.wake_up(); + net->getInterfaceAddress(); + net->dp.emit(); + } + } else if (nh->nlmsg_type == RTM_DELADDR) { + auto rtif = static_cast(NLMSG_DATA(nh)); + // Check for valid interface + if (rtif->ifi_index == static_cast(net->ifid_)) { + net->ipaddr_.clear(); + net->netmask_.clear(); + net->cidr_ = 0; + net->dp.emit(); + } + } else if (nh->nlmsg_type < RTM_NEWADDR) { + auto rtif = static_cast(NLMSG_DATA(nh)); + char ifname[IF_NAMESIZE]; + if_indextoname(rtif->ifi_index, ifname); + // Check for valid interface + if (net->checkInterface(rtif->ifi_index, ifname) && rtif->ifi_flags & IFF_RUNNING) { + net->linked_ = true; + net->ifname_ = ifname; + net->ifid_ = rtif->ifi_index; + net->dp.emit(); + } else if (rtif->ifi_index == net->ifid_) { + net->linked_ = false; + net->ifname_.clear(); + net->ifid_ = -1; + net->essid_.clear(); + net->signal_strength_dbm_ = 0; + net->signal_strength_ = 0; + // Check for a new interface and get info + auto new_iface = net->getPreferredIface(); + if (new_iface != -1) { + net->thread_timer_.wake_up(); + net->getInterfaceAddress(); + } + net->dp.emit(); } - net->dp.emit(); } return NL_SKIP; } @@ -515,7 +574,6 @@ bool waybar::modules::Network::associatedOrJoined(struct nlattr **bss) { } auto waybar::modules::Network::getInfo() -> void { - getInterfaceAddress(); struct nl_msg *nl_msg = nlmsg_alloc(); if (nl_msg == nullptr) { return; @@ -527,5 +585,44 @@ auto waybar::modules::Network::getInfo() -> void { nlmsg_free(nl_msg); return; } - nl_send_sync(sk_, nl_msg); + nl_send_sync(sock_, nl_msg); +} + +// https://gist.github.com/rressi/92af77630faf055934c723ce93ae2495 +bool waybar::modules::Network::wildcardMatch(const std::string &pattern, const std::string &text) { + auto P = int(pattern.size()); + auto T = int(text.size()); + + auto p = 0, fallback_p = -1; + auto t = 0, fallback_t = -1; + + while (t < T) { + // Wildcard match: + if (p < P && pattern[p] == '*') { + fallback_p = p++; // starting point after failures + fallback_t = t; // starting point after failures + } + + // Simple match: + else if (p < P && (pattern[p] == '?' || pattern[p] == text[t])) { + p++; + t++; + } + + // Failure, fall back just after last matched '*': + else if (fallback_p >= 0) { + p = fallback_p + 1; // position just after last matched '*" + t = ++fallback_t; // re-try to match text from here + } + + // There were no '*' before, so we fail here: + else { + return false; + } + } + + // Consume all '*' at the end of pattern: + while (p < P && pattern[p] == '*') p++; + + return p == P; } From 45ebee52a6b199caed2f05343f5cc93b1675df88 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 11:26:06 +0200 Subject: [PATCH 21/44] fix: typo --- src/modules/network.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/network.cpp b/src/modules/network.cpp index bdab3a8d..264d73e2 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -435,7 +435,7 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { auto rtif = static_cast(NLMSG_DATA(nh)); char ifname[IF_NAMESIZE]; if_indextoname(rtif->ifi_index, ifname); - // Auto detected network must be assigned here + // Auto detected network can also be assigned here if (net->checkInterface(rtif->ifi_index, ifname) && net->ifid_ == -1) { net->linked_ = true; net->ifname_ = ifname; From a09d2222be5b70df2138b0c143aa6ee80c249f0d Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 11:26:48 +0200 Subject: [PATCH 22/44] style: remove non wanted tags --- resources/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/config b/resources/config index 4d9a96d6..69da70fc 100644 --- a/resources/config +++ b/resources/config @@ -105,7 +105,7 @@ }, "network": { // "interface": "wlp2*", // (Optional) To force the use of this interface - "format-wifi": "{ifname}: {ipaddr}/{cidr} {essid} ({signalStrength}%) ", + "format-wifi": "{essid} ({signalStrength}%) ", "format-ethernet": "{ifname}: {ipaddr}/{cidr} ", "format-linked": "{ifname} (No IP) ", "format-disconnected": "Disconnected ⚠" From f3c467cc46d43b19cdcf442f2813101c322a2a54 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 11:27:22 +0200 Subject: [PATCH 23/44] refactor: remove non wanted headers --- src/modules/network.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 264d73e2..b7a5616a 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -1,8 +1,5 @@ #include "modules/network.hpp" #include -#include - -#include waybar::modules::Network::Network(const std::string &id, const Json::Value &config) : ALabel(config, "{ifname}", 60), From 9c67150884e2cab69ed9ae19379181caf3347c2a Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 12:14:12 +0200 Subject: [PATCH 24/44] refactor: prepare ipv6 --- src/modules/network.cpp | 50 +++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/modules/network.cpp b/src/modules/network.cpp index b7a5616a..1362ba2a 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -329,27 +329,33 @@ void waybar::modules::Network::getInterfaceAddress() { netmask_.clear(); cidr_ = 0; int success = getifaddrs(&ifaddr); - if (success == 0) { - ifa = ifaddr; - while (ifa != nullptr && ipaddr_.empty() && netmask_.empty()) { - if (ifa->ifa_addr != nullptr && ifa->ifa_addr->sa_family == family_) { - if (strcmp(ifa->ifa_name, ifname_.c_str()) == 0) { - ipaddr_ = inet_ntoa(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr); - netmask_ = inet_ntoa(((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr); - cidrRaw = ((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr.s_addr; - linked_ = ifa->ifa_flags & IFF_RUNNING; - unsigned int cidr = 0; - while (cidrRaw) { - cidr += cidrRaw & 1; - cidrRaw >>= 1; - } - cidr_ = cidr; - } - } - ifa = ifa->ifa_next; - } - freeifaddrs(ifaddr); + if (success != 0) { + return; } + ifa = ifaddr; + while (ifa != nullptr && ipaddr_.empty() && netmask_.empty()) { + if (ifa->ifa_addr != nullptr && ifa->ifa_addr->sa_family == family_ && + ifa->ifa_name == ifname_) { + char ipaddr[INET6_ADDRSTRLEN]; + ipaddr_ = inet_ntop(family_, + &reinterpret_cast(ifa->ifa_addr)->sin_addr, + ipaddr, + INET6_ADDRSTRLEN); + char netmask[INET6_ADDRSTRLEN]; + auto net_addr = reinterpret_cast(ifa->ifa_netmask); + netmask_ = inet_ntop(family_, &net_addr->sin_addr, netmask, INET6_ADDRSTRLEN); + cidrRaw = net_addr->sin_addr.s_addr; + linked_ = ifa->ifa_flags & IFF_RUNNING; + unsigned int cidr = 0; + while (cidrRaw) { + cidr += cidrRaw & 1; + cidrRaw >>= 1; + } + cidr_ = cidr; + } + ifa = ifa->ifa_next; + } + freeifaddrs(ifaddr); } int waybar::modules::Network::netlinkRequest(void *req, uint32_t reqlen, uint32_t groups) { @@ -394,7 +400,7 @@ int waybar::modules::Network::getPreferredIface() { ifname_ = config_["interface"].asString(); return ifid_; } else { - // Try with regex + // Try with wildcard struct ifaddrs *ifaddr, *ifa; int success = getifaddrs(&ifaddr); if (success != 0) { @@ -402,7 +408,7 @@ int waybar::modules::Network::getPreferredIface() { } ifa = ifaddr; ifid_ = -1; - while (ifa != nullptr && ipaddr_.empty() && netmask_.empty()) { + while (ifa != nullptr) { if (wildcardMatch(config_["interface"].asString(), ifa->ifa_name)) { ifid_ = if_nametoindex(ifa->ifa_name); break; From fbe19d886ad3932443e3bbab6a0a67c4509b773d Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 12:16:44 +0200 Subject: [PATCH 25/44] fix: drop memberships --- src/modules/network.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 1362ba2a..8a6c6a94 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -39,8 +39,10 @@ waybar::modules::Network::~Network() { } if (ev_sock_ != nullptr) { nl_socket_drop_membership(ev_sock_, RTNLGRP_LINK); - nl_socket_drop_membership(ev_sock_, RTMGRP_IPV4_IFADDR); - nl_socket_drop_membership(ev_sock_, RTMGRP_IPV6_IFADDR); + nl_socket_drop_membership(ev_sock_, RTNLGRP_IPV4_IFADDR); + nl_socket_drop_membership(ev_sock_, RTNLGRP_IPV6_IFADDR); + nl_socket_drop_membership(ev_sock_, RTNLGRP_IPV4_ROUTE); + nl_socket_drop_membership(ev_sock_, RTNLGRP_IPV6_ROUTE); nl_close(ev_sock_); nl_socket_free(ev_sock_); } From 31416ffae6fbfc36d8e67a0a5f745f4282531b48 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 12:19:47 +0200 Subject: [PATCH 26/44] fix: bar removed --- src/modules/network.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 8a6c6a94..2fe21fc8 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -120,6 +120,9 @@ void waybar::modules::Network::worker() { for (auto i = 0; i < ec; i++) { if (events[i].data.fd == nl_socket_get_fd(ev_sock_)) { nl_recvmsgs_default(ev_sock_); + } else { + thread_.stop(); + break; } } } From 0a14e7f3aba525519df6b894087f5da3562b42d1 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 12:22:08 +0200 Subject: [PATCH 27/44] feat: ipv6 family --- src/modules/network.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 2fe21fc8..f136adbe 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -5,7 +5,7 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf : ALabel(config, "{ifname}", 60), ifid_(-1), last_ext_iface_(-1), - family_(AF_INET), + family_(config["family"] == "ipv6" ? AF_INET6 : AF_INET), efd_(-1), ev_fd_(-1), cidr_(-1), From e12766a656731b9582ac3020b511db0ad5aced8f Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 17:09:25 +0200 Subject: [PATCH 28/44] fix: compilation on some os --- src/modules/network.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/modules/network.cpp b/src/modules/network.cpp index f136adbe..b5de4744 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -368,7 +368,12 @@ int waybar::modules::Network::netlinkRequest(void *req, uint32_t reqlen, uint32_ sa.nl_family = AF_NETLINK; sa.nl_groups = groups; struct iovec iov = {req, reqlen}; - struct msghdr msg = {&sa, sizeof(sa), &iov, 1, nullptr, 0, 0}; + struct msghdr msg = { + .msg_name = &sa, + .msg_namelen = sizeof(sa), + .msg_iov = &iov, + .msg_iovlen = 1, + }; return sendmsg(nl_socket_get_fd(ev_sock_), &msg, 0); } @@ -377,8 +382,13 @@ int waybar::modules::Network::netlinkResponse(void *resp, uint32_t resplen, uint sa.nl_family = AF_NETLINK; sa.nl_groups = groups; struct iovec iov = {resp, resplen}; - struct msghdr msg = {&sa, sizeof(sa), &iov, 1, nullptr, 0, 0}; - auto ret = recvmsg(nl_socket_get_fd(ev_sock_), &msg, 0); + struct msghdr msg = { + .msg_name = &sa, + .msg_namelen = sizeof(sa), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + auto ret = recvmsg(nl_socket_get_fd(ev_sock_), &msg, 0); if (msg.msg_flags & MSG_TRUNC) { return -1; } From 8901df97021d3ade5f5441eb36974a03f5f34edb Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 17:10:35 +0200 Subject: [PATCH 29/44] chore: add alpine dockerfile --- Dockerfiles/alpine | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Dockerfiles/alpine diff --git a/Dockerfiles/alpine b/Dockerfiles/alpine new file mode 100644 index 00000000..20d2c48e --- /dev/null +++ b/Dockerfiles/alpine @@ -0,0 +1,3 @@ +FROM alpine:latest + +RUN apk add --no-cache git meson alpine-sdk libinput-dev wayland-dev wayland-protocols mesa-dev libxkbcommon-dev eudev-dev pixman-dev gtkmm3-dev jsoncpp-dev libnl3-dev pulseaudio-dev libmpdclient-dev \ No newline at end of file From 4b4b74db0c29e7e3ef1e60899d3cf916d023bd5d Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 17:18:27 +0200 Subject: [PATCH 30/44] feat(Battery): get icon by state --- src/modules/battery.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index b51ed496..b01ff2b6 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -147,7 +147,7 @@ auto waybar::modules::Battery::update() -> void { event_box_.hide(); } else { event_box_.show(); - label_.set_markup( - fmt::format(format, fmt::arg("capacity", capacity), fmt::arg("icon", getIcon(capacity)))); + label_.set_markup(fmt::format( + format, fmt::arg("capacity", capacity), fmt::arg("icon", getIcon(capacity, state)))); } } From a1ffa7fa9f271dc2af1bc9d8fbf2e280365a312f Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2019 17:20:27 +0200 Subject: [PATCH 31/44] chore: enable alpine on Travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 75b012c2..ec87992e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ env: - distro: archlinux - distro: opensuse - distro: fedora + - distro: alpine before_install: - docker pull alexays/waybar:${distro} From b45dcdf74e8773f1fb695d11e7efaf437c2aef9b Mon Sep 17 00:00:00 2001 From: RX14 Date: Thu, 16 May 2019 22:18:43 +0100 Subject: [PATCH 32/44] Allow scrolling on the entire bar surface --- include/bar.hpp | 1 + include/modules/sway/workspaces.hpp | 3 ++- src/bar.cpp | 31 +++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/include/bar.hpp b/include/bar.hpp index c4cd8148..45bdf016 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -55,6 +55,7 @@ class Bar { void setMarginsAndZone(uint32_t height, uint32_t width); auto setupWidgets() -> void; void getModules(const Factory &, const std::string &); + bool handleScroll(GdkEventScroll*); void setupAltFormatKeyForModule(const std::string &module_name); void setupAltFormatKeyForModuleList(const char *module_list_name); diff --git a/include/modules/sway/workspaces.hpp b/include/modules/sway/workspaces.hpp index 84c2eb0e..97b82e74 100644 --- a/include/modules/sway/workspaces.hpp +++ b/include/modules/sway/workspaces.hpp @@ -19,6 +19,8 @@ class Workspaces : public IModule, public sigc::trackable { auto update() -> void; operator Gtk::Widget&(); + bool handleScroll(GdkEventScroll*); + private: void onCmd(const struct Ipc::ipc_response&); void onEvent(const struct Ipc::ipc_response&); @@ -27,7 +29,6 @@ class Workspaces : public IModule, public sigc::trackable { Gtk::Button& addButton(const Json::Value&); void onButtonReady(const Json::Value&, Gtk::Button&); std::string getIcon(const std::string&, const Json::Value&); - bool handleScroll(GdkEventScroll*); const std::string getCycleWorkspace(std::vector::iterator, bool prev) const; uint16_t getWorkspaceIndex(const std::string& name) const; std::string trimWorkspaceName(std::string); diff --git a/src/bar.cpp b/src/bar.cpp index 6c6de20c..cb0d01c6 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -72,6 +72,12 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) wl_surface_commit(surface); wl_display_roundtrip(client->wl_display); + + if (!config["disable-workspace-scroll"].asBool()) { + window.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); + window.signal_scroll_event().connect(sigc::mem_fun(*this, &Bar::handleScroll)); + } + setupWidgets(); } @@ -217,6 +223,31 @@ void waybar::Bar::handleSignal(int signal) { } } +bool waybar::Bar::handleScroll(GdkEventScroll *e) { + std::cerr << "handleScroll" << std::endl; + + for (auto& module : modules_left_) { + if (auto workspaces = dynamic_cast(module.get())) { + workspaces->handleScroll(e); + return true; + } + } + for (auto& module : modules_center_) { + if (auto workspaces = dynamic_cast(module.get())) { + workspaces->handleScroll(e); + return true; + } + } + for (auto& module : modules_right_) { + if (auto workspaces = dynamic_cast(module.get())) { + workspaces->handleScroll(e); + return true; + } + } + + return false; +} + void waybar::Bar::layerSurfaceHandleConfigure(void* data, struct zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width, uint32_t height) { auto o = static_cast(data); From d5c1e6f3122902b4eb056e6ebe8fa43f6289659a Mon Sep 17 00:00:00 2001 From: Olegs Jeremejevs Date: Tue, 14 May 2019 15:24:06 +0800 Subject: [PATCH 33/44] Change scroll-step unit to percent --- resources/config | 2 +- src/modules/pulseaudio.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/config b/resources/config index 69da70fc..f5349895 100644 --- a/resources/config +++ b/resources/config @@ -111,7 +111,7 @@ "format-disconnected": "Disconnected ⚠" }, "pulseaudio": { - //"scroll-step": 1, + // "scroll-step": 1, // %, can be a float "format": "{volume}% {icon}", "format-bluetooth": "{volume}% {icon}", "format-muted": "", diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index 099b1dc4..97c37936 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -77,7 +77,8 @@ bool waybar::modules::Pulseaudio::handleVolume(GdkEventScroll *e) { return false; } bool direction_up = false; - uint16_t change = config_["scroll-step"].isUInt() ? config_["scroll-step"].asUInt() * 100 : 100; + double volume_tick = (double)PA_VOLUME_NORM / 100; + pa_volume_t change = volume_tick; pa_cvolume pa_volume = pa_volume_; scrolling_ = true; if (e->direction == GDK_SCROLL_UP) { @@ -97,6 +98,11 @@ bool waybar::modules::Pulseaudio::handleVolume(GdkEventScroll *e) { } } + // isDouble returns true for integers as well, just in case + if (config_["scroll-step"].isDouble()) { + change = round(config_["scroll-step"].asDouble() * volume_tick); + } + if (direction_up) { if (volume_ + 1 < 100) { pa_cvolume_inc(&pa_volume, change); From 4d4cadb5aeb810cfa9d7c658294dd9e7d0ac1c64 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 17 May 2019 09:59:37 +0200 Subject: [PATCH 34/44] refactor: simpler code --- include/bar.hpp | 1 - include/modules/sway/workspaces.hpp | 5 ++--- src/bar.cpp | 31 ----------------------------- src/modules/sway/workspaces.cpp | 5 +++++ 4 files changed, 7 insertions(+), 35 deletions(-) diff --git a/include/bar.hpp b/include/bar.hpp index 45bdf016..c4cd8148 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -55,7 +55,6 @@ class Bar { void setMarginsAndZone(uint32_t height, uint32_t width); auto setupWidgets() -> void; void getModules(const Factory &, const std::string &); - bool handleScroll(GdkEventScroll*); void setupAltFormatKeyForModule(const std::string &module_name); void setupAltFormatKeyForModuleList(const char *module_list_name); diff --git a/include/modules/sway/workspaces.hpp b/include/modules/sway/workspaces.hpp index 97b82e74..8c7875cc 100644 --- a/include/modules/sway/workspaces.hpp +++ b/include/modules/sway/workspaces.hpp @@ -7,8 +7,8 @@ #include "bar.hpp" #include "client.hpp" #include "modules/sway/ipc/client.hpp" -#include "util/sleeper_thread.hpp" #include "util/json.hpp" +#include "util/sleeper_thread.hpp" namespace waybar::modules::sway { @@ -19,8 +19,6 @@ class Workspaces : public IModule, public sigc::trackable { auto update() -> void; operator Gtk::Widget&(); - bool handleScroll(GdkEventScroll*); - private: void onCmd(const struct Ipc::ipc_response&); void onEvent(const struct Ipc::ipc_response&); @@ -32,6 +30,7 @@ class Workspaces : public IModule, public sigc::trackable { const std::string getCycleWorkspace(std::vector::iterator, bool prev) const; uint16_t getWorkspaceIndex(const std::string& name) const; std::string trimWorkspaceName(std::string); + bool handleScroll(GdkEventScroll*); const Bar& bar_; const Json::Value& config_; diff --git a/src/bar.cpp b/src/bar.cpp index cb0d01c6..6c6de20c 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -72,12 +72,6 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) wl_surface_commit(surface); wl_display_roundtrip(client->wl_display); - - if (!config["disable-workspace-scroll"].asBool()) { - window.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); - window.signal_scroll_event().connect(sigc::mem_fun(*this, &Bar::handleScroll)); - } - setupWidgets(); } @@ -223,31 +217,6 @@ void waybar::Bar::handleSignal(int signal) { } } -bool waybar::Bar::handleScroll(GdkEventScroll *e) { - std::cerr << "handleScroll" << std::endl; - - for (auto& module : modules_left_) { - if (auto workspaces = dynamic_cast(module.get())) { - workspaces->handleScroll(e); - return true; - } - } - for (auto& module : modules_center_) { - if (auto workspaces = dynamic_cast(module.get())) { - workspaces->handleScroll(e); - return true; - } - } - for (auto& module : modules_right_) { - if (auto workspaces = dynamic_cast(module.get())) { - workspaces->handleScroll(e); - return true; - } - } - - return false; -} - void waybar::Bar::layerSurfaceHandleConfigure(void* data, struct zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width, uint32_t height) { auto o = static_cast(data); diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index f379c9aa..133c81ad 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -15,6 +15,11 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value ipc_.signal_event.connect(sigc::mem_fun(*this, &Workspaces::onEvent)); ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Workspaces::onCmd)); ipc_.sendCmd(IPC_GET_WORKSPACES); + if (!config["disable-workspace-scroll"].asBool()) { + auto &window = const_cast(bar_).window; + window.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); + window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll)); + } // Launch worker worker(); } From 9a091d774008b6b70a99dc6d588a8641a94558f8 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 17 May 2019 10:18:05 +0200 Subject: [PATCH 35/44] chore: 0.6.4 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 5514e118..111b1a9a 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project( 'waybar', 'cpp', 'c', - version: '0.6.3', + version: '0.6.4', license: 'MIT', default_options : [ 'cpp_std=c++17', From 17291dffdf623f21fe9902d59a0cf90b4f6a594e Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 17 May 2019 10:59:54 +0200 Subject: [PATCH 36/44] fix(Battery): plugged state --- src/modules/battery.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index b01ff2b6..2c1cc112 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -93,10 +93,14 @@ const std::tuple waybar::modules::Battery::getIn total += capacity; total_current += current_now; } - uint16_t capacity = total / batteries_.size(); - if (status == "Charging" && total_current != 0) { - status = "Plugged"; + if (!adapter_.empty() && status == "Discharging") { + bool online; + std::ifstream(adapter_ / "online") >> online; + if (online) { + status = "Plugged"; + } } + uint16_t capacity = total / batteries_.size(); return {capacity, total_current, status}; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; @@ -113,7 +117,7 @@ const std::string waybar::modules::Battery::getAdapterStatus(uint8_t capacity, return "Full"; } if (online) { - return current_now == 0 ? "Charging" : "Plugged"; + return "Charging"; } return "Discharging"; } From cb2d6e19970e4629a47faa05932929e8fc137f6f Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 17 May 2019 11:27:38 +0200 Subject: [PATCH 37/44] feat(Network): frequency --- include/modules/network.hpp | 2 ++ src/modules/network.cpp | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/modules/network.hpp b/include/modules/network.hpp index cbea4e48..3afae571 100644 --- a/include/modules/network.hpp +++ b/include/modules/network.hpp @@ -36,6 +36,7 @@ class Network : public ALabel { int netlinkResponse(void*, uint32_t, uint32_t groups = 0); void parseEssid(struct nlattr**); void parseSignal(struct nlattr**); + void parseFreq(struct nlattr**); bool associatedOrJoined(struct nlattr**); bool checkInterface(int if_index, std::string name); int getPreferredIface(); @@ -63,6 +64,7 @@ class Network : public ALabel { bool linked_; int32_t signal_strength_dbm_; uint8_t signal_strength_; + uint32_t frequency_; }; } // namespace waybar::modules diff --git a/src/modules/network.cpp b/src/modules/network.cpp index b5de4744..cca1d50b 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -10,7 +10,8 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf ev_fd_(-1), cidr_(-1), signal_strength_dbm_(0), - signal_strength_(0) { + signal_strength_(0), + frequency_(0) { label_.set_name("network"); if (!id.empty()) { label_.get_style_context()->add_class(id); @@ -184,6 +185,7 @@ auto waybar::modules::Network::update() -> void { fmt::arg("netmask", netmask_), fmt::arg("ipaddr", ipaddr_), fmt::arg("cidr", cidr_), + fmt::arg("frequency", frequency_), fmt::arg("icon", getIcon(signal_strength_, connectiontype))); label_.set_markup(text); if (tooltipEnabled()) { @@ -196,6 +198,7 @@ auto waybar::modules::Network::update() -> void { fmt::arg("netmask", netmask_), fmt::arg("ipaddr", ipaddr_), fmt::arg("cidr", cidr_), + fmt::arg("frequency", frequency_), fmt::arg("icon", getIcon(signal_strength_, connectiontype))); label_.set_tooltip_text(tooltip_text); } else { @@ -536,7 +539,7 @@ int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) { } net->parseEssid(bss); net->parseSignal(bss); - // TODO(someone): parse quality + net->parseFreq(bss); return NL_SKIP; } @@ -576,6 +579,13 @@ void waybar::modules::Network::parseSignal(struct nlattr **bss) { } } +void waybar::modules::Network::parseFreq(struct nlattr **bss) { + if (bss[NL80211_BSS_FREQUENCY] != nullptr) { + // in MHz + frequency_ = nla_get_u32(bss[NL80211_BSS_FREQUENCY]); + } +} + bool waybar::modules::Network::associatedOrJoined(struct nlattr **bss) { if (bss[NL80211_BSS_STATUS] == nullptr) { return false; From f8a47598bac2763b41c4e63e18c5ed9a5125cd47 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 17 May 2019 13:40:04 +0200 Subject: [PATCH 38/44] fix: roundtrip before bar creation --- src/client.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client.cpp b/src/client.cpp index 8713ec82..b927684b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -153,6 +153,7 @@ void waybar::Client::handleName(void * data, struct zxdg_output_v1 * /*xdg_ wl_output_destroy(output->output); zxdg_output_v1_destroy(output->xdg_output); } else { + wl_display_roundtrip(client->wl_display); for (const auto &config : configs) { client->bars.emplace_back(std::make_unique(output.get(), config)); Glib::RefPtr screen = client->bars.back()->window.get_screen(); From d8be72e4b6453b2b213fd59a6d36627f53737fda Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 17 May 2019 13:51:55 +0200 Subject: [PATCH 39/44] refactor: unexport tray watcher --- src/modules/sni/watcher.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modules/sni/watcher.cpp b/src/modules/sni/watcher.cpp index 1ba1324f..596a06d4 100644 --- a/src/modules/sni/watcher.cpp +++ b/src/modules/sni/watcher.cpp @@ -24,8 +24,7 @@ Watcher::~Watcher() { items_ = nullptr; } auto iface = G_DBUS_INTERFACE_SKELETON(watcher_); - auto conn = g_dbus_interface_skeleton_get_connection(iface); - g_dbus_interface_skeleton_unexport_from_connection(iface, conn); + g_dbus_interface_skeleton_unexport(iface); } void Watcher::busAcquired(const Glib::RefPtr& conn, Glib::ustring name) { From d2d9db23b52bfa88a84944a6c97890c373f5796f Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 17 May 2019 14:23:52 +0200 Subject: [PATCH 40/44] fix: uninitialized bool --- include/modules/sni/item.hpp | 6 ++--- src/modules/sni/item.cpp | 45 ++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/include/modules/sni/item.hpp b/include/modules/sni/item.hpp index 6706e32b..c8f835bd 100644 --- a/include/modules/sni/item.hpp +++ b/include/modules/sni/item.hpp @@ -46,7 +46,7 @@ class Item : public sigc::trackable { std::string menu; DbusmenuGtkMenu* dbus_menu = nullptr; Gtk::Menu* gtk_menu = nullptr; - bool item_is_menu; + bool item_is_menu = false; private: void proxyReady(Glib::RefPtr& result); @@ -59,8 +59,8 @@ class Item : public sigc::trackable { void updateImage(); Glib::RefPtr extractPixBuf(GVariant* variant); Glib::RefPtr getIconByName(const std::string& name, int size); - static void onMenuDestroyed(Item* self); - bool makeMenu(GdkEventButton* const& ev); + static void onMenuDestroyed(Item* self, GObject* old_menu_pointer); + void makeMenu(GdkEventButton* const& ev); bool handleClick(GdkEventButton* const& /*ev*/); Glib::RefPtr proxy_; diff --git a/src/modules/sni/item.cpp b/src/modules/sni/item.cpp index cfb5fef0..106b0611 100644 --- a/src/modules/sni/item.cpp +++ b/src/modules/sni/item.cpp @@ -276,39 +276,38 @@ Glib::RefPtr Item::getIconByName(const std::string& name, int reque name.c_str(), tmp_size, Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE); } -void Item::onMenuDestroyed(Item* self) { - self->gtk_menu = nullptr; - self->dbus_menu = nullptr; +void Item::onMenuDestroyed(Item* self, GObject* old_menu_pointer) { + if (old_menu_pointer == reinterpret_cast(self->dbus_menu)) { + self->gtk_menu = nullptr; + self->dbus_menu = nullptr; + } } -bool Item::makeMenu(GdkEventButton* const& ev) { - if (gtk_menu == nullptr) { - if (!menu.empty()) { - dbus_menu = dbusmenu_gtkmenu_new(bus_name.data(), menu.data()); - if (dbus_menu != nullptr) { - g_object_ref_sink(G_OBJECT(dbus_menu)); - g_object_weak_ref(G_OBJECT(dbus_menu), (GWeakNotify)onMenuDestroyed, this); - gtk_menu = Glib::wrap(GTK_MENU(dbus_menu)); - gtk_menu->attach_to_widget(event_box); - } +void Item::makeMenu(GdkEventButton* const& ev) { + if (gtk_menu == nullptr && !menu.empty()) { + dbus_menu = dbusmenu_gtkmenu_new(bus_name.data(), menu.data()); + if (dbus_menu != nullptr) { + g_object_ref_sink(G_OBJECT(dbus_menu)); + g_object_weak_ref(G_OBJECT(dbus_menu), (GWeakNotify)onMenuDestroyed, this); + gtk_menu = Glib::wrap(GTK_MENU(dbus_menu)); + gtk_menu->attach_to_widget(event_box); } } - if (gtk_menu != nullptr) { -#if GTK_CHECK_VERSION(3, 22, 0) - gtk_menu->popup_at_pointer(reinterpret_cast(ev)); -#else - gtk_menu->popup(ev->button, ev->time); -#endif - return true; - } - return false; } bool Item::handleClick(GdkEventButton* const& ev) { auto parameters = Glib::VariantContainerBase::create_tuple( {Glib::Variant::create(ev->x), Glib::Variant::create(ev->y)}); if ((ev->button == 1 && item_is_menu) || ev->button == 3) { - if (!makeMenu(ev)) { + makeMenu(ev); + if (gtk_menu != nullptr) { +#if GTK_CHECK_VERSION(3, 22, 0) + gtk_menu->popup_at_pointer(reinterpret_cast(ev)); +#else + gtk_menu->popup(ev->button, ev->time); +#endif + return true; + } else { proxy_->call("ContextMenu", parameters); return true; } From 9d3255fe9f6bc4ce015d6ec59d55c582a0a8edbf Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 17 May 2019 14:41:12 +0200 Subject: [PATCH 41/44] fix: remove redundant roundtrip --- src/bar.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/bar.cpp b/src/bar.cpp index 6c6de20c..57050995 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -20,7 +20,6 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) height_ = 0; width_ = 1; } - window.set_size_request(width_, height_); auto gtk_window = window.gobj(); auto gtk_widget = GTK_WIDGET(gtk_window); @@ -43,8 +42,6 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) auto height = config["height"].isUInt() ? config["height"].asUInt() : height_; auto width = config["width"].isUInt() ? config["width"].asUInt() : width_; - window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Bar::onConfigure)); - std::size_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; if (config["position"] == "bottom") { anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; @@ -70,9 +67,11 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) setMarginsAndZone(height, width); wl_surface_commit(surface); - wl_display_roundtrip(client->wl_display); setupWidgets(); + + window.set_size_request(width_, height_); + window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Bar::onConfigure)); } void waybar::Bar::setMarginsAndZone(uint32_t height, uint32_t width) { From 9234be854495a132031f23be332b82fb66b1f328 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 17 May 2019 14:45:02 +0200 Subject: [PATCH 42/44] revert: re-add rountrip before widgets setup --- src/bar.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bar.cpp b/src/bar.cpp index 57050995..dd7b8805 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -67,6 +67,7 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) setMarginsAndZone(height, width); wl_surface_commit(surface); + wl_display_roundtrip(client->wl_display); setupWidgets(); From 1e95f5d9b6dd87cdbad2bd6f2590c06fcaf09121 Mon Sep 17 00:00:00 2001 From: RX14 Date: Fri, 17 May 2019 17:37:24 +0100 Subject: [PATCH 43/44] Fix workspace scroll wrapping off the end of the list --- src/modules/sway/workspaces.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 133c81ad..54835144 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -223,7 +223,7 @@ const std::string Workspaces::getCycleWorkspace(std::vector::iterat else if (!prev && it != workspaces_.end()) ++it; if (!prev && it == workspaces_.end()) { - return (*(++workspaces_.begin()))["name"].asString(); + return (*(workspaces_.begin()))["name"].asString(); } return (*it)["name"].asString(); } @@ -250,4 +250,4 @@ void Workspaces::onButtonReady(const Json::Value &node, Gtk::Button &button) { Workspaces::operator Gtk::Widget &() { return box_; } -} // namespace waybar::modules::sway \ No newline at end of file +} // namespace waybar::modules::sway From 0d59f7b7d147008980eff295b60c522368c61a5d Mon Sep 17 00:00:00 2001 From: RX14 Date: Fri, 17 May 2019 17:42:11 +0100 Subject: [PATCH 44/44] Rename the "disable-workspace-scroll" option to "disable-bar-scroll" --- src/modules/sway/workspaces.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 133c81ad..5314bd4c 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -15,7 +15,7 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value ipc_.signal_event.connect(sigc::mem_fun(*this, &Workspaces::onEvent)); ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Workspaces::onCmd)); ipc_.sendCmd(IPC_GET_WORKSPACES); - if (!config["disable-workspace-scroll"].asBool()) { + if (!config["disable-bar-scroll"].asBool()) { auto &window = const_cast(bar_).window; window.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll)); @@ -250,4 +250,4 @@ void Workspaces::onButtonReady(const Json::Value &node, Gtk::Button &button) { Workspaces::operator Gtk::Widget &() { return box_; } -} // namespace waybar::modules::sway \ No newline at end of file +} // namespace waybar::modules::sway