Hello community, here is the log from the commit of package waybar for openSUSE:Factory checked in at 2020-01-04 19:21:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/waybar (Old) and /work/SRC/openSUSE:Factory/.waybar.new.6675 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "waybar" Sat Jan 4 19:21:07 2020 rev:17 rq:759783 version:0.9.0 Changes: -------- --- /work/SRC/openSUSE:Factory/waybar/waybar.changes 2019-12-23 22:48:39.750094641 +0100 +++ /work/SRC/openSUSE:Factory/.waybar.new.6675/waybar.changes 2020-01-04 19:21:07.625131543 +0100 @@ -1,0 +2,27 @@ +Sat Dec 28 13:26:47 UTC 2019 - Michael Vetter <[email protected]> + +- Add dependency on systemd and new gtk-layer-shell-devel + +------------------------------------------------------------------- +Sat Dec 28 12:17:51 UTC 2019 - Michael Vetter <[email protected]> + +- Update to 0.9.0: + Added: + * Use GTK Layer Shell for working Popups #441 + * Disk module #471 + * Man pages option #443 + * Battery: format time #455 + * Systemd user unit #460 + * Detect timezone changes #480 + * Pulseaudio: export desc as a format #507 + * Toggle opacity #510 + Changed: + * Fix man memory description #444 + * Fix output typo #445 + * Fix typo: persistant -> persistent #446 + * Fix exclusive zone #447 + * Network: clamp signal strength 334bc1e + * MPD: take lock in waitForEvent to prevent SIGABORT #467 + * Pulseaudio: audio scroll bound #475 + +------------------------------------------------------------------- Old: ---- 0.8.0.tar.gz New: ---- 0.9.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ waybar.spec ++++++ --- /var/tmp/diff_new_pack.w4dwf5/_old 2020-01-04 19:21:08.145131774 +0100 +++ /var/tmp/diff_new_pack.w4dwf5/_new 2020-01-04 19:21:08.153131777 +0100 @@ -1,7 +1,7 @@ # # spec file for package waybar # -# Copyright (c) 2019 SUSE LLC +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,39 +17,42 @@ Name: waybar -Version: 0.8.0 +Version: 0.9.0 Release: 0 Summary: Customizable Wayland bar for Sway and Wlroots based compositors License: MIT Group: System/GUI/Other URL: https://github.com/Alexays/Waybar Source: %{url}/archive/%{version}.tar.gz +BuildRequires: cmake BuildRequires: gcc-c++ +BuildRequires: gtk-layer-shell-devel BuildRequires: meson BuildRequires: ninja BuildRequires: pkgconfig +# optional: man pages +BuildRequires: scdoc +# optional: tray module +BuildRequires: pkgconfig(dbusmenu-gtk3-0.4) BuildRequires: pkgconfig(fmt) BuildRequires: pkgconfig(gio-unix-2.0) BuildRequires: pkgconfig(gtkmm-3.0) BuildRequires: pkgconfig(jsoncpp) BuildRequires: pkgconfig(libinput) +# optional: mpd module +BuildRequires: pkgconfig(libmpdclient) +# optional: network +BuildRequires: pkgconfig(libnl-3.0) +BuildRequires: pkgconfig(libnl-genl-3.0) +# optional: audio +BuildRequires: pkgconfig(libpulse) BuildRequires: pkgconfig(libudev) BuildRequires: pkgconfig(sigc++-2.0) BuildRequires: pkgconfig(spdlog) +BuildRequires: pkgconfig(systemd) BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(wayland-cursor) BuildRequires: pkgconfig(wayland-protocols) -# optional: man pages -BuildRequires: scdoc -# optional: tray module -BuildRequires: pkgconfig(dbusmenu-gtk3-0.4) -# optional: network -BuildRequires: pkgconfig(libnl-3.0) -BuildRequires: pkgconfig(libnl-genl-3.0) -# optional: audio -BuildRequires: pkgconfig(libpulse) -# optional: mpd module -BuildRequires: pkgconfig(libmpdclient) # optional: sway integration Recommends: sway @@ -70,5 +73,6 @@ %{_sysconfdir}/xdg/waybar/ %{_bindir}/waybar %{_mandir}/man?/%{name}* +%{_prefix}/lib/systemd/user/waybar.service %changelog ++++++ 0.8.0.tar.gz -> 0.9.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/.travis.yml new/Waybar-0.9.0/.travis.yml --- old/Waybar-0.8.0/.travis.yml 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/.travis.yml 2019-12-28 12:35:09.000000000 +0100 @@ -3,18 +3,21 @@ services: - docker +git: + submodules: false + env: - distro: debian - distro: archlinux - - distro: opensuse - distro: fedora - distro: alpine before_install: - docker pull alexays/waybar:${distro} + - find . -type f \( -name '*.cpp' -o -name '*.h' \) -print0 | xargs -r0 clang-format -i script: - echo FROM alexays/waybar:${distro} > Dockerfile - echo ADD . /root >> Dockerfile - docker build -t waybar . - - docker run waybar /bin/sh -c "cd /root && meson build && ninja -C build" \ No newline at end of file + - docker run waybar /bin/sh -c "cd /root && meson build -Dman-pages=enabled && ninja -C build" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/Dockerfiles/alpine new/Waybar-0.9.0/Dockerfiles/alpine --- old/Waybar-0.8.0/Dockerfiles/alpine 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/Dockerfiles/alpine 2019-12-28 12:35:09.000000000 +0100 @@ -1,3 +1,5 @@ +# vim: ft=Dockerfile + 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 scdoc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/Dockerfiles/archlinux new/Waybar-0.9.0/Dockerfiles/archlinux --- old/Waybar-0.8.0/Dockerfiles/archlinux 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/Dockerfiles/archlinux 2019-12-28 12:35:09.000000000 +0100 @@ -1,3 +1,5 @@ +# vim: ft=Dockerfile + FROM archlinux/base:latest RUN pacman -Syu --noconfirm && \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/Dockerfiles/debian new/Waybar-0.9.0/Dockerfiles/debian --- old/Waybar-0.8.0/Dockerfiles/debian 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/Dockerfiles/debian 2019-12-28 12:35:09.000000000 +0100 @@ -1,3 +1,5 @@ +# vim: ft=Dockerfile + FROM debian:sid RUN apt-get update && \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/Dockerfiles/fedora new/Waybar-0.9.0/Dockerfiles/fedora --- old/Waybar-0.8.0/Dockerfiles/fedora 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/Dockerfiles/fedora 2019-12-28 12:35:09.000000000 +0100 @@ -1,3 +1,5 @@ +# vim: ft=Dockerfile + FROM fedora:30 RUN dnf install sway meson git libinput-devel wayland-devel wayland-protocols-devel egl-wayland-devel mesa-libEGL-devel mesa-libGLES-devel mesa-libgbm-devel libxkbcommon-devel libudev-devel pixman-devel gtkmm30-devel jsoncpp-devel scdoc -y && \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/Dockerfiles/opensuse new/Waybar-0.9.0/Dockerfiles/opensuse --- old/Waybar-0.8.0/Dockerfiles/opensuse 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/Dockerfiles/opensuse 2019-12-28 12:35:09.000000000 +0100 @@ -1,3 +1,5 @@ +# vim: ft=Dockerfile + FROM opensuse/tumbleweed:latest RUN zypper -n up && \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/README.md new/Waybar-0.9.0/README.md --- old/Waybar-0.8.0/README.md 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/README.md 2019-12-28 12:35:09.000000000 +0100 @@ -2,7 +2,7 @@ > Highly customizable Wayland bar for Sway and Wlroots based compositors.<br> > Available in Arch > [community](https://www.archlinux.org/packages/community/x86_64/waybar/) or -[AUR](https://aur.archlinux.org/packages/waybar-git/) and [openSUSE](https://build.opensuse.org/package/show/X11:Wayland/waybar)<br> +[AUR](https://aur.archlinux.org/packages/waybar-git/), [openSUSE](https://build.opensuse.org/package/show/X11:Wayland/waybar), and [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=waybar)<br> > *Waybar [examples](https://github.com/Alexays/Waybar/wiki/Examples)* **Current features** @@ -12,6 +12,7 @@ - Battery - Network - Pulseaudio +- Disk - Memory - Cpu load average - Temperature @@ -55,6 +56,13 @@ libmpdclient [MPD module] ``` +On Ubuntu 19.10 you can install all the relevant dependencies using this command: + +``` +sudo apt install libgtkmm-3.0-dev libjsoncpp-dev libinput-dev libsigc++-2.0-dev libpulse-dev libnl-3-dev libdbusmenu-gtk3-dev libnl-genl-3-dev libfmt-dev clang-tidy scdoc libmpdclient-dev +``` + + Contributions welcome! - have fun :)<br> The style guidelines is [Google's](https://google.github.io/styleguide/cppguide.html) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/include/AModule.hpp new/Waybar-0.9.0/include/AModule.hpp --- old/Waybar-0.8.0/include/AModule.hpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/include/AModule.hpp 2019-12-28 12:35:09.000000000 +0100 @@ -26,7 +26,6 @@ const Json::Value &config_; Gtk::EventBox event_box_; - std::string click_param_; virtual bool handleToggle(GdkEventButton *const &ev); virtual bool handleScroll(GdkEventScroll *); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/include/bar.hpp new/Waybar-0.9.0/include/bar.hpp --- old/Waybar-0.8.0/include/bar.hpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/include/bar.hpp 2019-12-28 12:35:09.000000000 +0100 @@ -1,5 +1,6 @@ #pragma once +#include <gdkmm/monitor.h> #include <glibmm/refptr.h> #include <gtkmm/box.h> #include <gtkmm/cssprovider.h> @@ -15,10 +16,11 @@ class Factory; struct waybar_output { - struct wl_output * output = nullptr; - std::string name; - uint32_t wl_name; - struct zxdg_output_v1 *xdg_output = nullptr; + Glib::RefPtr<Gdk::Monitor> monitor; + std::string name; + + std::unique_ptr<struct zxdg_output_v1, decltype(&zxdg_output_v1_destroy)> xdg_output = { + nullptr, &zxdg_output_v1_destroy}; }; class Bar { @@ -30,13 +32,12 @@ auto toggle() -> void; void handleSignal(int); - struct waybar_output * output; - Json::Value config; - Gtk::Window window; - struct wl_surface * surface; - struct zwlr_layer_surface_v1 *layer_surface; - bool visible = true; - bool vertical = false; + struct waybar_output *output; + Json::Value config; + Gtk::Window window; + struct wl_surface * surface; + bool visible = true; + bool vertical = false; private: static constexpr const char *MIN_HEIGHT_MSG = @@ -51,11 +52,14 @@ uint32_t, uint32_t); static void layerSurfaceHandleClosed(void *, struct zwlr_layer_surface_v1 *); - void destroyOutput(); +#ifdef HAVE_GTK_LAYER_SHELL + void initGtkLayerShell(); +#endif void onConfigure(GdkEventConfigure *ev); void onRealize(); void onMap(GdkEventAny *ev); - void setMarginsAndZone(uint32_t height, uint32_t width); + void setExclusiveZone(uint32_t width, uint32_t height); + void setSurfaceSize(uint32_t width, uint32_t height); auto setupWidgets() -> void; void getModules(const Factory &, const std::string &); void setupAltFormatKeyForModule(const std::string &module_name); @@ -67,6 +71,9 @@ int bottom = 0; int left = 0; } margins_; + struct zwlr_layer_surface_v1 *layer_surface_; + // use gtk-layer-shell instead of handling layer surfaces directly + bool use_gls_ = false; uint32_t width_ = 0; uint32_t height_ = 1; uint8_t anchor_; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/include/client.hpp new/Waybar-0.9.0/include/client.hpp --- old/Waybar-0.8.0/include/client.hpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/include/client.hpp 2019-12-28 12:35:09.000000000 +0100 @@ -34,17 +34,15 @@ bool isValidOutput(const Json::Value &config, std::unique_ptr<struct waybar_output> &output); auto setupConfig(const std::string &config_file) -> void; auto setupCss(const std::string &css_file) -> void; - std::unique_ptr<struct waybar_output> &getOutput(uint32_t wl_name); + std::unique_ptr<struct waybar_output> &getOutput(void *); std::vector<Json::Value> getOutputConfigs(std::unique_ptr<struct waybar_output> &output); static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version); static void handleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name); - static void handleLogicalPosition(void *, struct zxdg_output_v1 *, int32_t, int32_t); - static void handleLogicalSize(void *, struct zxdg_output_v1 *, int32_t, int32_t); - static void handleDone(void *, struct zxdg_output_v1 *); - static void handleName(void *, struct zxdg_output_v1 *, const char *); - static void handleDescription(void *, struct zxdg_output_v1 *, const char *); + static void handleOutputName(void *, struct zxdg_output_v1 *, const char *); + void handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor); + void handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor); Json::Value config_; Glib::RefPtr<Gtk::StyleContext> style_context_; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/include/factory.hpp new/Waybar-0.9.0/include/factory.hpp --- old/Waybar-0.8.0/include/factory.hpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/include/factory.hpp 2019-12-28 12:35:09.000000000 +0100 @@ -13,6 +13,7 @@ #include "modules/cpu.hpp" #include "modules/idle_inhibitor.hpp" #include "modules/memory.hpp" +#include "modules/disk.hpp" #if defined(HAVE_DBUSMENU) && !defined(NO_FILESYSTEM) #include "modules/sni/tray.hpp" #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/include/modules/disk.hpp new/Waybar-0.9.0/include/modules/disk.hpp --- old/Waybar-0.8.0/include/modules/disk.hpp 1970-01-01 01:00:00.000000000 +0100 +++ new/Waybar-0.9.0/include/modules/disk.hpp 2019-12-28 12:35:09.000000000 +0100 @@ -0,0 +1,23 @@ +#pragma once + +#include <fmt/format.h> +#include <fstream> +#include <sys/statvfs.h> +#include "ALabel.hpp" +#include "util/sleeper_thread.hpp" +#include "util/format.hpp" + +namespace waybar::modules { + +class Disk : public ALabel { + public: + Disk(const std::string&, const Json::Value&); + ~Disk() = default; + auto update() -> void; + + private: + util::SleeperThread thread_; + std::string path_; +}; + +} // namespace waybar::modules diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/include/modules/mpd.hpp new/Waybar-0.9.0/include/modules/mpd.hpp --- old/Waybar-0.8.0/include/modules/mpd.hpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/include/modules/mpd.hpp 2019-12-28 12:35:09.000000000 +0100 @@ -65,6 +65,9 @@ unique_status status_; mpd_state state_; unique_song song_; + + // To make sure the previous periodic_updater stops before creating a new one + std::mutex periodic_lock_; }; } // namespace waybar::modules diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/include/modules/network.hpp new/Waybar-0.9.0/include/modules/network.hpp --- old/Waybar-0.8.0/include/modules/network.hpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/include/modules/network.hpp 2019-12-28 12:35:09.000000000 +0100 @@ -39,7 +39,7 @@ void parseFreq(struct nlattr**); bool associatedOrJoined(struct nlattr**); bool checkInterface(struct ifinfomsg* rtif, std::string name); - int getPreferredIface(int skip_idx = -1) const; + int getPreferredIface(int skip_idx = -1, bool wait = true) const; auto getInfo() -> void; void checkNewInterface(struct ifinfomsg* rtif); const std::string getNetworkState() const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/include/util/format.hpp new/Waybar-0.9.0/include/util/format.hpp --- old/Waybar-0.8.0/include/util/format.hpp 1970-01-01 01:00:00.000000000 +0100 +++ new/Waybar-0.9.0/include/util/format.hpp 2019-12-28 12:35:09.000000000 +0100 @@ -0,0 +1,84 @@ +#pragma once + +#include <fmt/format.h> + +class pow_format { + public: + pow_format(long long val, std::string&& unit, bool binary = false): + val_(val), unit_(unit), binary_(binary) { }; + + long long val_; + std::string unit_; + bool binary_; +}; + + +namespace fmt { + template <> + struct formatter<pow_format> { + char spec = 0; + int width = 0; + + template <typename ParseContext> + constexpr auto parse(ParseContext& ctx) -> decltype (ctx.begin()) { + auto it = ctx.begin(), end = ctx.end(); + if (it != end && *it == ':') ++it; + if (*it == '>' || *it == '<' || *it == '=') { + spec = *it; + ++it; + } + if (it == end || *it == '}') return it; + if ('0' <= *it && *it <= '9') { + // We ignore it for now, but keep it for compatibility with + // existing configs where the format for pow_format'ed numbers was + // 'string' and specifications such as {:>9} were valid. + // The rationale for ignoring it is that the only reason to specify + // an alignment and a with is to get a fixed width bar, and ">" is + // sufficient in this implementation. + width = parse_nonnegative_int(it, end, ctx); + } + return it; + } + + template<class FormatContext> + auto format(const pow_format& s, FormatContext &ctx) -> decltype (ctx.out()) { + const char* units[] = { "", "k", "M", "G", "T", "P", nullptr}; + + auto base = s.binary_ ? 1024ull : 1000ll; + auto fraction = (double) s.val_; + + int pow; + for (pow = 0; units[pow+1] != nullptr && fraction / base >= 1; ++pow) { + fraction /= base; + } + + auto max_width = 4 // coeff in {:.3g} format + + 1 // prefix from units array + + s.binary_ // for the 'i' in GiB. + + s.unit_.length(); + + const char * format; + std::string string; + switch (spec) { + case '>': + return format_to(ctx.out(), "{:>{}}", fmt::format("{}", s), max_width); + case '<': + return format_to(ctx.out(), "{:<{}}", fmt::format("{}", s), max_width); + case '=': + format = "{coefficient:<4.3g}{padding}{prefix}{unit}"; + break; + case 0: + default: + format = "{coefficient:.3g}{prefix}{unit}"; + break; + } + return format_to(ctx.out(), format + , fmt::arg("coefficient", fraction) + , fmt::arg("prefix", std::string() + units[pow] + ((s.binary_ && pow) ? "i" : "")) + , fmt::arg("unit", s.unit_) + , fmt::arg("padding", pow ? "" : s.binary_ ? " " : " ") + ); + } + }; +} + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/man/waybar-battery.5.scd new/Waybar-0.9.0/man/waybar-battery.5.scd --- old/Waybar-0.8.0/man/waybar-battery.5.scd 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/man/waybar-battery.5.scd 2019-12-28 12:35:09.000000000 +0100 @@ -32,6 +32,11 @@ default: {capacity}% ++ The format, how the time should be displayed. +*format-time* ++ + typeof: string ++ + default: {H} h {M} min ++ + The format, how the time should be displayed. + *format-icons* typeof: array/object Based on the current capacity, the corresponding icon gets selected. ++ @@ -78,6 +83,14 @@ *{time}*: Estimate of time until full or empty. Note that this is based on the power draw at the last refresh time, not an average. +# TIME FORMAT + +The *battery* module allows you to define how time should be formatted via *format-time*. + +The two arguments are: +*{H}*: Hours +*{M}*: Minutes + # CUSTOM FORMATS The *battery* module allows to define custom formats based on up to two factors. The best fitting format will be selected. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/man/waybar-disk.5.scd new/Waybar-0.9.0/man/waybar-disk.5.scd --- old/Waybar-0.8.0/man/waybar-disk.5.scd 1970-01-01 01:00:00.000000000 +0100 +++ new/Waybar-0.9.0/man/waybar-disk.5.scd 2019-12-28 12:35:09.000000000 +0100 @@ -0,0 +1,93 @@ +waybar-disk(5) + +# NAME + +waybar - disk module + +# DESCRIPTION + +The *disk* module displays the current disk space used. + +# CONFIGURATION + +Addressed by *disk* + +*path*: ++ + typeof: string ++ + default: "/" ++ + Any path residing in the filesystem or mountpoint for which the information should be displayed. + +*interval*: ++ + typeof: integer++ + default: 30 ++ + The interval in which the information gets polled. + +*format*: ++ + typeof: string ++ + default: "{percentage_used}%" ++ + The format, how information should be displayed. + +*rotate*: ++ + typeof: integer ++ + Positive value to rotate the text label. + +*max-length*: ++ + typeof: integer ++ + The maximum length in character the module should display. + +*on-click*: ++ + typeof: string ++ + Command to execute when clicked on the module. + +*on-click-right*: ++ + typeof: string ++ + Command to execute when you right clicked on the module. + +*on-scroll-up*: ++ + typeof: string ++ + Command to execute when scrolling up on the module. + +*on-scroll-down*: ++ + typeof: string ++ + Command to execute when scrolling down on the module. + +*smooth-scrolling-threshold*: ++ + typeof: double ++ + Threshold to be used when scrolling. + +*tooltip*: ++ + typeof: bool ++ + default: true ++ + Option to disable tooltip on hover. + +*tooltip-format*: ++ + typeof: string ++ + default: "{used} out of {total} used ({percentage_used}%)" ++ + The format of the information displayed in the tooltip. + +# FORMAT REPLACEMENTS + +*{percentage_used}*: Percentage of disk in use. + +*{percentage_free}*: Percentage of free disk space + +*{total}*: Total amount of space on the disk, partition or mountpoint. + +*{used}*: Amount of used disk space. + +*{free}*: Amount of available disk space for normal users. + +*{path}*: The path specified in the configuration. + +# EXAMPLES + +``` +"disk": { + "interval": 30, + "format": "{percentage_free}% free on {path}", +} +``` + +# STYLE + +- *#disk* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/man/waybar-memory.5.scd new/Waybar-0.9.0/man/waybar-memory.5.scd --- old/Waybar-0.8.0/man/waybar-memory.5.scd 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/man/waybar-memory.5.scd 2019-12-28 12:35:09.000000000 +0100 @@ -6,7 +6,7 @@ # DESCRIPTION -The *memory* module displays the current date and time. +The *memory* module displays the current memory utilization. # CONFIGURATION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/man/waybar-pulseaudio.5.scd new/Waybar-0.9.0/man/waybar-pulseaudio.5.scd --- old/Waybar-0.8.0/man/waybar-pulseaudio.5.scd 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/man/waybar-pulseaudio.5.scd 2019-12-28 12:35:09.000000000 +0100 @@ -36,7 +36,7 @@ *format-icons*: ++ typeof: array ++ - Based on the current port-name and volume, the corresponding icon gets selected. The order is *low* to *high*. See [`Icons`](#module-pulseaudio-config-icons) + Based on the current port-name and volume, the corresponding icon gets selected. The order is *low* to *high*. See *Icons*. *rotate*: ++ typeof: integer ++ @@ -82,15 +82,17 @@ # FORMAT REPLACEMENTS +*{desc}*: Pulseaudio port's description, for bluetooth it'll be the device name. + *{volume}*: Volume in percentage. -*{icon}*: Icon, as defined in `format-icons`. +*{icon}*: Icon, as defined in *format-icons*. -*{format_source}*: Source format, `format-source`, `format-source-muted`. +*{format_source}*: Source format, *format-source*, *format-source-muted*. # ICONS: -The following strings for `format-icons` are supported. +The following strings for *format-icons* are supported. If they are found in the current PulseAudio port name, the corresponding icons will be selected. - *default* (Shown, when no other port is found) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/man/waybar-states.5.scd new/Waybar-0.9.0/man/waybar-states.5.scd --- old/Waybar-0.8.0/man/waybar-states.5.scd 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/man/waybar-states.5.scd 2019-12-28 12:35:09.000000000 +0100 @@ -7,7 +7,7 @@ # STATES -- Every entry (*state*) consits of a *<name>* (typeof: *string*) and a *<value>* (typeof: *integer*). +- Every entry (*state*) consists of a *<name>* (typeof: *string*) and a *<value>* (typeof: *integer*). - The state can be addressed as a CSS class in the *style.css*. The name of the CSS class is the *<name>* of the state. Each class gets activated when the current capacity is equal or below the configured *<value>*. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/man/waybar-sway-workspaces.5.scd new/Waybar-0.9.0/man/waybar-sway-workspaces.5.scd --- old/Waybar-0.8.0/man/waybar-sway-workspaces.5.scd 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/man/waybar-sway-workspaces.5.scd 2019-12-28 12:35:09.000000000 +0100 @@ -76,15 +76,15 @@ - *urgent*: Will be shown, when workspace is flagged as urgent - *focused*: Will be shown, when workspace is focused -# PERSISTANT WORKSPACES +# PERSISTENT WORKSPACES -Each entry of *persistant_workspace* names a workspace that should always be shown. +Each entry of *persistent_workspace* names a workspace that should always be shown. Associated with that value is a list of outputs indicating *where* the workspace should be shown, an empty list denoting all outputs. ``` "sway/workspaces": { - "persistant_workspaces": { + "persistent_workspaces": { "3": [], // Always show a workspace with name '3', on all outputs if it does not exists "4": ["eDP-1"], // Always show a workspace with name '4', on output 'eDP-1' if it does not exists "5": ["eDP-1", "DP-2"] // Always show a workspace with name '5', on outputs 'eDP-1' and 'DP-2' if it does not exists @@ -120,4 +120,4 @@ - *#workspaces button.visible* - *#workspaces button.focused* - *#workspaces button.urgent* -- *#workspaces button.persistant* +- *#workspaces button.persistent* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/meson.build new/Waybar-0.9.0/meson.build --- old/Waybar-0.8.0/meson.build 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/meson.build 2019-12-28 12:35:09.000000000 +0100 @@ -1,6 +1,6 @@ project( 'waybar', 'cpp', 'c', - version: '0.8.0', + version: '0.9.0', license: 'MIT', default_options : [ 'cpp_std=c++17', @@ -52,7 +52,7 @@ wayland_client = dependency('wayland-client') wayland_cursor = dependency('wayland-cursor') wayland_protos = dependency('wayland-protocols') -gtkmm = dependency('gtkmm-3.0') +gtkmm = dependency('gtkmm-3.0', version : ['>=3.22.0']) dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4', required: get_option('dbusmenu-gtk')) giounix = dependency('gio-unix-2.0', required: get_option('dbusmenu-gtk')) jsoncpp = dependency('jsoncpp') @@ -62,6 +62,25 @@ libpulse = dependency('libpulse', required: get_option('pulseaudio')) libudev = dependency('libudev', required: get_option('libudev')) libmpdclient = dependency('libmpdclient', required: get_option('mpd')) +gtk_layer_shell = dependency('gtk-layer-shell-0', + required: get_option('gtk-layer-shell'), + fallback : ['gtk-layer-shell', 'gtk_layer_shell_dep']) +systemd = dependency('systemd', required: get_option('systemd')) + +prefix = get_option('prefix') +conf_data = configuration_data() +conf_data.set('prefix', prefix) + +if systemd.found() + user_units_dir = systemd.get_pkgconfig_variable('systemduserunitdir') + + configure_file( + configuration: conf_data, + input: './resources/waybar.service.in', + output: '@BASENAME@', + install_dir: user_units_dir + ) +endif src_files = files( 'src/factory.cpp', @@ -72,6 +91,7 @@ 'src/modules/clock.cpp', 'src/modules/custom.cpp', 'src/modules/cpu.cpp', + 'src/modules/disk.cpp', 'src/modules/idle_inhibitor.cpp', 'src/modules/temperature.cpp', 'src/main.cpp', @@ -119,6 +139,10 @@ src_files += 'src/modules/mpd.cpp' endif +if gtk_layer_shell.found() + add_project_arguments('-DHAVE_GTK_LAYER_SHELL', language: 'cpp') +endif + subdir('protocol') executable( @@ -141,7 +165,8 @@ libnlgen, libpulse, libudev, - libmpdclient + libmpdclient, + gtk_layer_shell ], include_directories: [include_directories('include')], install: true, @@ -153,7 +178,7 @@ install_dir: join_paths(get_option('out'), 'etc/xdg/waybar') ) -scdoc = dependency('scdoc', version: '>=1.9.2', native: true, required: false) +scdoc = dependency('scdoc', version: '>=1.9.2', native: true, required: get_option('man-pages')) if scdoc.found() scdoc_prog = find_program(scdoc.get_pkgconfig_variable('scdoc'), native: true) @@ -166,6 +191,7 @@ 'waybar-clock.5.scd', 'waybar-cpu.5.scd', 'waybar-custom.5.scd', + 'waybar-disk.5.scd', 'waybar-idle-inhibitor.5.scd', 'waybar-memory.5.scd', 'waybar-mpd.5.scd', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/meson_options.txt new/Waybar-0.9.0/meson_options.txt --- old/Waybar-0.8.0/meson_options.txt 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/meson_options.txt 2019-12-28 12:35:09.000000000 +0100 @@ -2,6 +2,9 @@ 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') +option('systemd', type: 'feature', value: 'auto', description: 'Install systemd user service unit') option('dbusmenu-gtk', type: 'feature', value: 'auto', description: 'Enable support for tray') +option('man-pages', type: 'feature', value: 'auto', description: 'Generate and install man pages') option('mpd', type: 'feature', value: 'auto', description: 'Enable support for the Music Player Daemon') option('out', type: 'string', value : '/', description: 'output prefix directory') +option('gtk-layer-shell', type: 'feature', value: 'auto', description: 'Use gtk-layer-shell library for popups support') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/resources/style.css new/Waybar-0.9.0/resources/style.css --- old/Waybar-0.8.0/resources/style.css 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/resources/style.css 2019-12-28 12:35:09.000000000 +0100 @@ -1,6 +1,7 @@ * { border: none; border-radius: 0; + /* `otf-font-awesome` is required to be installed for icons */ font-family: Roboto, Helvetica, Arial, sans-serif; font-size: 13px; min-height: 0; @@ -75,7 +76,8 @@ #custom-media, #tray, #mode, -#idle_inhibitor { +#idle_inhibitor, +#mpd { padding: 0 10px; margin: 0 4px; color: #ffffff; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/resources/waybar.service.in new/Waybar-0.9.0/resources/waybar.service.in --- old/Waybar-0.8.0/resources/waybar.service.in 1970-01-01 01:00:00.000000000 +0100 +++ new/Waybar-0.9.0/resources/waybar.service.in 2019-12-28 12:35:09.000000000 +0100 @@ -0,0 +1,12 @@ +[Unit] +Description=Highly customizable Wayland bar for Sway and Wlroots based compositors. +Documentation=https://github.com/Alexays/Waybar/wiki/ +PartOf=wayland-session.target + +[Service] +Type=dbus +BusName=fr.arouillard.waybar +ExecStart=@prefix@/bin/waybar + +[Install] +WantedBy=wayland-session.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/AModule.cpp new/Waybar-0.9.0/src/AModule.cpp --- old/Waybar-0.8.0/src/AModule.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/AModule.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -46,7 +46,7 @@ format = config_["on-click-forward"].asString(); } if (!format.empty()) { - pid_.push_back(util::command::forkExec(fmt::format(format, fmt::arg("arg", click_param_)))); + pid_.push_back(util::command::forkExec(format)); } dp.emit(); return true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/bar.cpp new/Waybar-0.9.0/src/bar.cpp --- old/Waybar-0.8.0/src/bar.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/bar.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -1,3 +1,7 @@ +#ifdef HAVE_GTK_LAYER_SHELL +#include <gtk-layer-shell.h> +#endif + #include "bar.hpp" #include "client.hpp" #include "factory.hpp" @@ -8,7 +12,7 @@ config(w_config), window{Gtk::WindowType::WINDOW_TOPLEVEL}, surface(nullptr), - layer_surface(nullptr), + layer_surface_(nullptr), anchor_(ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP), left_(Gtk::ORIENTATION_HORIZONTAL, 0), center_(Gtk::ORIENTATION_HORIZONTAL, 0), @@ -28,11 +32,6 @@ height_ = config["height"].isUInt() ? config["height"].asUInt() : height_; width_ = config["width"].isUInt() ? config["width"].asUInt() : width_; - window.signal_realize().connect_notify(sigc::mem_fun(*this, &Bar::onRealize)); - window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap)); - window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Bar::onConfigure)); - window.set_size_request(width_, height_); - if (config["position"] == "bottom") { anchor_ = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; } else if (config["position"] == "left") { @@ -53,6 +52,62 @@ vertical = true; } + if (config["margin-top"].isInt() || config["margin-right"].isInt() || + config["margin-bottom"].isInt() || config["margin-left"].isInt()) { + margins_ = { + config["margin-top"].isInt() ? config["margin-top"].asInt() : 0, + config["margin-right"].isInt() ? config["margin-right"].asInt() : 0, + config["margin-bottom"].isInt() ? config["margin-bottom"].asInt() : 0, + config["margin-left"].isInt() ? config["margin-left"].asInt() : 0, + }; + } else if (config["margin"].isString()) { + std::istringstream iss(config["margin"].asString()); + std::vector<std::string> margins{std::istream_iterator<std::string>(iss), {}}; + try { + if (margins.size() == 1) { + auto gaps = std::stoi(margins[0], nullptr, 10); + margins_ = {.top = gaps, .right = gaps, .bottom = gaps, .left = gaps}; + } + if (margins.size() == 2) { + auto vertical_margins = std::stoi(margins[0], nullptr, 10); + auto horizontal_margins = std::stoi(margins[1], nullptr, 10); + margins_ = {.top = vertical_margins, + .right = horizontal_margins, + .bottom = vertical_margins, + .left = horizontal_margins}; + } + if (margins.size() == 3) { + auto horizontal_margins = std::stoi(margins[1], nullptr, 10); + margins_ = {.top = std::stoi(margins[0], nullptr, 10), + .right = horizontal_margins, + .bottom = std::stoi(margins[2], nullptr, 10), + .left = horizontal_margins}; + } + if (margins.size() == 4) { + margins_ = {.top = std::stoi(margins[0], nullptr, 10), + .right = std::stoi(margins[1], nullptr, 10), + .bottom = std::stoi(margins[2], nullptr, 10), + .left = std::stoi(margins[3], nullptr, 10)}; + } + } catch (...) { + spdlog::warn("Invalid margins: {}", config["margin"].asString()); + } + } else if (config["margin"].isInt()) { + auto gaps = config["margin"].asInt(); + margins_ = {.top = gaps, .right = gaps, .bottom = gaps, .left = gaps}; + } + +#ifdef HAVE_GTK_LAYER_SHELL + use_gls_ = config["gtk-layer-shell"].isBool() ? config["gtk-layer-shell"].asBool() : true; + if (use_gls_) { + initGtkLayerShell(); + } +#endif + + window.signal_realize().connect_notify(sigc::mem_fun(*this, &Bar::onRealize)); + window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap)); + window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Bar::onConfigure)); + window.set_size_request(width_, height_); setupWidgets(); if (window.get_realized()) { @@ -86,11 +141,43 @@ tmp_width = ev->width; } } - if (tmp_width != width_ || tmp_height != height_) { - zwlr_layer_surface_v1_set_size(layer_surface, tmp_width, tmp_height); + if (use_gls_) { + width_ = tmp_width; + height_ = tmp_height; + spdlog::debug("Set surface size {}x{} for output {}", width_, height_, output->name); + setExclusiveZone(tmp_width, tmp_height); + } else if (tmp_width != width_ || tmp_height != height_) { + setSurfaceSize(tmp_width, tmp_height); } } +#ifdef HAVE_GTK_LAYER_SHELL +void waybar::Bar::initGtkLayerShell() { + auto gtk_window = window.gobj(); + // this has to be executed before GtkWindow.realize + gtk_layer_init_for_window(gtk_window); + gtk_layer_set_keyboard_interactivity(gtk_window, FALSE); + auto layer = config["layer"] == "top" ? GTK_LAYER_SHELL_LAYER_TOP : GTK_LAYER_SHELL_LAYER_BOTTOM; + gtk_layer_set_layer(gtk_window, layer); + gtk_layer_set_monitor(gtk_window, output->monitor->gobj()); + gtk_layer_set_namespace(gtk_window, "waybar"); + + gtk_layer_set_anchor( + gtk_window, GTK_LAYER_SHELL_EDGE_LEFT, anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); + gtk_layer_set_anchor( + gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); + gtk_layer_set_anchor( + gtk_window, GTK_LAYER_SHELL_EDGE_TOP, anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP); + gtk_layer_set_anchor( + gtk_window, GTK_LAYER_SHELL_EDGE_BOTTOM, anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM); + + gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_LEFT, margins_.left); + gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, margins_.right); + gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_TOP, margins_.top); + gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_BOTTOM, margins_.bottom); +} +#endif + void waybar::Bar::onRealize() { auto gdk_window = window.get_window()->gobj(); gdk_wayland_window_set_use_custom_surface(gdk_window); @@ -100,75 +187,74 @@ auto gdk_window = window.get_window()->gobj(); surface = gdk_wayland_window_get_wl_surface(gdk_window); + if (use_gls_) { + return; + } + auto client = waybar::Client::inst(); + // owned by output->monitor; no need to destroy + auto wl_output = gdk_wayland_monitor_get_wl_output(output->monitor->gobj()); auto layer = config["layer"] == "top" ? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; - layer_surface = zwlr_layer_shell_v1_get_layer_surface( - client->layer_shell, surface, output->output, layer, "waybar"); + layer_surface_ = zwlr_layer_shell_v1_get_layer_surface( + client->layer_shell, surface, wl_output, layer, "waybar"); + + zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface_, false); + zwlr_layer_surface_v1_set_anchor(layer_surface_, anchor_); + zwlr_layer_surface_v1_set_margin( + layer_surface_, margins_.top, margins_.right, margins_.bottom, margins_.left); + setSurfaceSize(width_, height_); + setExclusiveZone(width_, height_); - zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface, false); - zwlr_layer_surface_v1_set_anchor(layer_surface, anchor_); - zwlr_layer_surface_v1_set_size(layer_surface, width_, height_); - setMarginsAndZone(height_, width_); static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { .configure = layerSurfaceHandleConfigure, .closed = layerSurfaceHandleClosed, }; - zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, this); + zwlr_layer_surface_v1_add_listener(layer_surface_, &layer_surface_listener, this); wl_surface_commit(surface); wl_display_roundtrip(client->wl_display); } -void waybar::Bar::setMarginsAndZone(uint32_t height, uint32_t width) { - if (config["margin-top"].isInt() || config["margin-right"].isInt() || - config["margin-bottom"].isInt() || config["margin-left"].isInt()) { - margins_ = { - config["margin-top"].isInt() ? config["margin-top"].asInt() : 0, - config["margin-right"].isInt() ? config["margin-right"].asInt() : 0, - config["margin-bottom"].isInt() ? config["margin-bottom"].asInt() : 0, - config["margin-left"].isInt() ? config["margin-left"].asInt() : 0, - }; - } else if (config["margin"].isString()) { - std::istringstream iss(config["margin"].asString()); - std::vector<std::string> margins{std::istream_iterator<std::string>(iss), {}}; - try { - if (margins.size() == 1) { - auto gaps = std::stoi(margins[0], nullptr, 10); - margins_ = {.top = gaps, .right = gaps, .bottom = gaps, .left = gaps}; - } - if (margins.size() == 2) { - auto vertical_margins = std::stoi(margins[0], nullptr, 10); - auto horizontal_margins = std::stoi(margins[1], nullptr, 10); - margins_ = {.top = vertical_margins, - .right = horizontal_margins, - .bottom = vertical_margins, - .left = horizontal_margins}; - } - if (margins.size() == 3) { - auto horizontal_margins = std::stoi(margins[1], nullptr, 10); - margins_ = {.top = std::stoi(margins[0], nullptr, 10), - .right = horizontal_margins, - .bottom = std::stoi(margins[2], nullptr, 10), - .left = horizontal_margins}; - } - if (margins.size() == 4) { - margins_ = {.top = std::stoi(margins[0], nullptr, 10), - .right = std::stoi(margins[1], nullptr, 10), - .bottom = std::stoi(margins[2], nullptr, 10), - .left = std::stoi(margins[3], nullptr, 10)}; - } - } catch (...) { - spdlog::warn("Invalid margins: {}", config["margin"].asString()); +void waybar::Bar::setExclusiveZone(uint32_t width, uint32_t height) { + auto zone = 0; + if (visible) { + // exclusive zone already includes margin for anchored edge, + // only opposite margin should be added + if (vertical) { + zone += width; + zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) ? margins_.right : margins_.left; + } else { + zone += height; + zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) ? margins_.bottom : margins_.top; } - } else if (config["margin"].isInt()) { - auto gaps = config["margin"].asInt(); - margins_ = {.top = gaps, .right = gaps, .bottom = gaps, .left = gaps}; } - zwlr_layer_surface_v1_set_margin( - layer_surface, margins_.top, margins_.right, margins_.bottom, margins_.left); - auto zone = vertical ? width + margins_.right : height + margins_.bottom; - zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, zone); + spdlog::debug("Set exclusive zone {} for output {}", zone, output->name); + +#ifdef HAVE_GTK_LAYER_SHELL + if (use_gls_) { + gtk_layer_set_exclusive_zone(window.gobj(), zone); + } else +#endif + { + zwlr_layer_surface_v1_set_exclusive_zone(layer_surface_, zone); + } +} + +void waybar::Bar::setSurfaceSize(uint32_t width, uint32_t height) { + /* If the client is anchored to two opposite edges, layer_surface.configure will return + * size without margins for the axis. + * layer_surface.set_size, however, expects size with margins for the anchored axis. + * This is not specified by wlr-layer-shell and based on actual behavior of sway. + */ + if (vertical && height > 1) { + height += margins_.top + margins_.bottom; + } + if (!vertical && width > 1) { + width += margins_.right + margins_.left; + } + spdlog::debug("Set surface size {}x{} for output {}", width, height, output->name); + zwlr_layer_surface_v1_set_size(layer_surface_, width, height); } // Converting string to button code rn as to avoid doing it later @@ -240,8 +326,7 @@ o->height_ = height; o->window.set_size_request(o->width_, o->height_); o->window.resize(o->width_, o->height_); - auto zone = o->vertical ? width + o->margins_.right : height + o->margins_.bottom; - zwlr_layer_surface_v1_set_exclusive_zone(o->layer_surface, zone); + o->setExclusiveZone(width, height); spdlog::info(BAR_SIZE_MSG, o->width_ == 1 ? "auto" : std::to_string(o->width_), o->height_ == 1 ? "auto" : std::to_string(o->height_), @@ -253,9 +338,9 @@ void waybar::Bar::layerSurfaceHandleClosed(void* data, struct zwlr_layer_surface_v1* /*surface*/) { auto o = static_cast<waybar::Bar*>(data); - if (o->layer_surface) { - zwlr_layer_surface_v1_destroy(o->layer_surface); - o->layer_surface = nullptr; + if (o->layer_surface_) { + zwlr_layer_surface_v1_destroy(o->layer_surface_); + o->layer_surface_ = nullptr; } o->modules_left_.clear(); o->modules_center_.clear(); @@ -264,13 +349,14 @@ auto waybar::Bar::toggle() -> void { visible = !visible; - auto zone = visible ? height_ : 0; if (!visible) { window.get_style_context()->add_class("hidden"); + window.set_opacity(0); } else { window.get_style_context()->remove_class("hidden"); + window.set_opacity(1); } - zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, zone); + setExclusiveZone(width_, height_); wl_surface_commit(surface); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/client.cpp new/Waybar-0.9.0/src/client.cpp --- old/Waybar-0.8.0/src/client.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/client.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -1,4 +1,5 @@ #include "client.hpp" +#include <fmt/ostream.h> #include <spdlog/spdlog.h> #include <fstream> #include <iostream> @@ -33,11 +34,6 @@ if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { client->layer_shell = static_cast<struct zwlr_layer_shell_v1 *>( wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, version)); - } else if (strcmp(interface, wl_output_interface.name) == 0) { - auto wl_output = static_cast<struct wl_output *>( - wl_registry_bind(registry, name, &wl_output_interface, version)); - client->outputs_.emplace_back(new struct waybar_output({wl_output, "", name, nullptr})); - client->handleOutput(client->outputs_.back()); } else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 && version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) { client->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>(wl_registry_bind( @@ -50,58 +46,21 @@ void waybar::Client::handleGlobalRemove(void * data, struct wl_registry * /*registry*/, uint32_t name) { - auto client = static_cast<Client *>(data); - for (auto it = client->bars.begin(); it != client->bars.end();) { - if ((*it)->output->wl_name == name) { - auto output_name = (*it)->output->name; - (*it)->window.close(); - it = client->bars.erase(it); - spdlog::info("Bar removed from output: {}", output_name); - } else { - ++it; - } - } - auto it = std::find_if(client->outputs_.begin(), - client->outputs_.end(), - [&name](const auto &output) { return output->wl_name == name; }); - if (it != client->outputs_.end()) { - if ((*it)->xdg_output != nullptr) { - zxdg_output_v1_destroy((*it)->xdg_output); - (*it)->xdg_output = nullptr; - } - if ((*it)->output != nullptr) { - wl_output_destroy((*it)->output); - (*it)->output = nullptr; - } - client->outputs_.erase(it); - } + // Nothing here } void waybar::Client::handleOutput(std::unique_ptr<struct waybar_output> &output) { static const struct zxdg_output_v1_listener xdgOutputListener = { - .logical_position = handleLogicalPosition, - .logical_size = handleLogicalSize, - .done = handleDone, - .name = handleName, - .description = handleDescription, + .logical_position = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {}, + .logical_size = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {}, + .done = [](void *, struct zxdg_output_v1 *) {}, + .name = &handleOutputName, + .description = [](void *, struct zxdg_output_v1 *, const char *) {}, }; - output->xdg_output = zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, output->output); - zxdg_output_v1_add_listener(output->xdg_output, &xdgOutputListener, &output->wl_name); -} - -void waybar::Client::handleLogicalPosition(void * /*data*/, - struct zxdg_output_v1 * /*zxdg_output_v1*/, - int32_t /*x*/, int32_t /*y*/) { - // Nothing here -} - -void waybar::Client::handleLogicalSize(void * /*data*/, struct zxdg_output_v1 * /*zxdg_output_v1*/, - int32_t /*width*/, int32_t /*height*/) { - // Nothing here -} - -void waybar::Client::handleDone(void * /*data*/, struct zxdg_output_v1 * /*zxdg_output_v1*/) { - // Nothing here + // owned by output->monitor; no need to destroy + auto wl_output = gdk_wayland_monitor_get_wl_output(output->monitor->gobj()); + output->xdg_output.reset(zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, wl_output)); + zxdg_output_v1_add_listener(output->xdg_output.get(), &xdgOutputListener, output.get()); } bool waybar::Client::isValidOutput(const Json::Value & config, @@ -123,9 +82,9 @@ return found; } -std::unique_ptr<struct waybar::waybar_output> &waybar::Client::getOutput(uint32_t wl_name) { - auto it = std::find_if(outputs_.begin(), outputs_.end(), [&wl_name](const auto &output) { - return output->wl_name == wl_name; +std::unique_ptr<struct waybar::waybar_output> &waybar::Client::getOutput(void *addr) { + auto it = std::find_if(outputs_.begin(), outputs_.end(), [&addr](const auto &output) { + return output.get() == addr; }); if (it == outputs_.end()) { throw std::runtime_error("Unable to find valid output"); @@ -148,23 +107,19 @@ return configs; } -void waybar::Client::handleName(void * data, struct zxdg_output_v1 * /*xdg_output*/, - const char *name) { - auto wl_name = *static_cast<uint32_t *>(data); +void waybar::Client::handleOutputName(void * data, struct zxdg_output_v1 * /*xdg_output*/, + const char *name) { auto client = waybar::Client::inst(); try { - auto &output = client->getOutput(wl_name); + auto &output = client->getOutput(data); output->name = name; + spdlog::debug("Output detected: {} ({} {})", + name, + output->monitor->get_manufacturer(), + output->monitor->get_model()); auto configs = client->getOutputConfigs(output); if (configs.empty()) { - if (output->output != nullptr) { - wl_output_destroy(output->output); - output->output = nullptr; - } - if (output->xdg_output != nullptr) { - zxdg_output_v1_destroy(output->xdg_output); - output->xdg_output = nullptr; - } + output->xdg_output.reset(); } else { wl_display_roundtrip(client->wl_display); for (const auto &config : configs) { @@ -179,9 +134,26 @@ } } -void waybar::Client::handleDescription(void * /*data*/, struct zxdg_output_v1 * /*zxdg_output_v1*/, - const char * /*description*/) { - // Nothing here +void waybar::Client::handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor) { + auto &output = outputs_.emplace_back(new struct waybar_output({monitor})); + handleOutput(output); +} + +void waybar::Client::handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor) { + spdlog::debug("Output removed: {} {}", monitor->get_manufacturer(), monitor->get_model()); + for (auto it = bars.begin(); it != bars.end();) { + if ((*it)->output->monitor == monitor) { + auto output_name = (*it)->output->name; + (*it)->window.close(); + it = bars.erase(it); + spdlog::info("Bar removed from output: {}", output_name); + } else { + ++it; + } + } + std::remove_if(outputs_.begin(), outputs_.end(), [&monitor](const auto &output) { + return output->monitor == monitor; + }); } std::tuple<const std::string, const std::string> waybar::Client::getConfigs( @@ -240,6 +212,14 @@ if (layer_shell == nullptr || xdg_output_manager == nullptr) { throw std::runtime_error("Failed to acquire required resources."); } + // add existing outputs and subscribe to updates + for (auto i = 0; i < gdk_display->get_n_monitors(); ++i) { + auto monitor = gdk_display->get_monitor(i); + handleMonitorAdded(monitor); + } + gdk_display->signal_monitor_added().connect(sigc::mem_fun(*this, &Client::handleMonitorAdded)); + gdk_display->signal_monitor_removed().connect( + sigc::mem_fun(*this, &Client::handleMonitorRemoved)); } int waybar::Client::main(int argc, char *argv[]) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/factory.cpp new/Waybar-0.9.0/src/factory.cpp --- old/Waybar-0.8.0/src/factory.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/factory.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -35,6 +35,9 @@ if (ref == "clock") { return new waybar::modules::Clock(id, config_[name]); } + if (ref == "disk") { + return new waybar::modules::Disk(id, config_[name]); + } #if defined(HAVE_DBUSMENU) && !defined(NO_FILESYSTEM) if (ref == "tray") { return new waybar::modules::SNI::Tray(id, bar_, config_[name]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/modules/battery.cpp new/Waybar-0.9.0/src/modules/battery.cpp --- old/Waybar-0.8.0/src/modules/battery.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/modules/battery.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -130,7 +130,7 @@ return "Full"; } if (online) { - return "Charging"; + return "Plugged"; } return "Discharging"; } @@ -141,7 +141,11 @@ hoursRemaining = std::fabs(hoursRemaining); uint16_t full_hours = static_cast<uint16_t>(hoursRemaining); uint16_t minutes = static_cast<uint16_t>(60 * (hoursRemaining - full_hours)); - return std::to_string(full_hours) + " h " + std::to_string(minutes) + " min"; + auto format = std::string("{H} h {M} min"); + if (config_["format-time"].isString()) { + format = config_["format-time"].asString(); + } + return fmt::format(format, fmt::arg("H", full_hours), fmt::arg("M", minutes)); } auto waybar::modules::Battery::update() -> void { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/modules/clock.cpp new/Waybar-0.9.0/src/modules/clock.cpp --- old/Waybar-0.8.0/src/modules/clock.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/modules/clock.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -1,4 +1,5 @@ #include "modules/clock.hpp" +#include <time.h> waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) : ALabel(config, "clock", id, "{:%H:%M}", 60) { @@ -12,6 +13,7 @@ } auto waybar::modules::Clock::update() -> void { + tzset(); // Update timezone information auto now = std::chrono::system_clock::now(); auto localtime = fmt::localtime(std::chrono::system_clock::to_time_t(now)); auto text = fmt::format(format_, localtime); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/modules/disk.cpp new/Waybar-0.9.0/src/modules/disk.cpp --- old/Waybar-0.8.0/src/modules/disk.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/Waybar-0.9.0/src/modules/disk.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -0,0 +1,76 @@ +#include "modules/disk.hpp" + +using namespace waybar::util; + +waybar::modules::Disk::Disk(const std::string& id, const Json::Value& config) + : ALabel(config, "disk", id, "{}%", 30) + , path_("/") +{ + thread_ = [this] { + dp.emit(); + thread_.sleep_for(interval_); + }; + if (config["path"].isString()) { + path_ = config["path"].asString(); + } +} + +auto waybar::modules::Disk::update() -> void { + struct statvfs /* { + unsigned long f_bsize; // filesystem block size + unsigned long f_frsize; // fragment size + fsblkcnt_t f_blocks; // size of fs in f_frsize units + fsblkcnt_t f_bfree; // # free blocks + fsblkcnt_t f_bavail; // # free blocks for unprivileged users + fsfilcnt_t f_files; // # inodes + fsfilcnt_t f_ffree; // # free inodes + fsfilcnt_t f_favail; // # free inodes for unprivileged users + unsigned long f_fsid; // filesystem ID + unsigned long f_flag; // mount flags + unsigned long f_namemax; // maximum filename length + }; */ stats; + int err = statvfs(path_.c_str(), &stats); + + /* Conky options + fs_bar - Bar that shows how much space is used + fs_free - Free space on a file system + fs_free_perc - Free percentage of space + fs_size - File system size + fs_used - File system used space + */ + + if (err != 0) { + event_box_.hide(); + return; + } + + auto free = pow_format(stats.f_bavail * stats.f_bsize, "B", true); + auto used = pow_format((stats.f_blocks - stats.f_bavail) * stats.f_bsize, "B", true); + auto total = pow_format(stats.f_blocks * stats.f_bsize, "B", true); + + label_.set_markup(fmt::format(format_ + , stats.f_bavail * 100 / stats.f_blocks + , fmt::arg("free", free) + , fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks) + , fmt::arg("used", used) + , fmt::arg("percentage_used", (stats.f_blocks - stats.f_bavail) * 100 / stats.f_blocks) + , fmt::arg("total", total) + , fmt::arg("path", path_) + )); + if (tooltipEnabled()) { + std::string tooltip_format = "{used} used out of {total} on {path} ({percentage_used}%)"; + if (config_["tooltip-format"].isString()) { + tooltip_format = config_["tooltip-format"].asString(); + } + label_.set_tooltip_text(fmt::format(tooltip_format + , stats.f_bavail * 100 / stats.f_blocks + , fmt::arg("free", free) + , fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks) + , fmt::arg("used", used) + , fmt::arg("percentage_used", (stats.f_blocks - stats.f_bavail) * 100 / stats.f_blocks) + , fmt::arg("total", total) + , fmt::arg("path", path_) + )); + } + event_box_.show(); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/modules/mpd.cpp new/Waybar-0.9.0/src/modules/mpd.cpp --- old/Waybar-0.8.0/src/modules/mpd.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/modules/mpd.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -41,6 +41,10 @@ if (connection_ != nullptr) { try { bool wasPlaying = playing(); + if(!wasPlaying) { + // Wait until the periodic_updater has stopped + std::lock_guard periodic_guard(periodic_lock_); + } fetchState(); if (!wasPlaying && playing()) { periodic_updater().detach(); @@ -75,6 +79,7 @@ std::thread waybar::modules::MPD::periodic_updater() { return std::thread([this] { + std::lock_guard guard(periodic_lock_); while (connection_ != nullptr && playing()) { dp.emit(); std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -297,7 +302,7 @@ // Wait for a player (play/pause), option (random, shuffle, etc.), or playlist // change if (!mpd_send_idle_mask( - conn, static_cast<mpd_idle>(MPD_IDLE_PLAYER | MPD_IDLE_OPTIONS | MPD_IDLE_PLAYLIST))) { + conn, static_cast<mpd_idle>(MPD_IDLE_PLAYER | MPD_IDLE_OPTIONS | MPD_IDLE_QUEUE))) { checkErrors(conn); return; } @@ -306,6 +311,10 @@ // See issue #277: // https://github.com/Alexays/Waybar/issues/277 mpd_recv_idle(conn, /* disable_timeout = */ false); + // See issue #281: + // https://github.com/Alexays/Waybar/issues/281 + std::lock_guard guard(connection_lock_); + checkErrors(conn); mpd_response_finish(conn); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/modules/network.cpp new/Waybar-0.9.0/src/modules/network.cpp --- old/Waybar-0.8.0/src/modules/network.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/modules/network.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -2,9 +2,13 @@ #include <spdlog/spdlog.h> #include <sys/eventfd.h> #include <fstream> +#include "util/format.hpp" + namespace { +using namespace waybar::util; + constexpr const char *NETSTAT_FILE = "/proc/net/netstat"; // std::ifstream does not take std::string_view as param constexpr std::string_view BANDWIDTH_CATEGORY = "IpExt"; @@ -98,7 +102,7 @@ createEventSocket(); createInfoSocket(); - auto default_iface = getPreferredIface(); + auto default_iface = getPreferredIface(-1, false); if (default_iface != -1) { ifid_ = default_iface; char ifname[IF_NAMESIZE]; @@ -259,26 +263,6 @@ } getState(signal_strength_); - auto pow_format = [](unsigned long long value, const std::string &unit) { - if (value > 2000ull * 1000ull * 1000ull) { // > 2G - auto go = value / (1000 * 1000 * 1000); - return std::to_string(go) + "." + - std::to_string((value - go * 1000 * 1000 * 1000) / (100 * 1000 * 1000)) + "G" + unit; - - } else if (value > 2000ull * 1000ull) { // > 2M - auto mo = value / (1000 * 1000); - return std::to_string(mo) + "." + std::to_string((value - mo * 1000 * 1000) / (100 * 1000)) + - "M" + unit; - - } else if (value > 2000ull) { // > 2k - auto ko = value / 1000; - return std::to_string(ko) + "." + std::to_string((value - ko * 1000) / 100) + "k" + unit; - - } else { - return std::to_string(value) + unit; - } - }; - auto text = fmt::format( format_, fmt::arg("essid", essid_), @@ -531,7 +515,7 @@ return false; } -int waybar::modules::Network::getPreferredIface(int skip_idx) const { +int waybar::modules::Network::getPreferredIface(int skip_idx, bool wait) const { int ifid = -1; if (config_["interface"].isString()) { ifid = if_nametoindex(config_["interface"].asCString()); @@ -563,7 +547,9 @@ if (ifid > 0) { return ifid; } - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + if (wait) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } } return -1; } @@ -717,8 +703,9 @@ // WiFi-hardware usually operates in the range -90 to -20dBm. const int hardwareMax = -20; const int hardwareMin = -90; - signal_strength_ = - ((signal_strength_dbm_ - hardwareMin) / double{hardwareMax - hardwareMin}) * 100; + const int strength = + ((signal_strength_dbm_ - hardwareMin) / double{hardwareMax - hardwareMin}) * 100; + signal_strength_ = std::clamp(strength, 0, 100); } if (bss[NL80211_BSS_SIGNAL_UNSPEC] != nullptr) { signal_strength_ = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/modules/pulseaudio.cpp new/Waybar-0.9.0/src/modules/pulseaudio.cpp --- old/Waybar-0.8.0/src/modules/pulseaudio.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/modules/pulseaudio.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -86,7 +86,7 @@ change = round(config_["scroll-step"].asDouble() * volume_tick); } if (dir == SCROLL_DIR::UP) { - if (volume_ + 1 < 100) { + if (volume_ + 1 <= 100) { pa_cvolume_inc(&pa_volume, change); } } else if (dir == SCROLL_DIR::DOWN) { @@ -221,6 +221,7 @@ } format_source = fmt::format(format_source, fmt::arg("volume", source_volume_)); label_.set_markup(fmt::format(format, + fmt::arg("desc", desc_), fmt::arg("volume", volume_), fmt::arg("format_source", format_source), fmt::arg("icon", getIcon(volume_, getPortIcon())))); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/modules/sway/window.cpp new/Waybar-0.9.0/src/modules/sway/window.cpp --- old/Waybar-0.8.0/src/modules/sway/window.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/modules/sway/window.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -20,7 +20,7 @@ try { std::lock_guard<std::mutex> lock(mutex_); auto payload = parser_.parse(res.payload); - auto output = payload["ouput"].isString() ? payload["output"].asString() : ""; + auto output = payload["output"].isString() ? payload["output"].asString() : ""; std::tie(app_nb_, windowId_, window_, app_id_) = getFocusedNode(payload["nodes"], output); dp.emit(); } catch (const std::exception& e) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/src/modules/sway/workspaces.cpp new/Waybar-0.9.0/src/modules/sway/workspaces.cpp --- old/Waybar-0.8.0/src/modules/sway/workspaces.cpp 2019-08-29 11:56:57.000000000 +0200 +++ new/Waybar-0.9.0/src/modules/sway/workspaces.cpp 2019-12-28 12:35:09.000000000 +0100 @@ -49,9 +49,9 @@ : true; }); - // adding persistant workspaces (as per the config file) - if (config_["persistant_workspaces"].isObject()) { - const Json::Value & p_workspaces = config_["persistant_workspaces"]; + // adding persistent workspaces (as per the config file) + if (config_["persistent_workspaces"].isObject()) { + const Json::Value & p_workspaces = config_["persistent_workspaces"]; const std::vector<std::string> p_workspaces_names = p_workspaces.getMemberNames(); for (const std::string &p_w_name : p_workspaces_names) { @@ -88,6 +88,9 @@ std::sort(workspaces_.begin(), workspaces_.end(), [](const Json::Value &lhs, const Json::Value &rhs) { + if (lhs["name"].isInt() && rhs["name"].isInt()) { + return lhs["name"].asInt() < rhs["name"].asInt(); + } return lhs["name"].asString() < rhs["name"].asString(); }); } @@ -151,9 +154,9 @@ button.get_style_context()->remove_class("urgent"); } if ((*it)["target_output"].isString()) { - button.get_style_context()->add_class("persistant"); + button.get_style_context()->add_class("persistent"); } else { - button.get_style_context()->remove_class("persistant"); + button.get_style_context()->remove_class("persistent"); } if (needReorder) { box_.reorder_child(button, it - workspaces_.begin()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Waybar-0.8.0/subprojects/gtk-layer-shell.wrap new/Waybar-0.9.0/subprojects/gtk-layer-shell.wrap --- old/Waybar-0.8.0/subprojects/gtk-layer-shell.wrap 1970-01-01 01:00:00.000000000 +0100 +++ new/Waybar-0.9.0/subprojects/gtk-layer-shell.wrap 2019-12-28 12:35:09.000000000 +0100 @@ -0,0 +1,5 @@ +[wrap-file] +directory = gtk-layer-shell-0.1.0 +source_filename = gtk-layer-shell-0.1.0.tar.gz +source_hash = f7569e27ae30b1a94c3ad6c955cf56240d6bc272b760d9d266ce2ccdb94a5cf0 +source_url = https://github.com/wmww/gtk-layer-shell/archive/v0.1.0/gtk-layer-shell-0.1.0.tar.gz
