Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package waybar for openSUSE:Factory checked in at 2022-03-07 17:46:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/waybar (Old) and /work/SRC/openSUSE:Factory/.waybar.new.1958 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "waybar" Mon Mar 7 17:46:56 2022 rev:32 rq:959817 version:0.9.10 Changes: -------- --- /work/SRC/openSUSE:Factory/waybar/waybar.changes 2022-02-17 23:41:48.127700281 +0100 +++ /work/SRC/openSUSE:Factory/.waybar.new.1958/waybar.changes 2022-03-07 17:47:10.407115817 +0100 @@ -1,0 +2,37 @@ +Mon Mar 7 09:47:52 UTC 2022 - Michael Vetter <mvet...@suse.com> + +- Update to 0.9.10: + * avoid use-after-free in lambda + * style.css: add fontawesome to beginning of font list + * Fix remaining posix compatability issues in keyboard_state + * Don't use gnu extensions which are too new for debian and ubuntu + * Make error messages portable + * Improve keyboard_state error messages + * limit cpu load figure to 2 points + * Add 1 to songPosition in the MPD module + * fix #1431: audio output does not update on unplug + * move Glib ustring format helper to utils + * remove duplicated string manipulation methods + * ltrim and rtrim take argument by const-ref + * make functions in header file inline + * Update man page clock module - tooltip + * Fix disabled tooltip on clock module + * Update spotify example to work on copy paste + * Properly initialize distance_scrolled members. + * Fix Typo in Example for sway/mode + * Add config option "reverse-direction" + * use pack_end instead of pack_start + * sway/language: fix segmentation fault for layouts not found in XKBContext + * Show application icon when using sway window module + * battery: read status with spaces + * Use locale when formatting clock + * fix(man): add missing newlines to wlr docs. + * created a hotfix for libfmt-8.1.0 and above + * removed commented useless runtime errors + * changing want_route_dump to default to true, since we say we have gwaddr support + * maybe we shouldn't actually runtime error, but still doing a check + * explicitly checking for errors to silence unused variable warnings when writing to fd + * Add man + * Add swap flags + +------------------------------------------------------------------- Old: ---- 0.9.9.tar.xz New: ---- 0.9.10.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ waybar.spec ++++++ --- /var/tmp/diff_new_pack.Mwox2s/_old 2022-03-07 17:47:11.103115616 +0100 +++ /var/tmp/diff_new_pack.Mwox2s/_new 2022-03-07 17:47:11.111115614 +0100 @@ -17,7 +17,7 @@ Name: waybar -Version: 0.9.9 +Version: 0.9.10 Release: 0 Summary: Customizable Wayland bar for Sway and Wlroots based compositors License: MIT ++++++ 0.9.9.tar.xz -> 0.9.10.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/.github/workflows/freebsd.yml new/Waybar-0.9.10/.github/workflows/freebsd.yml --- old/Waybar-0.9.9/.github/workflows/freebsd.yml 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/.github/workflows/freebsd.yml 2022-03-06 14:54:48.000000000 +0100 @@ -11,7 +11,7 @@ steps: - uses: actions/checkout@v2 - name: Test in FreeBSD VM - uses: vmactions/freebsd-vm@v0.1.5 # aka FreeBSD 13.0 + uses: vmactions/freebsd-vm@v0.1.6 # aka FreeBSD 13.0 with: mem: 2048 usesh: true @@ -21,7 +21,7 @@ pkg install -y git # subprojects/date pkg install -y catch evdev-proto gtk-layer-shell gtkmm30 jsoncpp \ libdbusmenu libevdev libfmt libmpdclient libudev-devd meson \ - pkgconf pulseaudio scdoc sndio spdlog + pkgconf pulseaudio scdoc sndio spdlog wayland-protocols run: | meson build -Dman-pages=enabled ninja -C build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/include/AIconLabel.hpp new/Waybar-0.9.10/include/AIconLabel.hpp --- old/Waybar-0.9.9/include/AIconLabel.hpp 1970-01-01 01:00:00.000000000 +0100 +++ new/Waybar-0.9.10/include/AIconLabel.hpp 2022-03-06 14:54:48.000000000 +0100 @@ -0,0 +1,25 @@ +#pragma once + +#include <gtkmm/box.h> +#include <gtkmm/image.h> + +#include "ALabel.hpp" + +namespace waybar { + +class AIconLabel : public ALabel { + public: + AIconLabel(const Json::Value &config, const std::string &name, const std::string &id, + const std::string &format, uint16_t interval = 0, bool ellipsize = false, + bool enable_click = false, bool enable_scroll = false); + virtual ~AIconLabel() = default; + virtual auto update() -> void; + + protected: + Gtk::Image image_; + Gtk::Box box_; + + bool iconEnabled() const; +}; + +} // namespace waybar diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/include/modules/keyboard_state.hpp new/Waybar-0.9.10/include/modules/keyboard_state.hpp --- old/Waybar-0.9.9/include/modules/keyboard_state.hpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/include/modules/keyboard_state.hpp 2022-03-06 14:54:48.000000000 +0100 @@ -24,8 +24,6 @@ auto update() -> void; private: - static auto openDevice(const std::string&) -> std::pair<int, libevdev*>; - Gtk::Box box_; Gtk::Label numlock_label_; Gtk::Label capslock_label_; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/include/modules/sway/window.hpp new/Waybar-0.9.10/include/modules/sway/window.hpp --- old/Waybar-0.9.9/include/modules/sway/window.hpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/include/modules/sway/window.hpp 2022-03-06 14:54:48.000000000 +0100 @@ -2,7 +2,8 @@ #include <fmt/format.h> #include <tuple> -#include "ALabel.hpp" + +#include "AIconLabel.hpp" #include "bar.hpp" #include "client.hpp" #include "modules/sway/ipc/client.hpp" @@ -10,7 +11,7 @@ namespace waybar::modules::sway { -class Window : public ALabel, public sigc::trackable { +class Window : public AIconLabel, public sigc::trackable { public: Window(const std::string&, const waybar::Bar&, const Json::Value&); ~Window() = default; @@ -23,6 +24,7 @@ std::string& output); void getTree(); std::string rewriteTitle(const std::string& title); + void updateAppIcon(); const Bar& bar_; std::string window_; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/include/util/command.hpp new/Waybar-0.9.10/include/util/command.hpp --- old/Waybar-0.9.9/include/util/command.hpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/include/util/command.hpp 2022-03-06 14:54:48.000000000 +0100 @@ -68,7 +68,10 @@ inline FILE* open(const std::string& cmd, int& pid) { if (cmd == "") return nullptr; int fd[2]; - pipe(fd); + if (pipe(fd) != 0){ + spdlog::error("Unable to pipe fd"); + return nullptr; + } pid_t child_pid = fork(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/include/util/format.hpp new/Waybar-0.9.10/include/util/format.hpp --- old/Waybar-0.9.9/include/util/format.hpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/include/util/format.hpp 2022-03-06 14:54:48.000000000 +0100 @@ -1,6 +1,7 @@ #pragma once #include <fmt/format.h> +#include <glibmm/ustring.h> class pow_format { public: @@ -84,5 +85,15 @@ ); } }; + + + // Glib ustirng support + template <> + struct formatter<Glib::ustring> : formatter<std::string> { + template <typename FormatContext> + auto format(const Glib::ustring& value, FormatContext& ctx) { + return formatter<std::string>::format(value, ctx); + } + }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/include/util/string.hpp new/Waybar-0.9.10/include/util/string.hpp --- old/Waybar-0.9.9/include/util/string.hpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/include/util/string.hpp 2022-03-06 14:54:48.000000000 +0100 @@ -1,15 +1,17 @@ +#pragma once + #include <string> const std::string WHITESPACE = " \n\r\t\f\v"; -std::string ltrim(const std::string s) { +inline std::string ltrim(const std::string& s) { size_t begin = s.find_first_not_of(WHITESPACE); return (begin == std::string::npos) ? "" : s.substr(begin); } -std::string rtrim(const std::string s) { +inline std::string rtrim(const std::string& s) { size_t end = s.find_last_not_of(WHITESPACE); return (end == std::string::npos) ? "" : s.substr(0, end + 1); } -std::string trim(const std::string& s) { return rtrim(ltrim(s)); } +inline std::string trim(const std::string& s) { return rtrim(ltrim(s)); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/man/waybar-clock.5.scd new/Waybar-0.9.10/man/waybar-clock.5.scd --- old/Waybar-0.9.9/man/waybar-clock.5.scd 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/man/waybar-clock.5.scd 2022-03-06 14:54:48.000000000 +0100 @@ -86,6 +86,11 @@ typeof: double ++ Threshold to be used when scrolling. +*tooltip*: ++ + typeof: bool ++ + default: true ++ + Option to disable tooltip on hover. + View all valid format options in *strftime(3)*. # FORMAT REPLACEMENTS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/man/waybar-custom.5.scd new/Waybar-0.9.10/man/waybar-custom.5.scd --- old/Waybar-0.9.9/man/waybar-custom.5.scd 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/man/waybar-custom.5.scd 2022-03-06 14:54:48.000000000 +0100 @@ -151,7 +151,8 @@ "max-length": 40, "interval": 30, // Remove this if your script is endless and write in loop "exec": "$HOME/.config/waybar/mediaplayer.sh 2> /dev/null", // Script in resources folder - "exec-if": "pgrep spotify" + "exec-if": "pgrep spotify", + "return-type": "json" } ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/man/waybar-keyboard-state.5.scd new/Waybar-0.9.10/man/waybar-keyboard-state.5.scd --- old/Waybar-0.9.9/man/waybar-keyboard-state.5.scd 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/man/waybar-keyboard-state.5.scd 2022-03-06 14:54:48.000000000 +0100 @@ -8,6 +8,8 @@ The *keyboard-state* module displays the state of number lock, caps lock, and scroll lock. +You must be a member of the input group to use this module. + # CONFIGURATION *interval*: ++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/man/waybar-memory.5.scd new/Waybar-0.9.10/man/waybar-memory.5.scd --- old/Waybar-0.9.9/man/waybar-memory.5.scd 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/man/waybar-memory.5.scd 2022-03-06 14:54:48.000000000 +0100 @@ -84,12 +84,20 @@ *{percentage}*: Percentage of memory in use. +*{swapPercentage}*: Percentage of swap in use. + *{total}*: Amount of total memory available in GiB. +*{swapTotal}*: Amount of total swap available in GiB. + *{used}*: Amount of used memory in GiB. +*{swapUsed}*: Amount of used swap in GiB. + *{avail}*: Amount of available memory in GiB. +*{swapAvail}*: Amount of available swap in GiB. + # EXAMPLES ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/man/waybar-sway-mode.5.scd new/Waybar-0.9.10/man/waybar-sway-mode.5.scd --- old/Waybar-0.9.9/man/waybar-sway-mode.5.scd 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/man/waybar-sway-mode.5.scd 2022-03-06 14:54:48.000000000 +0100 @@ -69,7 +69,7 @@ # EXAMPLES ``` -"sway/window": { +"sway/mode": { "format": "??? {}", "max-length": 50 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/man/waybar-tray.5.scd new/Waybar-0.9.10/man/waybar-tray.5.scd --- old/Waybar-0.9.9/man/waybar-tray.5.scd 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/man/waybar-tray.5.scd 2022-03-06 14:54:48.000000000 +0100 @@ -29,6 +29,10 @@ typeof: integer ++ Defines the spacing between the tray icons. +*reverse-direction*: ++ + typeof: bool ++ + Defines if new app icons should be added in a reverse order + *on-update*: ++ typeof: string ++ Command to execute when the module is updated. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/man/waybar-wlr-taskbar.5.scd new/Waybar-0.9.10/man/waybar-wlr-taskbar.5.scd --- old/Waybar-0.9.9/man/waybar-wlr-taskbar.5.scd 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/man/waybar-wlr-taskbar.5.scd 2022-03-06 14:54:48.000000000 +0100 @@ -93,10 +93,15 @@ # CLICK ACTIONS *activate*: Bring the application into foreground. + *minimize*: Toggle application's minimized state. + *minimize-raise*: Bring the application into foreground or toggle its minimized state. + *maximize*: Toggle application's maximized state. + *fullscreen*: Toggle application's fullscreen state. + *close*: Close the application. # EXAMPLES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/man/waybar-wlr-workspaces.5.scd new/Waybar-0.9.10/man/waybar-wlr-workspaces.5.scd --- old/Waybar-0.9.9/man/waybar-wlr-workspaces.5.scd 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/man/waybar-wlr-workspaces.5.scd 2022-03-06 14:54:48.000000000 +0100 @@ -52,6 +52,7 @@ # CLICK ACTIONS *activate*: Switch to workspace. + *close*: Close the workspace. # ICONS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/meson.build new/Waybar-0.9.10/meson.build --- old/Waybar-0.9.9/meson.build 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/meson.build 2022-03-06 14:54:48.000000000 +0100 @@ -1,6 +1,6 @@ project( 'waybar', 'cpp', 'c', - version: '0.9.9', + version: '0.9.10', license: 'MIT', meson_version: '>= 0.49.0', default_options : [ @@ -142,6 +142,7 @@ 'src/factory.cpp', 'src/AModule.cpp', 'src/ALabel.cpp', + 'src/AIconLabel.cpp', 'src/modules/custom.cpp', 'src/modules/disk.cpp', 'src/modules/idle_inhibitor.cpp', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/resources/style.css new/Waybar-0.9.10/resources/style.css --- old/Waybar-0.9.9/resources/style.css 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/resources/style.css 2022-03-06 14:54:48.000000000 +0100 @@ -1,6 +1,6 @@ * { /* `otf-font-awesome` is required to be installed for icons */ - font-family: Roboto, Helvetica, Arial, sans-serif; + font-family: FontAwesome, Roboto, Helvetica, Arial, sans-serif; font-size: 13px; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/AIconLabel.cpp new/Waybar-0.9.10/src/AIconLabel.cpp --- old/Waybar-0.9.9/src/AIconLabel.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/Waybar-0.9.10/src/AIconLabel.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -0,0 +1,28 @@ +#include "AIconLabel.hpp" + +#include <gdkmm/pixbuf.h> + +namespace waybar { + +AIconLabel::AIconLabel(const Json::Value &config, const std::string &name, const std::string &id, + const std::string &format, uint16_t interval, bool ellipsize, + bool enable_click, bool enable_scroll) + : ALabel(config, name, id, format, interval, ellipsize, enable_click, enable_scroll) { + event_box_.remove(); + box_.set_orientation(Gtk::Orientation::ORIENTATION_HORIZONTAL); + box_.set_spacing(8); + box_.add(image_); + box_.add(label_); + event_box_.add(box_); +} + +auto AIconLabel::update() -> void { + image_.set_visible(image_.get_visible() && iconEnabled()); + ALabel::update(); +} + +bool AIconLabel::iconEnabled() const { + return config_["icon"].isBool() ? config_["icon"].asBool() : true; +} + +} // namespace waybar diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/AModule.cpp new/Waybar-0.9.10/src/AModule.cpp --- old/Waybar-0.9.9/src/AModule.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/AModule.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -6,7 +6,9 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::string& id, bool enable_click, bool enable_scroll) - : name_(std::move(name)), config_(std::move(config)) { + : name_(std::move(name)), config_(std::move(config)) + , distance_scrolled_y_(0.0) + , distance_scrolled_x_(0.0) { // configure events' user commands if (config_["on-click"].isString() || config_["on-click-middle"].isString() || config_["on-click-backward"].isString() || config_["on-click-forward"].isString() || diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/bar.cpp new/Waybar-0.9.10/src/bar.cpp --- old/Waybar-0.9.9/src/bar.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/bar.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -750,7 +750,7 @@ modules_right_.emplace_back(module_sp); } } - module->dp.connect([module, &name] { + module->dp.connect([module, name] { try { module->update(); } catch (const std::exception& e) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/battery.cpp new/Waybar-0.9.10/src/modules/battery.cpp --- old/Waybar-0.9.9/src/modules/battery.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/battery.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -161,7 +161,7 @@ uint32_t energy_now; uint32_t energy_full_design; std::string _status; - std::ifstream(bat / "status") >> _status; + std::getline(std::ifstream(bat / "status"), _status); // Some battery will report current and charge in ??A/??Ah. // Scale these by the voltage to get ??W/??Wh. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/clock.cpp new/Waybar-0.9.10/src/modules/clock.cpp --- old/Waybar-0.9.9/src/modules/clock.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/clock.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -99,7 +99,7 @@ // As date dep is not fully compatible, prefer fmt tzset(); auto localtime = fmt::localtime(std::chrono::system_clock::to_time_t(now)); - text = fmt::format(format_, localtime); + text = fmt::format(locale_, format_, localtime); } else { text = fmt::format(format_, wtime); } @@ -113,10 +113,10 @@ } auto tooltip_format = config_["tooltip-format"].asString(); text = fmt::format(tooltip_format, wtime, fmt::arg(kCalendarPlaceholder.c_str(), calendar_lines)); + label_.set_tooltip_markup(text); } } - label_.set_tooltip_markup(text); // Call parent update ALabel::update(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/cpu/common.cpp new/Waybar-0.9.10/src/modules/cpu/common.cpp --- old/Waybar-0.9.9/src/modules/cpu/common.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/cpu/common.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -62,7 +62,7 @@ double waybar::modules::Cpu::getCpuLoad() { double load[1]; if (getloadavg(load, 1) != -1) { - return load[0]; + return std::ceil(load[0] * 100.0) / 100.0; } throw std::runtime_error("Can't get Cpu load"); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/keyboard_state.cpp new/Waybar-0.9.10/src/modules/keyboard_state.cpp --- old/Waybar-0.9.9/src/modules/keyboard_state.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/keyboard_state.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -1,6 +1,8 @@ #include "modules/keyboard_state.hpp" +#include <errno.h> #include <filesystem> #include <spdlog/spdlog.h> +#include <string.h> extern "C" { #include <sys/types.h> @@ -8,6 +10,69 @@ #include <fcntl.h> } +class errno_error : public std::runtime_error { + public: + int code; + errno_error(int code, const std::string& msg) + : std::runtime_error(getErrorMsg(code, msg.c_str())), + code(code) {} + errno_error(int code, const char* msg) + : std::runtime_error(getErrorMsg(code, msg)), + code(code) {} + private: + static auto getErrorMsg(int err, const char* msg) -> std::string { + std::string error_msg{msg}; + error_msg += ": "; + +#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 32) + // strerrorname_np gets the error code's name; it's nice to have, but it's a recent GNU extension + const auto errno_name = strerrorname_np(err); + error_msg += errno_name; + error_msg += " "; +#endif + + const auto errno_str = strerror(err); + error_msg += errno_str; + + return error_msg; + } +}; + +auto openFile(const std::string& path, int flags) -> int { + int fd = open(path.c_str(), flags); + if (fd < 0) { + if (errno == EACCES) { + throw errno_error(errno, "Can't open " + path + " (are you in the input group?)"); + } else { + throw errno_error(errno, "Can't open " + path); + } + } + return fd; +} + +auto closeFile(int fd) -> void { + int res = close(fd); + if (res < 0) { + throw errno_error(errno, "Can't close file"); + } +} + +auto openDevice(int fd) -> libevdev* { + libevdev* dev; + int err = libevdev_new_from_fd(fd, &dev); + if (err < 0) { + throw errno_error(-err, "Can't create libevdev device"); + } + return dev; +} + +auto supportsLockStates(const libevdev* dev) -> bool { + return libevdev_has_event_type(dev, EV_LED) + && libevdev_has_event_code(dev, EV_LED, LED_NUML) + && libevdev_has_event_code(dev, EV_LED, LED_CAPSL) + && libevdev_has_event_code(dev, EV_LED, LED_SCROLLL); +} + waybar::modules::KeyboardState::KeyboardState(const std::string& id, const Bar& bar, const Json::Value& config) : AModule(config, "keyboard-state", id, false, !config["disable-scroll"].asBool()), box_(bar.vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0), @@ -48,26 +113,36 @@ if (config_["device-path"].isString()) { std::string dev_path = config_["device-path"].asString(); - std::tie(fd_, dev_) = openDevice(dev_path); + fd_ = openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY); + dev_ = openDevice(fd_); } else { DIR* dev_dir = opendir("/dev/input"); if (dev_dir == nullptr) { - throw std::runtime_error("Failed to open /dev/input"); + throw errno_error(errno, "Failed to open /dev/input"); } dirent *ep; while ((ep = readdir(dev_dir))) { if (ep->d_type != DT_CHR) continue; std::string dev_path = std::string("/dev/input/") + ep->d_name; + int fd = openFile(dev_path.c_str(), O_NONBLOCK | O_CLOEXEC | O_RDONLY); try { - std::tie(fd_, dev_) = openDevice(dev_path); - spdlog::info("Found device {} at '{}'", libevdev_get_name(dev_), dev_path); - break; - } catch (const std::runtime_error& e) { - continue; + auto dev = openDevice(fd); + if (supportsLockStates(dev)) { + spdlog::info("Found device {} at '{}'", libevdev_get_name(dev), dev_path); + fd_ = fd; + dev_ = dev; + break; + } + } catch (const errno_error& e) { + // ENOTTY just means the device isn't an evdev device, skip it + if (e.code != ENOTTY) { + spdlog::warn(e.what()); + } } + closeFile(fd); } if (dev_ == nullptr) { - throw std::runtime_error("Failed to find keyboard device"); + throw errno_error(errno, "Failed to find keyboard device"); } } @@ -79,35 +154,13 @@ waybar::modules::KeyboardState::~KeyboardState() { libevdev_free(dev_); - int err = close(fd_); - if (err < 0) { - // Not much we can do, so ignore it. + try { + closeFile(fd_); + } catch (const std::runtime_error& e) { + spdlog::warn(e.what()); } } -auto waybar::modules::KeyboardState::openDevice(const std::string& path) -> std::pair<int, libevdev*> { - int fd = open(path.c_str(), O_NONBLOCK | O_CLOEXEC | O_RDONLY); - if (fd < 0) { - throw std::runtime_error("Can't open " + path); - } - - libevdev* dev; - int err = libevdev_new_from_fd(fd, &dev); - if (err < 0) { - throw std::runtime_error("Can't create libevdev device"); - } - if (!libevdev_has_event_type(dev, EV_LED)) { - throw std::runtime_error("Device doesn't support LED events"); - } - if (!libevdev_has_event_code(dev, EV_LED, LED_NUML) - || !libevdev_has_event_code(dev, EV_LED, LED_CAPSL) - || !libevdev_has_event_code(dev, EV_LED, LED_SCROLLL)) { - throw std::runtime_error("Device doesn't support num lock, caps lock, or scroll lock events"); - } - - return std::make_pair(fd, dev); -} - auto waybar::modules::KeyboardState::update() -> void { int err = LIBEVDEV_READ_STATUS_SUCCESS; while (err == LIBEVDEV_READ_STATUS_SUCCESS) { @@ -117,8 +170,8 @@ err = libevdev_next_event(dev_, LIBEVDEV_READ_FLAG_SYNC, &ev); } } - if (err != -EAGAIN) { - throw std::runtime_error("Failed to sync evdev device"); + if (-err != EAGAIN) { + throw errno_error(-err, "Failed to sync evdev device"); } int numl = libevdev_get_event_value(dev_, EV_LED, LED_NUML); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/memory/common.cpp new/Waybar-0.9.10/src/modules/memory/common.cpp --- old/Waybar-0.9.9/src/modules/memory/common.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/memory/common.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -12,7 +12,15 @@ parseMeminfo(); unsigned long memtotal = meminfo_["MemTotal"]; + unsigned long swaptotal = 0; + if (meminfo_.count("SwapTotal")) { + swaptotal = meminfo_["SwapTotal"]; + } unsigned long memfree; + unsigned long swapfree = 0; + if (meminfo_.count("SwapFree")) { + swapfree = meminfo_["SwapFree"]; + } if (meminfo_.count("MemAvailable")) { // New kernels (3.4+) have an accurate available memory field. memfree = meminfo_["MemAvailable"] + meminfo_["zfs_size"]; @@ -24,9 +32,16 @@ if (memtotal > 0 && memfree >= 0) { auto total_ram_gigabytes = memtotal / std::pow(1024, 2); + auto total_swap_gigabytes = swaptotal / std::pow(1024, 2); int used_ram_percentage = 100 * (memtotal - memfree) / memtotal; + int used_swap_percentage = 0; + if (swaptotal && swapfree) { + used_swap_percentage = 100 * (swaptotal - swapfree) / swaptotal; + } auto used_ram_gigabytes = (memtotal - memfree) / std::pow(1024, 2); + auto used_swap_gigabytes = (swaptotal - swapfree) / std::pow(1024, 2); auto available_ram_gigabytes = memfree / std::pow(1024, 2); + auto available_swap_gigabytes = swapfree / std::pow(1024, 2); auto format = format_; auto state = getState(used_ram_percentage); @@ -43,9 +58,13 @@ used_ram_percentage, fmt::arg("icon", getIcon(used_ram_percentage, icons)), fmt::arg("total", total_ram_gigabytes), + fmt::arg("swapTotal", total_swap_gigabytes), fmt::arg("percentage", used_ram_percentage), + fmt::arg("swapPercentage", used_swap_percentage), fmt::arg("used", used_ram_gigabytes), - fmt::arg("avail", available_ram_gigabytes))); + fmt::arg("swapUsed", used_swap_gigabytes), + fmt::arg("avail", available_ram_gigabytes), + fmt::arg("swapAvail", available_swap_gigabytes))); } if (tooltipEnabled()) { @@ -54,9 +73,13 @@ label_.set_tooltip_text(fmt::format(tooltip_format, used_ram_percentage, fmt::arg("total", total_ram_gigabytes), + fmt::arg("swapTotal", total_swap_gigabytes), fmt::arg("percentage", used_ram_percentage), + fmt::arg("swapPercentage", used_swap_percentage), fmt::arg("used", used_ram_gigabytes), - fmt::arg("avail", available_ram_gigabytes))); + fmt::arg("swapUsed", used_swap_gigabytes), + fmt::arg("avail", available_ram_gigabytes), + fmt::arg("swapAvail", available_swap_gigabytes))); } else { label_.set_tooltip_text(fmt::format("{:.{}f}GiB used", used_ram_gigabytes, 1)); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/mpd/mpd.cpp new/Waybar-0.9.10/src/modules/mpd/mpd.cpp --- old/Waybar-0.9.9/src/modules/mpd/mpd.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/mpd/mpd.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -129,7 +129,7 @@ album = getTag(MPD_TAG_ALBUM); title = getTag(MPD_TAG_TITLE); date = getTag(MPD_TAG_DATE); - song_pos = mpd_status_get_song_pos(status_.get()); + song_pos = mpd_status_get_song_pos(status_.get()) + 1; volume = mpd_status_get_volume(status_.get()); if (volume < 0) { volume = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/network.cpp new/Waybar-0.9.10/src/modules/network.cpp --- old/Waybar-0.9.9/src/modules/network.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/network.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -78,7 +78,7 @@ family_(config["family"] == "ipv6" ? AF_INET6 : AF_INET), efd_(-1), ev_fd_(-1), - want_route_dump_(false), + want_route_dump_(true), want_link_dump_(false), want_addr_dump_(false), dump_in_progress_(false), @@ -106,7 +106,7 @@ } if (!config_["interface"].isString()) { - // "interface" isn't configure, then try to guess the external + // "interface" isn't configured, then try to guess the external // interface currently used for internet. want_route_dump_ = true; } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/pulseaudio.cpp new/Waybar-0.9.10/src/modules/pulseaudio.cpp --- old/Waybar-0.9.9/src/modules/pulseaudio.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/pulseaudio.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -54,7 +54,9 @@ c, static_cast<enum pa_subscription_mask>(static_cast<int>(PA_SUBSCRIPTION_MASK_SERVER) | static_cast<int>(PA_SUBSCRIPTION_MASK_SINK) | - static_cast<int>(PA_SUBSCRIPTION_MASK_SOURCE)), + static_cast<int>(PA_SUBSCRIPTION_MASK_SINK_INPUT) | + static_cast<int>(PA_SUBSCRIPTION_MASK_SOURCE) | + static_cast<int>(PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT)), nullptr, nullptr); break; @@ -121,8 +123,12 @@ pa_context_get_server_info(context, serverInfoCb, data); } else if (facility == PA_SUBSCRIPTION_EVENT_SINK) { pa_context_get_sink_info_by_index(context, idx, sinkInfoCb, data); + } else if (facility == PA_SUBSCRIPTION_EVENT_SINK_INPUT) { + pa_context_get_sink_info_list(context, sinkInfoCb, data); } else if (facility == PA_SUBSCRIPTION_EVENT_SOURCE) { pa_context_get_source_info_by_index(context, idx, sourceInfoCb, data); + } else if (facility == PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT) { + pa_context_get_source_info_list(context, sourceInfoCb, data); } } @@ -279,7 +285,7 @@ fmt::arg("source_desc", source_desc_), fmt::arg("icon", getIcon(volume_, getPulseIcon())))); getState(volume_); - + if (tooltipEnabled()) { if (tooltip_format.empty() && config_["tooltip-format"].isString()) { tooltip_format = config_["tooltip-format"].asString(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/sni/item.cpp new/Waybar-0.9.10/src/modules/sni/item.cpp --- old/Waybar-0.9.9/src/modules/sni/item.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/sni/item.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -8,13 +8,7 @@ #include <fstream> #include <map> -template <> -struct fmt::formatter<Glib::ustring> : formatter<std::string> { - template <typename FormatContext> - auto format(const Glib::ustring& value, FormatContext& ctx) { - return formatter<std::string>::format(value, ctx); - } -}; +#include "util/format.hpp" template <> struct fmt::formatter<Glib::VariantBase> : formatter<std::string> { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/sni/tray.cpp new/Waybar-0.9.10/src/modules/sni/tray.cpp --- old/Waybar-0.9.9/src/modules/sni/tray.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/sni/tray.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -25,7 +25,11 @@ } void Tray::onAdd(std::unique_ptr<Item>& item) { - box_.pack_start(item->event_box); + if (config_["reverse-direction"].isBool() && config_["reverse-direction"].asBool()) { + box_.pack_end(item->event_box); + } else { + box_.pack_start(item->event_box); + } dp.emit(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/sway/language.cpp new/Waybar-0.9.10/src/modules/sway/language.cpp --- old/Waybar-0.9.9/src/modules/sway/language.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/sway/language.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -154,7 +154,10 @@ std::map<std::string, int> short_name_to_number_map; for (const auto& used_layout_name : used_layouts) { - auto used_layout = &layouts_map_.find(used_layout_name)->second; + auto found = layouts_map_.find(used_layout_name); + if (found == layouts_map_.end()) + continue; + auto used_layout = &found->second; auto layouts_with_same_name_list = found_by_short_names[used_layout->short_name]; if (layouts_with_same_name_list.size() < 2) { continue; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/sway/window.cpp new/Waybar-0.9.10/src/modules/sway/window.cpp --- old/Waybar-0.9.9/src/modules/sway/window.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/sway/window.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -1,11 +1,20 @@ #include "modules/sway/window.hpp" + +#include <gdkmm/pixbuf.h> +#include <glibmm/fileutils.h> +#include <glibmm/keyfile.h> +#include <glibmm/miscutils.h> +#include <gtkmm/enums.h> #include <spdlog/spdlog.h> + +#include <filesystem> #include <regex> +#include <string> namespace waybar::modules::sway { Window::Window(const std::string& id, const Bar& bar, const Json::Value& config) - : ALabel(config, "window", id, "{}", 0, true), bar_(bar), windowId_(-1) { + : AIconLabel(config, "window", id, "{}", 0, true), bar_(bar), windowId_(-1) { ipc_.subscribe(R"(["window","workspace"])"); ipc_.signal_event.connect(sigc::mem_fun(*this, &Window::onEvent)); ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Window::onCmd)); @@ -29,12 +38,60 @@ auto payload = parser_.parse(res.payload); auto output = payload["output"].isString() ? payload["output"].asString() : ""; std::tie(app_nb_, windowId_, window_, app_id_) = getFocusedNode(payload["nodes"], output); + updateAppIcon(); dp.emit(); } catch (const std::exception& e) { spdlog::error("Window: {}", e.what()); } } +std::optional<std::string> getDesktopFilePath(const std::string& app_id) { + const auto data_dirs = Glib::get_system_data_dirs(); + for (const auto& data_dir : data_dirs) { + const auto desktop_file_path = data_dir + "applications/" + app_id + ".desktop"; + if (std::filesystem::exists(desktop_file_path)) { + return desktop_file_path; + } + } + return {}; +} + +std::optional<Glib::ustring> getIconName(const std::string& app_id) { + const auto desktop_file_path = getDesktopFilePath(app_id); + if (!desktop_file_path.has_value()) { + return {}; + } + try { + Glib::KeyFile desktop_file; + desktop_file.load_from_file(desktop_file_path.value()); + const auto icon_name = desktop_file.get_string("Desktop Entry", "Icon"); + if (icon_name.empty()) { + return {}; + } + return icon_name; + } catch (Glib::FileError& error) { + spdlog::warn( + "Error while loading desktop file {}: {}", desktop_file_path.value(), error.what().c_str()); + } catch (Glib::KeyFileError& error) { + spdlog::warn( + "Error while loading desktop file {}: {}", desktop_file_path.value(), error.what().c_str()); + } + return {}; +} + +void Window::updateAppIcon() { + if (!iconEnabled()) { + return; + } + const auto icon_name = getIconName(app_id_); + if (icon_name.has_value()) { + image_.set_from_icon_name(icon_name.value(), Gtk::ICON_SIZE_LARGE_TOOLBAR); + image_.set_visible(true); + return; + } + image_.set_visible(false); +} + auto Window::update() -> void { if (!old_app_id_.empty()) { bar_.window.get_style_context()->remove_class(old_app_id_); @@ -63,7 +120,7 @@ label_.set_tooltip_text(window_); } // Call parent update - ALabel::update(); + AIconLabel::update(); } int leafNodesInWorkspace(const Json::Value& node) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.9.9/src/modules/wlr/taskbar.cpp new/Waybar-0.9.10/src/modules/wlr/taskbar.cpp --- old/Waybar-0.9.9/src/modules/wlr/taskbar.cpp 2022-01-10 09:58:29.000000000 +0100 +++ new/Waybar-0.9.10/src/modules/wlr/taskbar.cpp 2022-03-06 14:54:48.000000000 +0100 @@ -4,6 +4,7 @@ #include "glibmm/fileutils.h" #include "glibmm/refptr.h" #include "util/format.hpp" +#include "util/string.hpp" #include <algorithm> #include <cctype> @@ -26,27 +27,6 @@ namespace waybar::modules::wlr { -/* String manipulation methods */ -const std::string WHITESPACE = " \n\r\t\f\v"; - -static std::string ltrim(const std::string& s) -{ - size_t start = s.find_first_not_of(WHITESPACE); - return (start == std::string::npos) ? "" : s.substr(start); -} - -static std::string rtrim(const std::string& s) -{ - size_t end = s.find_last_not_of(WHITESPACE); - return (end == std::string::npos) ? "" : s.substr(0, end + 1); -} - -static std::string trim(const std::string& s) -{ - return rtrim(ltrim(s)); -} - - /* Icon loading functions */ static std::vector<std::string> search_prefix() {