mirror of
https://github.com/rad4day/Waybar.git
synced 2023-12-21 10:22:59 +01:00
Compare commits
49 Commits
Author | SHA1 | Date | |
---|---|---|---|
7f74de977c | |||
028b184f7b | |||
564fdcb369 | |||
3c9b533997 | |||
ec75be0bc3 | |||
c2e9ed6091 | |||
a37b4687ff | |||
ee29a35aa5 | |||
0be8e200ce | |||
46e5dd93d4 | |||
2ee4a51546 | |||
91996a85c1 | |||
460d25ac45 | |||
648eecdd83 | |||
f04ff38567 | |||
d20a586734 | |||
1962caf144 | |||
9dbf057f58 | |||
918146c16b | |||
0b01b35c76 | |||
f3fb955d75 | |||
fcf2d18a01 | |||
b05d4cd413 | |||
9b89fc6470 | |||
c06725aa69 | |||
5ae5821929 | |||
74e40432e5 | |||
6e69af8967 | |||
be2fa743eb | |||
5fdb122829 | |||
6e73c6db61 | |||
253366baf4 | |||
ecec02c8be | |||
070619fa34 | |||
d4ace4b4d8 | |||
5fd92b3c28 | |||
c0a39f34cd | |||
2a9fa1a4b9 | |||
07147878a9 | |||
ffadd5c1a7 | |||
2b34f3a30f | |||
85d60f95c4 | |||
755d38d4d6 | |||
b673279a43 | |||
9e1200ae32 | |||
e999cca7a6 | |||
d24d85bebf | |||
97bd637f5d | |||
23d4a811db |
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
custom: https://paypal.me/ARouillard
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
> Highly customizable Wayland bar for Sway and Wlroots based compositors.<br>
|
> Highly customizable Wayland bar for Sway and Wlroots based compositors.<br>
|
||||||
> Available in Arch [community](https://www.archlinux.org/packages/community/x86_64/waybar/) or
|
> Available in Arch [community](https://www.archlinux.org/packages/community/x86_64/waybar/) or
|
||||||
[AUR](https://aur.archlinux.org/packages/waybar-git/) and [openSUSE](https://build.opensuse.org/package/show/X11:Wayland/waybar)
|
[AUR](https://aur.archlinux.org/packages/waybar-git/) and [openSUSE](https://build.opensuse.org/package/show/X11:Wayland/waybar)<br>
|
||||||
|
> *Waybar [examples](https://github.com/Alexays/Waybar/wiki/Examples)*
|
||||||
|
|
||||||
**Current features**
|
**Current features**
|
||||||
- Sway (Workspaces, Binding mode, Focused window name)
|
- Sway (Workspaces, Binding mode, Focused window name)
|
||||||
@ -42,6 +43,7 @@ $ waybar
|
|||||||
gtkmm3
|
gtkmm3
|
||||||
jsoncpp
|
jsoncpp
|
||||||
libinput
|
libinput
|
||||||
|
|
||||||
libsigc++
|
libsigc++
|
||||||
fmt
|
fmt
|
||||||
wayland
|
wayland
|
||||||
|
@ -10,7 +10,8 @@ namespace waybar {
|
|||||||
|
|
||||||
class ALabel : public IModule {
|
class ALabel : public IModule {
|
||||||
public:
|
public:
|
||||||
ALabel(const Json::Value &, const std::string &format, uint16_t interval = 0);
|
ALabel(const Json::Value &, const std::string &, const std::string &, const std::string &format,
|
||||||
|
uint16_t interval = 0);
|
||||||
virtual ~ALabel();
|
virtual ~ALabel();
|
||||||
virtual auto update() -> void;
|
virtual auto update() -> void;
|
||||||
virtual std::string getIcon(uint16_t, const std::string &alt = "", uint16_t max = 0);
|
virtual std::string getIcon(uint16_t, const std::string &alt = "", uint16_t max = 0);
|
||||||
|
@ -52,6 +52,8 @@ class Bar {
|
|||||||
|
|
||||||
void destroyOutput();
|
void destroyOutput();
|
||||||
void onConfigure(GdkEventConfigure *ev);
|
void onConfigure(GdkEventConfigure *ev);
|
||||||
|
void onRealize();
|
||||||
|
void onMap(GdkEventAny *ev);
|
||||||
void setMarginsAndZone(uint32_t height, uint32_t width);
|
void setMarginsAndZone(uint32_t height, uint32_t width);
|
||||||
auto setupWidgets() -> void;
|
auto setupWidgets() -> void;
|
||||||
void getModules(const Factory &, const std::string &);
|
void getModules(const Factory &, const std::string &);
|
||||||
@ -66,6 +68,7 @@ class Bar {
|
|||||||
} margins_;
|
} margins_;
|
||||||
uint32_t width_ = 0;
|
uint32_t width_ = 0;
|
||||||
uint32_t height_ = 1;
|
uint32_t height_ = 1;
|
||||||
|
uint8_t anchor_;
|
||||||
Gtk::Box left_;
|
Gtk::Box left_;
|
||||||
Gtk::Box center_;
|
Gtk::Box center_;
|
||||||
Gtk::Box right_;
|
Gtk::Box right_;
|
||||||
|
@ -26,13 +26,14 @@ class Client {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Client() = default;
|
Client() = default;
|
||||||
void setupConfigs(const std::string &config, const std::string &style);
|
std::tuple<const std::string, const std::string> getConfigs(const std::string &config,
|
||||||
|
const std::string &style) const;
|
||||||
void bindInterfaces();
|
void bindInterfaces();
|
||||||
const std::string getValidPath(const std::vector<std::string> &paths);
|
const std::string getValidPath(const std::vector<std::string> &paths) const;
|
||||||
void handleOutput(std::unique_ptr<struct waybar_output> &output);
|
void handleOutput(std::unique_ptr<struct waybar_output> &output);
|
||||||
bool isValidOutput(const Json::Value &config, std::unique_ptr<struct waybar_output> &output);
|
bool isValidOutput(const Json::Value &config, std::unique_ptr<struct waybar_output> &output);
|
||||||
auto setupConfig() -> void;
|
auto setupConfig(const std::string &config_file) -> void;
|
||||||
auto setupCss() -> void;
|
auto setupCss(const std::string &css_file) -> void;
|
||||||
std::unique_ptr<struct waybar_output> &getOutput(uint32_t wl_name);
|
std::unique_ptr<struct waybar_output> &getOutput(uint32_t wl_name);
|
||||||
std::vector<Json::Value> getOutputConfigs(std::unique_ptr<struct waybar_output> &output);
|
std::vector<Json::Value> getOutputConfigs(std::unique_ptr<struct waybar_output> &output);
|
||||||
|
|
||||||
@ -46,8 +47,6 @@ class Client {
|
|||||||
static void handleDescription(void *, struct zxdg_output_v1 *, const char *);
|
static void handleDescription(void *, struct zxdg_output_v1 *, const char *);
|
||||||
|
|
||||||
Json::Value config_;
|
Json::Value config_;
|
||||||
std::string css_file_;
|
|
||||||
std::string config_file_;
|
|
||||||
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::vector<std::unique_ptr<struct waybar_output>> outputs_;
|
||||||
|
@ -47,7 +47,6 @@ class Backlight : public ALabel {
|
|||||||
template <class ForwardIt, class Inserter>
|
template <class ForwardIt, class Inserter>
|
||||||
static void enumerate_devices(ForwardIt first, ForwardIt last, Inserter inserter, udev *udev);
|
static void enumerate_devices(ForwardIt first, ForwardIt last, Inserter inserter, udev *udev);
|
||||||
|
|
||||||
const std::string name_;
|
|
||||||
const std::string preferred_device_;
|
const std::string preferred_device_;
|
||||||
static constexpr int EPOLL_MAX_EVENTS = 16;
|
static constexpr int EPOLL_MAX_EVENTS = 16;
|
||||||
|
|
||||||
@ -57,6 +56,6 @@ class Backlight : public ALabel {
|
|||||||
std::mutex udev_thread_mutex_;
|
std::mutex udev_thread_mutex_;
|
||||||
std::vector<BacklightDev> devices_;
|
std::vector<BacklightDev> devices_;
|
||||||
// thread must destruct before shared data
|
// thread must destruct before shared data
|
||||||
waybar::util::SleeperThread udev_thread_;
|
util::SleeperThread udev_thread_;
|
||||||
};
|
};
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
@ -37,13 +37,14 @@ class Battery : public ALabel {
|
|||||||
const std::tuple<uint8_t, float, std::string> getInfos() const;
|
const std::tuple<uint8_t, float, std::string> getInfos() const;
|
||||||
const std::string formatTimeRemaining(float hoursRemaining);
|
const std::string formatTimeRemaining(float hoursRemaining);
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
|
||||||
util::SleeperThread thread_timer_;
|
|
||||||
std::vector<fs::path> batteries_;
|
std::vector<fs::path> batteries_;
|
||||||
fs::path adapter_;
|
fs::path adapter_;
|
||||||
int fd_;
|
int fd_;
|
||||||
std::vector<int> wds_;
|
std::vector<int> wds_;
|
||||||
std::string old_status_;
|
std::string old_status_;
|
||||||
|
|
||||||
|
util::SleeperThread thread_;
|
||||||
|
util::SleeperThread thread_timer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
@ -14,7 +14,7 @@ class Clock : public ALabel {
|
|||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
waybar::util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include <fstream>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <fstream>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
@ -26,7 +26,8 @@ class Cpu : public ALabel {
|
|||||||
std::vector<std::tuple<size_t, size_t>> parseCpuinfo();
|
std::vector<std::tuple<size_t, size_t>> parseCpuinfo();
|
||||||
|
|
||||||
std::vector<std::tuple<size_t, size_t>> prev_times_;
|
std::vector<std::tuple<size_t, size_t>> prev_times_;
|
||||||
waybar::util::SleeperThread thread_;
|
|
||||||
|
util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
@ -12,7 +12,7 @@ namespace waybar::modules {
|
|||||||
|
|
||||||
class Custom : public ALabel {
|
class Custom : public ALabel {
|
||||||
public:
|
public:
|
||||||
Custom(const std::string&, const Json::Value&);
|
Custom(const std::string&, const std::string&, const Json::Value&);
|
||||||
~Custom();
|
~Custom();
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
void refresh(int /*signal*/);
|
void refresh(int /*signal*/);
|
||||||
@ -31,11 +31,12 @@ class Custom : public ALabel {
|
|||||||
std::string tooltip_;
|
std::string tooltip_;
|
||||||
std::vector<std::string> class_;
|
std::vector<std::string> class_;
|
||||||
int percentage_;
|
int percentage_;
|
||||||
waybar::util::SleeperThread thread_;
|
|
||||||
waybar::util::command::res output_;
|
|
||||||
waybar::util::JsonParser parser_;
|
|
||||||
FILE* fp_;
|
FILE* fp_;
|
||||||
int pid_;
|
int pid_;
|
||||||
|
util::command::res output_;
|
||||||
|
util::JsonParser parser_;
|
||||||
|
|
||||||
|
util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
@ -15,10 +15,12 @@ class Memory : public ALabel {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static inline const std::string data_dir_ = "/proc/meminfo";
|
static inline const std::string data_dir_ = "/proc/meminfo";
|
||||||
|
void parseMeminfo();
|
||||||
|
|
||||||
unsigned long memtotal_;
|
unsigned long memtotal_;
|
||||||
unsigned long memfree_;
|
unsigned long memfree_;
|
||||||
void parseMeminfo();
|
|
||||||
waybar::util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
@ -30,24 +30,23 @@ class Network : public ALabel {
|
|||||||
void worker();
|
void worker();
|
||||||
void createInfoSocket();
|
void createInfoSocket();
|
||||||
void createEventSocket();
|
void createEventSocket();
|
||||||
int getExternalInterface(int skip_idx = -1);
|
int getExternalInterface(int skip_idx = -1) const;
|
||||||
void getInterfaceAddress();
|
void getInterfaceAddress();
|
||||||
int netlinkRequest(void*, uint32_t, uint32_t groups = 0);
|
int netlinkRequest(void*, uint32_t, uint32_t groups = 0) const;
|
||||||
int netlinkResponse(void*, uint32_t, uint32_t groups = 0);
|
int netlinkResponse(void*, uint32_t, uint32_t groups = 0) const;
|
||||||
void parseEssid(struct nlattr**);
|
void parseEssid(struct nlattr**);
|
||||||
void parseSignal(struct nlattr**);
|
void parseSignal(struct nlattr**);
|
||||||
void parseFreq(struct nlattr**);
|
void parseFreq(struct nlattr**);
|
||||||
bool associatedOrJoined(struct nlattr**);
|
bool associatedOrJoined(struct nlattr**);
|
||||||
bool checkInterface(struct ifinfomsg* rtif, std::string name);
|
bool checkInterface(struct ifinfomsg* rtif, std::string name);
|
||||||
int getPreferredIface(int skip_idx = -1);
|
int getPreferredIface(int skip_idx = -1) const;
|
||||||
auto getInfo() -> void;
|
auto getInfo() -> void;
|
||||||
|
void checkNewInterface(struct ifinfomsg* rtif);
|
||||||
|
const std::string getNetworkState() const;
|
||||||
void clearIface();
|
void clearIface();
|
||||||
bool wildcardMatch(const std::string& pattern, const std::string& text);
|
bool wildcardMatch(const std::string& pattern, const std::string& text) const;
|
||||||
|
|
||||||
waybar::util::SleeperThread thread_;
|
|
||||||
waybar::util::SleeperThread thread_timer_;
|
|
||||||
int ifid_;
|
int ifid_;
|
||||||
int last_ext_iface_;
|
|
||||||
sa_family_t family_;
|
sa_family_t family_;
|
||||||
struct sockaddr_nl nladdr_ = {0};
|
struct sockaddr_nl nladdr_ = {0};
|
||||||
struct nl_sock* sock_ = nullptr;
|
struct nl_sock* sock_ = nullptr;
|
||||||
@ -60,15 +59,18 @@ class Network : public ALabel {
|
|||||||
unsigned long long bandwidth_down_total_;
|
unsigned long long bandwidth_down_total_;
|
||||||
unsigned long long bandwidth_up_total_;
|
unsigned long long bandwidth_up_total_;
|
||||||
|
|
||||||
|
std::string state_;
|
||||||
std::string essid_;
|
std::string essid_;
|
||||||
std::string ifname_;
|
std::string ifname_;
|
||||||
std::string ipaddr_;
|
std::string ipaddr_;
|
||||||
std::string netmask_;
|
std::string netmask_;
|
||||||
int cidr_;
|
int cidr_;
|
||||||
bool linked_;
|
|
||||||
int32_t signal_strength_dbm_;
|
int32_t signal_strength_dbm_;
|
||||||
uint8_t signal_strength_;
|
uint8_t signal_strength_;
|
||||||
uint32_t frequency_;
|
uint32_t frequency_;
|
||||||
|
|
||||||
|
util::SleeperThread thread_;
|
||||||
|
util::SleeperThread thread_timer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
#include "modules/sway/ipc/client.hpp"
|
#include "modules/sway/ipc/client.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
@ -20,10 +20,11 @@ class Mode : public ALabel, public sigc::trackable {
|
|||||||
void onEvent(const struct Ipc::ipc_response&);
|
void onEvent(const struct Ipc::ipc_response&);
|
||||||
void worker();
|
void worker();
|
||||||
|
|
||||||
waybar::util::SleeperThread thread_;
|
|
||||||
Ipc ipc_;
|
|
||||||
std::string mode_;
|
std::string mode_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
|
|
||||||
|
util::SleeperThread thread_;
|
||||||
|
Ipc ipc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::sway
|
} // namespace waybar::modules::sway
|
@ -25,13 +25,16 @@ class Window : public ALabel, public sigc::trackable {
|
|||||||
void getTree();
|
void getTree();
|
||||||
|
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
waybar::util::SleeperThread thread_;
|
|
||||||
Ipc ipc_;
|
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
std::string window_;
|
std::string window_;
|
||||||
int windowId_;
|
int windowId_;
|
||||||
std::string app_id_;
|
std::string app_id_;
|
||||||
|
std::string old_app_id_;
|
||||||
|
std::size_t app_nb_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
|
|
||||||
|
util::SleeperThread thread_;
|
||||||
|
Ipc ipc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::sway
|
} // namespace waybar::modules::sway
|
||||||
|
@ -36,13 +36,14 @@ class Workspaces : public IModule, public sigc::trackable {
|
|||||||
const Json::Value& config_;
|
const Json::Value& config_;
|
||||||
std::vector<Json::Value> workspaces_;
|
std::vector<Json::Value> workspaces_;
|
||||||
std::vector<std::string> workspaces_order_;
|
std::vector<std::string> workspaces_order_;
|
||||||
waybar::util::SleeperThread thread_;
|
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
Ipc ipc_;
|
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
bool scrolling_;
|
bool scrolling_;
|
||||||
std::unordered_map<std::string, Gtk::Button> buttons_;
|
std::unordered_map<std::string, Gtk::Button> buttons_;
|
||||||
|
|
||||||
|
util::SleeperThread thread_;
|
||||||
|
Ipc ipc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::sway
|
} // namespace waybar::modules::sway
|
||||||
|
@ -18,7 +18,7 @@ class Temperature : public ALabel {
|
|||||||
bool isCritical(uint16_t);
|
bool isCritical(uint16_t);
|
||||||
|
|
||||||
std::string file_path_;
|
std::string file_path_;
|
||||||
waybar::util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
@ -33,7 +33,7 @@ inline int close(FILE* fp, pid_t pid) {
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
while (waitpid(pid, &stat, 0) == -1) {
|
while (waitpid(pid, &stat, 0) == -1) {
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
stat = -1;
|
stat = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,6 +90,8 @@ inline int32_t forkExec(std::string cmd) {
|
|||||||
setpgid(pid, pid);
|
setpgid(pid, pid);
|
||||||
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 {
|
||||||
|
signal(SIGCHLD,SIG_IGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
|
@ -14,7 +14,10 @@ class SleeperThread {
|
|||||||
|
|
||||||
SleeperThread(std::function<void()> func)
|
SleeperThread(std::function<void()> func)
|
||||||
: thread_{[this, func] {
|
: thread_{[this, func] {
|
||||||
while (do_run_) func();
|
while (do_run_) {
|
||||||
|
signal_ = false;
|
||||||
|
func();
|
||||||
|
}
|
||||||
}} {}
|
}} {}
|
||||||
|
|
||||||
SleeperThread& operator=(std::function<void()> func) {
|
SleeperThread& operator=(std::function<void()> func) {
|
||||||
@ -42,7 +45,10 @@ class SleeperThread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto wake_up() {
|
auto wake_up() {
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lck(mutex_);
|
||||||
signal_ = true;
|
signal_ = true;
|
||||||
|
}
|
||||||
condvar_.notify_all();
|
condvar_.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
project(
|
project(
|
||||||
'waybar', 'cpp', 'c',
|
'waybar', 'cpp', 'c',
|
||||||
version: '0.6.6',
|
version: '0.6.9',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
default_options : [
|
default_options : [
|
||||||
'cpp_std=c++17',
|
'cpp_std=c++17',
|
||||||
|
@ -39,7 +39,7 @@ def on_metadata(player, metadata, manager):
|
|||||||
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())
|
||||||
|
|
||||||
if player.props.status != 'Playing':
|
if player.props.status != 'Playing' and track_info:
|
||||||
track_info = ' ' + track_info
|
track_info = ' ' + track_info
|
||||||
write_output(track_info, player)
|
write_output(track_info, player)
|
||||||
|
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
window#waybar {
|
window#waybar {
|
||||||
background: rgba(43, 48, 59, 0.5);
|
background-color: rgba(43, 48, 59, 0.5);
|
||||||
border-bottom: 3px solid rgba(100, 114, 125, 0.5);
|
border-bottom: 3px solid rgba(100, 114, 125, 0.5);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
transition-property: background, background-color;
|
transition-property: background-color;
|
||||||
transition-duration: .5s;
|
transition-duration: .5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,10 +20,10 @@ window#waybar.hidden {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
window#waybar.empty {
|
window#waybar.empty {
|
||||||
background: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
window#waybar.solo {
|
window#waybar.solo {
|
||||||
background: #FFFFFF;
|
background-color: #FFFFFF;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -39,13 +39,13 @@ window#waybar.chromium {
|
|||||||
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
||||||
#workspaces button {
|
#workspaces button {
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
background: transparent;
|
background-color: transparent;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
border-bottom: 3px solid transparent;
|
border-bottom: 3px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#workspaces button.focused {
|
#workspaces button.focused {
|
||||||
background: #64727D;
|
background-color: #64727D;
|
||||||
border-bottom: 3px solid #ffffff;
|
border-bottom: 3px solid #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ window#waybar.chromium {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#mode {
|
#mode {
|
||||||
background: #64727D;
|
background-color: #64727D;
|
||||||
border-bottom: 3px solid #ffffff;
|
border-bottom: 3px solid #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ window#waybar.chromium {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#battery.critical:not(.charging) {
|
#battery.critical:not(.charging) {
|
||||||
background: #f53c3c;
|
background-color: #f53c3c;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
animation-name: blink;
|
animation-name: blink;
|
||||||
animation-duration: 0.5s;
|
animation-duration: 0.5s;
|
||||||
@ -100,56 +100,56 @@ label:focus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#cpu {
|
#cpu {
|
||||||
background: #2ecc71;
|
background-color: #2ecc71;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#memory {
|
#memory {
|
||||||
background: #9b59b6;
|
background-color: #9b59b6;
|
||||||
}
|
}
|
||||||
|
|
||||||
#backlight {
|
#backlight {
|
||||||
background: #90b1b1;
|
background-color: #90b1b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#network {
|
#network {
|
||||||
background: #2980b9;
|
background-color: #2980b9;
|
||||||
}
|
}
|
||||||
|
|
||||||
#network.disconnected {
|
#network.disconnected {
|
||||||
background: #f53c3c;
|
background-color: #f53c3c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pulseaudio {
|
#pulseaudio {
|
||||||
background: #f1c40f;
|
background-color: #f1c40f;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pulseaudio.muted {
|
#pulseaudio.muted {
|
||||||
background: #90b1b1;
|
background-color: #90b1b1;
|
||||||
color: #2a5c45;
|
color: #2a5c45;
|
||||||
}
|
}
|
||||||
|
|
||||||
#custom-media {
|
#custom-media {
|
||||||
background: #66cc99;
|
background-color: #66cc99;
|
||||||
color: #2a5c45;
|
color: #2a5c45;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-spotify {
|
#custom-media.custom-spotify {
|
||||||
background: #66cc99;
|
background-color: #66cc99;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-vlc {
|
#custom-media.custom-vlc {
|
||||||
background: #ffa000;
|
background-color: #ffa000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#temperature {
|
#temperature {
|
||||||
background: #f0932b;
|
background-color: #f0932b;
|
||||||
}
|
}
|
||||||
|
|
||||||
#temperature.critical {
|
#temperature.critical {
|
||||||
background: #eb4d4b;
|
background-color: #eb4d4b;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tray {
|
#tray {
|
||||||
@ -166,18 +166,18 @@ label:focus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#mpd {
|
#mpd {
|
||||||
background: #66cc99;
|
background-color: #66cc99;
|
||||||
color: #2a5c45;
|
color: #2a5c45;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mpd.disconnected {
|
#mpd.disconnected {
|
||||||
background: #f53c3c;
|
background-color: #f53c3c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mpd.stopped {
|
#mpd.stopped {
|
||||||
background: #90b1b1;
|
background-color: #90b1b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mpd.paused {
|
#mpd.paused {
|
||||||
background: #51a37a;
|
background-color: #51a37a;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <util/command.hpp>
|
#include <util/command.hpp>
|
||||||
|
|
||||||
waybar::ALabel::ALabel(const Json::Value& config, const std::string& format, uint16_t interval)
|
waybar::ALabel::ALabel(const Json::Value& config, const std::string& name, const std::string& id,
|
||||||
|
const std::string& format, uint16_t interval)
|
||||||
: config_(config),
|
: config_(config),
|
||||||
format_(config_["format"].isString() ? config_["format"].asString() : format),
|
format_(config_["format"].isString() ? config_["format"].asString() : format),
|
||||||
interval_(config_["interval"] == "once"
|
interval_(config_["interval"] == "once"
|
||||||
@ -10,6 +11,10 @@ waybar::ALabel::ALabel(const Json::Value& config, const std::string& format, uin
|
|||||||
: std::chrono::seconds(
|
: std::chrono::seconds(
|
||||||
config_["interval"].isUInt() ? config_["interval"].asUInt() : interval)),
|
config_["interval"].isUInt() ? config_["interval"].asUInt() : interval)),
|
||||||
default_format_(format_) {
|
default_format_(format_) {
|
||||||
|
label_.set_name(name);
|
||||||
|
if (!id.empty()) {
|
||||||
|
label_.get_style_context()->add_class(id);
|
||||||
|
}
|
||||||
event_box_.add(label_);
|
event_box_.add(label_);
|
||||||
if (config_["max-length"].isUInt()) {
|
if (config_["max-length"].isUInt()) {
|
||||||
label_.set_max_width_chars(config_["max-length"].asUInt());
|
label_.set_max_width_chars(config_["max-length"].asUInt());
|
||||||
@ -64,8 +69,7 @@ bool waybar::ALabel::handleToggle(GdkEventButton* const& e) {
|
|||||||
format = config_["on-click-forward"].asString();
|
format = config_["on-click-forward"].asString();
|
||||||
}
|
}
|
||||||
if (!format.empty()) {
|
if (!format.empty()) {
|
||||||
pid_.push_back(
|
pid_.push_back(util::command::forkExec(fmt::format(format, fmt::arg("arg", click_param))));
|
||||||
waybar::util::command::forkExec(fmt::format(format, fmt::arg("arg", click_param))));
|
|
||||||
}
|
}
|
||||||
if (config_["format-alt-click"].isUInt() && e->button == config_["format-alt-click"].asUInt()) {
|
if (config_["format-alt-click"].isUInt() && e->button == config_["format-alt-click"].asUInt()) {
|
||||||
alt_ = !alt_;
|
alt_ = !alt_;
|
||||||
@ -101,9 +105,9 @@ bool waybar::ALabel::handleScroll(GdkEventScroll* e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (direction_up && config_["on-scroll-up"].isString()) {
|
if (direction_up && config_["on-scroll-up"].isString()) {
|
||||||
pid_.push_back(waybar::util::command::forkExec(config_["on-scroll-up"].asString()));
|
pid_.push_back(util::command::forkExec(config_["on-scroll-up"].asString()));
|
||||||
} else if (config_["on-scroll-down"].isString()) {
|
} else if (config_["on-scroll-down"].isString()) {
|
||||||
pid_.push_back(waybar::util::command::forkExec(config_["on-scroll-down"].asString()));
|
pid_.push_back(util::command::forkExec(config_["on-scroll-down"].asString()));
|
||||||
}
|
}
|
||||||
dp.emit();
|
dp.emit();
|
||||||
return true;
|
return true;
|
||||||
|
150
src/bar.cpp
150
src/bar.cpp
@ -9,6 +9,7 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& 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),
|
||||||
left_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
left_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||||
center_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
center_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||||
right_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
right_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||||
@ -16,46 +17,33 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
|||||||
window.set_title("waybar");
|
window.set_title("waybar");
|
||||||
window.set_name("waybar");
|
window.set_name("waybar");
|
||||||
window.set_decorated(false);
|
window.set_decorated(false);
|
||||||
|
window.get_style_context()->add_class(output->name);
|
||||||
|
|
||||||
if (config["position"] == "right" || config["position"] == "left") {
|
if (config["position"] == "right" || config["position"] == "left") {
|
||||||
height_ = 0;
|
height_ = 0;
|
||||||
width_ = 1;
|
width_ = 1;
|
||||||
}
|
}
|
||||||
|
height_ = config["height"].isUInt() ? config["height"].asUInt() : height_;
|
||||||
|
width_ = config["width"].isUInt() ? config["width"].asUInt() : width_;
|
||||||
|
|
||||||
auto gtk_window = window.gobj();
|
window.signal_realize().connect_notify(sigc::mem_fun(*this, &Bar::onRealize));
|
||||||
auto gtk_widget = GTK_WIDGET(gtk_window);
|
window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap));
|
||||||
gtk_widget_realize(gtk_widget);
|
window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Bar::onConfigure));
|
||||||
auto gdk_window = window.get_window()->gobj();
|
window.set_size_request(width_, height_);
|
||||||
gdk_wayland_window_set_use_custom_surface(gdk_window);
|
|
||||||
surface = gdk_wayland_window_get_wl_surface(gdk_window);
|
|
||||||
|
|
||||||
std::size_t layer =
|
|
||||||
config["layer"] == "top" ? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
|
|
||||||
auto client = waybar::Client::inst();
|
|
||||||
layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
|
||||||
client->layer_shell, surface, output->output, layer, "waybar");
|
|
||||||
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
|
||||||
.configure = layerSurfaceHandleConfigure,
|
|
||||||
.closed = layerSurfaceHandleClosed,
|
|
||||||
};
|
|
||||||
zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, this);
|
|
||||||
|
|
||||||
auto height = config["height"].isUInt() ? config["height"].asUInt() : height_;
|
|
||||||
auto width = config["width"].isUInt() ? config["width"].asUInt() : width_;
|
|
||||||
|
|
||||||
std::size_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
|
||||||
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") {
|
||||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
anchor_ = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
||||||
} else if (config["position"] == "right") {
|
} else if (config["position"] == "right") {
|
||||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
anchor_ = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||||
}
|
}
|
||||||
if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM || anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) {
|
if (anchor_ == ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM ||
|
||||||
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
anchor_ == ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) {
|
||||||
} else if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT ||
|
anchor_ |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||||
anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) {
|
} else if (anchor_ == ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT ||
|
||||||
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
anchor_ == ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) {
|
||||||
|
anchor_ |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||||
left_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
left_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
||||||
center_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
center_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
||||||
right_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
right_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
||||||
@ -63,17 +51,71 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
|||||||
vertical = true;
|
vertical = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
zwlr_layer_surface_v1_set_anchor(layer_surface, anchor);
|
setupWidgets();
|
||||||
zwlr_layer_surface_v1_set_size(layer_surface, width, height);
|
|
||||||
setMarginsAndZone(height, width);
|
if (window.get_realized()) {
|
||||||
|
onRealize();
|
||||||
|
}
|
||||||
|
window.show_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::Bar::onConfigure(GdkEventConfigure* ev) {
|
||||||
|
auto tmp_height = height_;
|
||||||
|
auto tmp_width = width_;
|
||||||
|
if (ev->height > static_cast<int>(height_)) {
|
||||||
|
// Default minimal value
|
||||||
|
if (height_ != 1) {
|
||||||
|
spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height);
|
||||||
|
}
|
||||||
|
if (config["height"].isUInt()) {
|
||||||
|
spdlog::info(SIZE_DEFINED, "Height");
|
||||||
|
} else {
|
||||||
|
tmp_height = ev->height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev->width > static_cast<int>(width_)) {
|
||||||
|
// Default minimal value
|
||||||
|
if (width_ != 1) {
|
||||||
|
spdlog::warn(MIN_WIDTH_MSG, width_, ev->width);
|
||||||
|
}
|
||||||
|
if (config["width"].isUInt()) {
|
||||||
|
spdlog::info(SIZE_DEFINED, "Width");
|
||||||
|
} else {
|
||||||
|
tmp_width = ev->width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tmp_width != width_ || tmp_height != height_) {
|
||||||
|
zwlr_layer_surface_v1_set_size(layer_surface, tmp_width, tmp_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::Bar::onRealize() {
|
||||||
|
auto gdk_window = window.get_window()->gobj();
|
||||||
|
gdk_wayland_window_set_use_custom_surface(gdk_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::Bar::onMap(GdkEventAny* ev) {
|
||||||
|
auto gdk_window = window.get_window()->gobj();
|
||||||
|
surface = gdk_wayland_window_get_wl_surface(gdk_window);
|
||||||
|
|
||||||
|
auto client = waybar::Client::inst();
|
||||||
|
auto layer =
|
||||||
|
config["layer"] == "top" ? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
|
||||||
|
layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
||||||
|
client->layer_shell, surface, output->output, layer, "waybar");
|
||||||
|
|
||||||
|
zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface, false);
|
||||||
|
zwlr_layer_surface_v1_set_anchor(layer_surface, anchor_);
|
||||||
|
zwlr_layer_surface_v1_set_size(layer_surface, width_, height_);
|
||||||
|
setMarginsAndZone(height_, width_);
|
||||||
|
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
||||||
|
.configure = layerSurfaceHandleConfigure,
|
||||||
|
.closed = layerSurfaceHandleClosed,
|
||||||
|
};
|
||||||
|
zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, this);
|
||||||
|
|
||||||
wl_surface_commit(surface);
|
wl_surface_commit(surface);
|
||||||
wl_display_roundtrip(client->wl_display);
|
wl_display_roundtrip(client->wl_display);
|
||||||
|
|
||||||
setupWidgets();
|
|
||||||
|
|
||||||
window.set_size_request(width_, height_);
|
|
||||||
window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Bar::onConfigure));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Bar::setMarginsAndZone(uint32_t height, uint32_t width) {
|
void waybar::Bar::setMarginsAndZone(uint32_t height, uint32_t width) {
|
||||||
@ -127,36 +169,6 @@ void waybar::Bar::setMarginsAndZone(uint32_t height, uint32_t width) {
|
|||||||
zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, zone);
|
zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Bar::onConfigure(GdkEventConfigure* ev) {
|
|
||||||
auto tmp_height = height_;
|
|
||||||
auto tmp_width = width_;
|
|
||||||
if (ev->height > static_cast<int>(height_)) {
|
|
||||||
// Default minimal value
|
|
||||||
if (height_ != 1) {
|
|
||||||
spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height);
|
|
||||||
}
|
|
||||||
if (config["height"].isUInt()) {
|
|
||||||
spdlog::info(SIZE_DEFINED, "Height");
|
|
||||||
} else {
|
|
||||||
tmp_height = ev->height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev->width > static_cast<int>(width_)) {
|
|
||||||
// Default minimal value
|
|
||||||
if (width_ != 1) {
|
|
||||||
spdlog::warn(MIN_WIDTH_MSG, width_, ev->width);
|
|
||||||
}
|
|
||||||
if (config["width"].isUInt()) {
|
|
||||||
spdlog::info(SIZE_DEFINED, "Width");
|
|
||||||
} else {
|
|
||||||
tmp_width = ev->width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tmp_width != width_ || tmp_height != height_) {
|
|
||||||
zwlr_layer_surface_v1_set_size(layer_surface, tmp_width, tmp_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
|
||||||
void waybar::Bar::setupAltFormatKeyForModule(const std::string& module_name) {
|
void waybar::Bar::setupAltFormatKeyForModule(const std::string& module_name) {
|
||||||
if (config.isMember(module_name)) {
|
if (config.isMember(module_name)) {
|
||||||
@ -239,7 +251,10 @@ 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) {
|
||||||
zwlr_layer_surface_v1_destroy(o->layer_surface);
|
zwlr_layer_surface_v1_destroy(o->layer_surface);
|
||||||
|
o->layer_surface = nullptr;
|
||||||
|
}
|
||||||
o->modules_left_.clear();
|
o->modules_left_.clear();
|
||||||
o->modules_center_.clear();
|
o->modules_center_.clear();
|
||||||
o->modules_right_.clear();
|
o->modules_right_.clear();
|
||||||
@ -313,5 +328,4 @@ auto waybar::Bar::setupWidgets() -> void {
|
|||||||
for (auto const& module : modules_right_) {
|
for (auto const& module : modules_right_) {
|
||||||
right_.pack_end(*module, false, false, 0);
|
right_.pack_end(*module, false, false, 0);
|
||||||
}
|
}
|
||||||
window.show_all();
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
#include "util/clara.hpp"
|
#include "util/clara.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ waybar::Client *waybar::Client::inst() {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string waybar::Client::getValidPath(const std::vector<std::string> &paths) {
|
const std::string waybar::Client::getValidPath(const std::vector<std::string> &paths) const {
|
||||||
wordexp_t p;
|
wordexp_t p;
|
||||||
|
|
||||||
for (const std::string &path : paths) {
|
for (const std::string &path : paths) {
|
||||||
@ -172,8 +172,9 @@ void waybar::Client::handleDescription(void * /*data*/, struct zxdg_output_v1 *
|
|||||||
// Nothing here
|
// Nothing here
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Client::setupConfigs(const std::string &config, const std::string &style) {
|
std::tuple<const std::string, const std::string> waybar::Client::getConfigs(
|
||||||
config_file_ = config.empty() ? getValidPath({
|
const std::string &config, const std::string &style) const {
|
||||||
|
auto config_file = config.empty() ? getValidPath({
|
||||||
"$XDG_CONFIG_HOME/waybar/config",
|
"$XDG_CONFIG_HOME/waybar/config",
|
||||||
"$HOME/.config/waybar/config",
|
"$HOME/.config/waybar/config",
|
||||||
"$HOME/waybar/config",
|
"$HOME/waybar/config",
|
||||||
@ -181,7 +182,7 @@ void waybar::Client::setupConfigs(const std::string &config, const std::string &
|
|||||||
"./resources/config",
|
"./resources/config",
|
||||||
})
|
})
|
||||||
: config;
|
: config;
|
||||||
css_file_ = style.empty() ? getValidPath({
|
auto css_file = style.empty() ? getValidPath({
|
||||||
"$XDG_CONFIG_HOME/waybar/style.css",
|
"$XDG_CONFIG_HOME/waybar/style.css",
|
||||||
"$HOME/.config/waybar/style.css",
|
"$HOME/.config/waybar/style.css",
|
||||||
"$HOME/waybar/style.css",
|
"$HOME/waybar/style.css",
|
||||||
@ -189,14 +190,15 @@ void waybar::Client::setupConfigs(const std::string &config, const std::string &
|
|||||||
"./resources/style.css",
|
"./resources/style.css",
|
||||||
})
|
})
|
||||||
: style;
|
: style;
|
||||||
if (css_file_.empty() || config_file_.empty()) {
|
if (css_file.empty() || config_file.empty()) {
|
||||||
throw std::runtime_error("Missing required resources files");
|
throw std::runtime_error("Missing required resources files");
|
||||||
}
|
}
|
||||||
spdlog::info("Resources files: {}, {}", config_file_, css_file_);
|
spdlog::info("Resources files: {}, {}", config_file, css_file);
|
||||||
|
return {config_file, css_file};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::Client::setupConfig() -> void {
|
auto waybar::Client::setupConfig(const std::string &config_file) -> void {
|
||||||
std::ifstream file(config_file_);
|
std::ifstream file(config_file);
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
throw std::runtime_error("Can't open config file");
|
throw std::runtime_error("Can't open config file");
|
||||||
}
|
}
|
||||||
@ -205,12 +207,12 @@ auto waybar::Client::setupConfig() -> void {
|
|||||||
config_ = parser.parse(str);
|
config_ = parser.parse(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::Client::setupCss() -> void {
|
auto waybar::Client::setupCss(const std::string &css_file) -> void {
|
||||||
css_provider_ = Gtk::CssProvider::create();
|
css_provider_ = Gtk::CssProvider::create();
|
||||||
style_context_ = Gtk::StyleContext::create();
|
style_context_ = Gtk::StyleContext::create();
|
||||||
|
|
||||||
// Load our css file, wherever that may be hiding
|
// Load our css file, wherever that may be hiding
|
||||||
if (!css_provider_->load_from_path(css_file_)) {
|
if (!css_provider_->load_from_path(css_file)) {
|
||||||
throw std::runtime_error("Can't open style file");
|
throw std::runtime_error("Can't open style file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,15 +231,6 @@ void waybar::Client::bindInterfaces() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int waybar::Client::main(int argc, char *argv[]) {
|
int waybar::Client::main(int argc, char *argv[]) {
|
||||||
gtk_app = Gtk::Application::create(argc, argv, "fr.arouillard.waybar");
|
|
||||||
gdk_display = Gdk::Display::get_default();
|
|
||||||
if (!gdk_display) {
|
|
||||||
throw std::runtime_error("Can't find display");
|
|
||||||
}
|
|
||||||
if (!GDK_IS_WAYLAND_DISPLAY(gdk_display->gobj())) {
|
|
||||||
throw std::runtime_error("Bar need to run under Wayland");
|
|
||||||
}
|
|
||||||
wl_display = gdk_wayland_display_get_wl_display(gdk_display->gobj());
|
|
||||||
bool show_help = false;
|
bool show_help = false;
|
||||||
bool show_version = false;
|
bool show_version = false;
|
||||||
std::string config;
|
std::string config;
|
||||||
@ -268,9 +261,18 @@ int waybar::Client::main(int argc, char *argv[]) {
|
|||||||
if (!log_level.empty()) {
|
if (!log_level.empty()) {
|
||||||
spdlog::set_level(spdlog::level::from_str(log_level));
|
spdlog::set_level(spdlog::level::from_str(log_level));
|
||||||
}
|
}
|
||||||
setupConfigs(config, style);
|
gtk_app = Gtk::Application::create(argc, argv, "fr.arouillard.waybar");
|
||||||
setupConfig();
|
gdk_display = Gdk::Display::get_default();
|
||||||
setupCss();
|
if (!gdk_display) {
|
||||||
|
throw std::runtime_error("Can't find display");
|
||||||
|
}
|
||||||
|
if (!GDK_IS_WAYLAND_DISPLAY(gdk_display->gobj())) {
|
||||||
|
throw std::runtime_error("Bar need to run under Wayland");
|
||||||
|
}
|
||||||
|
wl_display = gdk_wayland_display_get_wl_display(gdk_display->gobj());
|
||||||
|
auto [config_file, css_file] = getConfigs(config, style);
|
||||||
|
setupConfig(config_file);
|
||||||
|
setupCss(css_file);
|
||||||
bindInterfaces();
|
bindInterfaces();
|
||||||
gtk_app->hold();
|
gtk_app->hold();
|
||||||
gtk_app->run();
|
gtk_app->run();
|
||||||
|
@ -64,7 +64,7 @@ waybar::IModule* waybar::Factory::makeModule(const std::string& name) const {
|
|||||||
return new waybar::modules::Temperature(id, config_[name]);
|
return new waybar::modules::Temperature(id, config_[name]);
|
||||||
}
|
}
|
||||||
if (ref.compare(0, 7, "custom/") == 0 && ref.size() > 7) {
|
if (ref.compare(0, 7, "custom/") == 0 && ref.size() > 7) {
|
||||||
return new waybar::modules::Custom(ref.substr(7), config_[name]);
|
return new waybar::modules::Custom(ref.substr(7), id, config_[name]);
|
||||||
}
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
auto err = fmt::format("Disabling module \"{}\", {}", name, e.what());
|
auto err = fmt::format("Disabling module \"{}\", {}", name, e.what());
|
||||||
|
@ -88,12 +88,9 @@ int waybar::modules::Backlight::BacklightDev::get_max() const { return max_; }
|
|||||||
|
|
||||||
void waybar::modules::Backlight::BacklightDev::set_max(int max) { max_ = max; }
|
void waybar::modules::Backlight::BacklightDev::set_max(int max) { max_ = max; }
|
||||||
|
|
||||||
waybar::modules::Backlight::Backlight(const std::string &name, const Json::Value &config)
|
waybar::modules::Backlight::Backlight(const std::string &id, const Json::Value &config)
|
||||||
: ALabel(config, "{percent}%", 2),
|
: ALabel(config, "backlight", id, "{percent}%", 2),
|
||||||
name_(name),
|
|
||||||
preferred_device_(config["device"].isString() ? config["device"].asString() : "") {
|
preferred_device_(config["device"].isString() ? config["device"].asString() : "") {
|
||||||
label_.set_name("backlight");
|
|
||||||
|
|
||||||
// Get initial state
|
// Get initial state
|
||||||
{
|
{
|
||||||
std::unique_ptr<udev, UdevDeleter> udev_check{udev_new()};
|
std::unique_ptr<udev, UdevDeleter> udev_check{udev_new()};
|
||||||
@ -213,7 +210,8 @@ void waybar::modules::Backlight::upsert_device(ForwardIt first, ForwardIt last,
|
|||||||
const char *name = udev_device_get_sysname(dev);
|
const char *name = udev_device_get_sysname(dev);
|
||||||
check_nn(name);
|
check_nn(name);
|
||||||
|
|
||||||
const char *actual_brightness_attr = strcmp(name, "amdgpu_bl0") == 0 ? "brightness" : "actual_brightness";
|
const char *actual_brightness_attr =
|
||||||
|
strcmp(name, "amdgpu_bl0") == 0 ? "brightness" : "actual_brightness";
|
||||||
|
|
||||||
const char *actual = udev_device_get_sysattr_value(dev, actual_brightness_attr);
|
const char *actual = udev_device_get_sysattr_value(dev, actual_brightness_attr);
|
||||||
check_nn(actual);
|
check_nn(actual);
|
||||||
|
@ -2,11 +2,7 @@
|
|||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
waybar::modules::Battery::Battery(const std::string& id, const Json::Value& config)
|
waybar::modules::Battery::Battery(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "{capacity}%", 60) {
|
: ALabel(config, "battery", id, "{capacity}%", 60) {
|
||||||
label_.set_name("battery");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
getBatteries();
|
getBatteries();
|
||||||
fd_ = inotify_init1(IN_CLOEXEC);
|
fd_ = inotify_init1(IN_CLOEXEC);
|
||||||
if (fd_ == -1) {
|
if (fd_ == -1) {
|
||||||
|
@ -1,20 +1,13 @@
|
|||||||
#include "modules/clock.hpp"
|
#include "modules/clock.hpp"
|
||||||
|
|
||||||
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, "{:%H:%M}", 60) {
|
: ALabel(config, "clock", id, "{:%H:%M}", 60) {
|
||||||
label_.set_name("clock");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
dp.emit();
|
dp.emit();
|
||||||
auto now = std::chrono::system_clock::now();
|
auto now = std::chrono::system_clock::now();
|
||||||
auto timeout = std::chrono::floor<std::chrono::seconds>(now + interval_);
|
auto timeout = std::chrono::floor<std::chrono::seconds>(now + interval_);
|
||||||
auto time_s = std::chrono::time_point_cast<std::chrono::seconds>(timeout);
|
auto diff = std::chrono::seconds(timeout.time_since_epoch().count() % interval_.count());
|
||||||
auto sub_m =
|
thread_.sleep_until(timeout - diff);
|
||||||
std::chrono::duration_cast<std::chrono::seconds>(time_s.time_since_epoch()).count() %
|
|
||||||
interval_.count();
|
|
||||||
thread_.sleep_until(timeout - std::chrono::seconds(sub_m));
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,7 @@
|
|||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
waybar::modules::Cpu::Cpu(const std::string& id, const Json::Value& config)
|
waybar::modules::Cpu::Cpu(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "{usage}%", 10) {
|
: ALabel(config, "cpu", id, "{usage}%", 10) {
|
||||||
label_.set_name("cpu");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
dp.emit();
|
dp.emit();
|
||||||
thread_.sleep_for(interval_);
|
thread_.sleep_for(interval_);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#include "modules/custom.hpp"
|
#include "modules/custom.hpp"
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
waybar::modules::Custom::Custom(const std::string& name, const Json::Value& config)
|
waybar::modules::Custom::Custom(const std::string& name, const std::string& id,
|
||||||
: ALabel(config, "{}"), name_(name), fp_(nullptr), pid_(-1) {
|
const Json::Value& config)
|
||||||
label_.set_name("custom-" + name_);
|
: ALabel(config, "custom-" + name, id, "{}"), name_(name), fp_(nullptr), pid_(-1) {
|
||||||
if (config_["exec"].isString()) {
|
if (config_["exec"].isString()) {
|
||||||
if (interval_.count() > 0) {
|
if (interval_.count() > 0) {
|
||||||
delayWorker();
|
delayWorker();
|
||||||
@ -25,14 +25,14 @@ void waybar::modules::Custom::delayWorker() {
|
|||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
bool can_update = true;
|
bool can_update = true;
|
||||||
if (config_["exec-if"].isString()) {
|
if (config_["exec-if"].isString()) {
|
||||||
auto res = waybar::util::command::exec(config_["exec-if"].asString());
|
auto res = util::command::exec(config_["exec-if"].asString());
|
||||||
if (res.exit_code != 0) {
|
if (res.exit_code != 0) {
|
||||||
can_update = false;
|
can_update = false;
|
||||||
event_box_.hide();
|
event_box_.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (can_update) {
|
if (can_update) {
|
||||||
output_ = waybar::util::command::exec(config_["exec"].asString());
|
output_ = util::command::exec(config_["exec"].asString());
|
||||||
dp.emit();
|
dp.emit();
|
||||||
}
|
}
|
||||||
thread_.sleep_for(interval_);
|
thread_.sleep_for(interval_);
|
||||||
@ -74,7 +74,7 @@ void waybar::modules::Custom::continuousWorker() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Custom::refresh(int sig /*signal*/) {
|
void waybar::modules::Custom::refresh(int sig) {
|
||||||
if (sig == SIGRTMIN + config_["signal"].asInt()) {
|
if (sig == SIGRTMIN + config_["signal"].asInt()) {
|
||||||
thread_.wake_up();
|
thread_.wake_up();
|
||||||
}
|
}
|
||||||
@ -102,12 +102,14 @@ auto waybar::modules::Custom::update() -> void {
|
|||||||
} else {
|
} else {
|
||||||
parseOutputRaw();
|
parseOutputRaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto str = fmt::format(format_,
|
auto str = fmt::format(format_,
|
||||||
text_,
|
text_,
|
||||||
fmt::arg("alt", alt_),
|
fmt::arg("alt", alt_),
|
||||||
fmt::arg("icon", getIcon(percentage_, alt_)),
|
fmt::arg("icon", getIcon(percentage_, alt_)),
|
||||||
fmt::arg("percentage", percentage_));
|
fmt::arg("percentage", percentage_));
|
||||||
|
if (str.empty()) {
|
||||||
|
event_box_.hide();
|
||||||
|
} else {
|
||||||
label_.set_markup(str);
|
label_.set_markup(str);
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
if (text_ == tooltip_) {
|
if (text_ == tooltip_) {
|
||||||
@ -123,10 +125,10 @@ auto waybar::modules::Custom::update() -> void {
|
|||||||
for (auto const& c : class_) {
|
for (auto const& c : class_) {
|
||||||
label_.get_style_context()->add_class(c);
|
label_.get_style_context()->add_class(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
event_box_.show();
|
event_box_.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void waybar::modules::Custom::parseOutputRaw() {
|
void waybar::modules::Custom::parseOutputRaw() {
|
||||||
std::istringstream output(output_.out);
|
std::istringstream output(output_.out);
|
||||||
|
@ -3,15 +3,11 @@
|
|||||||
|
|
||||||
waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar,
|
waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar,
|
||||||
const Json::Value& config)
|
const Json::Value& config)
|
||||||
: ALabel(config, "{status}"),
|
: ALabel(config, "idle_inhibitor", id, "{status}"),
|
||||||
bar_(bar),
|
bar_(bar),
|
||||||
status_("deactivated"),
|
status_("deactivated"),
|
||||||
idle_inhibitor_(nullptr),
|
idle_inhibitor_(nullptr),
|
||||||
pid_(-1) {
|
pid_(-1) {
|
||||||
label_.set_name("idle_inhibitor");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
|
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
|
||||||
event_box_.signal_button_press_event().connect(
|
event_box_.signal_button_press_event().connect(
|
||||||
sigc::mem_fun(*this, &IdleInhibitor::handleToggle));
|
sigc::mem_fun(*this, &IdleInhibitor::handleToggle));
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
#include "modules/memory.hpp"
|
#include "modules/memory.hpp"
|
||||||
|
|
||||||
waybar::modules::Memory::Memory(const std::string& id, const Json::Value& config)
|
waybar::modules::Memory::Memory(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "{}%", 30) {
|
: ALabel(config, "memory", id, "{}%", 30) {
|
||||||
label_.set_name("memory");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
dp.emit();
|
dp.emit();
|
||||||
thread_.sleep_for(interval_);
|
thread_.sleep_for(interval_);
|
||||||
@ -20,7 +16,8 @@ auto waybar::modules::Memory::update() -> void {
|
|||||||
auto available_ram_gigabytes = 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_, used_ram_percentage,
|
label_.set_markup(fmt::format(format_,
|
||||||
|
used_ram_percentage,
|
||||||
fmt::arg("percentage", used_ram_percentage),
|
fmt::arg("percentage", used_ram_percentage),
|
||||||
fmt::arg("used", used_ram_gigabytes),
|
fmt::arg("used", used_ram_gigabytes),
|
||||||
fmt::arg("avail", available_ram_gigabytes)));
|
fmt::arg("avail", available_ram_gigabytes)));
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
waybar::modules::MPD::MPD(const std::string& id, const Json::Value& config)
|
waybar::modules::MPD::MPD(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "{album} - {artist} - {title}", 5),
|
: ALabel(config, "mpd", id, "{album} - {artist} - {title}", 5),
|
||||||
module_name_(id.empty() ? "mpd" : "mpd#" + id),
|
module_name_(id.empty() ? "mpd" : "mpd#" + id),
|
||||||
server_(nullptr),
|
server_(nullptr),
|
||||||
port_(config_["port"].isUInt() ? config["port"].asUInt() : 0),
|
port_(config_["port"].isUInt() ? config["port"].asUInt() : 0),
|
||||||
@ -21,11 +21,6 @@ waybar::modules::MPD::MPD(const std::string& id, const Json::Value& config)
|
|||||||
spdlog::warn("{}: `timeout` configuration should be an unsigned int", module_name_);
|
spdlog::warn("{}: `timeout` configuration should be an unsigned int", module_name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
label_.set_name("mpd");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config["server"].isNull()) {
|
if (!config["server"].isNull()) {
|
||||||
if (!config_["server"].isString()) {
|
if (!config_["server"].isString()) {
|
||||||
spdlog::warn("{}:`server` configuration should be a string", module_name_);
|
spdlog::warn("{}:`server` configuration should be a string", module_name_);
|
||||||
|
@ -73,9 +73,8 @@ std::optional<unsigned long long> read_netstat(std::string_view category, std::s
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
waybar::modules::Network::Network(const std::string &id, const Json::Value &config)
|
waybar::modules::Network::Network(const std::string &id, const Json::Value &config)
|
||||||
: ALabel(config, "{ifname}", 60),
|
: ALabel(config, "network", id, "{ifname}", 60),
|
||||||
ifid_(-1),
|
ifid_(-1),
|
||||||
last_ext_iface_(-1),
|
|
||||||
family_(config["family"] == "ipv6" ? AF_INET6 : AF_INET),
|
family_(config["family"] == "ipv6" ? AF_INET6 : AF_INET),
|
||||||
efd_(-1),
|
efd_(-1),
|
||||||
ev_fd_(-1),
|
ev_fd_(-1),
|
||||||
@ -83,11 +82,6 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf
|
|||||||
signal_strength_dbm_(0),
|
signal_strength_dbm_(0),
|
||||||
signal_strength_(0),
|
signal_strength_(0),
|
||||||
frequency_(0) {
|
frequency_(0) {
|
||||||
label_.set_name("network");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto down_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_DOWN_TOTAL_KEY);
|
auto down_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_DOWN_TOTAL_KEY);
|
||||||
auto up_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_UP_TOTAL_KEY);
|
auto up_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_UP_TOTAL_KEY);
|
||||||
if (down_octets) {
|
if (down_octets) {
|
||||||
@ -102,10 +96,11 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf
|
|||||||
bandwidth_up_total_ = 0;
|
bandwidth_up_total_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
createInfoSocket();
|
|
||||||
createEventSocket();
|
createEventSocket();
|
||||||
|
createInfoSocket();
|
||||||
auto default_iface = getPreferredIface();
|
auto default_iface = getPreferredIface();
|
||||||
if (default_iface != -1) {
|
if (default_iface != -1) {
|
||||||
|
ifid_ = default_iface;
|
||||||
char ifname[IF_NAMESIZE];
|
char ifname[IF_NAMESIZE];
|
||||||
if_indextoname(default_iface, ifname);
|
if_indextoname(default_iface, ifname);
|
||||||
ifname_ = ifname;
|
ifname_ = ifname;
|
||||||
@ -126,8 +121,11 @@ waybar::modules::Network::~Network() {
|
|||||||
}
|
}
|
||||||
if (ev_sock_ != nullptr) {
|
if (ev_sock_ != nullptr) {
|
||||||
nl_socket_drop_membership(ev_sock_, RTNLGRP_LINK);
|
nl_socket_drop_membership(ev_sock_, RTNLGRP_LINK);
|
||||||
|
if (family_ == AF_INET) {
|
||||||
nl_socket_drop_membership(ev_sock_, RTNLGRP_IPV4_IFADDR);
|
nl_socket_drop_membership(ev_sock_, RTNLGRP_IPV4_IFADDR);
|
||||||
|
} else {
|
||||||
nl_socket_drop_membership(ev_sock_, RTNLGRP_IPV6_IFADDR);
|
nl_socket_drop_membership(ev_sock_, RTNLGRP_IPV6_IFADDR);
|
||||||
|
}
|
||||||
nl_close(ev_sock_);
|
nl_close(ev_sock_);
|
||||||
nl_socket_free(ev_sock_);
|
nl_socket_free(ev_sock_);
|
||||||
}
|
}
|
||||||
@ -137,17 +135,21 @@ waybar::modules::Network::~Network() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Network::createInfoSocket() {
|
void waybar::modules::Network::createEventSocket() {
|
||||||
ev_sock_ = nl_socket_alloc();
|
ev_sock_ = nl_socket_alloc();
|
||||||
nl_socket_disable_seq_check(ev_sock_);
|
nl_socket_disable_seq_check(ev_sock_);
|
||||||
nl_socket_modify_cb(ev_sock_, NL_CB_VALID, NL_CB_CUSTOM, handleEvents, this);
|
nl_socket_modify_cb(ev_sock_, NL_CB_VALID, NL_CB_CUSTOM, handleEvents, this);
|
||||||
nl_join_groups(ev_sock_, RTMGRP_LINK);
|
auto groups = RTMGRP_LINK | (family_ == AF_INET ? RTMGRP_IPV4_IFADDR : RTMGRP_IPV6_IFADDR);
|
||||||
|
nl_join_groups(ev_sock_, groups); // Deprecated
|
||||||
if (nl_connect(ev_sock_, NETLINK_ROUTE) != 0) {
|
if (nl_connect(ev_sock_, NETLINK_ROUTE) != 0) {
|
||||||
throw std::runtime_error("Can't connect network socket");
|
throw std::runtime_error("Can't connect network socket");
|
||||||
}
|
}
|
||||||
nl_socket_add_membership(ev_sock_, RTNLGRP_LINK);
|
nl_socket_add_membership(ev_sock_, RTNLGRP_LINK);
|
||||||
|
if (family_ == AF_INET) {
|
||||||
nl_socket_add_membership(ev_sock_, RTNLGRP_IPV4_IFADDR);
|
nl_socket_add_membership(ev_sock_, RTNLGRP_IPV4_IFADDR);
|
||||||
|
} else {
|
||||||
nl_socket_add_membership(ev_sock_, RTNLGRP_IPV6_IFADDR);
|
nl_socket_add_membership(ev_sock_, RTNLGRP_IPV6_IFADDR);
|
||||||
|
}
|
||||||
efd_ = epoll_create1(EPOLL_CLOEXEC);
|
efd_ = epoll_create1(EPOLL_CLOEXEC);
|
||||||
if (efd_ < 0) {
|
if (efd_ < 0) {
|
||||||
throw std::runtime_error("Can't create epoll");
|
throw std::runtime_error("Can't create epoll");
|
||||||
@ -174,7 +176,7 @@ void waybar::modules::Network::createInfoSocket() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Network::createEventSocket() {
|
void waybar::modules::Network::createInfoSocket() {
|
||||||
sock_ = nl_socket_alloc();
|
sock_ = nl_socket_alloc();
|
||||||
if (genl_connect(sock_) != 0) {
|
if (genl_connect(sock_) != 0) {
|
||||||
throw std::runtime_error("Can't connect to netlink socket");
|
throw std::runtime_error("Can't connect to netlink socket");
|
||||||
@ -204,9 +206,7 @@ void waybar::modules::Network::worker() {
|
|||||||
int ec = epoll_wait(efd_, events.data(), EPOLL_MAX, -1);
|
int ec = epoll_wait(efd_, events.data(), EPOLL_MAX, -1);
|
||||||
if (ec > 0) {
|
if (ec > 0) {
|
||||||
for (auto i = 0; i < ec; i++) {
|
for (auto i = 0; i < ec; i++) {
|
||||||
if (events[i].data.fd == nl_socket_get_fd(ev_sock_)) {
|
if (events[i].data.fd != nl_socket_get_fd(ev_sock_) || nl_recvmsgs_default(ev_sock_) < 0) {
|
||||||
nl_recvmsgs_default(ev_sock_);
|
|
||||||
} else {
|
|
||||||
thread_.stop();
|
thread_.stop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -215,10 +215,16 @@ void waybar::modules::Network::worker() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string waybar::modules::Network::getNetworkState() const {
|
||||||
|
if (ifid_ == -1) return "disconnected";
|
||||||
|
if (ipaddr_.empty()) return "linked";
|
||||||
|
if (essid_.empty()) return "ethernet";
|
||||||
|
return "wifi";
|
||||||
|
}
|
||||||
|
|
||||||
auto waybar::modules::Network::update() -> void {
|
auto waybar::modules::Network::update() -> void {
|
||||||
std::string connectiontype;
|
|
||||||
std::string tooltip_format;
|
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
std::string tooltip_format;
|
||||||
auto down_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_DOWN_TOTAL_KEY);
|
auto down_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_DOWN_TOTAL_KEY);
|
||||||
auto up_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_UP_TOTAL_KEY);
|
auto up_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_UP_TOTAL_KEY);
|
||||||
|
|
||||||
@ -233,45 +239,22 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
bandwidth_up = *up_octets - bandwidth_up_total_;
|
bandwidth_up = *up_octets - bandwidth_up_total_;
|
||||||
bandwidth_up_total_ = *up_octets;
|
bandwidth_up_total_ = *up_octets;
|
||||||
}
|
}
|
||||||
if (ifid_ <= 0 || !linked_) {
|
|
||||||
if (config_["format-disconnected"].isString()) {
|
|
||||||
default_format_ = config_["format-disconnected"].asString();
|
|
||||||
}
|
|
||||||
if (config_["tooltip-format-disconnected"].isString()) {
|
|
||||||
tooltip_format = config_["tooltip-format-disconnected"].asString();
|
|
||||||
}
|
|
||||||
label_.get_style_context()->add_class("disconnected");
|
|
||||||
connectiontype = "disconnected";
|
|
||||||
} else {
|
|
||||||
if (essid_.empty()) {
|
|
||||||
if (config_["format-ethernet"].isString()) {
|
|
||||||
default_format_ = config_["format-ethernet"].asString();
|
|
||||||
}
|
|
||||||
if (config_["tooltip-format-ethernet"].isString()) {
|
|
||||||
tooltip_format = config_["tooltip-format-ethernet"].asString();
|
|
||||||
}
|
|
||||||
connectiontype = "ethernet";
|
|
||||||
} else if (ipaddr_.empty()) {
|
|
||||||
if (config_["format-linked"].isString()) {
|
|
||||||
default_format_ = config_["format-linked"].asString();
|
|
||||||
}
|
|
||||||
if (config_["tooltip-format-linked"].isString()) {
|
|
||||||
tooltip_format = config_["tooltip-format-linked"].asString();
|
|
||||||
}
|
|
||||||
connectiontype = "linked";
|
|
||||||
} else {
|
|
||||||
if (config_["format-wifi"].isString()) {
|
|
||||||
default_format_ = config_["format-wifi"].asString();
|
|
||||||
}
|
|
||||||
if (config_["tooltip-format-wifi"].isString()) {
|
|
||||||
tooltip_format = config_["tooltip-format-wifi"].asString();
|
|
||||||
}
|
|
||||||
connectiontype = "wifi";
|
|
||||||
}
|
|
||||||
label_.get_style_context()->remove_class("disconnected");
|
|
||||||
}
|
|
||||||
if (!alt_) {
|
if (!alt_) {
|
||||||
|
auto state = getNetworkState();
|
||||||
|
if (!state_.empty() && label_.get_style_context()->has_class(state_)) {
|
||||||
|
label_.get_style_context()->remove_class(state_);
|
||||||
|
}
|
||||||
|
if (config_["format-" + state].isString()) {
|
||||||
|
default_format_ = config_["format-" + state].asString();
|
||||||
|
}
|
||||||
|
if (config_["tooltip-format-" + state].isString()) {
|
||||||
|
tooltip_format = config_["tooltip-format-" + state].asString();
|
||||||
|
}
|
||||||
|
if (!label_.get_style_context()->has_class(state)) {
|
||||||
|
label_.get_style_context()->add_class(state);
|
||||||
|
}
|
||||||
format_ = default_format_;
|
format_ = default_format_;
|
||||||
|
state_ = state;
|
||||||
}
|
}
|
||||||
getState(signal_strength_);
|
getState(signal_strength_);
|
||||||
|
|
||||||
@ -305,7 +288,7 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
fmt::arg("ipaddr", ipaddr_),
|
fmt::arg("ipaddr", ipaddr_),
|
||||||
fmt::arg("cidr", cidr_),
|
fmt::arg("cidr", cidr_),
|
||||||
fmt::arg("frequency", frequency_),
|
fmt::arg("frequency", frequency_),
|
||||||
fmt::arg("icon", getIcon(signal_strength_, connectiontype)),
|
fmt::arg("icon", getIcon(signal_strength_, state_)),
|
||||||
fmt::arg("bandwidthDownBits", pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")),
|
fmt::arg("bandwidthDownBits", pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")),
|
||||||
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")),
|
||||||
@ -328,7 +311,7 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
fmt::arg("ipaddr", ipaddr_),
|
fmt::arg("ipaddr", ipaddr_),
|
||||||
fmt::arg("cidr", cidr_),
|
fmt::arg("cidr", cidr_),
|
||||||
fmt::arg("frequency", frequency_),
|
fmt::arg("frequency", frequency_),
|
||||||
fmt::arg("icon", getIcon(signal_strength_, connectiontype)),
|
fmt::arg("icon", getIcon(signal_strength_, state_)),
|
||||||
fmt::arg("bandwidthDownBits",
|
fmt::arg("bandwidthDownBits",
|
||||||
pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")),
|
pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")),
|
||||||
fmt::arg("bandwidthUpBits", pow_format(bandwidth_up * 8ull / interval_.count(), "b/s")),
|
fmt::arg("bandwidthUpBits", pow_format(bandwidth_up * 8ull / interval_.count(), "b/s")),
|
||||||
@ -344,7 +327,7 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Based on https://gist.github.com/Yawning/c70d804d4b8ae78cc698
|
// Based on https://gist.github.com/Yawning/c70d804d4b8ae78cc698
|
||||||
int waybar::modules::Network::getExternalInterface(int skip_idx) {
|
int waybar::modules::Network::getExternalInterface(int skip_idx) const {
|
||||||
static const uint32_t route_buffer_size = 8192;
|
static const uint32_t route_buffer_size = 8192;
|
||||||
struct nlmsghdr * hdr = nullptr;
|
struct nlmsghdr * hdr = nullptr;
|
||||||
struct rtmsg * rt = nullptr;
|
struct rtmsg * rt = nullptr;
|
||||||
@ -462,22 +445,19 @@ int waybar::modules::Network::getExternalInterface(int skip_idx) {
|
|||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
last_ext_iface_ = ifidx;
|
|
||||||
return ifidx;
|
return ifidx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Network::getInterfaceAddress() {
|
void waybar::modules::Network::getInterfaceAddress() {
|
||||||
unsigned int cidrRaw;
|
unsigned int cidrRaw;
|
||||||
struct ifaddrs *ifaddr, *ifa;
|
struct ifaddrs *ifaddr, *ifa;
|
||||||
ipaddr_.clear();
|
|
||||||
netmask_.clear();
|
|
||||||
cidr_ = 0;
|
cidr_ = 0;
|
||||||
int success = getifaddrs(&ifaddr);
|
int success = getifaddrs(&ifaddr);
|
||||||
if (success != 0) {
|
if (success != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ifa = ifaddr;
|
ifa = ifaddr;
|
||||||
while (ifa != nullptr && ipaddr_.empty() && netmask_.empty()) {
|
while (ifa != nullptr) {
|
||||||
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];
|
||||||
@ -489,20 +469,20 @@ void waybar::modules::Network::getInterfaceAddress() {
|
|||||||
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(family_, &net_addr->sin_addr, netmask, INET6_ADDRSTRLEN);
|
||||||
cidrRaw = net_addr->sin_addr.s_addr;
|
cidrRaw = net_addr->sin_addr.s_addr;
|
||||||
linked_ = ifa->ifa_flags & IFF_RUNNING;
|
|
||||||
unsigned int cidr = 0;
|
unsigned int cidr = 0;
|
||||||
while (cidrRaw) {
|
while (cidrRaw) {
|
||||||
cidr += cidrRaw & 1;
|
cidr += cidrRaw & 1;
|
||||||
cidrRaw >>= 1;
|
cidrRaw >>= 1;
|
||||||
}
|
}
|
||||||
cidr_ = cidr;
|
cidr_ = cidr;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ifa = ifa->ifa_next;
|
ifa = ifa->ifa_next;
|
||||||
}
|
}
|
||||||
freeifaddrs(ifaddr);
|
freeifaddrs(ifaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int waybar::modules::Network::netlinkRequest(void *req, uint32_t reqlen, uint32_t groups) {
|
int waybar::modules::Network::netlinkRequest(void *req, uint32_t reqlen, uint32_t groups) const {
|
||||||
struct sockaddr_nl sa = {};
|
struct sockaddr_nl sa = {};
|
||||||
sa.nl_family = AF_NETLINK;
|
sa.nl_family = AF_NETLINK;
|
||||||
sa.nl_groups = groups;
|
sa.nl_groups = groups;
|
||||||
@ -516,7 +496,7 @@ int waybar::modules::Network::netlinkRequest(void *req, uint32_t reqlen, uint32_
|
|||||||
return sendmsg(nl_socket_get_fd(ev_sock_), &msg, 0);
|
return sendmsg(nl_socket_get_fd(ev_sock_), &msg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int waybar::modules::Network::netlinkResponse(void *resp, uint32_t resplen, uint32_t groups) {
|
int waybar::modules::Network::netlinkResponse(void *resp, uint32_t resplen, uint32_t groups) const {
|
||||||
struct sockaddr_nl sa = {};
|
struct sockaddr_nl sa = {};
|
||||||
sa.nl_family = AF_NETLINK;
|
sa.nl_family = AF_NETLINK;
|
||||||
sa.nl_groups = groups;
|
sa.nl_groups = groups;
|
||||||
@ -539,20 +519,23 @@ bool waybar::modules::Network::checkInterface(struct ifinfomsg *rtif, std::strin
|
|||||||
return config_["interface"].asString() == name ||
|
return config_["interface"].asString() == name ||
|
||||||
wildcardMatch(config_["interface"].asString(), name);
|
wildcardMatch(config_["interface"].asString(), name);
|
||||||
}
|
}
|
||||||
|
// getExternalInterface may need some delay to detect external interface
|
||||||
|
for (uint8_t tries = 0; tries < MAX_RETRY; tries += 1) {
|
||||||
auto external_iface = getExternalInterface();
|
auto external_iface = getExternalInterface();
|
||||||
if (external_iface == -1) {
|
if (external_iface > 0) {
|
||||||
// Try with lastest working external iface
|
|
||||||
return last_ext_iface_ == rtif->ifi_index;
|
|
||||||
}
|
|
||||||
return external_iface == rtif->ifi_index;
|
return external_iface == rtif->ifi_index;
|
||||||
}
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int waybar::modules::Network::getPreferredIface(int skip_idx) {
|
int waybar::modules::Network::getPreferredIface(int skip_idx) const {
|
||||||
|
int ifid = -1;
|
||||||
if (config_["interface"].isString()) {
|
if (config_["interface"].isString()) {
|
||||||
ifid_ = if_nametoindex(config_["interface"].asCString());
|
ifid = if_nametoindex(config_["interface"].asCString());
|
||||||
if (ifid_ > 0) {
|
if (ifid > 0) {
|
||||||
ifname_ = config_["interface"].asString();
|
return ifid;
|
||||||
return ifid_;
|
|
||||||
} else {
|
} else {
|
||||||
// Try with wildcard
|
// Try with wildcard
|
||||||
struct ifaddrs *ifaddr, *ifa;
|
struct ifaddrs *ifaddr, *ifa;
|
||||||
@ -561,24 +544,26 @@ int waybar::modules::Network::getPreferredIface(int skip_idx) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ifa = ifaddr;
|
ifa = ifaddr;
|
||||||
ifid_ = -1;
|
ifid = -1;
|
||||||
while (ifa != nullptr) {
|
while (ifa != nullptr) {
|
||||||
if (wildcardMatch(config_["interface"].asString(), ifa->ifa_name)) {
|
if (ifa->ifa_addr->sa_family == family_ &&
|
||||||
ifid_ = if_nametoindex(ifa->ifa_name);
|
wildcardMatch(config_["interface"].asString(), ifa->ifa_name)) {
|
||||||
|
ifid = if_nametoindex(ifa->ifa_name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ifa = ifa->ifa_next;
|
ifa = ifa->ifa_next;
|
||||||
}
|
}
|
||||||
freeifaddrs(ifaddr);
|
freeifaddrs(ifaddr);
|
||||||
return ifid_;
|
return ifid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ifid_ = getExternalInterface(skip_idx);
|
// getExternalInterface may need some delay to detect external interface
|
||||||
if (ifid_ > 0) {
|
for (uint8_t tries = 0; tries < MAX_RETRY; tries += 1) {
|
||||||
char ifname[IF_NAMESIZE];
|
ifid = getExternalInterface(skip_idx);
|
||||||
if_indextoname(ifid_, ifname);
|
if (ifid > 0) {
|
||||||
ifname_ = ifname;
|
return ifid;
|
||||||
return ifid_;
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -591,64 +576,80 @@ void waybar::modules::Network::clearIface() {
|
|||||||
signal_strength_dbm_ = 0;
|
signal_strength_dbm_ = 0;
|
||||||
signal_strength_ = 0;
|
signal_strength_ = 0;
|
||||||
frequency_ = 0;
|
frequency_ = 0;
|
||||||
linked_ = false;
|
}
|
||||||
|
|
||||||
|
void waybar::modules::Network::checkNewInterface(struct ifinfomsg *rtif) {
|
||||||
|
auto new_iface = getPreferredIface(rtif->ifi_index);
|
||||||
|
if (new_iface != -1) {
|
||||||
|
ifid_ = new_iface;
|
||||||
|
char ifname[IF_NAMESIZE];
|
||||||
|
if_indextoname(new_iface, ifname);
|
||||||
|
ifname_ = ifname;
|
||||||
|
getInterfaceAddress();
|
||||||
|
thread_timer_.wake_up();
|
||||||
|
} else {
|
||||||
|
ifid_ = -1;
|
||||||
|
dp.emit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) {
|
int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) {
|
||||||
auto net = static_cast<waybar::modules::Network *>(data);
|
auto net = static_cast<waybar::modules::Network *>(data);
|
||||||
auto nh = nlmsg_hdr(msg);
|
|
||||||
std::lock_guard<std::mutex> lock(net->mutex_);
|
std::lock_guard<std::mutex> lock(net->mutex_);
|
||||||
|
auto nh = nlmsg_hdr(msg);
|
||||||
if (nh->nlmsg_type == RTM_NEWADDR) {
|
auto ifi = static_cast<struct ifinfomsg *>(NLMSG_DATA(nh));
|
||||||
auto rtif = static_cast<struct ifinfomsg *>(NLMSG_DATA(nh));
|
if (nh->nlmsg_type == RTM_DELADDR) {
|
||||||
char ifname[IF_NAMESIZE];
|
|
||||||
if_indextoname(rtif->ifi_index, ifname);
|
|
||||||
// Auto detected network can also be assigned here
|
|
||||||
if ((net->ifid_ == -1 || rtif->ifi_index != net->ifid_) && net->checkInterface(rtif, ifname)) {
|
|
||||||
// If iface is different, clear data
|
|
||||||
if (rtif->ifi_index != net->ifid_) {
|
|
||||||
net->clearIface();
|
|
||||||
}
|
|
||||||
net->linked_ = true;
|
|
||||||
net->ifname_ = ifname;
|
|
||||||
net->ifid_ = rtif->ifi_index;
|
|
||||||
}
|
|
||||||
// Check for valid interface
|
// Check for valid interface
|
||||||
if (rtif->ifi_index == net->ifid_) {
|
if (ifi->ifi_index == net->ifid_) {
|
||||||
net->linked_ = true;
|
|
||||||
// Get Iface and WIFI info
|
|
||||||
net->getInterfaceAddress();
|
|
||||||
net->thread_timer_.wake_up();
|
|
||||||
}
|
|
||||||
} else if (nh->nlmsg_type == RTM_DELADDR) {
|
|
||||||
auto rtif = static_cast<struct ifinfomsg *>(NLMSG_DATA(nh));
|
|
||||||
// Check for valid interface
|
|
||||||
if (rtif->ifi_index == net->ifid_) {
|
|
||||||
net->ipaddr_.clear();
|
net->ipaddr_.clear();
|
||||||
net->netmask_.clear();
|
net->netmask_.clear();
|
||||||
net->cidr_ = 0;
|
net->cidr_ = 0;
|
||||||
net->dp.emit();
|
if (!(ifi->ifi_flags & IFF_RUNNING)) {
|
||||||
}
|
|
||||||
} else if (nh->nlmsg_type < RTM_NEWADDR) {
|
|
||||||
auto rtif = static_cast<struct ifinfomsg *>(NLMSG_DATA(nh));
|
|
||||||
char ifname[IF_NAMESIZE];
|
|
||||||
if_indextoname(rtif->ifi_index, ifname);
|
|
||||||
// Check for valid interface
|
|
||||||
if (rtif->ifi_flags & IFF_RUNNING && net->checkInterface(rtif, ifname)) {
|
|
||||||
net->linked_ = true;
|
|
||||||
net->ifname_ = ifname;
|
|
||||||
net->ifid_ = rtif->ifi_index;
|
|
||||||
net->dp.emit();
|
|
||||||
} else if (rtif->ifi_index == net->ifid_) {
|
|
||||||
net->clearIface();
|
net->clearIface();
|
||||||
// Check for a new interface and get info
|
// Check for a new interface and get info
|
||||||
auto new_iface = net->getPreferredIface(rtif->ifi_index);
|
net->checkNewInterface(ifi);
|
||||||
if (new_iface != -1) {
|
|
||||||
net->getInterfaceAddress();
|
|
||||||
net->thread_timer_.wake_up();
|
|
||||||
} else {
|
} else {
|
||||||
net->dp.emit();
|
net->dp.emit();
|
||||||
}
|
}
|
||||||
|
return NL_OK;
|
||||||
|
}
|
||||||
|
} else if (nh->nlmsg_type == RTM_NEWLINK || nh->nlmsg_type == RTM_DELLINK) {
|
||||||
|
char ifname[IF_NAMESIZE];
|
||||||
|
if_indextoname(ifi->ifi_index, ifname);
|
||||||
|
// Check for valid interface
|
||||||
|
if (ifi->ifi_index != net->ifid_ && net->checkInterface(ifi, ifname)) {
|
||||||
|
net->ifname_ = ifname;
|
||||||
|
net->ifid_ = ifi->ifi_index;
|
||||||
|
// Get Iface and WIFI info
|
||||||
|
net->getInterfaceAddress();
|
||||||
|
net->thread_timer_.wake_up();
|
||||||
|
return NL_OK;
|
||||||
|
} else if (ifi->ifi_index == net->ifid_ &&
|
||||||
|
(!(ifi->ifi_flags & IFF_RUNNING) || !(ifi->ifi_flags & IFF_UP) ||
|
||||||
|
!net->checkInterface(ifi, ifname))) {
|
||||||
|
net->clearIface();
|
||||||
|
// Check for a new interface and get info
|
||||||
|
net->checkNewInterface(ifi);
|
||||||
|
return NL_OK;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
char ifname[IF_NAMESIZE];
|
||||||
|
if_indextoname(ifi->ifi_index, ifname);
|
||||||
|
// Auto detected network can also be assigned here
|
||||||
|
if (ifi->ifi_index != net->ifid_ && net->checkInterface(ifi, ifname)) {
|
||||||
|
// If iface is different, clear data
|
||||||
|
if (ifi->ifi_index != net->ifid_) {
|
||||||
|
net->clearIface();
|
||||||
|
}
|
||||||
|
net->ifname_ = ifname;
|
||||||
|
net->ifid_ = ifi->ifi_index;
|
||||||
|
}
|
||||||
|
// Check for valid interface
|
||||||
|
if (ifi->ifi_index == net->ifid_) {
|
||||||
|
// Get Iface and WIFI info
|
||||||
|
net->getInterfaceAddress();
|
||||||
|
net->thread_timer_.wake_up();
|
||||||
|
return NL_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NL_SKIP;
|
return NL_SKIP;
|
||||||
@ -686,11 +687,10 @@ int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) {
|
|||||||
net->parseEssid(bss);
|
net->parseEssid(bss);
|
||||||
net->parseSignal(bss);
|
net->parseSignal(bss);
|
||||||
net->parseFreq(bss);
|
net->parseFreq(bss);
|
||||||
return NL_SKIP;
|
return NL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Network::parseEssid(struct nlattr **bss) {
|
void waybar::modules::Network::parseEssid(struct nlattr **bss) {
|
||||||
essid_.clear();
|
|
||||||
if (bss[NL80211_BSS_INFORMATION_ELEMENTS] != nullptr) {
|
if (bss[NL80211_BSS_INFORMATION_ELEMENTS] != nullptr) {
|
||||||
auto ies = static_cast<char *>(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]));
|
auto ies = static_cast<char *>(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]));
|
||||||
auto ies_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
|
auto ies_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
|
||||||
@ -763,7 +763,8 @@ auto waybar::modules::Network::getInfo() -> void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://gist.github.com/rressi/92af77630faf055934c723ce93ae2495
|
// https://gist.github.com/rressi/92af77630faf055934c723ce93ae2495
|
||||||
bool waybar::modules::Network::wildcardMatch(const std::string &pattern, const std::string &text) {
|
bool waybar::modules::Network::wildcardMatch(const std::string &pattern,
|
||||||
|
const std::string &text) const {
|
||||||
auto P = int(pattern.size());
|
auto P = int(pattern.size());
|
||||||
auto T = int(text.size());
|
auto T = int(text.size());
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "modules/pulseaudio.hpp"
|
#include "modules/pulseaudio.hpp"
|
||||||
|
|
||||||
waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value &config)
|
waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value &config)
|
||||||
: ALabel(config, "{volume}%"),
|
: ALabel(config, "pulseaudio", id, "{volume}%"),
|
||||||
mainloop_(nullptr),
|
mainloop_(nullptr),
|
||||||
mainloop_api_(nullptr),
|
mainloop_api_(nullptr),
|
||||||
context_(nullptr),
|
context_(nullptr),
|
||||||
@ -12,10 +12,6 @@ waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value
|
|||||||
source_idx_(0),
|
source_idx_(0),
|
||||||
source_volume_(0),
|
source_volume_(0),
|
||||||
source_muted_(false) {
|
source_muted_(false) {
|
||||||
label_.set_name("pulseaudio");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
mainloop_ = pa_threaded_mainloop_new();
|
mainloop_ = pa_threaded_mainloop_new();
|
||||||
if (mainloop_ == nullptr) {
|
if (mainloop_ == nullptr) {
|
||||||
throw std::runtime_error("pa_mainloop_new() failed.");
|
throw std::runtime_error("pa_mainloop_new() failed.");
|
||||||
@ -132,6 +128,10 @@ void waybar::modules::Pulseaudio::subscribeCb(pa_context * conte
|
|||||||
pa_subscription_event_type_t type, uint32_t idx,
|
pa_subscription_event_type_t type, uint32_t idx,
|
||||||
void *data) {
|
void *data) {
|
||||||
unsigned facility = type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK;
|
unsigned facility = type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK;
|
||||||
|
unsigned operation = type & PA_SUBSCRIPTION_EVENT_TYPE_MASK;
|
||||||
|
if (operation != PA_SUBSCRIPTION_EVENT_CHANGE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (facility == PA_SUBSCRIPTION_EVENT_SINK) {
|
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) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
#include "modules/sni/item.hpp"
|
||||||
#include <glibmm/main.h>
|
#include <glibmm/main.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
#include "modules/sni/item.hpp"
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<Glib::ustring> : formatter<std::string> {
|
struct fmt::formatter<Glib::ustring> : formatter<std::string> {
|
||||||
@ -334,7 +334,7 @@ void Item::makeMenu(GdkEventButton* const& ev) {
|
|||||||
bool Item::handleClick(GdkEventButton* const& ev) {
|
bool Item::handleClick(GdkEventButton* const& ev) {
|
||||||
auto parameters = Glib::VariantContainerBase::create_tuple(
|
auto parameters = Glib::VariantContainerBase::create_tuple(
|
||||||
{Glib::Variant<int>::create(ev->x), Glib::Variant<int>::create(ev->y)});
|
{Glib::Variant<int>::create(ev->x), Glib::Variant<int>::create(ev->y)});
|
||||||
if ((ev->button == 1 && item_is_menu) || ev->button == 3) {
|
if ((ev->button == 1 && (item_is_menu || !menu.empty())) || ev->button == 3) {
|
||||||
makeMenu(ev);
|
makeMenu(ev);
|
||||||
if (gtk_menu != nullptr) {
|
if (gtk_menu != nullptr) {
|
||||||
#if GTK_CHECK_VERSION(3, 22, 0)
|
#if GTK_CHECK_VERSION(3, 22, 0)
|
||||||
|
@ -3,11 +3,7 @@
|
|||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
Mode::Mode(const std::string& id, const Json::Value& config) : ALabel(config, "{}") {
|
Mode::Mode(const std::string& id, const Json::Value& config) : ALabel(config, "mode", id, "{}") {
|
||||||
label_.set_name("mode");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
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
|
||||||
|
@ -4,13 +4,8 @@
|
|||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
Window::Window(const std::string& id, const Bar& bar, const Json::Value& config)
|
Window::Window(const std::string& id, const Bar& bar, const Json::Value& config)
|
||||||
: ALabel(config, "{}"), bar_(bar), windowId_(-1) {
|
: ALabel(config, "window", id, "{}"), bar_(bar), windowId_(-1) {
|
||||||
label_.set_name("window");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
if (label_.get_max_width_chars() == -1) {
|
if (label_.get_max_width_chars() == -1) {
|
||||||
label_.set_hexpand(true);
|
|
||||||
label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END);
|
label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END);
|
||||||
}
|
}
|
||||||
ipc_.subscribe(R"(["window","workspace"])");
|
ipc_.subscribe(R"(["window","workspace"])");
|
||||||
@ -28,33 +23,8 @@ void Window::onCmd(const struct Ipc::ipc_response& res) {
|
|||||||
try {
|
try {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
auto payload = parser_.parse(res.payload);
|
auto payload = parser_.parse(res.payload);
|
||||||
auto [nb, id, name, app_id] = getFocusedNode(payload);
|
std::tie(app_nb_, windowId_, window_, app_id_) = getFocusedNode(payload);
|
||||||
if (!app_id_.empty()) {
|
|
||||||
bar_.window.get_style_context()->remove_class(app_id_);
|
|
||||||
}
|
|
||||||
if (nb == 0) {
|
|
||||||
bar_.window.get_style_context()->remove_class("solo");
|
|
||||||
if (!bar_.window.get_style_context()->has_class("empty")) {
|
|
||||||
bar_.window.get_style_context()->add_class("empty");
|
|
||||||
}
|
|
||||||
} else if (nb == 1) {
|
|
||||||
bar_.window.get_style_context()->remove_class("empty");
|
|
||||||
if (!bar_.window.get_style_context()->has_class("solo")) {
|
|
||||||
bar_.window.get_style_context()->add_class("solo");
|
|
||||||
}
|
|
||||||
if (!app_id.empty() && !bar_.window.get_style_context()->has_class(app_id)) {
|
|
||||||
bar_.window.get_style_context()->add_class(app_id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bar_.window.get_style_context()->remove_class("solo");
|
|
||||||
bar_.window.get_style_context()->remove_class("empty");
|
|
||||||
}
|
|
||||||
app_id_ = app_id;
|
|
||||||
if (windowId_ != id || window_ != name) {
|
|
||||||
windowId_ = id;
|
|
||||||
window_ = name;
|
|
||||||
dp.emit();
|
dp.emit();
|
||||||
}
|
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
spdlog::error("Window: {}", e.what());
|
spdlog::error("Window: {}", e.what());
|
||||||
}
|
}
|
||||||
@ -71,6 +41,27 @@ void Window::worker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto Window::update() -> void {
|
auto Window::update() -> void {
|
||||||
|
if (!old_app_id_.empty()) {
|
||||||
|
bar_.window.get_style_context()->remove_class(old_app_id_);
|
||||||
|
}
|
||||||
|
if (app_nb_ == 0) {
|
||||||
|
bar_.window.get_style_context()->remove_class("solo");
|
||||||
|
if (!bar_.window.get_style_context()->has_class("empty")) {
|
||||||
|
bar_.window.get_style_context()->add_class("empty");
|
||||||
|
}
|
||||||
|
} else if (app_nb_ == 1) {
|
||||||
|
bar_.window.get_style_context()->remove_class("empty");
|
||||||
|
if (!bar_.window.get_style_context()->has_class("solo")) {
|
||||||
|
bar_.window.get_style_context()->add_class("solo");
|
||||||
|
}
|
||||||
|
if (!app_id_.empty() && !bar_.window.get_style_context()->has_class(app_id_)) {
|
||||||
|
bar_.window.get_style_context()->add_class(app_id_);
|
||||||
|
old_app_id_ = app_id_;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bar_.window.get_style_context()->remove_class("solo");
|
||||||
|
bar_.window.get_style_context()->remove_class("empty");
|
||||||
|
}
|
||||||
label_.set_markup(fmt::format(format_, window_));
|
label_.set_markup(fmt::format(format_, window_));
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
label_.set_tooltip_text(window_);
|
label_.set_tooltip_text(window_);
|
||||||
|
@ -16,7 +16,7 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value
|
|||||||
ipc_.signal_event.connect(sigc::mem_fun(*this, &Workspaces::onEvent));
|
ipc_.signal_event.connect(sigc::mem_fun(*this, &Workspaces::onEvent));
|
||||||
ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Workspaces::onCmd));
|
ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Workspaces::onCmd));
|
||||||
ipc_.sendCmd(IPC_GET_WORKSPACES);
|
ipc_.sendCmd(IPC_GET_WORKSPACES);
|
||||||
if (!config["disable-bar-scroll"].asBool()) {
|
if (config["enable-bar-scroll"].asBool()) {
|
||||||
auto &window = const_cast<Bar &>(bar_).window;
|
auto &window = const_cast<Bar &>(bar_).window;
|
||||||
window.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
window.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
||||||
window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
||||||
@ -80,6 +80,7 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) {
|
|||||||
// Adding to all outputs
|
// Adding to all outputs
|
||||||
Json::Value v;
|
Json::Value v;
|
||||||
v["name"] = p_w_name;
|
v["name"] = p_w_name;
|
||||||
|
v["target_output"] = "";
|
||||||
workspaces_.emplace_back(std::move(v));
|
workspaces_.emplace_back(std::move(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,6 +155,11 @@ auto Workspaces::update() -> void {
|
|||||||
} else {
|
} else {
|
||||||
button.get_style_context()->remove_class("urgent");
|
button.get_style_context()->remove_class("urgent");
|
||||||
}
|
}
|
||||||
|
if ((*it)["target_output"].isString()) {
|
||||||
|
button.get_style_context()->add_class("persistant");
|
||||||
|
} else {
|
||||||
|
button.get_style_context()->remove_class("persistant");
|
||||||
|
}
|
||||||
if (needReorder) {
|
if (needReorder) {
|
||||||
box_.reorder_child(button, it - workspaces_.begin());
|
box_.reorder_child(button, it - workspaces_.begin());
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "modules/temperature.hpp"
|
#include "modules/temperature.hpp"
|
||||||
|
|
||||||
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, "{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 {
|
} else {
|
||||||
@ -12,10 +12,6 @@ waybar::modules::Temperature::Temperature(const std::string& id, const Json::Val
|
|||||||
if (!temp.is_open()) {
|
if (!temp.is_open()) {
|
||||||
throw std::runtime_error("Can't open " + file_path_);
|
throw std::runtime_error("Can't open " + file_path_);
|
||||||
}
|
}
|
||||||
label_.set_name("temperature");
|
|
||||||
if (!id.empty()) {
|
|
||||||
label_.get_style_context()->add_class(id);
|
|
||||||
}
|
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
dp.emit();
|
dp.emit();
|
||||||
thread_.sleep_for(interval_);
|
thread_.sleep_for(interval_);
|
||||||
|
Reference in New Issue
Block a user