Merge branch 'master' into on-update
commit
4a7dd400fe
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
FROM alpine:latest
|
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
|
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 pugixml libnl3-dev pulseaudio-dev libmpdclient-dev scdoc
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
FROM archlinux/base:latest
|
FROM archlinux/base:latest
|
||||||
|
|
||||||
RUN pacman -Syu --noconfirm && \
|
RUN pacman -Syu --noconfirm && \
|
||||||
pacman -S git meson base-devel libinput wayland wayland-protocols pixman libxkbcommon mesa gtkmm3 jsoncpp scdoc --noconfirm
|
pacman -S git meson base-devel libinput wayland wayland-protocols pixman libxkbcommon mesa gtkmm3 jsoncpp pugixml scdoc --noconfirm
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
FROM debian:sid
|
FROM debian:sid
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y build-essential meson ninja-build git pkg-config libinput10 libinput-dev wayland-protocols libwayland-client0 libwayland-cursor0 libwayland-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libxkbcommon-dev libudev-dev libpixman-1-dev libgtkmm-3.0-dev libjsoncpp-dev scdoc && \
|
apt-get install -y build-essential meson ninja-build git pkg-config libinput10 libpugixml-dev libinput-dev wayland-protocols libwayland-client0 libwayland-cursor0 libwayland-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libxkbcommon-dev libudev-dev libpixman-1-dev libgtkmm-3.0-dev libjsoncpp-dev scdoc && \
|
||||||
apt-get clean
|
apt-get clean
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
FROM fedora:30
|
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 && \
|
RUN dnf install sway meson git libinput-devel wayland-devel wayland-protocols-devel pugixml-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 && \
|
||||||
dnf group install "C Development Tools and Libraries" -y && \
|
dnf group install "C Development Tools and Libraries" -y && \
|
||||||
dnf clean all -y
|
dnf clean all -y
|
||||||
|
|
|
@ -4,4 +4,4 @@ FROM opensuse/tumbleweed:latest
|
||||||
|
|
||||||
RUN zypper -n up && \
|
RUN zypper -n up && \
|
||||||
zypper -n install -t pattern devel_C_C++ && \
|
zypper -n install -t pattern devel_C_C++ && \
|
||||||
zypper -n install git meson clang libinput10 libinput-devel libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel scdoc
|
zypper -n install git meson clang libinput10 libinput-devel libpugixml1 libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel scdoc
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
.PHONY: build build-debug run clean default install
|
.PHONY: build build-debug run clean default install
|
||||||
|
|
||||||
default: run
|
default: build
|
||||||
|
|
||||||
build:
|
build:
|
||||||
meson build
|
meson build
|
||||||
|
|
27
README.md
27
README.md
|
@ -49,6 +49,9 @@ libsigc++
|
||||||
fmt
|
fmt
|
||||||
wayland
|
wayland
|
||||||
wlroots
|
wlroots
|
||||||
|
libgtk-3-dev [gtk-layer-shell]
|
||||||
|
gobject-introspection [gtk-layer-shell]
|
||||||
|
libgirepository1.0-dev [gtk-layer-shell]
|
||||||
libpulse [Pulseaudio module]
|
libpulse [Pulseaudio module]
|
||||||
libnl [Network module]
|
libnl [Network module]
|
||||||
sway [Sway modules]
|
sway [Sway modules]
|
||||||
|
@ -56,6 +59,30 @@ libdbusmenu-gtk3 [Tray module]
|
||||||
libmpdclient [MPD module]
|
libmpdclient [MPD module]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On Ubuntu 19.10 you can install all the relevant dependencies using this command:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt install \
|
||||||
|
clang-tidy \
|
||||||
|
gobject-introspection \
|
||||||
|
libdbusmenu-gtk3-dev \
|
||||||
|
libfmt-dev \
|
||||||
|
libgirepository1.0-dev \
|
||||||
|
libgtk-3-dev \
|
||||||
|
libgtkmm-3.0-dev \
|
||||||
|
libinput-dev \
|
||||||
|
libjsoncpp-dev \
|
||||||
|
libmpdclient-dev \
|
||||||
|
libnl-3-dev \
|
||||||
|
libnl-genl-3-dev \
|
||||||
|
libpulse-dev \
|
||||||
|
libsigc++-2.0-dev \
|
||||||
|
libspdlog-dev \
|
||||||
|
libwayland-dev \
|
||||||
|
scdoc
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Contributions welcome! - have fun :)<br>
|
Contributions welcome! - have fun :)<br>
|
||||||
The style guidelines is [Google's](https://google.github.io/styleguide/cppguide.html)
|
The style guidelines is [Google's](https://google.github.io/styleguide/cppguide.html)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <gdkmm/monitor.h>
|
||||||
#include <glibmm/refptr.h>
|
#include <glibmm/refptr.h>
|
||||||
#include <gtkmm/box.h>
|
#include <gtkmm/box.h>
|
||||||
#include <gtkmm/cssprovider.h>
|
#include <gtkmm/cssprovider.h>
|
||||||
|
@ -15,10 +16,11 @@ namespace waybar {
|
||||||
|
|
||||||
class Factory;
|
class Factory;
|
||||||
struct waybar_output {
|
struct waybar_output {
|
||||||
struct wl_output * output = nullptr;
|
Glib::RefPtr<Gdk::Monitor> monitor;
|
||||||
std::string name;
|
std::string name;
|
||||||
uint32_t wl_name;
|
|
||||||
struct zxdg_output_v1 *xdg_output = nullptr;
|
std::unique_ptr<struct zxdg_output_v1, decltype(&zxdg_output_v1_destroy)> xdg_output = {
|
||||||
|
nullptr, &zxdg_output_v1_destroy};
|
||||||
};
|
};
|
||||||
|
|
||||||
class Bar {
|
class Bar {
|
||||||
|
@ -30,11 +32,10 @@ class Bar {
|
||||||
auto toggle() -> void;
|
auto toggle() -> void;
|
||||||
void handleSignal(int);
|
void handleSignal(int);
|
||||||
|
|
||||||
struct waybar_output * output;
|
struct waybar_output *output;
|
||||||
Json::Value config;
|
Json::Value config;
|
||||||
Gtk::Window window;
|
Gtk::Window window;
|
||||||
struct wl_surface * surface;
|
struct wl_surface * surface;
|
||||||
struct zwlr_layer_surface_v1 *layer_surface;
|
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
bool vertical = false;
|
bool vertical = false;
|
||||||
|
|
||||||
|
@ -51,7 +52,9 @@ class Bar {
|
||||||
uint32_t, uint32_t);
|
uint32_t, uint32_t);
|
||||||
static void layerSurfaceHandleClosed(void *, struct zwlr_layer_surface_v1 *);
|
static void layerSurfaceHandleClosed(void *, struct zwlr_layer_surface_v1 *);
|
||||||
|
|
||||||
void destroyOutput();
|
#ifdef HAVE_GTK_LAYER_SHELL
|
||||||
|
void initGtkLayerShell();
|
||||||
|
#endif
|
||||||
void onConfigure(GdkEventConfigure *ev);
|
void onConfigure(GdkEventConfigure *ev);
|
||||||
void onRealize();
|
void onRealize();
|
||||||
void onMap(GdkEventAny *ev);
|
void onMap(GdkEventAny *ev);
|
||||||
|
@ -68,6 +71,9 @@ class Bar {
|
||||||
int bottom = 0;
|
int bottom = 0;
|
||||||
int left = 0;
|
int left = 0;
|
||||||
} margins_;
|
} 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 width_ = 0;
|
||||||
uint32_t height_ = 1;
|
uint32_t height_ = 1;
|
||||||
uint8_t anchor_;
|
uint8_t anchor_;
|
||||||
|
|
|
@ -30,26 +30,24 @@ class Client {
|
||||||
const std::string &style) const;
|
const std::string &style) const;
|
||||||
void bindInterfaces();
|
void bindInterfaces();
|
||||||
const std::string getValidPath(const std::vector<std::string> &paths) const;
|
const std::string getValidPath(const std::vector<std::string> &paths) const;
|
||||||
void handleOutput(std::unique_ptr<struct waybar_output> &output);
|
void handleOutput(struct waybar_output &output);
|
||||||
bool isValidOutput(const Json::Value &config, std::unique_ptr<struct waybar_output> &output);
|
bool isValidOutput(const Json::Value &config, struct waybar_output &output);
|
||||||
auto setupConfig(const std::string &config_file) -> void;
|
auto setupConfig(const std::string &config_file) -> void;
|
||||||
auto setupCss(const std::string &css_file) -> void;
|
auto setupCss(const std::string &css_file) -> void;
|
||||||
std::unique_ptr<struct waybar_output> &getOutput(uint32_t wl_name);
|
struct waybar_output &getOutput(void *);
|
||||||
std::vector<Json::Value> getOutputConfigs(std::unique_ptr<struct waybar_output> &output);
|
std::vector<Json::Value> getOutputConfigs(struct waybar_output &output);
|
||||||
|
|
||||||
static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
|
static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
|
||||||
const char *interface, uint32_t version);
|
const char *interface, uint32_t version);
|
||||||
static void handleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name);
|
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 handleOutputName(void *, struct zxdg_output_v1 *, const char *);
|
||||||
static void handleLogicalSize(void *, struct zxdg_output_v1 *, int32_t, int32_t);
|
void handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor);
|
||||||
static void handleDone(void *, struct zxdg_output_v1 *);
|
void handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor);
|
||||||
static void handleName(void *, struct zxdg_output_v1 *, const char *);
|
|
||||||
static void handleDescription(void *, struct zxdg_output_v1 *, const char *);
|
|
||||||
|
|
||||||
Json::Value config_;
|
Json::Value config_;
|
||||||
Glib::RefPtr<Gtk::StyleContext> style_context_;
|
Glib::RefPtr<Gtk::StyleContext> style_context_;
|
||||||
Glib::RefPtr<Gtk::CssProvider> css_provider_;
|
Glib::RefPtr<Gtk::CssProvider> css_provider_;
|
||||||
std::vector<std::unique_ptr<struct waybar_output>> outputs_;
|
std::list<struct waybar_output> outputs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|
|
@ -6,11 +6,17 @@
|
||||||
#else
|
#else
|
||||||
#include <fmt/chrono.h>
|
#include <fmt/chrono.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <date/tz.h>
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
struct waybar_time {
|
||||||
|
std::locale locale;
|
||||||
|
date::zoned_seconds ztime;
|
||||||
|
};
|
||||||
|
|
||||||
class Clock : public ALabel {
|
class Clock : public ALabel {
|
||||||
public:
|
public:
|
||||||
Clock(const std::string&, const Json::Value&);
|
Clock(const std::string&, const Json::Value&);
|
||||||
|
@ -19,6 +25,15 @@ class Clock : public ALabel {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
|
std::locale locale_;
|
||||||
|
const date::time_zone* time_zone_;
|
||||||
|
bool fixed_time_zone_;
|
||||||
|
date::year_month_day cached_calendar_ymd_;
|
||||||
|
std::string cached_calendar_text_;
|
||||||
|
|
||||||
|
auto calendar_text(const waybar_time& wtime) -> std::string;
|
||||||
|
auto weekdays_header(const date::weekday& first_dow, std::ostream& os) -> void;
|
||||||
|
auto first_day_of_week() -> date::weekday;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|
|
@ -17,8 +17,7 @@ class Memory : public ALabel {
|
||||||
static inline const std::string data_dir_ = "/proc/meminfo";
|
static inline const std::string data_dir_ = "/proc/meminfo";
|
||||||
void parseMeminfo();
|
void parseMeminfo();
|
||||||
|
|
||||||
unsigned long memtotal_;
|
std::unordered_map<std::string, unsigned long> meminfo_;
|
||||||
unsigned long memfree_;
|
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,6 +36,7 @@ class MPD : public ALabel {
|
||||||
|
|
||||||
bool stopped();
|
bool stopped();
|
||||||
bool playing();
|
bool playing();
|
||||||
|
bool paused();
|
||||||
|
|
||||||
const std::string module_name_;
|
const std::string module_name_;
|
||||||
|
|
||||||
|
|
|
@ -34,14 +34,17 @@ class Pulseaudio : public ALabel {
|
||||||
pa_cvolume pa_volume_;
|
pa_cvolume pa_volume_;
|
||||||
bool muted_;
|
bool muted_;
|
||||||
std::string port_name_;
|
std::string port_name_;
|
||||||
|
std::string form_factor_;
|
||||||
std::string desc_;
|
std::string desc_;
|
||||||
std::string monitor_;
|
std::string monitor_;
|
||||||
|
std::string default_sink_name_;
|
||||||
// SOURCE
|
// SOURCE
|
||||||
uint32_t source_idx_{0};
|
uint32_t source_idx_{0};
|
||||||
uint16_t source_volume_;
|
uint16_t source_volume_;
|
||||||
bool source_muted_;
|
bool source_muted_;
|
||||||
std::string source_port_name_;
|
std::string source_port_name_;
|
||||||
std::string source_desc_;
|
std::string source_desc_;
|
||||||
|
std::string default_source_name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|
|
@ -21,7 +21,7 @@ class Tray : public AModule {
|
||||||
|
|
||||||
static inline std::size_t nb_hosts_ = 0;
|
static inline std::size_t nb_hosts_ = 0;
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
SNI::Watcher watcher_;
|
SNI::Watcher::singleton watcher_;
|
||||||
SNI::Host host_;
|
SNI::Host host_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,24 @@
|
||||||
namespace waybar::modules::SNI {
|
namespace waybar::modules::SNI {
|
||||||
|
|
||||||
class Watcher {
|
class Watcher {
|
||||||
|
private:
|
||||||
|
Watcher();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Watcher(std::size_t id);
|
|
||||||
~Watcher();
|
~Watcher();
|
||||||
|
|
||||||
|
using singleton = std::shared_ptr<Watcher>;
|
||||||
|
static singleton getInstance() {
|
||||||
|
static std::weak_ptr<Watcher> weak;
|
||||||
|
|
||||||
|
std::shared_ptr<Watcher> strong = weak.lock();
|
||||||
|
if (!strong) {
|
||||||
|
strong = std::shared_ptr<Watcher>(new Watcher());
|
||||||
|
weak = strong;
|
||||||
|
}
|
||||||
|
return strong;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef enum { GF_WATCH_TYPE_HOST, GF_WATCH_TYPE_ITEM } GfWatchType;
|
typedef enum { GF_WATCH_TYPE_HOST, GF_WATCH_TYPE_ITEM } GfWatchType;
|
||||||
|
|
||||||
|
@ -34,7 +48,6 @@ class Watcher {
|
||||||
void updateRegisteredItems(SnWatcher *obj);
|
void updateRegisteredItems(SnWatcher *obj);
|
||||||
|
|
||||||
uint32_t bus_name_id_;
|
uint32_t bus_name_id_;
|
||||||
uint32_t watcher_id_;
|
|
||||||
GSList * hosts_ = nullptr;
|
GSList * hosts_ = nullptr;
|
||||||
GSList * items_ = nullptr;
|
GSList * items_ = nullptr;
|
||||||
SnWatcher *watcher_ = nullptr;
|
SnWatcher *watcher_ = nullptr;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include "ipc.hpp"
|
#include "ipc.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ class Ipc {
|
||||||
void sendCmd(uint32_t type, const std::string &payload = "");
|
void sendCmd(uint32_t type, const std::string &payload = "");
|
||||||
void subscribe(const std::string &payload);
|
void subscribe(const std::string &payload);
|
||||||
void handleEvent();
|
void handleEvent();
|
||||||
|
void setWorker(std::function<void()> &&func);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static inline const std::string ipc_magic_ = "i3-ipc";
|
static inline const std::string ipc_magic_ = "i3-ipc";
|
||||||
|
@ -41,6 +43,7 @@ class Ipc {
|
||||||
int fd_;
|
int fd_;
|
||||||
int fd_event_;
|
int fd_event_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
|
util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::sway
|
} // namespace waybar::modules::sway
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
#include "modules/sway/ipc/client.hpp"
|
#include "modules/sway/ipc/client.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
|
||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
|
@ -18,13 +17,10 @@ class Mode : public ALabel, public sigc::trackable {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onEvent(const struct Ipc::ipc_response&);
|
void onEvent(const struct Ipc::ipc_response&);
|
||||||
void worker();
|
|
||||||
|
|
||||||
std::string mode_;
|
std::string mode_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
|
||||||
Ipc ipc_;
|
Ipc ipc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
#include "modules/sway/ipc/client.hpp"
|
#include "modules/sway/ipc/client.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
|
||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
|
@ -20,7 +19,6 @@ class Window : public ALabel, public sigc::trackable {
|
||||||
private:
|
private:
|
||||||
void onEvent(const struct Ipc::ipc_response&);
|
void onEvent(const struct Ipc::ipc_response&);
|
||||||
void onCmd(const struct Ipc::ipc_response&);
|
void onCmd(const struct Ipc::ipc_response&);
|
||||||
void worker();
|
|
||||||
std::tuple<std::size_t, int, std::string, std::string> getFocusedNode(const Json::Value& nodes,
|
std::tuple<std::size_t, int, std::string, std::string> getFocusedNode(const Json::Value& nodes,
|
||||||
std::string& output);
|
std::string& output);
|
||||||
void getTree();
|
void getTree();
|
||||||
|
@ -33,8 +31,6 @@ class Window : public ALabel, public sigc::trackable {
|
||||||
std::size_t app_nb_;
|
std::size_t app_nb_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
|
||||||
Ipc ipc_;
|
Ipc ipc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <gtkmm/button.h>
|
#include <gtkmm/button.h>
|
||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
|
@ -8,7 +9,6 @@
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
#include "modules/sway/ipc/client.hpp"
|
#include "modules/sway/ipc/client.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
|
||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ class Workspaces : public AModule, public sigc::trackable {
|
||||||
private:
|
private:
|
||||||
void onCmd(const struct Ipc::ipc_response&);
|
void onCmd(const struct Ipc::ipc_response&);
|
||||||
void onEvent(const struct Ipc::ipc_response&);
|
void onEvent(const struct Ipc::ipc_response&);
|
||||||
void worker();
|
|
||||||
bool filterButtons();
|
bool filterButtons();
|
||||||
Gtk::Button& addButton(const Json::Value&);
|
Gtk::Button& addButton(const Json::Value&);
|
||||||
void onButtonReady(const Json::Value&, Gtk::Button&);
|
void onButtonReady(const Json::Value&, Gtk::Button&);
|
||||||
|
@ -38,8 +37,6 @@ class Workspaces : public AModule, public sigc::trackable {
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::unordered_map<std::string, Gtk::Button> buttons_;
|
std::unordered_map<std::string, Gtk::Button> buttons_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
|
||||||
Ipc ipc_;
|
Ipc ipc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,10 @@ inline struct res exec(std::string cmd) {
|
||||||
if (!fp) return {-1, ""};
|
if (!fp) return {-1, ""};
|
||||||
auto output = command::read(fp);
|
auto output = command::read(fp);
|
||||||
auto stat = command::close(fp, pid);
|
auto stat = command::close(fp, pid);
|
||||||
|
if (WIFEXITED(stat)) {
|
||||||
return {WEXITSTATUS(stat), output};
|
return {WEXITSTATUS(stat), output};
|
||||||
|
}
|
||||||
|
return {-1, output};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int32_t forkExec(std::string cmd) {
|
inline int32_t forkExec(std::string cmd) {
|
||||||
|
@ -88,6 +91,7 @@ inline int32_t forkExec(std::string cmd) {
|
||||||
// Child executes the command
|
// Child executes the command
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
setpgid(pid, pid);
|
setpgid(pid, pid);
|
||||||
|
signal(SIGCHLD, SIG_DFL);
|
||||||
execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
|
execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
|
||||||
exit(0);
|
exit(0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -36,6 +36,10 @@ The *backlight* module displays the current backlight level.
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when the module is clicked.
|
Command to execute when the module is clicked.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right* ++
|
*on-click-right* ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when the module is right clicked.
|
Command to execute when the module is right clicked.
|
||||||
|
|
|
@ -18,6 +18,10 @@ The *battery* module displays the current capacity and state (eg. charging) of y
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
The adapter to monitor, as in /sys/class/power_supply/ instead of auto detect.
|
The adapter to monitor, as in /sys/class/power_supply/ instead of auto detect.
|
||||||
|
|
||||||
|
*full-at* ++
|
||||||
|
typeof: integer ++
|
||||||
|
Define the max percentage of the battery, usefull for an old battery, e.g. 96
|
||||||
|
|
||||||
*interval* ++
|
*interval* ++
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
default: 60 ++
|
default: 60 ++
|
||||||
|
@ -37,32 +41,36 @@ The *battery* module displays the current capacity and state (eg. charging) of y
|
||||||
default: {H} h {M} min ++
|
default: {H} h {M} min ++
|
||||||
The format, how the time should be displayed.
|
The format, how the time should be displayed.
|
||||||
|
|
||||||
*format-icons*
|
*format-icons*: ++
|
||||||
typeof: array/object
|
typeof: array/object ++
|
||||||
Based on the current capacity, the corresponding icon gets selected. ++
|
Based on the current capacity, the corresponding icon gets selected. ++
|
||||||
The order is *low* to *high*. Or by the state if it is an object.
|
The order is *low* to *high*. Or by the state if it is an object.
|
||||||
|
|
||||||
*max-length* ++
|
*max-length*: ++
|
||||||
typeof: integer++
|
typeof: integer++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
*rotate* ++
|
*rotate*: ++
|
||||||
typeof: integer++
|
typeof: integer++
|
||||||
Positive value to rotate the text label.
|
Positive value to rotate the text label.
|
||||||
|
|
||||||
*on-click* ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right* ++
|
*on-click-right* ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
|
||||||
*on-scroll-up* ++
|
*on-scroll-up*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when scrolling up on the module.
|
Command to execute when scrolling up on the module.
|
||||||
|
|
||||||
*on-scroll-down* ++
|
*on-scroll-down*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when scrolling down on the module.
|
Command to execute when scrolling down on the module.
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,18 @@ The *clock* module displays the current date and time.
|
||||||
*format*: ++
|
*format*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
default: {:%H:%M} ++
|
default: {:%H:%M} ++
|
||||||
The format, how the date and time should be displayed.
|
The format, how the date and time should be displayed. ++
|
||||||
|
It uses the format of the date library. See https://howardhinnant.github.io/date/date.html#to_stream_formatting for details.
|
||||||
|
|
||||||
|
*timezone*: ++
|
||||||
|
typeof: string ++
|
||||||
|
default: inferred local timezone ++
|
||||||
|
The timezone to display the time in, e.g. America/New_York.
|
||||||
|
|
||||||
|
*locale*: ++
|
||||||
|
typeof: string ++
|
||||||
|
default: inferred from current locale ++
|
||||||
|
A locale to be used to display the time. Intended to render times in custom timezones with the proper language and format.
|
||||||
|
|
||||||
*max-length*: ++
|
*max-length*: ++
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
|
@ -32,6 +43,10 @@ The *clock* module displays the current date and time.
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
@ -50,6 +65,10 @@ The *clock* module displays the current date and time.
|
||||||
|
|
||||||
View all valid format options in *strftime(3)*.
|
View all valid format options in *strftime(3)*.
|
||||||
|
|
||||||
|
# FORMAT REPLACEMENTS
|
||||||
|
|
||||||
|
*{calendar}*: Current month calendar
|
||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -36,6 +36,10 @@ The *cpu* module displays the current cpu utilization.
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
|
|
@ -33,6 +33,12 @@ Addressed by *custom/<name>*
|
||||||
You can update it manually with a signal. If no *interval* is defined,
|
You can update it manually with a signal. If no *interval* is defined,
|
||||||
it is assumed that the out script loops it self.
|
it is assumed that the out script loops it self.
|
||||||
|
|
||||||
|
*restart-interval*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The restart interval (in seconds).
|
||||||
|
Can't be used with the *interval* option, so only with continuous scripts.
|
||||||
|
Once the script exit, it'll be re-executed after the *restart-interval*.
|
||||||
|
|
||||||
*signal*: ++
|
*signal*: ++
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The signal number used to update the module.
|
The signal number used to update the module.
|
||||||
|
@ -59,6 +65,10 @@ Addressed by *custom/<name>*
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
|
|
@ -39,6 +39,10 @@ Addressed by *disk*
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
|
|
@ -31,6 +31,10 @@ screensaving, also known as "presentation mode".
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module. A click also toggles the state
|
Command to execute when clicked on the module. A click also toggles the state
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
|
|
@ -38,6 +38,10 @@ Addressed by *memory*
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
|
|
@ -38,13 +38,17 @@ Addressed by *mpd*
|
||||||
*format*: ++
|
*format*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
default: "{album} - {artist} - {title}" ++
|
default: "{album} - {artist} - {title}" ++
|
||||||
Information displayed when a song is playing or paused
|
Information displayed when a song is playing.
|
||||||
|
|
||||||
*format-stopped*: ++
|
*format-stopped*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
default: "stopped" ++
|
default: "stopped" ++
|
||||||
Information displayed when the player is stopped.
|
Information displayed when the player is stopped.
|
||||||
|
|
||||||
|
*format-paused*: ++
|
||||||
|
typeof: string ++
|
||||||
|
This format is used when a song is paused.
|
||||||
|
|
||||||
*format-disconnected*: ++
|
*format-disconnected*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
default: "disconnected" ++
|
default: "disconnected" ++
|
||||||
|
@ -77,6 +81,10 @@ Addressed by *mpd*
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
|
|
@ -21,6 +21,11 @@ Addressed by *network*
|
||||||
default: 60 ++
|
default: 60 ++
|
||||||
The interval in which the network information gets polled (e.g. signal strength).
|
The interval in which the network information gets polled (e.g. signal strength).
|
||||||
|
|
||||||
|
*family*: ++
|
||||||
|
typeof: string ++
|
||||||
|
default: *ipv4* ++
|
||||||
|
The address family that is used for the format replacement {ipaddr} and to determine if a network connection is present.
|
||||||
|
|
||||||
*format*: ++
|
*format*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
default: *{ifname}* ++
|
default: *{ifname}* ++
|
||||||
|
@ -42,6 +47,11 @@ Addressed by *network*
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
This format is used when the displayed interface is disconnected.
|
This format is used when the displayed interface is disconnected.
|
||||||
|
|
||||||
|
*format-icons*: ++
|
||||||
|
typeof: array/object ++
|
||||||
|
Based on the current signal strength, the corresponding icon gets selected. ++
|
||||||
|
The order is *low* to *high*. Or by the state if it is an object.
|
||||||
|
|
||||||
*rotate*: ++
|
*rotate*: ++
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
Positive value to rotate the text label.
|
Positive value to rotate the text label.
|
||||||
|
@ -54,6 +64,10 @@ Addressed by *network*
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
@ -117,6 +131,8 @@ Addressed by *network*
|
||||||
|
|
||||||
*{bandwidthDownOctets}*: Instant down speed in octets/seconds.
|
*{bandwidthDownOctets}*: Instant down speed in octets/seconds.
|
||||||
|
|
||||||
|
*{icon}*: Icon, as defined in *format-icons*.
|
||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -59,6 +59,10 @@ Additionally you can control the volume by scrolling *up* or *down* while the cu
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
@ -96,16 +100,17 @@ The following strings for *format-icons* are supported.
|
||||||
If they are found in the current PulseAudio port name, the corresponding icons will be selected.
|
If they are found in the current PulseAudio port name, the corresponding icons will be selected.
|
||||||
|
|
||||||
- *default* (Shown, when no other port is found)
|
- *default* (Shown, when no other port is found)
|
||||||
- *headphones*
|
- *headphone*
|
||||||
- *speaker*
|
- *speaker*
|
||||||
- *hdmi*
|
- *hdmi*
|
||||||
- *headset*
|
- *headset*
|
||||||
- *handsfree*
|
- *hands-free*
|
||||||
- *portable*
|
- *portable*
|
||||||
- *car*
|
- *car*
|
||||||
- *hifi*
|
- *hifi*
|
||||||
- *phone*
|
- *phone*
|
||||||
|
|
||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -29,6 +29,10 @@ Addressed by *sway/mode*
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
|
|
@ -29,6 +29,10 @@ Addressed by *sway/window*
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
|
|
@ -19,7 +19,7 @@ Addressed by *sway/workspaces*
|
||||||
|
|
||||||
*format*: ++
|
*format*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
default: {name} ++
|
default: {value} ++
|
||||||
The format, how information should be displayed.
|
The format, how information should be displayed.
|
||||||
|
|
||||||
*format-icons*: ++
|
*format-icons*: ++
|
||||||
|
@ -62,7 +62,9 @@ Addressed by *sway/workspaces*
|
||||||
|
|
||||||
# FORMAT REPLACEMENTS
|
# FORMAT REPLACEMENTS
|
||||||
|
|
||||||
*{name}*: Name of the workspace, as defined by sway.
|
*{value}*: Name of the workspace, as defined by sway.
|
||||||
|
|
||||||
|
*{name}*: Number stripped from workspace value.
|
||||||
|
|
||||||
*{icon}*: Icon, as defined in *format-icons*.
|
*{icon}*: Icon, as defined in *format-icons*.
|
||||||
|
|
||||||
|
@ -75,6 +77,7 @@ Additional to workspace name matching, the following *format-icons* can be set.
|
||||||
- *default*: Will be shown, when no string matches is found.
|
- *default*: Will be shown, when no string matches is found.
|
||||||
- *urgent*: Will be shown, when workspace is flagged as urgent
|
- *urgent*: Will be shown, when workspace is flagged as urgent
|
||||||
- *focused*: Will be shown, when workspace is focused
|
- *focused*: Will be shown, when workspace is focused
|
||||||
|
- *persistent*: Will be shown, when workspace is persistent one.
|
||||||
|
|
||||||
# PERSISTENT WORKSPACES
|
# PERSISTENT WORKSPACES
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,17 @@ Addressed by *temperature*
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
The temperature path to use, e.g. */sys/class/hwmon/hwmon2/temp1_input* instead of one in */sys/class/thermal/*.
|
The temperature path to use, e.g. */sys/class/hwmon/hwmon2/temp1_input* instead of one in */sys/class/thermal/*.
|
||||||
|
|
||||||
|
*hwmon-path-abs*: ++
|
||||||
|
typeof: string ++
|
||||||
|
The path of the hwmon-directory of the device, e.g. */sys/devices/pci0000:00/0000:00:18.3/hwmon*. (Note that the subdirectory *hwmon/hwmon#*, where *#* is a number is not part of the path!) Has to be used together with *input-filename*.
|
||||||
|
|
||||||
|
*input-filename*: ++
|
||||||
|
typeof: string ++
|
||||||
|
The temperature filename of your *hwmon-path-abs*, e.g. *temp1_input*
|
||||||
|
|
||||||
*critical-threshold*: ++
|
*critical-threshold*: ++
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The threshold before it is considered critical (Celcius).
|
The threshold before it is considered critical (Celsius).
|
||||||
|
|
||||||
*interval*: ++
|
*interval*: ++
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
|
@ -36,11 +44,11 @@ Addressed by *temperature*
|
||||||
*format*: ++
|
*format*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
default: {temperatureC}°C ++
|
default: {temperatureC}°C ++
|
||||||
The format (Celcius/Farenheit) in which the temperature should be displayed.
|
The format (Celsius/Fahrenheit) in which the temperature should be displayed.
|
||||||
|
|
||||||
*format-icons*: ++
|
*format-icons*: ++
|
||||||
typeof: array ++
|
typeof: array ++
|
||||||
Based on the current temperature (Celcius) and *critical-threshold* if available, the corresponding icon gets selected. The order is *low* to *high*.
|
Based on the current temperature (Celsius) and *critical-threshold* if available, the corresponding icon gets selected. The order is *low* to *high*.
|
||||||
|
|
||||||
*rotate*: ++
|
*rotate*: ++
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
|
@ -54,6 +62,10 @@ Addressed by *temperature*
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you clicked on the module.
|
Command to execute when you clicked on the module.
|
||||||
|
|
||||||
|
*on-click-middle*: ++
|
||||||
|
typeof: string ++
|
||||||
|
Command to execute when middle-clicked on the module using mousewheel.
|
||||||
|
|
||||||
*on-click-right*: ++
|
*on-click-right*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you right clicked on the module.
|
Command to execute when you right clicked on the module.
|
||||||
|
@ -77,7 +89,7 @@ Addressed by *temperature*
|
||||||
|
|
||||||
# FORMAT REPLACEMENTS
|
# FORMAT REPLACEMENTS
|
||||||
|
|
||||||
*{temperatureC}*: Temperature in Celcius.
|
*{temperatureC}*: Temperature in Celsius.
|
||||||
|
|
||||||
*{temperatureF}*: Temperature in Fahrenheit.
|
*{temperatureF}*: Temperature in Fahrenheit.
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ Also a minimal example configuration can be found on the at the bottom of this m
|
||||||
*layer* ++
|
*layer* ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
default: bottom ++
|
default: bottom ++
|
||||||
Decide if the bar is displayed in front of the windows or behind them.
|
Decide if the bar is displayed in front (*top*) of the windows or behind (*bottom*)
|
||||||
|
them.
|
||||||
|
|
||||||
*output* ++
|
*output* ++
|
||||||
typeof: string|array ++
|
typeof: string|array ++
|
||||||
|
@ -66,6 +67,12 @@ Also a minimal example configuration can be found on the at the bottom of this m
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Optional name added as a CSS class, for styling multiple waybars.
|
Optional name added as a CSS class, for styling multiple waybars.
|
||||||
|
|
||||||
|
*gtk-layer-shell* ++
|
||||||
|
typeof: bool ++
|
||||||
|
default: true ++
|
||||||
|
Option to disable the use of gtk-layer-shell for popups.
|
||||||
|
Only functional if compiled with gtk-layer-shell support.
|
||||||
|
|
||||||
# MODULE FORMAT
|
# MODULE FORMAT
|
||||||
|
|
||||||
You can use PangoMarkupFormat (See https://developer.gnome.org/pango/stable/PangoMarkupFormat.html#PangoMarkupFormat).
|
You can use PangoMarkupFormat (See https://developer.gnome.org/pango/stable/PangoMarkupFormat.html#PangoMarkupFormat).
|
||||||
|
|
39
meson.build
39
meson.build
|
@ -1,6 +1,6 @@
|
||||||
project(
|
project(
|
||||||
'waybar', 'cpp', 'c',
|
'waybar', 'cpp', 'c',
|
||||||
version: '0.8.0',
|
version: '0.9.2',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
default_options : [
|
default_options : [
|
||||||
'cpp_std=c++17',
|
'cpp_std=c++17',
|
||||||
|
@ -9,6 +9,8 @@ project(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
compiler = meson.get_compiler('cpp')
|
||||||
|
|
||||||
cpp_args = []
|
cpp_args = []
|
||||||
cpp_link_args = []
|
cpp_link_args = []
|
||||||
|
|
||||||
|
@ -16,13 +18,14 @@ if get_option('libcxx')
|
||||||
cpp_args += ['-stdlib=libc++']
|
cpp_args += ['-stdlib=libc++']
|
||||||
cpp_link_args += ['-stdlib=libc++', '-lc++abi']
|
cpp_link_args += ['-stdlib=libc++', '-lc++abi']
|
||||||
|
|
||||||
|
if compiler.has_link_argument('-lc++fs')
|
||||||
cpp_link_args += ['-lc++fs']
|
cpp_link_args += ['-lc++fs']
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
cpp_link_args += ['-lstdc++fs']
|
cpp_link_args += ['-lstdc++fs']
|
||||||
endif
|
endif
|
||||||
|
|
||||||
compiler = meson.get_compiler('cpp')
|
git = find_program('git', native: true, required: false)
|
||||||
git = find_program('git', required: false)
|
|
||||||
|
|
||||||
if not git.found()
|
if not git.found()
|
||||||
add_project_arguments('-DVERSION="@0@"'.format(meson.project_version()), language: 'cpp')
|
add_project_arguments('-DVERSION="@0@"'.format(meson.project_version()), language: 'cpp')
|
||||||
|
@ -42,6 +45,22 @@ if not compiler.has_header('filesystem')
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
code = '''
|
||||||
|
#include <langinfo.h>
|
||||||
|
#include <locale.h>
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
locale_t locale = newlocale(LC_ALL, "en_US.UTF-8", nullptr);
|
||||||
|
char* str;
|
||||||
|
str = nl_langinfo_l(_NL_TIME_WEEK_1STDAY, locale);
|
||||||
|
str = nl_langinfo_l(_NL_TIME_FIRST_WEEKDAY, locale);
|
||||||
|
freelocale(locale);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
if compiler.links(code, name : 'nl_langinfo with _NL_TIME_WEEK_1STDAY, _NL_TIME_FIRST_WEEKDAY')
|
||||||
|
add_project_arguments('-DHAVE_LANGINFO_1STDAY', language: 'cpp')
|
||||||
|
endif
|
||||||
|
|
||||||
add_global_arguments(cpp_args, language : 'cpp')
|
add_global_arguments(cpp_args, language : 'cpp')
|
||||||
add_global_link_arguments(cpp_link_args, language : 'cpp')
|
add_global_link_arguments(cpp_link_args, language : 'cpp')
|
||||||
|
|
||||||
|
@ -52,7 +71,7 @@ spdlog = dependency('spdlog', version : ['>=1.3.1'], fallback : ['spdlog', 'spdl
|
||||||
wayland_client = dependency('wayland-client')
|
wayland_client = dependency('wayland-client')
|
||||||
wayland_cursor = dependency('wayland-cursor')
|
wayland_cursor = dependency('wayland-cursor')
|
||||||
wayland_protos = dependency('wayland-protocols')
|
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'))
|
dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4', required: get_option('dbusmenu-gtk'))
|
||||||
giounix = dependency('gio-unix-2.0', required: get_option('dbusmenu-gtk'))
|
giounix = dependency('gio-unix-2.0', required: get_option('dbusmenu-gtk'))
|
||||||
jsoncpp = dependency('jsoncpp')
|
jsoncpp = dependency('jsoncpp')
|
||||||
|
@ -62,7 +81,11 @@ libnlgen = dependency('libnl-genl-3.0', required: get_option('libnl'))
|
||||||
libpulse = dependency('libpulse', required: get_option('pulseaudio'))
|
libpulse = dependency('libpulse', required: get_option('pulseaudio'))
|
||||||
libudev = dependency('libudev', required: get_option('libudev'))
|
libudev = dependency('libudev', required: get_option('libudev'))
|
||||||
libmpdclient = dependency('libmpdclient', required: get_option('mpd'))
|
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'))
|
systemd = dependency('systemd', required: get_option('systemd'))
|
||||||
|
tz_dep = dependency('date', default_options : [ 'use_system_tzdb=true' ], fallback: [ 'date', 'tz_dep' ])
|
||||||
|
|
||||||
prefix = get_option('prefix')
|
prefix = get_option('prefix')
|
||||||
conf_data = configuration_data()
|
conf_data = configuration_data()
|
||||||
|
@ -136,6 +159,10 @@ if libmpdclient.found()
|
||||||
src_files += 'src/modules/mpd.cpp'
|
src_files += 'src/modules/mpd.cpp'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if gtk_layer_shell.found()
|
||||||
|
add_project_arguments('-DHAVE_GTK_LAYER_SHELL', language: 'cpp')
|
||||||
|
endif
|
||||||
|
|
||||||
subdir('protocol')
|
subdir('protocol')
|
||||||
|
|
||||||
executable(
|
executable(
|
||||||
|
@ -158,7 +185,9 @@ executable(
|
||||||
libnlgen,
|
libnlgen,
|
||||||
libpulse,
|
libpulse,
|
||||||
libudev,
|
libudev,
|
||||||
libmpdclient
|
libmpdclient,
|
||||||
|
gtk_layer_shell,
|
||||||
|
tz_dep
|
||||||
],
|
],
|
||||||
include_directories: [include_directories('include')],
|
include_directories: [include_directories('include')],
|
||||||
install: true,
|
install: true,
|
||||||
|
|
|
@ -7,3 +7,4 @@ option('dbusmenu-gtk', type: 'feature', value: 'auto', description: 'Enable supp
|
||||||
option('man-pages', type: 'feature', value: 'auto', description: 'Generate and install man pages')
|
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('mpd', type: 'feature', value: 'auto', description: 'Enable support for the Music Player Daemon')
|
||||||
option('out', type: 'string', value : '/', description: 'output prefix directory')
|
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')
|
||||||
|
|
|
@ -31,7 +31,9 @@
|
||||||
<property name='Id' type='s' access='read'/>
|
<property name='Id' type='s' access='read'/>
|
||||||
<property name='Title' type='s' access='read'/>
|
<property name='Title' type='s' access='read'/>
|
||||||
<property name='Status' type='s' access='read'/>
|
<property name='Status' type='s' access='read'/>
|
||||||
|
<!-- See discussion on pull #536
|
||||||
<property name='WindowId' type='u' access='read'/>
|
<property name='WindowId' type='u' access='read'/>
|
||||||
|
-->
|
||||||
<property name='IconThemePath' type='s' access='read'/>
|
<property name='IconThemePath' type='s' access='read'/>
|
||||||
<property name='IconName' type='s' access='read'/>
|
<property name='IconName' type='s' access='read'/>
|
||||||
<property name='IconPixmap' type='a(iiay)' access='read'/>
|
<property name='IconPixmap' type='a(iiay)' access='read'/>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"layer": "top", // Waybar at top layer
|
// "layer": "top", // Waybar at top layer
|
||||||
// "position": "bottom", // Waybar position (top|bottom|left|right)
|
// "position": "bottom", // Waybar position (top|bottom|left|right)
|
||||||
"height": 30, // Waybar height (to be removed for auto height)
|
"height": 30, // Waybar height (to be removed for auto height)
|
||||||
// "width": 1280, // Waybar width
|
// "width": 1280, // Waybar width
|
||||||
|
@ -64,7 +64,8 @@
|
||||||
"spacing": 10
|
"spacing": 10
|
||||||
},
|
},
|
||||||
"clock": {
|
"clock": {
|
||||||
"tooltip-format": "{:%Y-%m-%d | %H:%M}",
|
// "timezone": "America/New_York",
|
||||||
|
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
|
||||||
"format-alt": "{:%Y-%m-%d}"
|
"format-alt": "{:%Y-%m-%d}"
|
||||||
},
|
},
|
||||||
"cpu": {
|
"cpu": {
|
||||||
|
@ -121,8 +122,8 @@
|
||||||
"format-source": "{volume}% ",
|
"format-source": "{volume}% ",
|
||||||
"format-source-muted": "",
|
"format-source-muted": "",
|
||||||
"format-icons": {
|
"format-icons": {
|
||||||
"headphones": "",
|
"headphone": "",
|
||||||
"handsfree": "",
|
"hands-free": "",
|
||||||
"headset": "",
|
"headset": "",
|
||||||
"phone": "",
|
"phone": "",
|
||||||
"portable": "",
|
"portable": "",
|
||||||
|
|
|
@ -38,6 +38,8 @@ def on_metadata(player, metadata, manager):
|
||||||
elif player.get_artist() != '' and player.get_title() != '':
|
elif player.get_artist() != '' and player.get_title() != '':
|
||||||
track_info = '{artist} - {title}'.format(artist=player.get_artist(),
|
track_info = '{artist} - {title}'.format(artist=player.get_artist(),
|
||||||
title=player.get_title())
|
title=player.get_title())
|
||||||
|
else:
|
||||||
|
track_info = player.get_title()
|
||||||
|
|
||||||
if player.props.status != 'Playing' and track_info:
|
if player.props.status != 'Playing' and track_info:
|
||||||
track_info = ' ' + track_info
|
track_info = ' ' + track_info
|
||||||
|
@ -77,7 +79,7 @@ def signal_handler(sig, frame):
|
||||||
def parse_arguments():
|
def parse_arguments():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
# Increase verbosity with every occurance of -v
|
# Increase verbosity with every occurence of -v
|
||||||
parser.add_argument('-v', '--verbose', action='count', default=0)
|
parser.add_argument('-v', '--verbose', action='count', default=0)
|
||||||
|
|
||||||
# Define for which player we're listening
|
# Define for which player we're listening
|
||||||
|
@ -123,4 +125,3 @@ def main():
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
Description=Highly customizable Wayland bar for Sway and Wlroots based compositors.
|
Description=Highly customizable Wayland bar for Sway and Wlroots based compositors.
|
||||||
Documentation=https://github.com/Alexays/Waybar/wiki/
|
Documentation=https://github.com/Alexays/Waybar/wiki/
|
||||||
PartOf=wayland-session.target
|
PartOf=wayland-session.target
|
||||||
|
After=wayland-session.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=dbus
|
Type=dbus
|
||||||
|
|
97
src/bar.cpp
97
src/bar.cpp
|
@ -1,3 +1,7 @@
|
||||||
|
#ifdef HAVE_GTK_LAYER_SHELL
|
||||||
|
#include <gtk-layer-shell.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
#include "factory.hpp"
|
#include "factory.hpp"
|
||||||
|
@ -8,7 +12,7 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
||||||
config(w_config),
|
config(w_config),
|
||||||
window{Gtk::WindowType::WINDOW_TOPLEVEL},
|
window{Gtk::WindowType::WINDOW_TOPLEVEL},
|
||||||
surface(nullptr),
|
surface(nullptr),
|
||||||
layer_surface(nullptr),
|
layer_surface_(nullptr),
|
||||||
anchor_(ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP),
|
anchor_(ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP),
|
||||||
left_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
left_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||||
center_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
center_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||||
|
@ -28,11 +32,6 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
||||||
height_ = config["height"].isUInt() ? config["height"].asUInt() : height_;
|
height_ = config["height"].isUInt() ? config["height"].asUInt() : height_;
|
||||||
width_ = config["width"].isUInt() ? config["width"].asUInt() : width_;
|
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") {
|
if (config["position"] == "bottom") {
|
||||||
anchor_ = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
anchor_ = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||||
} else if (config["position"] == "left") {
|
} else if (config["position"] == "left") {
|
||||||
|
@ -98,6 +97,17 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
||||||
margins_ = {.top = gaps, .right = gaps, .bottom = gaps, .left = gaps};
|
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();
|
setupWidgets();
|
||||||
|
|
||||||
if (window.get_realized()) {
|
if (window.get_realized()) {
|
||||||
|
@ -131,11 +141,48 @@ void waybar::Bar::onConfigure(GdkEventConfigure* ev) {
|
||||||
tmp_width = ev->width;
|
tmp_width = ev->width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tmp_width != width_ || tmp_height != 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);
|
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);
|
||||||
|
|
||||||
|
if (width_ > 1 && height_ > 1) {
|
||||||
|
/* configure events are not emitted if the bar is using initial size */
|
||||||
|
setExclusiveZone(width_, height_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void waybar::Bar::onRealize() {
|
void waybar::Bar::onRealize() {
|
||||||
auto gdk_window = window.get_window()->gobj();
|
auto gdk_window = window.get_window()->gobj();
|
||||||
gdk_wayland_window_set_use_custom_surface(gdk_window);
|
gdk_wayland_window_set_use_custom_surface(gdk_window);
|
||||||
|
@ -145,16 +192,22 @@ void waybar::Bar::onMap(GdkEventAny* ev) {
|
||||||
auto gdk_window = window.get_window()->gobj();
|
auto gdk_window = window.get_window()->gobj();
|
||||||
surface = gdk_wayland_window_get_wl_surface(gdk_window);
|
surface = gdk_wayland_window_get_wl_surface(gdk_window);
|
||||||
|
|
||||||
|
if (use_gls_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto client = waybar::Client::inst();
|
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 =
|
auto layer =
|
||||||
config["layer"] == "top" ? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
|
config["layer"] == "top" ? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
|
||||||
layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
layer_surface_ = zwlr_layer_shell_v1_get_layer_surface(
|
||||||
client->layer_shell, surface, output->output, layer, "waybar");
|
client->layer_shell, surface, wl_output, layer, "waybar");
|
||||||
|
|
||||||
zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface, false);
|
zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface_, false);
|
||||||
zwlr_layer_surface_v1_set_anchor(layer_surface, anchor_);
|
zwlr_layer_surface_v1_set_anchor(layer_surface_, anchor_);
|
||||||
zwlr_layer_surface_v1_set_margin(
|
zwlr_layer_surface_v1_set_margin(
|
||||||
layer_surface, margins_.top, margins_.right, margins_.bottom, margins_.left);
|
layer_surface_, margins_.top, margins_.right, margins_.bottom, margins_.left);
|
||||||
setSurfaceSize(width_, height_);
|
setSurfaceSize(width_, height_);
|
||||||
setExclusiveZone(width_, height_);
|
setExclusiveZone(width_, height_);
|
||||||
|
|
||||||
|
@ -162,7 +215,7 @@ void waybar::Bar::onMap(GdkEventAny* ev) {
|
||||||
.configure = layerSurfaceHandleConfigure,
|
.configure = layerSurfaceHandleConfigure,
|
||||||
.closed = layerSurfaceHandleClosed,
|
.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_surface_commit(surface);
|
||||||
wl_display_roundtrip(client->wl_display);
|
wl_display_roundtrip(client->wl_display);
|
||||||
|
@ -182,7 +235,15 @@ void waybar::Bar::setExclusiveZone(uint32_t width, uint32_t height) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spdlog::debug("Set exclusive zone {} for output {}", zone, output->name);
|
spdlog::debug("Set exclusive zone {} for output {}", zone, output->name);
|
||||||
zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, zone);
|
|
||||||
|
#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) {
|
void waybar::Bar::setSurfaceSize(uint32_t width, uint32_t height) {
|
||||||
|
@ -198,7 +259,7 @@ void waybar::Bar::setSurfaceSize(uint32_t width, uint32_t height) {
|
||||||
width += margins_.right + margins_.left;
|
width += margins_.right + margins_.left;
|
||||||
}
|
}
|
||||||
spdlog::debug("Set surface size {}x{} for output {}", width, height, output->name);
|
spdlog::debug("Set surface size {}x{} for output {}", width, height, output->name);
|
||||||
zwlr_layer_surface_v1_set_size(layer_surface, width, height);
|
zwlr_layer_surface_v1_set_size(layer_surface_, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converting string to button code rn as to avoid doing it later
|
// Converting string to button code rn as to avoid doing it later
|
||||||
|
@ -282,9 +343,9 @@ void waybar::Bar::layerSurfaceHandleConfigure(void* data, struct zwlr_layer_surf
|
||||||
|
|
||||||
void waybar::Bar::layerSurfaceHandleClosed(void* data, struct zwlr_layer_surface_v1* /*surface*/) {
|
void waybar::Bar::layerSurfaceHandleClosed(void* data, struct zwlr_layer_surface_v1* /*surface*/) {
|
||||||
auto o = static_cast<waybar::Bar*>(data);
|
auto o = static_cast<waybar::Bar*>(data);
|
||||||
if (o->layer_surface) {
|
if (o->layer_surface_) {
|
||||||
zwlr_layer_surface_v1_destroy(o->layer_surface);
|
zwlr_layer_surface_v1_destroy(o->layer_surface_);
|
||||||
o->layer_surface = nullptr;
|
o->layer_surface_ = nullptr;
|
||||||
}
|
}
|
||||||
o->modules_left_.clear();
|
o->modules_left_.clear();
|
||||||
o->modules_center_.clear();
|
o->modules_center_.clear();
|
||||||
|
|
134
src/client.cpp
134
src/client.cpp
|
@ -1,4 +1,5 @@
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
|
#include <fmt/ostream.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -33,11 +34,6 @@ void waybar::Client::handleGlobal(void *data, struct wl_registry *registry, uint
|
||||||
if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
||||||
client->layer_shell = static_cast<struct zwlr_layer_shell_v1 *>(
|
client->layer_shell = static_cast<struct zwlr_layer_shell_v1 *>(
|
||||||
wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, version));
|
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 &&
|
} else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 &&
|
||||||
version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
|
version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
|
||||||
client->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>(wl_registry_bind(
|
client->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>(wl_registry_bind(
|
||||||
|
@ -50,91 +46,51 @@ void waybar::Client::handleGlobal(void *data, struct wl_registry *registry, uint
|
||||||
|
|
||||||
void waybar::Client::handleGlobalRemove(void * data, struct wl_registry * /*registry*/,
|
void waybar::Client::handleGlobalRemove(void * data, struct wl_registry * /*registry*/,
|
||||||
uint32_t name) {
|
uint32_t name) {
|
||||||
auto client = static_cast<Client *>(data);
|
// Nothing here
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Client::handleOutput(std::unique_ptr<struct waybar_output> &output) {
|
void waybar::Client::handleOutput(struct waybar_output &output) {
|
||||||
static const struct zxdg_output_v1_listener xdgOutputListener = {
|
static const struct zxdg_output_v1_listener xdgOutputListener = {
|
||||||
.logical_position = handleLogicalPosition,
|
.logical_position = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {},
|
||||||
.logical_size = handleLogicalSize,
|
.logical_size = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {},
|
||||||
.done = handleDone,
|
.done = [](void *, struct zxdg_output_v1 *) {},
|
||||||
.name = handleName,
|
.name = &handleOutputName,
|
||||||
.description = handleDescription,
|
.description = [](void *, struct zxdg_output_v1 *, const char *) {},
|
||||||
};
|
};
|
||||||
output->xdg_output = zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, output->output);
|
// owned by output->monitor; no need to destroy
|
||||||
zxdg_output_v1_add_listener(output->xdg_output, &xdgOutputListener, &output->wl_name);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Client::handleLogicalPosition(void * /*data*/,
|
bool waybar::Client::isValidOutput(const Json::Value &config, struct waybar_output &output) {
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
bool waybar::Client::isValidOutput(const Json::Value & config,
|
|
||||||
std::unique_ptr<struct waybar_output> &output) {
|
|
||||||
bool found = true;
|
bool found = true;
|
||||||
if (config["output"].isArray()) {
|
if (config["output"].isArray()) {
|
||||||
bool in_array = false;
|
bool in_array = false;
|
||||||
for (auto const &output_conf : config["output"]) {
|
for (auto const &output_conf : config["output"]) {
|
||||||
if (output_conf.isString() && output_conf.asString() == output->name) {
|
if (output_conf.isString() && output_conf.asString() == output.name) {
|
||||||
in_array = true;
|
in_array = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
found = in_array;
|
found = in_array;
|
||||||
}
|
}
|
||||||
if (config["output"].isString() && config["output"].asString() != output->name) {
|
if (config["output"].isString() && config["output"].asString() != output.name) {
|
||||||
found = false;
|
found = false;
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<struct waybar::waybar_output> &waybar::Client::getOutput(uint32_t wl_name) {
|
struct waybar::waybar_output &waybar::Client::getOutput(void *addr) {
|
||||||
auto it = std::find_if(outputs_.begin(), outputs_.end(), [&wl_name](const auto &output) {
|
auto it = std::find_if(
|
||||||
return output->wl_name == wl_name;
|
outputs_.begin(), outputs_.end(), [&addr](const auto &output) { return &output == addr; });
|
||||||
});
|
|
||||||
if (it == outputs_.end()) {
|
if (it == outputs_.end()) {
|
||||||
throw std::runtime_error("Unable to find valid output");
|
throw std::runtime_error("Unable to find valid output");
|
||||||
}
|
}
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Json::Value> waybar::Client::getOutputConfigs(
|
std::vector<Json::Value> waybar::Client::getOutputConfigs(struct waybar_output &output) {
|
||||||
std::unique_ptr<struct waybar_output> &output) {
|
|
||||||
std::vector<Json::Value> configs;
|
std::vector<Json::Value> configs;
|
||||||
if (config_.isArray()) {
|
if (config_.isArray()) {
|
||||||
for (auto const &config : config_) {
|
for (auto const &config : config_) {
|
||||||
|
@ -148,27 +104,23 @@ std::vector<Json::Value> waybar::Client::getOutputConfigs(
|
||||||
return configs;
|
return configs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Client::handleName(void * data, struct zxdg_output_v1 * /*xdg_output*/,
|
void waybar::Client::handleOutputName(void * data, struct zxdg_output_v1 * /*xdg_output*/,
|
||||||
const char *name) {
|
const char *name) {
|
||||||
auto wl_name = *static_cast<uint32_t *>(data);
|
|
||||||
auto client = waybar::Client::inst();
|
auto client = waybar::Client::inst();
|
||||||
try {
|
try {
|
||||||
auto &output = client->getOutput(wl_name);
|
auto &output = client->getOutput(data);
|
||||||
output->name = name;
|
output.name = name;
|
||||||
|
spdlog::debug("Output detected: {} ({} {})",
|
||||||
|
name,
|
||||||
|
output.monitor->get_manufacturer(),
|
||||||
|
output.monitor->get_model());
|
||||||
auto configs = client->getOutputConfigs(output);
|
auto configs = client->getOutputConfigs(output);
|
||||||
if (configs.empty()) {
|
if (configs.empty()) {
|
||||||
if (output->output != nullptr) {
|
output.xdg_output.reset();
|
||||||
wl_output_destroy(output->output);
|
|
||||||
output->output = nullptr;
|
|
||||||
}
|
|
||||||
if (output->xdg_output != nullptr) {
|
|
||||||
zxdg_output_v1_destroy(output->xdg_output);
|
|
||||||
output->xdg_output = nullptr;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
wl_display_roundtrip(client->wl_display);
|
wl_display_roundtrip(client->wl_display);
|
||||||
for (const auto &config : configs) {
|
for (const auto &config : configs) {
|
||||||
client->bars.emplace_back(std::make_unique<Bar>(output.get(), config));
|
client->bars.emplace_back(std::make_unique<Bar>(&output, config));
|
||||||
Glib::RefPtr<Gdk::Screen> screen = client->bars.back()->window.get_screen();
|
Glib::RefPtr<Gdk::Screen> screen = client->bars.back()->window.get_screen();
|
||||||
client->style_context_->add_provider_for_screen(
|
client->style_context_->add_provider_for_screen(
|
||||||
screen, client->css_provider_, GTK_STYLE_PROVIDER_PRIORITY_USER);
|
screen, client->css_provider_, GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||||
|
@ -179,9 +131,25 @@ void waybar::Client::handleName(void * data, struct zxdg_output_v1 * /*xdg_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Client::handleDescription(void * /*data*/, struct zxdg_output_v1 * /*zxdg_output_v1*/,
|
void waybar::Client::handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor) {
|
||||||
const char * /*description*/) {
|
auto &output = outputs_.emplace_back();
|
||||||
// Nothing here
|
output.monitor = 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outputs_.remove_if([&monitor](const auto &output) { return output.monitor == monitor; });
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<const std::string, const std::string> waybar::Client::getConfigs(
|
std::tuple<const std::string, const std::string> waybar::Client::getConfigs(
|
||||||
|
@ -240,6 +208,14 @@ void waybar::Client::bindInterfaces() {
|
||||||
if (layer_shell == nullptr || xdg_output_manager == nullptr) {
|
if (layer_shell == nullptr || xdg_output_manager == nullptr) {
|
||||||
throw std::runtime_error("Failed to acquire required resources.");
|
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[]) {
|
int waybar::Client::main(int argc, char *argv[]) {
|
||||||
|
|
|
@ -115,6 +115,16 @@ const std::tuple<uint8_t, float, std::string> waybar::modules::Battery::getInfos
|
||||||
time_remaining = -(float)(total_energy_full - total_energy) / total_power;
|
time_remaining = -(float)(total_energy_full - total_energy) / total_power;
|
||||||
}
|
}
|
||||||
uint16_t capacity = total / batteries_.size();
|
uint16_t capacity = total / batteries_.size();
|
||||||
|
// Handle full-at
|
||||||
|
if (config_["full-at"].isUInt()) {
|
||||||
|
auto full_at = config_["full-at"].asUInt();
|
||||||
|
if (full_at < 100) {
|
||||||
|
capacity = static_cast<float>(capacity / full_at) * 100;
|
||||||
|
if (capacity > full_at) {
|
||||||
|
capacity = full_at;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return {capacity, time_remaining, status};
|
return {capacity, time_remaining, status};
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
spdlog::error("Battery: {}", e.what());
|
spdlog::error("Battery: {}", e.what());
|
||||||
|
@ -163,7 +173,12 @@ auto waybar::modules::Battery::update() -> void {
|
||||||
}
|
}
|
||||||
label_.set_tooltip_text(tooltip_text);
|
label_.set_tooltip_text(tooltip_text);
|
||||||
}
|
}
|
||||||
|
// Transform to lowercase
|
||||||
std::transform(status.begin(), status.end(), status.begin(), ::tolower);
|
std::transform(status.begin(), status.end(), status.begin(), ::tolower);
|
||||||
|
// Replace space with dash
|
||||||
|
std::transform(status.begin(), status.end(), status.begin(), [](char ch) {
|
||||||
|
return ch == ' ' ? '-' : ch;
|
||||||
|
});
|
||||||
auto format = format_;
|
auto format = format_;
|
||||||
auto state = getState(capacity, true);
|
auto state = getState(capacity, true);
|
||||||
if (!old_status_.empty()) {
|
if (!old_status_.empty()) {
|
||||||
|
|
|
@ -1,8 +1,28 @@
|
||||||
#include "modules/clock.hpp"
|
#include "modules/clock.hpp"
|
||||||
#include <time.h>
|
#include <sstream>
|
||||||
|
#include <type_traits>
|
||||||
|
#ifdef HAVE_LANGINFO_1STDAY
|
||||||
|
#include <langinfo.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using waybar::modules::waybar_time;
|
||||||
|
|
||||||
waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "clock", id, "{:%H:%M}", 60) {
|
: ALabel(config, "clock", id, "{:%H:%M}", 60)
|
||||||
|
, fixed_time_zone_(false)
|
||||||
|
{
|
||||||
|
if (config_["timezone"].isString()) {
|
||||||
|
time_zone_ = date::locate_zone(config_["timezone"].asString());
|
||||||
|
fixed_time_zone_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_["locale"].isString()) {
|
||||||
|
locale_ = std::locale(config_["locale"].asString());
|
||||||
|
} else {
|
||||||
|
locale_ = std::locale("");
|
||||||
|
}
|
||||||
|
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
dp.emit();
|
dp.emit();
|
||||||
auto now = std::chrono::system_clock::now();
|
auto now = std::chrono::system_clock::now();
|
||||||
|
@ -13,21 +33,115 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::modules::Clock::update() -> void {
|
auto waybar::modules::Clock::update() -> void {
|
||||||
tzset(); // Update timezone information
|
if (!fixed_time_zone_) {
|
||||||
|
// Time zone can change. Be sure to pick that.
|
||||||
|
time_zone_ = date::current_zone();
|
||||||
|
}
|
||||||
auto now = std::chrono::system_clock::now();
|
auto now = std::chrono::system_clock::now();
|
||||||
auto localtime = fmt::localtime(std::chrono::system_clock::to_time_t(now));
|
waybar_time wtime = {locale_,
|
||||||
auto text = fmt::format(format_, localtime);
|
date::make_zoned(time_zone_, date::floor<std::chrono::seconds>(now))};
|
||||||
|
|
||||||
|
auto text = fmt::format(format_, wtime);
|
||||||
label_.set_markup(text);
|
label_.set_markup(text);
|
||||||
|
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
if (config_["tooltip-format"].isString()) {
|
if (config_["tooltip-format"].isString()) {
|
||||||
|
const auto calendar = calendar_text(wtime);
|
||||||
auto tooltip_format = config_["tooltip-format"].asString();
|
auto tooltip_format = config_["tooltip-format"].asString();
|
||||||
auto tooltip_text = fmt::format(tooltip_format, localtime);
|
auto tooltip_text = fmt::format(tooltip_format, wtime, fmt::arg("calendar", calendar));
|
||||||
label_.set_tooltip_text(tooltip_text);
|
label_.set_tooltip_markup(tooltip_text);
|
||||||
} else {
|
} else {
|
||||||
label_.set_tooltip_text(text);
|
label_.set_tooltip_markup(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
ALabel::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::string {
|
||||||
|
const auto daypoint = date::floor<date::days>(wtime.ztime.get_local_time());
|
||||||
|
const auto ymd = date::year_month_day(daypoint);
|
||||||
|
if (cached_calendar_ymd_ == ymd) {
|
||||||
|
return cached_calendar_text_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const date::year_month ym(ymd.year(), ymd.month());
|
||||||
|
const auto curr_day = ymd.day();
|
||||||
|
|
||||||
|
std::stringstream os;
|
||||||
|
const auto first_dow = first_day_of_week();
|
||||||
|
weekdays_header(first_dow, os);
|
||||||
|
|
||||||
|
// First week prefixed with spaces if needed.
|
||||||
|
auto wd = date::weekday(ym/1);
|
||||||
|
auto empty_days = (wd - first_dow).count();
|
||||||
|
if (empty_days > 0) {
|
||||||
|
os << std::string(empty_days * 3 - 1, ' ');
|
||||||
|
}
|
||||||
|
auto last_day = (ym/date::literals::last).day();
|
||||||
|
for (auto d = date::day(1); d <= last_day; ++d, ++wd) {
|
||||||
|
if (wd != first_dow) {
|
||||||
|
os << ' ';
|
||||||
|
} else if (unsigned(d) != 1) {
|
||||||
|
os << '\n';
|
||||||
|
}
|
||||||
|
if (d == curr_day) {
|
||||||
|
os << "<b><u>" << date::format("%e", d) << "</u></b>";
|
||||||
|
} else {
|
||||||
|
os << date::format("%e", d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = os.str();
|
||||||
|
cached_calendar_ymd_ = ymd;
|
||||||
|
cached_calendar_text_ = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto waybar::modules::Clock::weekdays_header(const date::weekday& first_dow, std::ostream& os) -> void {
|
||||||
|
auto wd = first_dow;
|
||||||
|
do {
|
||||||
|
if (wd != first_dow) os << ' ';
|
||||||
|
Glib::ustring wd_ustring(date::format(locale_, "%a", wd));
|
||||||
|
auto wd_len = wd_ustring.length();
|
||||||
|
if (wd_len > 2) {
|
||||||
|
wd_ustring = wd_ustring.substr(0, 2);
|
||||||
|
wd_len = 2;
|
||||||
|
}
|
||||||
|
const std::string pad(2 - wd_len, ' ');
|
||||||
|
os << pad << wd_ustring;
|
||||||
|
} while (++wd != first_dow);
|
||||||
|
os << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LANGINFO_1STDAY
|
||||||
|
template <auto fn>
|
||||||
|
using deleter_from_fn = std::integral_constant<decltype(fn), fn>;
|
||||||
|
|
||||||
|
template <typename T, auto fn>
|
||||||
|
using deleting_unique_ptr = std::unique_ptr<T, deleter_from_fn<fn>>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Computations done similarly to Linux cal utility.
|
||||||
|
auto waybar::modules::Clock::first_day_of_week() -> date::weekday {
|
||||||
|
#ifdef HAVE_LANGINFO_1STDAY
|
||||||
|
deleting_unique_ptr<std::remove_pointer<locale_t>::type, freelocale>
|
||||||
|
posix_locale{newlocale(LC_ALL, locale_.name().c_str(), nullptr)};
|
||||||
|
if (posix_locale) {
|
||||||
|
const int i = (std::intptr_t) nl_langinfo_l(_NL_TIME_WEEK_1STDAY, posix_locale.get());
|
||||||
|
auto ymd = date::year(i / 10000)/(i / 100 % 100)/(i % 100);
|
||||||
|
auto wd = date::weekday(ymd);
|
||||||
|
uint8_t j = *nl_langinfo_l(_NL_TIME_FIRST_WEEKDAY, posix_locale.get());
|
||||||
|
return wd + date::days(j - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return date::Sunday;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct fmt::formatter<waybar_time> : fmt::formatter<std::tm> {
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const waybar_time& t, FormatContext& ctx) {
|
||||||
|
return format_to(ctx.out(), "{}", date::format(t.locale, fmt::to_string(tm_format), t.ztime));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -49,20 +49,25 @@ void waybar::modules::Custom::continuousWorker() {
|
||||||
thread_ = [&] {
|
thread_ = [&] {
|
||||||
char* buff = nullptr;
|
char* buff = nullptr;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
bool restart = false;
|
||||||
if (getline(&buff, &len, fp_) == -1) {
|
if (getline(&buff, &len, fp_) == -1) {
|
||||||
int exit_code = 1;
|
int exit_code = 1;
|
||||||
if (fp_) {
|
if (fp_) {
|
||||||
exit_code = WEXITSTATUS(util::command::close(fp_, pid_));
|
exit_code = WEXITSTATUS(util::command::close(fp_, pid_));
|
||||||
fp_ = nullptr;
|
fp_ = nullptr;
|
||||||
}
|
}
|
||||||
thread_.stop();
|
|
||||||
if (exit_code != 0) {
|
if (exit_code != 0) {
|
||||||
output_ = {exit_code, ""};
|
output_ = {exit_code, ""};
|
||||||
dp.emit();
|
dp.emit();
|
||||||
spdlog::error("{} stopped unexpectedly, is it endless?", name_);
|
spdlog::error("{} stopped unexpectedly, is it endless?", name_);
|
||||||
}
|
}
|
||||||
|
if (config_["restart-interval"].isUInt()) {
|
||||||
|
restart = true;
|
||||||
|
} else {
|
||||||
|
thread_.stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
std::string output = buff;
|
std::string output = buff;
|
||||||
|
|
||||||
// Remove last newline
|
// Remove last newline
|
||||||
|
@ -71,6 +76,14 @@ void waybar::modules::Custom::continuousWorker() {
|
||||||
}
|
}
|
||||||
output_ = {0, output};
|
output_ = {0, output};
|
||||||
dp.emit();
|
dp.emit();
|
||||||
|
if (restart) {
|
||||||
|
pid_ = -1;
|
||||||
|
fp_ = util::command::open(cmd, pid_);
|
||||||
|
if (!fp_) {
|
||||||
|
throw std::runtime_error("Unable to open " + cmd);
|
||||||
|
}
|
||||||
|
thread_.sleep_for(std::chrono::seconds(config_["restart-interval"].asUInt()));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,23 @@ waybar::modules::Memory::Memory(const std::string& id, const Json::Value& config
|
||||||
|
|
||||||
auto waybar::modules::Memory::update() -> void {
|
auto waybar::modules::Memory::update() -> void {
|
||||||
parseMeminfo();
|
parseMeminfo();
|
||||||
if (memtotal_ > 0 && memfree_ >= 0) {
|
|
||||||
auto total_ram_gigabytes = memtotal_ / std::pow(1024, 2);
|
unsigned long memtotal = meminfo_["MemTotal"];
|
||||||
int used_ram_percentage = 100 * (memtotal_ - memfree_) / memtotal_;
|
unsigned long memfree;
|
||||||
auto used_ram_gigabytes = (memtotal_ - memfree_) / std::pow(1024, 2);
|
if (meminfo_.count("MemAvailable")) {
|
||||||
auto available_ram_gigabytes = memfree_ / std::pow(1024, 2);
|
// New kernels (3.4+) have an accurate available memory field.
|
||||||
|
memfree = meminfo_["MemAvailable"];
|
||||||
|
} else {
|
||||||
|
// Old kernel; give a best-effort approximation of available memory.
|
||||||
|
memfree = meminfo_["MemFree"] + meminfo_["Buffers"] + meminfo_["Cached"] +
|
||||||
|
meminfo_["SReclaimable"] - meminfo_["Shmem"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memtotal > 0 && memfree >= 0) {
|
||||||
|
auto total_ram_gigabytes = memtotal / std::pow(1024, 2);
|
||||||
|
int used_ram_percentage = 100 * (memtotal - memfree) / memtotal;
|
||||||
|
auto used_ram_gigabytes = (memtotal - memfree) / std::pow(1024, 2);
|
||||||
|
auto available_ram_gigabytes = memfree / std::pow(1024, 2);
|
||||||
|
|
||||||
getState(used_ram_percentage);
|
getState(used_ram_percentage);
|
||||||
label_.set_markup(fmt::format(format_,
|
label_.set_markup(fmt::format(format_,
|
||||||
|
@ -35,7 +47,6 @@ auto waybar::modules::Memory::update() -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Memory::parseMeminfo() {
|
void waybar::modules::Memory::parseMeminfo() {
|
||||||
int64_t memfree = -1, membuffer = -1, memcache = -1, memavail = -1;
|
|
||||||
std::ifstream info(data_dir_);
|
std::ifstream info(data_dir_);
|
||||||
if (!info.is_open()) {
|
if (!info.is_open()) {
|
||||||
throw std::runtime_error("Can't open " + data_dir_);
|
throw std::runtime_error("Can't open " + data_dir_);
|
||||||
|
@ -46,23 +57,9 @@ void waybar::modules::Memory::parseMeminfo() {
|
||||||
if (posDelim == std::string::npos) {
|
if (posDelim == std::string::npos) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name = line.substr(0, posDelim);
|
std::string name = line.substr(0, posDelim);
|
||||||
int64_t value = std::stol(line.substr(posDelim + 1));
|
int64_t value = std::stol(line.substr(posDelim + 1));
|
||||||
|
meminfo_[name] = value;
|
||||||
if (name.compare("MemTotal") == 0) {
|
|
||||||
memtotal_ = value;
|
|
||||||
} else if (name.compare("MemAvailable") == 0) {
|
|
||||||
memavail = value;
|
|
||||||
} else if (name.compare("MemFree") == 0) {
|
|
||||||
memfree = value;
|
|
||||||
} else if (name.compare("Buffers") == 0) {
|
|
||||||
membuffer = value;
|
|
||||||
} else if (name.compare("Cached") == 0) {
|
|
||||||
memcache = value;
|
|
||||||
}
|
}
|
||||||
if (memtotal_ > 0 && (memavail >= 0 || (memfree > -1 && membuffer > -1 && memcache > -1))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memfree_ = memavail >= 0 ? memavail : memfree + membuffer + memcache;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,9 @@ void waybar::modules::MPD::setLabel() {
|
||||||
if (playing()) {
|
if (playing()) {
|
||||||
label_.get_style_context()->add_class("playing");
|
label_.get_style_context()->add_class("playing");
|
||||||
label_.get_style_context()->remove_class("paused");
|
label_.get_style_context()->remove_class("paused");
|
||||||
} else {
|
} else if (paused()) {
|
||||||
|
format =
|
||||||
|
config_["format-paused"].isString() ? config_["format-paused"].asString() : config_["format"].asString();
|
||||||
label_.get_style_context()->add_class("paused");
|
label_.get_style_context()->add_class("paused");
|
||||||
label_.get_style_context()->remove_class("playing");
|
label_.get_style_context()->remove_class("playing");
|
||||||
}
|
}
|
||||||
|
@ -349,3 +351,5 @@ bool waybar::modules::MPD::stopped() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waybar::modules::MPD::playing() { return connection_ != nullptr && state_ == MPD_STATE_PLAY; }
|
bool waybar::modules::MPD::playing() { return connection_ != nullptr && state_ == MPD_STATE_PLAY; }
|
||||||
|
|
||||||
|
bool waybar::modules::MPD::paused() { return connection_ != nullptr && state_ == MPD_STATE_PAUSE; }
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <cassert>
|
||||||
#include "util/format.hpp"
|
#include "util/format.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,8 +279,13 @@ auto waybar::modules::Network::update() -> void {
|
||||||
fmt::arg("bandwidthUpBits", pow_format(bandwidth_up * 8ull / interval_.count(), "b/s")),
|
fmt::arg("bandwidthUpBits", pow_format(bandwidth_up * 8ull / interval_.count(), "b/s")),
|
||||||
fmt::arg("bandwidthDownOctets", pow_format(bandwidth_down / interval_.count(), "o/s")),
|
fmt::arg("bandwidthDownOctets", pow_format(bandwidth_down / interval_.count(), "o/s")),
|
||||||
fmt::arg("bandwidthUpOctets", pow_format(bandwidth_up / interval_.count(), "o/s")));
|
fmt::arg("bandwidthUpOctets", pow_format(bandwidth_up / interval_.count(), "o/s")));
|
||||||
if (text != label_.get_label()) {
|
if (text.compare(label_.get_label()) != 0) {
|
||||||
label_.set_markup(text);
|
label_.set_markup(text);
|
||||||
|
if (text.empty()) {
|
||||||
|
event_box_.hide();
|
||||||
|
} else {
|
||||||
|
event_box_.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
if (tooltip_format.empty() && config_["tooltip-format"].isString()) {
|
if (tooltip_format.empty() && config_["tooltip-format"].isString()) {
|
||||||
|
@ -437,7 +443,6 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Network::getInterfaceAddress() {
|
void waybar::modules::Network::getInterfaceAddress() {
|
||||||
unsigned int cidrRaw;
|
|
||||||
struct ifaddrs *ifaddr, *ifa;
|
struct ifaddrs *ifaddr, *ifa;
|
||||||
cidr_ = 0;
|
cidr_ = 0;
|
||||||
int success = getifaddrs(&ifaddr);
|
int success = getifaddrs(&ifaddr);
|
||||||
|
@ -449,19 +454,35 @@ void waybar::modules::Network::getInterfaceAddress() {
|
||||||
if (ifa->ifa_addr != nullptr && ifa->ifa_addr->sa_family == family_ &&
|
if (ifa->ifa_addr != nullptr && ifa->ifa_addr->sa_family == family_ &&
|
||||||
ifa->ifa_name == ifname_) {
|
ifa->ifa_name == ifname_) {
|
||||||
char ipaddr[INET6_ADDRSTRLEN];
|
char ipaddr[INET6_ADDRSTRLEN];
|
||||||
ipaddr_ = inet_ntop(family_,
|
char netmask[INET6_ADDRSTRLEN];
|
||||||
|
unsigned int cidr = 0;
|
||||||
|
if (family_ == AF_INET) {
|
||||||
|
ipaddr_ = inet_ntop(AF_INET,
|
||||||
&reinterpret_cast<struct sockaddr_in *>(ifa->ifa_addr)->sin_addr,
|
&reinterpret_cast<struct sockaddr_in *>(ifa->ifa_addr)->sin_addr,
|
||||||
ipaddr,
|
ipaddr,
|
||||||
INET6_ADDRSTRLEN);
|
INET_ADDRSTRLEN);
|
||||||
char netmask[INET6_ADDRSTRLEN];
|
|
||||||
auto net_addr = reinterpret_cast<struct sockaddr_in *>(ifa->ifa_netmask);
|
auto net_addr = reinterpret_cast<struct sockaddr_in *>(ifa->ifa_netmask);
|
||||||
netmask_ = inet_ntop(family_, &net_addr->sin_addr, netmask, INET6_ADDRSTRLEN);
|
netmask_ = inet_ntop(AF_INET, &net_addr->sin_addr, netmask, INET_ADDRSTRLEN);
|
||||||
cidrRaw = net_addr->sin_addr.s_addr;
|
unsigned int cidrRaw = net_addr->sin_addr.s_addr;
|
||||||
unsigned int cidr = 0;
|
|
||||||
while (cidrRaw) {
|
while (cidrRaw) {
|
||||||
cidr += cidrRaw & 1;
|
cidr += cidrRaw & 1;
|
||||||
cidrRaw >>= 1;
|
cidrRaw >>= 1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ipaddr_ = inet_ntop(AF_INET6,
|
||||||
|
&reinterpret_cast<struct sockaddr_in6 *>(ifa->ifa_addr)->sin6_addr,
|
||||||
|
ipaddr,
|
||||||
|
INET6_ADDRSTRLEN);
|
||||||
|
auto net_addr = reinterpret_cast<struct sockaddr_in6 *>(ifa->ifa_netmask);
|
||||||
|
netmask_ = inet_ntop(AF_INET6, &net_addr->sin6_addr, netmask, INET6_ADDRSTRLEN);
|
||||||
|
for (size_t i = 0; i < sizeof(net_addr->sin6_addr.s6_addr); ++i) {
|
||||||
|
unsigned char cidrRaw = net_addr->sin6_addr.s6_addr[i];
|
||||||
|
while (cidrRaw) {
|
||||||
|
cidr += cidrRaw & 1;
|
||||||
|
cidrRaw >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
cidr_ = cidr;
|
cidr_ = cidr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value
|
||||||
if (context_ == nullptr) {
|
if (context_ == nullptr) {
|
||||||
throw std::runtime_error("pa_context_new() failed.");
|
throw std::runtime_error("pa_context_new() failed.");
|
||||||
}
|
}
|
||||||
if (pa_context_connect(context_, nullptr, PA_CONTEXT_NOAUTOSPAWN, nullptr) < 0) {
|
if (pa_context_connect(context_, nullptr, PA_CONTEXT_NOFAIL, nullptr) < 0) {
|
||||||
auto err =
|
auto err =
|
||||||
fmt::format("pa_context_connect() failed: {}", pa_strerror(pa_context_errno(context_)));
|
fmt::format("pa_context_connect() failed: {}", pa_strerror(pa_context_errno(context_)));
|
||||||
throw std::runtime_error(err);
|
throw std::runtime_error(err);
|
||||||
|
@ -52,7 +52,8 @@ void waybar::modules::Pulseaudio::contextStateCb(pa_context *c, void *data) {
|
||||||
pa_context_set_subscribe_callback(c, subscribeCb, data);
|
pa_context_set_subscribe_callback(c, subscribeCb, data);
|
||||||
pa_context_subscribe(
|
pa_context_subscribe(
|
||||||
c,
|
c,
|
||||||
static_cast<enum pa_subscription_mask>(static_cast<int>(PA_SUBSCRIPTION_MASK_SINK) |
|
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_SOURCE)),
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
@ -109,7 +110,9 @@ void waybar::modules::Pulseaudio::subscribeCb(pa_context * conte
|
||||||
if (operation != PA_SUBSCRIPTION_EVENT_CHANGE) {
|
if (operation != PA_SUBSCRIPTION_EVENT_CHANGE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (facility == PA_SUBSCRIPTION_EVENT_SINK) {
|
if (facility == PA_SUBSCRIPTION_EVENT_SERVER) {
|
||||||
|
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);
|
pa_context_get_sink_info_by_index(context, idx, sinkInfoCb, data);
|
||||||
} else if (facility == PA_SUBSCRIPTION_EVENT_SOURCE) {
|
} else if (facility == PA_SUBSCRIPTION_EVENT_SOURCE) {
|
||||||
pa_context_get_source_info_by_index(context, idx, sourceInfoCb, data);
|
pa_context_get_source_info_by_index(context, idx, sourceInfoCb, data);
|
||||||
|
@ -131,15 +134,15 @@ void waybar::modules::Pulseaudio::volumeModifyCb(pa_context *c, int success, voi
|
||||||
*/
|
*/
|
||||||
void waybar::modules::Pulseaudio::sourceInfoCb(pa_context * /*context*/, const pa_source_info *i,
|
void waybar::modules::Pulseaudio::sourceInfoCb(pa_context * /*context*/, const pa_source_info *i,
|
||||||
int /*eol*/, void *data) {
|
int /*eol*/, void *data) {
|
||||||
if (i != nullptr) {
|
auto pa = static_cast<waybar::modules::Pulseaudio *>(data);
|
||||||
auto self = static_cast<waybar::modules::Pulseaudio *>(data);
|
if (i != nullptr && pa->default_source_name_ == i->name) {
|
||||||
auto source_volume = static_cast<float>(pa_cvolume_avg(&(i->volume))) / float{PA_VOLUME_NORM};
|
auto source_volume = static_cast<float>(pa_cvolume_avg(&(i->volume))) / float{PA_VOLUME_NORM};
|
||||||
self->source_volume_ = std::round(source_volume * 100.0F);
|
pa->source_volume_ = std::round(source_volume * 100.0F);
|
||||||
self->source_idx_ = i->index;
|
pa->source_idx_ = i->index;
|
||||||
self->source_muted_ = i->mute != 0;
|
pa->source_muted_ = i->mute != 0;
|
||||||
self->source_desc_ = i->description;
|
pa->source_desc_ = i->description;
|
||||||
self->source_port_name_ = i->active_port != nullptr ? i->active_port->name : "Unknown";
|
pa->source_port_name_ = i->active_port != nullptr ? i->active_port->name : "Unknown";
|
||||||
self->dp.emit();
|
pa->dp.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,9 +150,9 @@ void waybar::modules::Pulseaudio::sourceInfoCb(pa_context * /*context*/, const p
|
||||||
* Called when the requested sink information is ready.
|
* Called when the requested sink information is ready.
|
||||||
*/
|
*/
|
||||||
void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i,
|
void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i,
|
||||||
int /*eol*/, void * data) {
|
int /*eol*/, void *data) {
|
||||||
if (i != nullptr) {
|
|
||||||
auto pa = static_cast<waybar::modules::Pulseaudio *>(data);
|
auto pa = static_cast<waybar::modules::Pulseaudio *>(data);
|
||||||
|
if (i != nullptr && pa->default_sink_name_ == i->name) {
|
||||||
pa->pa_volume_ = i->volume;
|
pa->pa_volume_ = i->volume;
|
||||||
float volume = static_cast<float>(pa_cvolume_avg(&(pa->pa_volume_))) / float{PA_VOLUME_NORM};
|
float volume = static_cast<float>(pa_cvolume_avg(&(pa->pa_volume_))) / float{PA_VOLUME_NORM};
|
||||||
pa->sink_idx_ = i->index;
|
pa->sink_idx_ = i->index;
|
||||||
|
@ -158,6 +161,9 @@ void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, const pa_
|
||||||
pa->desc_ = i->description;
|
pa->desc_ = i->description;
|
||||||
pa->monitor_ = i->monitor_source_name;
|
pa->monitor_ = i->monitor_source_name;
|
||||||
pa->port_name_ = i->active_port != nullptr ? i->active_port->name : "Unknown";
|
pa->port_name_ = i->active_port != nullptr ? i->active_port->name : "Unknown";
|
||||||
|
if (auto ff = pa_proplist_gets(i->proplist, PA_PROP_DEVICE_FORM_FACTOR)) {
|
||||||
|
pa->form_factor_ = ff;
|
||||||
|
}
|
||||||
pa->dp.emit();
|
pa->dp.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,16 +174,20 @@ void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, const pa_
|
||||||
*/
|
*/
|
||||||
void waybar::modules::Pulseaudio::serverInfoCb(pa_context *context, const pa_server_info *i,
|
void waybar::modules::Pulseaudio::serverInfoCb(pa_context *context, const pa_server_info *i,
|
||||||
void *data) {
|
void *data) {
|
||||||
|
auto pa = static_cast<waybar::modules::Pulseaudio *>(data);
|
||||||
|
pa->default_sink_name_ = i->default_sink_name;
|
||||||
|
pa->default_source_name_ = i->default_source_name;
|
||||||
|
|
||||||
pa_context_get_sink_info_by_name(context, i->default_sink_name, sinkInfoCb, data);
|
pa_context_get_sink_info_by_name(context, i->default_sink_name, sinkInfoCb, data);
|
||||||
pa_context_get_source_info_by_name(context, i->default_source_name, sourceInfoCb, data);
|
pa_context_get_source_info_by_name(context, i->default_source_name, sourceInfoCb, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::array<std::string, 9> ports = {
|
static const std::array<std::string, 9> ports = {
|
||||||
"headphones",
|
"headphone",
|
||||||
"speaker",
|
"speaker",
|
||||||
"hdmi",
|
"hdmi",
|
||||||
"headset",
|
"headset",
|
||||||
"handsfree",
|
"hands-free",
|
||||||
"portable",
|
"portable",
|
||||||
"car",
|
"car",
|
||||||
"hifi",
|
"hifi",
|
||||||
|
@ -185,7 +195,7 @@ static const std::array<std::string, 9> ports = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string waybar::modules::Pulseaudio::getPortIcon() const {
|
const std::string waybar::modules::Pulseaudio::getPortIcon() const {
|
||||||
std::string nameLC = port_name_;
|
std::string nameLC = port_name_ + form_factor_;
|
||||||
std::transform(nameLC.begin(), nameLC.end(), nameLC.begin(), ::tolower);
|
std::transform(nameLC.begin(), nameLC.end(), nameLC.begin(), ::tolower);
|
||||||
for (auto const &port : ports) {
|
for (auto const &port : ports) {
|
||||||
if (nameLC.find(port) != std::string::npos) {
|
if (nameLC.find(port) != std::string::npos) {
|
||||||
|
@ -197,6 +207,7 @@ const std::string waybar::modules::Pulseaudio::getPortIcon() const {
|
||||||
|
|
||||||
auto waybar::modules::Pulseaudio::update() -> void {
|
auto waybar::modules::Pulseaudio::update() -> void {
|
||||||
auto format = format_;
|
auto format = format_;
|
||||||
|
if (!alt_) {
|
||||||
std::string format_name = "format";
|
std::string format_name = "format";
|
||||||
if (monitor_.find("a2dp_sink") != std::string::npos) {
|
if (monitor_.find("a2dp_sink") != std::string::npos) {
|
||||||
format_name = format_name + "-bluetooth";
|
format_name = format_name + "-bluetooth";
|
||||||
|
@ -204,7 +215,11 @@ auto waybar::modules::Pulseaudio::update() -> void {
|
||||||
} else {
|
} else {
|
||||||
label_.get_style_context()->remove_class("bluetooth");
|
label_.get_style_context()->remove_class("bluetooth");
|
||||||
}
|
}
|
||||||
if (muted_ ) {
|
if (muted_) {
|
||||||
|
// Check muted bluetooth format exist, otherwise fallback to default muted format
|
||||||
|
if (format_name != "format" && !config_[format_name + "-muted"].isString()) {
|
||||||
|
format_name = "format";
|
||||||
|
}
|
||||||
format_name = format_name + "-muted";
|
format_name = format_name + "-muted";
|
||||||
label_.get_style_context()->add_class("muted");
|
label_.get_style_context()->add_class("muted");
|
||||||
} else {
|
} else {
|
||||||
|
@ -212,6 +227,7 @@ auto waybar::modules::Pulseaudio::update() -> void {
|
||||||
}
|
}
|
||||||
format =
|
format =
|
||||||
config_[format_name].isString() ? config_[format_name].asString() : format;
|
config_[format_name].isString() ? config_[format_name].asString() : format;
|
||||||
|
}
|
||||||
// TODO: find a better way to split source/sink
|
// TODO: find a better way to split source/sink
|
||||||
std::string format_source = "{volume}%";
|
std::string format_source = "{volume}%";
|
||||||
if (source_muted_ && config_["format-source-muted"].isString()) {
|
if (source_muted_ && config_["format-source-muted"].isString()) {
|
||||||
|
|
|
@ -265,7 +265,11 @@ void Item::updateImage() {
|
||||||
if (pixbuf->gobj() != nullptr) {
|
if (pixbuf->gobj() != nullptr) {
|
||||||
// An icon specified by path and filename may be the wrong size for
|
// An icon specified by path and filename may be the wrong size for
|
||||||
// the tray
|
// the tray
|
||||||
pixbuf = pixbuf->scale_simple(icon_size, icon_size, Gdk::InterpType::INTERP_BILINEAR);
|
// Keep the aspect ratio and scale to make the height equal to icon_size
|
||||||
|
// If people have non square icons, assume they want it to grow in width not height
|
||||||
|
int width = icon_size * pixbuf->get_width() / pixbuf->get_height();
|
||||||
|
|
||||||
|
pixbuf = pixbuf->scale_simple(width, icon_size, Gdk::InterpType::INTERP_BILINEAR);
|
||||||
image.set(pixbuf);
|
image.set(pixbuf);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace waybar::modules::SNI {
|
||||||
Tray::Tray(const std::string& id, const Bar& bar, const Json::Value& config)
|
Tray::Tray(const std::string& id, const Bar& bar, const Json::Value& config)
|
||||||
: AModule(config, "tray", id),
|
: AModule(config, "tray", id),
|
||||||
box_(bar.vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0),
|
box_(bar.vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||||
watcher_(nb_hosts_),
|
watcher_(SNI::Watcher::getInstance()),
|
||||||
host_(nb_hosts_, config, std::bind(&Tray::onAdd, this, std::placeholders::_1),
|
host_(nb_hosts_, config, std::bind(&Tray::onAdd, this, std::placeholders::_1),
|
||||||
std::bind(&Tray::onRemove, this, std::placeholders::_1)) {
|
std::bind(&Tray::onRemove, this, std::placeholders::_1)) {
|
||||||
spdlog::warn(
|
spdlog::warn(
|
||||||
|
|
|
@ -3,14 +3,13 @@
|
||||||
|
|
||||||
using namespace waybar::modules::SNI;
|
using namespace waybar::modules::SNI;
|
||||||
|
|
||||||
Watcher::Watcher(std::size_t id)
|
Watcher::Watcher()
|
||||||
: bus_name_id_(Gio::DBus::own_name(Gio::DBus::BusType::BUS_TYPE_SESSION,
|
: bus_name_id_(Gio::DBus::own_name(Gio::DBus::BusType::BUS_TYPE_SESSION,
|
||||||
"org.kde.StatusNotifierWatcher",
|
"org.kde.StatusNotifierWatcher",
|
||||||
sigc::mem_fun(*this, &Watcher::busAcquired),
|
sigc::mem_fun(*this, &Watcher::busAcquired),
|
||||||
Gio::DBus::SlotNameAcquired(), Gio::DBus::SlotNameLost(),
|
Gio::DBus::SlotNameAcquired(), Gio::DBus::SlotNameLost(),
|
||||||
Gio::DBus::BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
|
Gio::DBus::BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
|
||||||
Gio::DBus::BUS_NAME_OWNER_FLAGS_REPLACE)),
|
Gio::DBus::BUS_NAME_OWNER_FLAGS_REPLACE)),
|
||||||
watcher_id_(id),
|
|
||||||
watcher_(sn_watcher_skeleton_new()) {}
|
watcher_(sn_watcher_skeleton_new()) {}
|
||||||
|
|
||||||
Watcher::~Watcher() {
|
Watcher::~Watcher() {
|
||||||
|
@ -23,6 +22,7 @@ Watcher::~Watcher() {
|
||||||
g_slist_free_full(items_, gfWatchFree);
|
g_slist_free_full(items_, gfWatchFree);
|
||||||
items_ = nullptr;
|
items_ = nullptr;
|
||||||
}
|
}
|
||||||
|
Gio::DBus::unown_name(bus_name_id_);
|
||||||
auto iface = G_DBUS_INTERFACE_SKELETON(watcher_);
|
auto iface = G_DBUS_INTERFACE_SKELETON(watcher_);
|
||||||
g_dbus_interface_skeleton_unexport(iface);
|
g_dbus_interface_skeleton_unexport(iface);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ void Watcher::busAcquired(const Glib::RefPtr<Gio::DBus::Connection>& conn, Glib:
|
||||||
if (error != nullptr) {
|
if (error != nullptr) {
|
||||||
// Don't print an error when a watcher is already present
|
// Don't print an error when a watcher is already present
|
||||||
if (error->code != 2) {
|
if (error->code != 2) {
|
||||||
spdlog::error("Watcher {}: {}", watcher_id_, error->message);
|
spdlog::error("Watcher: {}", error->message);
|
||||||
}
|
}
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -10,19 +10,23 @@ Ipc::Ipc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ipc::~Ipc() {
|
Ipc::~Ipc() {
|
||||||
|
thread_.stop();
|
||||||
|
|
||||||
|
if (fd_ > 0) {
|
||||||
// To fail the IPC header
|
// To fail the IPC header
|
||||||
write(fd_, "close-sway-ipc", 14);
|
write(fd_, "close-sway-ipc", 14);
|
||||||
write(fd_event_, "close-sway-ipc", 14);
|
|
||||||
if (fd_ > 0) {
|
|
||||||
close(fd_);
|
close(fd_);
|
||||||
fd_ = -1;
|
fd_ = -1;
|
||||||
}
|
}
|
||||||
if (fd_event_ > 0) {
|
if (fd_event_ > 0) {
|
||||||
|
write(fd_event_, "close-sway-ipc", 14);
|
||||||
close(fd_event_);
|
close(fd_event_);
|
||||||
fd_event_ = -1;
|
fd_event_ = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ipc::setWorker(std::function<void()>&& func) { thread_ = func; }
|
||||||
|
|
||||||
const std::string Ipc::getSocketPath() const {
|
const std::string Ipc::getSocketPath() const {
|
||||||
const char* env = getenv("SWAYSOCK");
|
const char* env = getenv("SWAYSOCK");
|
||||||
if (env != nullptr) {
|
if (env != nullptr) {
|
||||||
|
|
|
@ -8,7 +8,13 @@ Mode::Mode(const std::string& id, const Json::Value& config)
|
||||||
ipc_.subscribe(R"(["mode"])");
|
ipc_.subscribe(R"(["mode"])");
|
||||||
ipc_.signal_event.connect(sigc::mem_fun(*this, &Mode::onEvent));
|
ipc_.signal_event.connect(sigc::mem_fun(*this, &Mode::onEvent));
|
||||||
// Launch worker
|
// Launch worker
|
||||||
worker();
|
ipc_.setWorker([this] {
|
||||||
|
try {
|
||||||
|
ipc_.handleEvent();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::error("Mode: {}", e.what());
|
||||||
|
}
|
||||||
|
});
|
||||||
dp.emit();
|
dp.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,16 +37,6 @@ void Mode::onEvent(const struct Ipc::ipc_response& res) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mode::worker() {
|
|
||||||
thread_ = [this] {
|
|
||||||
try {
|
|
||||||
ipc_.handleEvent();
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
spdlog::error("Mode: {}", e.what());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Mode::update() -> void {
|
auto Mode::update() -> void {
|
||||||
if (mode_.empty()) {
|
if (mode_.empty()) {
|
||||||
event_box_.hide();
|
event_box_.hide();
|
||||||
|
|
|
@ -11,7 +11,13 @@ Window::Window(const std::string& id, const Bar& bar, const Json::Value& config)
|
||||||
// Get Initial focused window
|
// Get Initial focused window
|
||||||
getTree();
|
getTree();
|
||||||
// Launch worker
|
// Launch worker
|
||||||
worker();
|
ipc_.setWorker([this] {
|
||||||
|
try {
|
||||||
|
ipc_.handleEvent();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::error("Window: {}", e.what());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::onEvent(const struct Ipc::ipc_response& res) { getTree(); }
|
void Window::onEvent(const struct Ipc::ipc_response& res) { getTree(); }
|
||||||
|
@ -28,16 +34,6 @@ void Window::onCmd(const struct Ipc::ipc_response& res) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::worker() {
|
|
||||||
thread_ = [this] {
|
|
||||||
try {
|
|
||||||
ipc_.handleEvent();
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
spdlog::error("Window: {}", e.what());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Window::update() -> void {
|
auto Window::update() -> void {
|
||||||
if (!old_app_id_.empty()) {
|
if (!old_app_id_.empty()) {
|
||||||
bar_.window.get_style_context()->remove_class(old_app_id_);
|
bar_.window.get_style_context()->remove_class(old_app_id_);
|
||||||
|
|
|
@ -22,7 +22,13 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value
|
||||||
window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
||||||
}
|
}
|
||||||
// Launch worker
|
// Launch worker
|
||||||
worker();
|
ipc_.setWorker([this] {
|
||||||
|
try {
|
||||||
|
ipc_.handleEvent();
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
spdlog::error("Workspaces: {}", e.what());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspaces::onEvent(const struct Ipc::ipc_response &res) {
|
void Workspaces::onEvent(const struct Ipc::ipc_response &res) {
|
||||||
|
@ -102,16 +108,6 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspaces::worker() {
|
|
||||||
thread_ = [this] {
|
|
||||||
try {
|
|
||||||
ipc_.handleEvent();
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
spdlog::error("Workspaces: {}", e.what());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Workspaces::filterButtons() {
|
bool Workspaces::filterButtons() {
|
||||||
bool needReorder = false;
|
bool needReorder = false;
|
||||||
for (auto it = buttons_.begin(); it != buttons_.end();) {
|
for (auto it = buttons_.begin(); it != buttons_.end();) {
|
||||||
|
@ -161,12 +157,13 @@ auto Workspaces::update() -> void {
|
||||||
if (needReorder) {
|
if (needReorder) {
|
||||||
box_.reorder_child(button, it - workspaces_.begin());
|
box_.reorder_child(button, it - workspaces_.begin());
|
||||||
}
|
}
|
||||||
std::string output = getIcon((*it)["name"].asString(), *it);
|
std::string output = (*it)["name"].asString();
|
||||||
if (config_["format"].isString()) {
|
if (config_["format"].isString()) {
|
||||||
auto format = config_["format"].asString();
|
auto format = config_["format"].asString();
|
||||||
output = fmt::format(format,
|
output = fmt::format(format,
|
||||||
fmt::arg("icon", output),
|
fmt::arg("icon", getIcon(output, *it)),
|
||||||
fmt::arg("name", trimWorkspaceName((*it)["name"].asString())),
|
fmt::arg("value", output),
|
||||||
|
fmt::arg("name", trimWorkspaceName(output)),
|
||||||
fmt::arg("index", (*it)["num"].asString()));
|
fmt::arg("index", (*it)["num"].asString()));
|
||||||
}
|
}
|
||||||
if (!config_["disable-markup"].asBool()) {
|
if (!config_["disable-markup"].asBool()) {
|
||||||
|
@ -211,6 +208,8 @@ std::string Workspaces::getIcon(const std::string &name, const Json::Value &node
|
||||||
if (config_["format-icons"][key].isString() && node[key].asBool()) {
|
if (config_["format-icons"][key].isString() && node[key].asBool()) {
|
||||||
return config_["format-icons"][key].asString();
|
return config_["format-icons"][key].asString();
|
||||||
}
|
}
|
||||||
|
} else if (config_["format_icons"]["persistent"].isString() && node["target_output"].isString()) {
|
||||||
|
return config_["format-icons"]["persistent"].asString();
|
||||||
} else if (config_["format-icons"][key].isString()) {
|
} else if (config_["format-icons"][key].isString()) {
|
||||||
return config_["format-icons"][key].asString();
|
return config_["format-icons"][key].asString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#include "modules/temperature.hpp"
|
#include "modules/temperature.hpp"
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
waybar::modules::Temperature::Temperature(const std::string& id, const Json::Value& config)
|
waybar::modules::Temperature::Temperature(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "temperature", id, "{temperatureC}°C", 10) {
|
: ALabel(config, "temperature", id, "{temperatureC}°C", 10) {
|
||||||
if (config_["hwmon-path"].isString()) {
|
if (config_["hwmon-path"].isString()) {
|
||||||
file_path_ = config_["hwmon-path"].asString();
|
file_path_ = config_["hwmon-path"].asString();
|
||||||
|
} else if (config_["hwmon-path-abs"].isString() && config_["input-filename"].isString()) {
|
||||||
|
file_path_ = (*std::filesystem::directory_iterator(config_["hwmon-path-abs"].asString())).path().u8string() + "/" + config_["input-filename"].asString();
|
||||||
} else {
|
} else {
|
||||||
auto zone = config_["thermal-zone"].isInt() ? config_["thermal-zone"].asInt() : 0;
|
auto zone = config_["thermal-zone"].isInt() ? config_["thermal-zone"].asInt() : 0;
|
||||||
file_path_ = fmt::format("/sys/class/thermal/thermal_zone{}/temp", zone);
|
file_path_ = fmt::format("/sys/class/thermal/thermal_zone{}/temp", zone);
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
[wrap-file]
|
||||||
|
source_url=https://github.com/HowardHinnant/date/archive/v2.4.1.tar.gz
|
||||||
|
source_filename=date-2.4.1.tar.gz
|
||||||
|
source_hash=98907d243397483bd7ad889bf6c66746db0d7d2a39cc9aacc041834c40b65b98
|
||||||
|
directory=date-2.4.1
|
||||||
|
|
||||||
|
patch_url = https://github.com/mesonbuild/hinnant-date/releases/download/2.4.1-1/hinnant-date.zip
|
||||||
|
patch_filename = hinnant-date-2.4.1-1-wrap.zip
|
||||||
|
patch_hash = 2061673a6f8e6d63c3a40df4da58fa2b3de2835fd9b3e74649e8279599f3a8f6
|
|
@ -5,6 +5,6 @@ source_url = https://github.com/fmtlib/fmt/archive/5.3.0.tar.gz
|
||||||
source_filename = fmt-5.3.0.tar.gz
|
source_filename = fmt-5.3.0.tar.gz
|
||||||
source_hash = defa24a9af4c622a7134076602070b45721a43c51598c8456ec6f2c4dbb51c89
|
source_hash = defa24a9af4c622a7134076602070b45721a43c51598c8456ec6f2c4dbb51c89
|
||||||
|
|
||||||
patch_url = https://wrapdb.mesonbuild.com/v1/projects/fmt/5.3.0/1/get_zip
|
patch_url = https://github.com/mesonbuild/fmt/releases/download/5.3.0-1/fmt.zip
|
||||||
patch_filename = fmt-5.3.0-1-wrap.zip
|
patch_filename = fmt-5.3.0-1-wrap.zip
|
||||||
patch_hash = 18f21a3b8833949c35d4ac88a7059577d5fa24b98786e4b1b2d3d81bb811440f
|
patch_hash = 18f21a3b8833949c35d4ac88a7059577d5fa24b98786e4b1b2d3d81bb811440f
|
|
@ -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
|
|
@ -5,6 +5,6 @@ source_url = https://github.com/gabime/spdlog/archive/v1.3.1.tar.gz
|
||||||
source_filename = v1.3.1.tar.gz
|
source_filename = v1.3.1.tar.gz
|
||||||
source_hash = 160845266e94db1d4922ef755637f6901266731c4cb3b30b45bf41efa0e6ab70
|
source_hash = 160845266e94db1d4922ef755637f6901266731c4cb3b30b45bf41efa0e6ab70
|
||||||
|
|
||||||
patch_url = https://wrapdb.mesonbuild.com/v1/projects/spdlog/1.3.1/1/get_zip
|
patch_url = https://github.com/mesonbuild/spdlog/releases/download/1.3.1-1/spdlog.zip
|
||||||
patch_filename = spdlog-1.3.1-1-wrap.zip
|
patch_filename = spdlog-1.3.1-1-wrap.zip
|
||||||
patch_hash = 715a0229781019b853d409cc0bf891ee4b9d3a17bec0cf87f4ad30b28bbecc87
|
patch_hash = 715a0229781019b853d409cc0bf891ee4b9d3a17bec0cf87f4ad30b28bbecc87
|
||||||
|
|
Loading…
Reference in New Issue