mirror of
https://github.com/rad4day/Waybar.git
synced 2023-12-21 10:22:59 +01:00
Merge branch 'Alexays:master' into master
This commit is contained in:
commit
4ed13df092
57
ext4fuse.rb
Normal file
57
ext4fuse.rb
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
class MacFuseRequirement < Requirement
|
||||||
|
fatal true
|
||||||
|
|
||||||
|
satisfy(build_env: false) { self.class.binary_mac_fuse_installed? }
|
||||||
|
|
||||||
|
def self.binary_mac_fuse_installed?
|
||||||
|
File.exist?("/usr/local/include/fuse/fuse.h") &&
|
||||||
|
!File.symlink?("/usr/local/include/fuse")
|
||||||
|
end
|
||||||
|
|
||||||
|
env do
|
||||||
|
ENV.append_path "PKG_CONFIG_PATH", HOMEBREW_LIBRARY/"Homebrew/os/mac/pkgconfig/fuse"
|
||||||
|
ENV.append_path "PKG_CONFIG_PATH", "/usr/local/lib/pkgconfig"
|
||||||
|
|
||||||
|
unless HOMEBREW_PREFIX.to_s == "/usr/local"
|
||||||
|
ENV.append_path "HOMEBREW_LIBRARY_PATHS", "/usr/local/lib"
|
||||||
|
ENV.append_path "HOMEBREW_INCLUDE_PATHS", "/usr/local/include/fuse"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def message
|
||||||
|
"macFUSE is required. Please run `brew install --cask macfuse` first."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Ext4fuse < Formula
|
||||||
|
desc "Read-only implementation of ext4 for FUSE"
|
||||||
|
homepage "https://github.com/gerard/ext4fuse"
|
||||||
|
url "https://github.com/gerard/ext4fuse/archive/v0.1.3.tar.gz"
|
||||||
|
sha256 "550f1e152c4de7d4ea517ee1c708f57bfebb0856281c508511419db45aa3ca9f"
|
||||||
|
license "GPL-2.0"
|
||||||
|
head "https://github.com/gerard/ext4fuse.git"
|
||||||
|
|
||||||
|
bottle do
|
||||||
|
sha256 cellar: :any, catalina: "446dde5e84b058966ead0cde5e38e9411f465732527f6decfa1c0dcdbd4abbef"
|
||||||
|
sha256 cellar: :any, mojave: "88c4918bf5218f99295e539fe4499152edb3b60b6659e44ddd68b22359f512ae"
|
||||||
|
sha256 cellar: :any, high_sierra: "fc69c8993afd0ffc16a73c9c036ca8f83c77ac2a19b3237f76f9ccee8b30bbc9"
|
||||||
|
sha256 cellar: :any, sierra: "fe8bbe7cd5362f00ff06ef750926bf349d60563c20b0ecf212778631c8912ba2"
|
||||||
|
sha256 cellar: :any, el_capitan: "291047c821b7b205d85be853fb005510c6ab01bd4c2a2193c192299b6f049d35"
|
||||||
|
sha256 cellar: :any, yosemite: "b11f564b7e7c08af0b0a3e9854973d39809bf2d8a56014f4882772b2f7307ac1"
|
||||||
|
end
|
||||||
|
|
||||||
|
depends_on "pkg-config" => :build
|
||||||
|
|
||||||
|
on_macos do
|
||||||
|
depends_on MacFuseRequirement => :build
|
||||||
|
end
|
||||||
|
|
||||||
|
on_linux do
|
||||||
|
depends_on "libfuse"
|
||||||
|
end
|
||||||
|
|
||||||
|
def install
|
||||||
|
system "make"
|
||||||
|
bin.install "ext4fuse"
|
||||||
|
end
|
||||||
|
end
|
34
include/AButton.hpp
Normal file
34
include/AButton.hpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glibmm/markup.h>
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <gtkmm/label.h>
|
||||||
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
|
||||||
|
namespace waybar {
|
||||||
|
|
||||||
|
class AButton : public AModule {
|
||||||
|
public:
|
||||||
|
AButton(const Json::Value &, const std::string &, const std::string &, const std::string &format,
|
||||||
|
uint16_t interval = 0, bool ellipsize = false, bool enable_click = false,
|
||||||
|
bool enable_scroll = false);
|
||||||
|
virtual ~AButton() = default;
|
||||||
|
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::vector<std::string> &alts, uint16_t max = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Gtk::Button button_ = Gtk::Button(name_);
|
||||||
|
Gtk::Label *label_ = (Gtk::Label *)button_.get_child();
|
||||||
|
std::string format_;
|
||||||
|
const std::chrono::seconds interval_;
|
||||||
|
bool alt_ = false;
|
||||||
|
std::string default_format_;
|
||||||
|
|
||||||
|
virtual bool handleToggle(GdkEventButton *const &e);
|
||||||
|
virtual std::string getState(uint8_t value, bool lesser = false);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar
|
@ -23,8 +23,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_HYPRLAND
|
#ifdef HAVE_HYPRLAND
|
||||||
#include "modules/hyprland/backend.hpp"
|
#include "modules/hyprland/backend.hpp"
|
||||||
#include "modules/hyprland/window.hpp"
|
|
||||||
#include "modules/hyprland/language.hpp"
|
#include "modules/hyprland/language.hpp"
|
||||||
|
#include "modules/hyprland/window.hpp"
|
||||||
#endif
|
#endif
|
||||||
#if defined(__linux__) && !defined(NO_FILESYSTEM)
|
#if defined(__linux__) && !defined(NO_FILESYSTEM)
|
||||||
#include "modules/battery.hpp"
|
#include "modules/battery.hpp"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ struct udev_device;
|
|||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Backlight : public ALabel {
|
class Backlight : public AButton {
|
||||||
class BacklightDev {
|
class BacklightDev {
|
||||||
public:
|
public:
|
||||||
BacklightDev() = default;
|
BacklightDev() = default;
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
@ -24,7 +24,7 @@ namespace fs = std::experimental::filesystem;
|
|||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Battery : public ALabel {
|
class Battery : public AButton {
|
||||||
public:
|
public:
|
||||||
Battery(const std::string&, const Json::Value&);
|
Battery(const std::string&, const Json::Value&);
|
||||||
~Battery();
|
~Battery();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#ifdef WANT_RFKILL
|
#ifdef WANT_RFKILL
|
||||||
#include "util/rfkill.hpp"
|
#include "util/rfkill.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Bluetooth : public ALabel {
|
class Bluetooth : public AButton {
|
||||||
struct ControllerInfo {
|
struct ControllerInfo {
|
||||||
std::string path;
|
std::string path;
|
||||||
std::string address;
|
std::string address;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <date/tz.h>
|
#include <date/tz.h>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
@ -14,7 +14,7 @@ namespace modules {
|
|||||||
const std::string kCalendarPlaceholder = "calendar";
|
const std::string kCalendarPlaceholder = "calendar";
|
||||||
const std::string KTimezonedTimeListPlaceholder = "timezoned_time_list";
|
const std::string KTimezonedTimeListPlaceholder = "timezoned_time_list";
|
||||||
|
|
||||||
class Clock : public ALabel {
|
class Clock : public AButton {
|
||||||
public:
|
public:
|
||||||
Clock(const std::string&, const Json::Value&);
|
Clock(const std::string&, const Json::Value&);
|
||||||
~Clock() = default;
|
~Clock() = default;
|
||||||
|
@ -9,12 +9,12 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Cpu : public ALabel {
|
class Cpu : public AButton {
|
||||||
public:
|
public:
|
||||||
Cpu(const std::string&, const Json::Value&);
|
Cpu(const std::string&, const Json::Value&);
|
||||||
~Cpu() = default;
|
~Cpu() = default;
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/command.hpp"
|
#include "util/command.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Custom : public ALabel {
|
class Custom : public AButton {
|
||||||
public:
|
public:
|
||||||
Custom(const std::string&, const std::string&, const Json::Value&);
|
Custom(const std::string&, const std::string&, const Json::Value&);
|
||||||
~Custom();
|
~Custom();
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/format.hpp"
|
#include "util/format.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Disk : public ALabel {
|
class Disk : public AButton {
|
||||||
public:
|
public:
|
||||||
Disk(const std::string&, const Json::Value&);
|
Disk(const std::string&, const Json::Value&);
|
||||||
~Disk() = default;
|
~Disk() = default;
|
||||||
|
@ -1,30 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace waybar::modules::hyprland {
|
namespace waybar::modules::hyprland {
|
||||||
class IPC {
|
class IPC {
|
||||||
public:
|
public:
|
||||||
IPC() { startIPC(); }
|
IPC() { startIPC(); }
|
||||||
|
|
||||||
void registerForIPC(const std::string&, std::function<void(const std::string&)>);
|
void registerForIPC(const std::string&, std::function<void(const std::string&)>);
|
||||||
|
|
||||||
std::string getSocket1Reply(const std::string& rq);
|
std::string getSocket1Reply(const std::string& rq);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void startIPC();
|
||||||
|
void parseIPC(const std::string&);
|
||||||
|
|
||||||
void startIPC();
|
std::mutex callbackMutex;
|
||||||
void parseIPC(const std::string&);
|
std::deque<std::pair<std::string, std::function<void(const std::string&)>>> callbacks;
|
||||||
|
|
||||||
std::mutex callbackMutex;
|
|
||||||
std::deque<std::pair<std::string, std::function<void(const std::string&)>>> callbacks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<IPC> gIPC;
|
inline std::unique_ptr<IPC> gIPC;
|
||||||
inline bool modulesReady = false;
|
inline bool modulesReady = false;
|
||||||
};
|
}; // namespace waybar::modules::hyprland
|
||||||
|
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "modules/hyprland/backend.hpp"
|
#include "modules/hyprland/backend.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::hyprland {
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
class Language : public waybar::ALabel {
|
class Language : public waybar::AButton {
|
||||||
public:
|
public:
|
||||||
Language(const std::string&, const waybar::Bar&, const Json::Value&);
|
Language(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
~Language() = default;
|
~Language() = default;
|
||||||
|
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onEvent(const std::string&);
|
void onEvent(const std::string&);
|
||||||
|
|
||||||
void initLanguage();
|
void initLanguage();
|
||||||
@ -26,4 +26,4 @@ private:
|
|||||||
std::string layoutName_;
|
std::string layoutName_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace waybar::modules::hyprland
|
||||||
|
@ -10,19 +10,22 @@
|
|||||||
namespace waybar::modules::hyprland {
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
class Window : public waybar::ALabel {
|
class Window : public waybar::ALabel {
|
||||||
public:
|
public:
|
||||||
Window(const std::string&, const waybar::Bar&, const Json::Value&);
|
Window(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
~Window() = default;
|
~Window() = default;
|
||||||
|
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint getActiveWorkspaceID(std::string);
|
||||||
|
std::string getLastWindowTitle(uint);
|
||||||
void onEvent(const std::string&);
|
void onEvent(const std::string&);
|
||||||
|
|
||||||
|
bool separate_outputs;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::string lastView;
|
std::string lastView;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace waybar::modules::hyprland
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class IdleInhibitor : public ALabel {
|
class IdleInhibitor : public AButton {
|
||||||
sigc::connection timeout_;
|
sigc::connection timeout_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -20,6 +20,7 @@ class IdleInhibitor : public ALabel {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool handleToggle(GdkEventButton* const& e);
|
bool handleToggle(GdkEventButton* const& e);
|
||||||
|
void toggleStatus();
|
||||||
|
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
struct zwp_idle_inhibitor_v1* idle_inhibitor_;
|
struct zwp_idle_inhibitor_v1* idle_inhibitor_;
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Inhibitor : public ALabel {
|
class Inhibitor : public AButton {
|
||||||
public:
|
public:
|
||||||
Inhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
|
Inhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
~Inhibitor() override;
|
~Inhibitor() override;
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fstream>
|
|
||||||
#include <jack/jack.h>
|
#include <jack/jack.h>
|
||||||
#include <jack/thread.h>
|
#include <jack/thread.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
@ -11,26 +13,26 @@ namespace waybar::modules {
|
|||||||
|
|
||||||
class JACK : public ALabel {
|
class JACK : public ALabel {
|
||||||
public:
|
public:
|
||||||
JACK(const std::string&, const Json::Value&);
|
JACK(const std::string &, const Json::Value &);
|
||||||
~JACK() = default;
|
~JACK() = default;
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
|
|
||||||
int bufSize(jack_nframes_t size);
|
int bufSize(jack_nframes_t size);
|
||||||
int sampleRate(jack_nframes_t rate);
|
int sampleRate(jack_nframes_t rate);
|
||||||
int xrun();
|
int xrun();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string JACKState();
|
std::string JACKState();
|
||||||
|
|
||||||
jack_client_t* client_;
|
jack_client_t *client_;
|
||||||
jack_nframes_t bufsize_;
|
jack_nframes_t bufsize_;
|
||||||
jack_nframes_t samplerate_;
|
jack_nframes_t samplerate_;
|
||||||
unsigned int xruns_;
|
unsigned int xruns_;
|
||||||
float load_;
|
float load_;
|
||||||
bool running_;
|
bool running_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
std::string state_;
|
std::string state_;
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Memory : public ALabel {
|
class Memory : public AButton {
|
||||||
public:
|
public:
|
||||||
Memory(const std::string&, const Json::Value&);
|
Memory(const std::string&, const Json::Value&);
|
||||||
~Memory() = default;
|
~Memory() = default;
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "modules/mpd/state.hpp"
|
#include "modules/mpd/state.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class MPD : public ALabel {
|
class MPD : public AButton {
|
||||||
friend class detail::Context;
|
friend class detail::Context;
|
||||||
|
|
||||||
// State machine
|
// State machine
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
class MPD;
|
class MPD;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
#ifdef WANT_RFKILL
|
#ifdef WANT_RFKILL
|
||||||
#include "util/rfkill.hpp"
|
#include "util/rfkill.hpp"
|
||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Network : public ALabel {
|
class Network : public AButton {
|
||||||
public:
|
public:
|
||||||
Network(const std::string&, const Json::Value&);
|
Network(const std::string&, const Json::Value&);
|
||||||
~Network();
|
~Network();
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Pulseaudio : public ALabel {
|
class Pulseaudio : public AButton {
|
||||||
public:
|
public:
|
||||||
Pulseaudio(const std::string&, const Json::Value&);
|
Pulseaudio(const std::string&, const Json::Value&);
|
||||||
~Pulseaudio();
|
~Pulseaudio();
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
#include <fmt/chrono.h>
|
#include <fmt/chrono.h>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Clock : public ALabel {
|
class Clock : public AButton {
|
||||||
public:
|
public:
|
||||||
Clock(const std::string&, const Json::Value&);
|
Clock(const std::string&, const Json::Value&);
|
||||||
~Clock() = default;
|
~Clock() = default;
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Sndio : public ALabel {
|
class Sndio : public AButton {
|
||||||
public:
|
public:
|
||||||
Sndio(const std::string &, const Json::Value &);
|
Sndio(const std::string &, const Json::Value &);
|
||||||
~Sndio();
|
~Sndio();
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
#include "modules/sway/ipc/client.hpp"
|
#include "modules/sway/ipc/client.hpp"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
class Language : public ALabel, public sigc::trackable {
|
class Language : public AButton, public sigc::trackable {
|
||||||
public:
|
public:
|
||||||
Language(const std::string& id, const Json::Value& config);
|
Language(const std::string& id, const Json::Value& config);
|
||||||
~Language() = default;
|
~Language() = default;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
#include "modules/sway/ipc/client.hpp"
|
#include "modules/sway/ipc/client.hpp"
|
||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
class Mode : public ALabel, public sigc::trackable {
|
class Mode : public AButton, public sigc::trackable {
|
||||||
public:
|
public:
|
||||||
Mode(const std::string&, const Json::Value&);
|
Mode(const std::string&, const Json::Value&);
|
||||||
~Mode() = default;
|
~Mode() = default;
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AButton.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Temperature : public ALabel {
|
class Temperature : public AButton {
|
||||||
public:
|
public:
|
||||||
Temperature(const std::string&, const Json::Value&);
|
Temperature(const std::string&, const Json::Value&);
|
||||||
~Temperature() = default;
|
~Temperature() = default;
|
||||||
|
@ -56,9 +56,10 @@ struct formatter<pow_format> {
|
|||||||
fraction /= base;
|
fraction /= base;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto max_width = 4 // coeff in {:.3g} format
|
auto number_width = 5 // coeff in {:.1f} format
|
||||||
+ 1 // prefix from units array
|
+ s.binary_; // potential 4th digit before the decimal point
|
||||||
+ s.binary_ // for the 'i' in GiB.
|
auto max_width = number_width + 1 // prefix from units array
|
||||||
|
+ s.binary_ // for the 'i' in GiB.
|
||||||
+ s.unit_.length();
|
+ s.unit_.length();
|
||||||
|
|
||||||
const char* format;
|
const char* format;
|
||||||
@ -69,15 +70,16 @@ struct formatter<pow_format> {
|
|||||||
case '<':
|
case '<':
|
||||||
return format_to(ctx.out(), "{:<{}}", fmt::format("{}", s), max_width);
|
return format_to(ctx.out(), "{:<{}}", fmt::format("{}", s), max_width);
|
||||||
case '=':
|
case '=':
|
||||||
format = "{coefficient:<4.3g}{padding}{prefix}{unit}";
|
format = "{coefficient:<{number_width}.1f}{padding}{prefix}{unit}";
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
format = "{coefficient:.3g}{prefix}{unit}";
|
format = "{coefficient:.1f}{prefix}{unit}";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return format_to(
|
return format_to(
|
||||||
ctx.out(), format, fmt::arg("coefficient", fraction),
|
ctx.out(), format, fmt::arg("coefficient", fraction),
|
||||||
|
fmt::arg("number_width", number_width),
|
||||||
fmt::arg("prefix", std::string() + units[pow] + ((s.binary_ && pow) ? "i" : "")),
|
fmt::arg("prefix", std::string() + units[pow] + ((s.binary_ && pow) ? "i" : "")),
|
||||||
fmt::arg("unit", s.unit_),
|
fmt::arg("unit", s.unit_),
|
||||||
fmt::arg("padding", pow ? ""
|
fmt::arg("padding", pow ? ""
|
||||||
|
6
include/util/sanitize_str.hpp
Normal file
6
include/util/sanitize_str.hpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace waybar::util {
|
||||||
|
std::string sanitize_string(std::string str);
|
||||||
|
} // namespace waybar::util
|
@ -63,6 +63,11 @@ screensaving, also known as "presentation mode".
|
|||||||
typeof: double ++
|
typeof: double ++
|
||||||
Threshold to be used when scrolling.
|
Threshold to be used when scrolling.
|
||||||
|
|
||||||
|
*start-activated*: ++
|
||||||
|
typeof: bool ++
|
||||||
|
default: *false* ++
|
||||||
|
Whether the inhibit should be activated when starting waybar.
|
||||||
|
|
||||||
*timeout*: ++
|
*timeout*: ++
|
||||||
typeof: double ++
|
typeof: double ++
|
||||||
The number of minutes the inhibit should last.
|
The number of minutes the inhibit should last.
|
||||||
|
@ -101,6 +101,10 @@ Additionally you can control the volume by scrolling *up* or *down* while the cu
|
|||||||
default: 100 ++
|
default: 100 ++
|
||||||
The maximum volume that can be set, in percentage.
|
The maximum volume that can be set, in percentage.
|
||||||
|
|
||||||
|
*ignored-sinks*: ++
|
||||||
|
typeof: array ++
|
||||||
|
Sinks in this list will not be shown as the active sink by Waybar. Entries should be the sink's description field.
|
||||||
|
|
||||||
# FORMAT REPLACEMENTS
|
# FORMAT REPLACEMENTS
|
||||||
|
|
||||||
*{desc}*: Pulseaudio port's description, for bluetooth it'll be the device name.
|
*{desc}*: Pulseaudio port's description, for bluetooth it'll be the device name.
|
||||||
|
@ -143,6 +143,7 @@ endif
|
|||||||
src_files = files(
|
src_files = files(
|
||||||
'src/factory.cpp',
|
'src/factory.cpp',
|
||||||
'src/AModule.cpp',
|
'src/AModule.cpp',
|
||||||
|
'src/AButton.cpp',
|
||||||
'src/ALabel.cpp',
|
'src/ALabel.cpp',
|
||||||
'src/AIconLabel.cpp',
|
'src/AIconLabel.cpp',
|
||||||
'src/modules/custom.cpp',
|
'src/modules/custom.cpp',
|
||||||
@ -155,7 +156,8 @@ src_files = files(
|
|||||||
'src/client.cpp',
|
'src/client.cpp',
|
||||||
'src/config.cpp',
|
'src/config.cpp',
|
||||||
'src/group.cpp',
|
'src/group.cpp',
|
||||||
'src/util/ustring_clen.cpp'
|
'src/util/ustring_clen.cpp',
|
||||||
|
'src/util/sanitize_str.cpp'
|
||||||
)
|
)
|
||||||
|
|
||||||
if is_linux
|
if is_linux
|
||||||
|
@ -34,6 +34,12 @@ window#waybar.chromium {
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
||||||
|
button:hover {
|
||||||
|
background: inherit;
|
||||||
|
box-shadow: inset 0 -3px #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
#workspaces button {
|
#workspaces button {
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
@ -45,10 +51,8 @@ window#waybar.chromium {
|
|||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
|
||||||
#workspaces button:hover {
|
#workspaces button:hover {
|
||||||
background: rgba(0, 0, 0, 0.2);
|
background: rgba(0, 0, 0, 0.2);
|
||||||
box-shadow: inset 0 -3px #ffffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#workspaces button.focused {
|
#workspaces button.focused {
|
||||||
|
154
src/AButton.cpp
Normal file
154
src/AButton.cpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
#include "AButton.hpp"
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <util/command.hpp>
|
||||||
|
|
||||||
|
namespace waybar {
|
||||||
|
|
||||||
|
AButton::AButton(const Json::Value& config, const std::string& name, const std::string& id,
|
||||||
|
const std::string& format, uint16_t interval, bool ellipsize, bool enable_click,
|
||||||
|
bool enable_scroll)
|
||||||
|
: AModule(config, name, id, config["format-alt"].isString() || enable_click, enable_scroll),
|
||||||
|
format_(config_["format"].isString() ? config_["format"].asString() : format),
|
||||||
|
interval_(config_["interval"] == "once"
|
||||||
|
? std::chrono::seconds(100000000)
|
||||||
|
: std::chrono::seconds(
|
||||||
|
config_["interval"].isUInt() ? config_["interval"].asUInt() : interval)),
|
||||||
|
default_format_(format_) {
|
||||||
|
button_.set_name(name);
|
||||||
|
button_.set_relief(Gtk::RELIEF_NONE);
|
||||||
|
if (!id.empty()) {
|
||||||
|
button_.get_style_context()->add_class(id);
|
||||||
|
}
|
||||||
|
event_box_.add(button_);
|
||||||
|
if (config_["max-length"].isUInt()) {
|
||||||
|
label_->set_max_width_chars(config_["max-length"].asInt());
|
||||||
|
label_->set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END);
|
||||||
|
label_->set_single_line_mode(true);
|
||||||
|
} else if (ellipsize && label_->get_max_width_chars() == -1) {
|
||||||
|
label_->set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END);
|
||||||
|
label_->set_single_line_mode(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_["min-length"].isUInt()) {
|
||||||
|
label_->set_width_chars(config_["min-length"].asUInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint rotate = 0;
|
||||||
|
|
||||||
|
if (config_["rotate"].isUInt()) {
|
||||||
|
rotate = config["rotate"].asUInt();
|
||||||
|
label_->set_angle(rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_["align"].isDouble()) {
|
||||||
|
auto align = config_["align"].asFloat();
|
||||||
|
if (rotate == 90 || rotate == 270) {
|
||||||
|
label_->set_yalign(align);
|
||||||
|
} else {
|
||||||
|
label_->set_xalign(align);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(config_["on-click"].isString() || config_["on-click-middle"].isString() ||
|
||||||
|
config_["on-click-backward"].isString() || config_["on-click-forward"].isString() ||
|
||||||
|
config_["on-click-right"].isString() || config_["format-alt"].isString() || enable_click)) {
|
||||||
|
button_.set_sensitive(false);
|
||||||
|
} else {
|
||||||
|
button_.signal_pressed().connect([this] {
|
||||||
|
GdkEventButton* e = (GdkEventButton*)gdk_event_new(GDK_BUTTON_PRESS);
|
||||||
|
e->button = 1;
|
||||||
|
handleToggle(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto AButton::update() -> void { AModule::update(); }
|
||||||
|
|
||||||
|
std::string AButton::getIcon(uint16_t percentage, const std::string& alt, uint16_t max) {
|
||||||
|
auto format_icons = config_["format-icons"];
|
||||||
|
if (format_icons.isObject()) {
|
||||||
|
if (!alt.empty() && (format_icons[alt].isString() || format_icons[alt].isArray())) {
|
||||||
|
format_icons = format_icons[alt];
|
||||||
|
} else {
|
||||||
|
format_icons = format_icons["default"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (format_icons.isArray()) {
|
||||||
|
auto size = format_icons.size();
|
||||||
|
auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1);
|
||||||
|
format_icons = format_icons[idx];
|
||||||
|
}
|
||||||
|
if (format_icons.isString()) {
|
||||||
|
return format_icons.asString();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AButton::getIcon(uint16_t percentage, const std::vector<std::string>& alts,
|
||||||
|
uint16_t max) {
|
||||||
|
auto format_icons = config_["format-icons"];
|
||||||
|
if (format_icons.isObject()) {
|
||||||
|
std::string _alt = "default";
|
||||||
|
for (const auto& alt : alts) {
|
||||||
|
if (!alt.empty() && (format_icons[alt].isString() || format_icons[alt].isArray())) {
|
||||||
|
_alt = alt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
format_icons = format_icons[_alt];
|
||||||
|
}
|
||||||
|
if (format_icons.isArray()) {
|
||||||
|
auto size = format_icons.size();
|
||||||
|
auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1);
|
||||||
|
format_icons = format_icons[idx];
|
||||||
|
}
|
||||||
|
if (format_icons.isString()) {
|
||||||
|
return format_icons.asString();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool waybar::AButton::handleToggle(GdkEventButton* const& e) {
|
||||||
|
if (config_["format-alt-click"].isUInt() && e->button == config_["format-alt-click"].asUInt()) {
|
||||||
|
alt_ = !alt_;
|
||||||
|
if (alt_ && config_["format-alt"].isString()) {
|
||||||
|
format_ = config_["format-alt"].asString();
|
||||||
|
} else {
|
||||||
|
format_ = default_format_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AModule::handleToggle(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AButton::getState(uint8_t value, bool lesser) {
|
||||||
|
if (!config_["states"].isObject()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// Get current state
|
||||||
|
std::vector<std::pair<std::string, uint8_t>> states;
|
||||||
|
if (config_["states"].isObject()) {
|
||||||
|
for (auto it = config_["states"].begin(); it != config_["states"].end(); ++it) {
|
||||||
|
if (it->isUInt() && it.key().isString()) {
|
||||||
|
states.emplace_back(it.key().asString(), it->asUInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Sort states
|
||||||
|
std::sort(states.begin(), states.end(), [&lesser](auto& a, auto& b) {
|
||||||
|
return lesser ? a.second < b.second : a.second > b.second;
|
||||||
|
});
|
||||||
|
std::string valid_state;
|
||||||
|
for (auto const& state : states) {
|
||||||
|
if ((lesser ? value <= state.second : value >= state.second) && valid_state.empty()) {
|
||||||
|
button_.get_style_context()->add_class(state.first);
|
||||||
|
valid_state = state.first;
|
||||||
|
} else {
|
||||||
|
button_.get_style_context()->remove_class(state.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace waybar
|
@ -87,7 +87,7 @@ 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 &id, const Json::Value &config)
|
waybar::modules::Backlight::Backlight(const std::string &id, const Json::Value &config)
|
||||||
: ALabel(config, "backlight", id, "{percent}%", 2),
|
: AButton(config, "backlight", id, "{percent}%", 2),
|
||||||
preferred_device_(config["device"].isString() ? config["device"].asString() : "") {
|
preferred_device_(config["device"].isString() ? config["device"].asString() : "") {
|
||||||
// Get initial state
|
// Get initial state
|
||||||
{
|
{
|
||||||
@ -174,19 +174,19 @@ auto waybar::modules::Backlight::update() -> void {
|
|||||||
|
|
||||||
const uint8_t percent =
|
const uint8_t percent =
|
||||||
best->get_max() == 0 ? 100 : round(best->get_actual() * 100.0f / best->get_max());
|
best->get_max() == 0 ? 100 : round(best->get_actual() * 100.0f / best->get_max());
|
||||||
label_.set_markup(fmt::format(format_, fmt::arg("percent", std::to_string(percent)),
|
label_->set_markup(fmt::format(format_, fmt::arg("percent", std::to_string(percent)),
|
||||||
fmt::arg("icon", getIcon(percent))));
|
fmt::arg("icon", getIcon(percent))));
|
||||||
getState(percent);
|
getState(percent);
|
||||||
} else {
|
} else {
|
||||||
if (!previous_best_.has_value()) {
|
if (!previous_best_.has_value()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
label_.set_markup("");
|
label_->set_markup("");
|
||||||
}
|
}
|
||||||
previous_best_ = best == nullptr ? std::nullopt : std::optional{*best};
|
previous_best_ = best == nullptr ? std::nullopt : std::optional{*best};
|
||||||
previous_format_ = format_;
|
previous_format_ = format_;
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ForwardIt>
|
template <class ForwardIt>
|
||||||
|
@ -3,7 +3,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, "battery", id, "{capacity}%", 60) {
|
: AButton(config, "battery", id, "{capacity}%", 60) {
|
||||||
battery_watch_fd_ = inotify_init1(IN_CLOEXEC);
|
battery_watch_fd_ = inotify_init1(IN_CLOEXEC);
|
||||||
if (battery_watch_fd_ == -1) {
|
if (battery_watch_fd_ == -1) {
|
||||||
throw std::runtime_error("Unable to listen batteries.");
|
throw std::runtime_error("Unable to listen batteries.");
|
||||||
@ -108,7 +108,7 @@ void waybar::modules::Battery::refreshBatteries() {
|
|||||||
}
|
}
|
||||||
auto adap_defined = config_["adapter"].isString();
|
auto adap_defined = config_["adapter"].isString();
|
||||||
if (((adap_defined && dir_name == config_["adapter"].asString()) || !adap_defined) &&
|
if (((adap_defined && dir_name == config_["adapter"].asString()) || !adap_defined) &&
|
||||||
fs::exists(node.path() / "online")) {
|
(fs::exists(node.path() / "online") || fs::exists(node.path() / "status"))) {
|
||||||
adapter_ = node.path();
|
adapter_ = node.path();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,124 +156,305 @@ const std::tuple<uint8_t, float, std::string, float> waybar::modules::Battery::g
|
|||||||
std::lock_guard<std::mutex> guard(battery_list_mutex_);
|
std::lock_guard<std::mutex> guard(battery_list_mutex_);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
uint32_t total_power = 0; // μW
|
uint32_t total_power = 0; // μW
|
||||||
|
bool total_power_exists = false;
|
||||||
uint32_t total_energy = 0; // μWh
|
uint32_t total_energy = 0; // μWh
|
||||||
|
bool total_energy_exists = false;
|
||||||
uint32_t total_energy_full = 0;
|
uint32_t total_energy_full = 0;
|
||||||
|
bool total_energy_full_exists = false;
|
||||||
uint32_t total_energy_full_design = 0;
|
uint32_t total_energy_full_design = 0;
|
||||||
uint32_t total_capacity{0};
|
bool total_energy_full_design_exists = false;
|
||||||
|
uint32_t total_capacity = 0;
|
||||||
|
bool total_capacity_exists = false;
|
||||||
|
|
||||||
std::string status = "Unknown";
|
std::string status = "Unknown";
|
||||||
for (auto const& item : batteries_) {
|
for (auto const& item : batteries_) {
|
||||||
auto bat = item.first;
|
auto bat = item.first;
|
||||||
uint32_t power_now;
|
|
||||||
uint32_t energy_full;
|
|
||||||
uint32_t energy_now;
|
|
||||||
uint32_t energy_full_design;
|
|
||||||
uint32_t capacity{0};
|
|
||||||
std::string _status;
|
std::string _status;
|
||||||
std::getline(std::ifstream(bat / "status"), _status);
|
std::getline(std::ifstream(bat / "status"), _status);
|
||||||
|
|
||||||
// Some battery will report current and charge in μA/μAh.
|
// Some battery will report current and charge in μA/μAh.
|
||||||
// Scale these by the voltage to get μW/μWh.
|
// Scale these by the voltage to get μW/μWh.
|
||||||
if (fs::exists(bat / "current_now") || fs::exists(bat / "current_avg")) {
|
|
||||||
uint32_t voltage_now;
|
uint32_t capacity = 0;
|
||||||
uint32_t current_now;
|
bool capacity_exists = false;
|
||||||
uint32_t charge_now;
|
if (fs::exists(bat / "capacity")) {
|
||||||
uint32_t charge_full;
|
capacity_exists = true;
|
||||||
uint32_t charge_full_design;
|
|
||||||
// Some batteries have only *_avg, not *_now
|
|
||||||
if (fs::exists(bat / "voltage_now"))
|
|
||||||
std::ifstream(bat / "voltage_now") >> voltage_now;
|
|
||||||
else
|
|
||||||
std::ifstream(bat / "voltage_avg") >> voltage_now;
|
|
||||||
if (fs::exists(bat / "current_now"))
|
|
||||||
std::ifstream(bat / "current_now") >> current_now;
|
|
||||||
else
|
|
||||||
std::ifstream(bat / "current_avg") >> current_now;
|
|
||||||
std::ifstream(bat / "charge_full") >> charge_full;
|
|
||||||
std::ifstream(bat / "charge_full_design") >> charge_full_design;
|
|
||||||
if (fs::exists(bat / "charge_now"))
|
|
||||||
std::ifstream(bat / "charge_now") >> charge_now;
|
|
||||||
else {
|
|
||||||
// charge_now is missing on some systems, estimate using capacity.
|
|
||||||
uint32_t capacity;
|
|
||||||
std::ifstream(bat / "capacity") >> capacity;
|
|
||||||
charge_now = (capacity * charge_full) / 100;
|
|
||||||
}
|
|
||||||
power_now = ((uint64_t)current_now * (uint64_t)voltage_now) / 1000000;
|
|
||||||
energy_now = ((uint64_t)charge_now * (uint64_t)voltage_now) / 1000000;
|
|
||||||
energy_full = ((uint64_t)charge_full * (uint64_t)voltage_now) / 1000000;
|
|
||||||
energy_full_design = ((uint64_t)charge_full_design * (uint64_t)voltage_now) / 1000000;
|
|
||||||
} // Gamepads such as PS Dualshock provide the only capacity
|
|
||||||
else if (fs::exists(bat / "energy_now") && fs::exists(bat / "energy_full")) {
|
|
||||||
std::ifstream(bat / "power_now") >> power_now;
|
|
||||||
std::ifstream(bat / "energy_now") >> energy_now;
|
|
||||||
std::ifstream(bat / "energy_full") >> energy_full;
|
|
||||||
std::ifstream(bat / "energy_full_design") >> energy_full_design;
|
|
||||||
} else {
|
|
||||||
std::ifstream(bat / "capacity") >> capacity;
|
std::ifstream(bat / "capacity") >> capacity;
|
||||||
power_now = 0;
|
}
|
||||||
energy_now = 0;
|
|
||||||
energy_full = 0;
|
uint32_t current_now = 0;
|
||||||
energy_full_design = 0;
|
bool current_now_exists = false;
|
||||||
|
if (fs::exists(bat / "current_now")) {
|
||||||
|
current_now_exists = true;
|
||||||
|
std::ifstream(bat / "current_now") >> current_now;
|
||||||
|
} else if (fs::exists(bat / "current_avg")) {
|
||||||
|
current_now_exists = true;
|
||||||
|
std::ifstream(bat / "current_avg") >> current_now;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t voltage_now = 0;
|
||||||
|
bool voltage_now_exists = false;
|
||||||
|
if (fs::exists(bat / "voltage_now")) {
|
||||||
|
voltage_now_exists = true;
|
||||||
|
std::ifstream(bat / "voltage_now") >> voltage_now;
|
||||||
|
} else if (fs::exists(bat / "voltage_avg")) {
|
||||||
|
voltage_now_exists = true;
|
||||||
|
std::ifstream(bat / "voltage_avg") >> voltage_now;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t charge_full = 0;
|
||||||
|
bool charge_full_exists = false;
|
||||||
|
if (fs::exists(bat / "charge_full")) {
|
||||||
|
charge_full_exists = true;
|
||||||
|
std::ifstream(bat / "charge_full") >> charge_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t charge_full_design = 0;
|
||||||
|
bool charge_full_design_exists = false;
|
||||||
|
if (fs::exists(bat / "charge_full_design")) {
|
||||||
|
charge_full_design_exists = true;
|
||||||
|
std::ifstream(bat / "charge_full_design") >> charge_full_design;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t charge_now = 0;
|
||||||
|
bool charge_now_exists = false;
|
||||||
|
if (fs::exists(bat / "charge_now")) {
|
||||||
|
charge_now_exists = true;
|
||||||
|
std::ifstream(bat / "charge_now") >> charge_now;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t power_now = 0;
|
||||||
|
bool power_now_exists = false;
|
||||||
|
if (fs::exists(bat / "power_now")) {
|
||||||
|
power_now_exists = true;
|
||||||
|
std::ifstream(bat / "power_now") >> power_now;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t energy_now = 0;
|
||||||
|
bool energy_now_exists = false;
|
||||||
|
if (fs::exists(bat / "energy_now")) {
|
||||||
|
energy_now_exists = true;
|
||||||
|
std::ifstream(bat / "energy_now") >> energy_now;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t energy_full = 0;
|
||||||
|
bool energy_full_exists = false;
|
||||||
|
if (fs::exists(bat / "energy_full")) {
|
||||||
|
energy_full_exists = true;
|
||||||
|
std::ifstream(bat / "energy_full") >> energy_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t energy_full_design = 0;
|
||||||
|
bool energy_full_design_exists = false;
|
||||||
|
if (fs::exists(bat / "energy_full_design")) {
|
||||||
|
energy_full_design_exists = true;
|
||||||
|
std::ifstream(bat / "energy_full_design") >> energy_full_design;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!voltage_now_exists) {
|
||||||
|
if (power_now_exists && current_now_exists && current_now != 0) {
|
||||||
|
voltage_now_exists = true;
|
||||||
|
voltage_now = 1000000 * (uint64_t)power_now / (uint64_t)current_now;
|
||||||
|
} else if (energy_full_design_exists && charge_full_design_exists &&
|
||||||
|
charge_full_design != 0) {
|
||||||
|
voltage_now_exists = true;
|
||||||
|
voltage_now = 1000000 * (uint64_t)energy_full_design / (uint64_t)charge_full_design;
|
||||||
|
} else if (energy_now_exists) {
|
||||||
|
if (charge_now_exists && charge_now != 0) {
|
||||||
|
voltage_now_exists = true;
|
||||||
|
voltage_now = 1000000 * (uint64_t)energy_now / (uint64_t)charge_now;
|
||||||
|
} else if (capacity_exists && charge_full_exists) {
|
||||||
|
charge_now_exists = true;
|
||||||
|
charge_now = (uint64_t)charge_full * (uint64_t)capacity / 100;
|
||||||
|
if (charge_full != 0 && capacity != 0) {
|
||||||
|
voltage_now_exists = true;
|
||||||
|
voltage_now =
|
||||||
|
1000000 * (uint64_t)energy_now * 100 / (uint64_t)charge_full / (uint64_t)capacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (energy_full_exists) {
|
||||||
|
if (charge_full_exists && charge_full != 0) {
|
||||||
|
voltage_now_exists = true;
|
||||||
|
voltage_now = 1000000 * (uint64_t)energy_full / (uint64_t)charge_full;
|
||||||
|
} else if (charge_now_exists && capacity_exists) {
|
||||||
|
if (capacity != 0) {
|
||||||
|
charge_full_exists = true;
|
||||||
|
charge_full = 100 * (uint64_t)charge_now / (uint64_t)capacity;
|
||||||
|
}
|
||||||
|
if (charge_now != 0) {
|
||||||
|
voltage_now_exists = true;
|
||||||
|
voltage_now =
|
||||||
|
10000 * (uint64_t)energy_full * (uint64_t)capacity / (uint64_t)charge_now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!capacity_exists) {
|
||||||
|
if (charge_now_exists && charge_full_exists && charge_full != 0) {
|
||||||
|
capacity_exists = true;
|
||||||
|
capacity = 100 * (uint64_t)charge_now / (uint64_t)charge_full;
|
||||||
|
} else if (energy_now_exists && energy_full_exists && energy_full != 0) {
|
||||||
|
capacity_exists = true;
|
||||||
|
capacity = 100 * (uint64_t)energy_now / (uint64_t)energy_full;
|
||||||
|
} else if (charge_now_exists && energy_full_exists && voltage_now_exists) {
|
||||||
|
if (!charge_full_exists && voltage_now != 0) {
|
||||||
|
charge_full_exists = true;
|
||||||
|
charge_full = 1000000 * (uint64_t)energy_full / (uint64_t)voltage_now;
|
||||||
|
}
|
||||||
|
if (energy_full != 0) {
|
||||||
|
capacity_exists = true;
|
||||||
|
capacity = (uint64_t)charge_now * (uint64_t)voltage_now / 10000 / (uint64_t)energy_full;
|
||||||
|
}
|
||||||
|
} else if (charge_full_exists && energy_now_exists && voltage_now_exists) {
|
||||||
|
if (!charge_now_exists && voltage_now != 0) {
|
||||||
|
charge_now_exists = true;
|
||||||
|
charge_now = 1000000 * (uint64_t)energy_now / (uint64_t)voltage_now;
|
||||||
|
}
|
||||||
|
if (voltage_now != 0 && charge_full != 0) {
|
||||||
|
capacity_exists = true;
|
||||||
|
capacity = 100 * 1000000 * (uint64_t)energy_now / (uint64_t)voltage_now /
|
||||||
|
(uint64_t)charge_full;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!energy_now_exists && voltage_now_exists) {
|
||||||
|
if (charge_now_exists) {
|
||||||
|
energy_now_exists = true;
|
||||||
|
energy_now = (uint64_t)charge_now * (uint64_t)voltage_now / 1000000;
|
||||||
|
} else if (capacity_exists && charge_full_exists) {
|
||||||
|
charge_now_exists = true;
|
||||||
|
charge_now = (uint64_t)capacity * (uint64_t)charge_full / 100;
|
||||||
|
energy_now_exists = true;
|
||||||
|
energy_now =
|
||||||
|
(uint64_t)voltage_now * (uint64_t)capacity * (uint64_t)charge_full / 1000000 / 100;
|
||||||
|
} else if (capacity_exists && energy_full) {
|
||||||
|
if (voltage_now != 0) {
|
||||||
|
charge_full_exists = true;
|
||||||
|
charge_full = 1000000 * (uint64_t)energy_full / (uint64_t)voltage_now;
|
||||||
|
charge_now_exists = true;
|
||||||
|
charge_now = (uint64_t)capacity * 10000 * (uint64_t)energy_full / (uint64_t)voltage_now;
|
||||||
|
}
|
||||||
|
energy_now_exists = true;
|
||||||
|
energy_now = (uint64_t)capacity * (uint64_t)energy_full / 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!energy_full_exists && voltage_now_exists) {
|
||||||
|
if (charge_full_exists) {
|
||||||
|
energy_full_exists = true;
|
||||||
|
energy_full = (uint64_t)charge_full * (uint64_t)voltage_now / 1000000;
|
||||||
|
} else if (charge_now_exists && capacity_exists && capacity != 0) {
|
||||||
|
charge_full_exists = true;
|
||||||
|
charge_full = 100 * (uint64_t)charge_now / (uint64_t)capacity;
|
||||||
|
energy_full_exists = true;
|
||||||
|
energy_full = (uint64_t)charge_now * (uint64_t)voltage_now / (uint64_t)capacity / 10000;
|
||||||
|
} else if (capacity_exists && energy_now) {
|
||||||
|
if (voltage_now != 0) {
|
||||||
|
charge_now_exists = true;
|
||||||
|
charge_now = 1000000 * (uint64_t)energy_now / (uint64_t)voltage_now;
|
||||||
|
}
|
||||||
|
if (capacity != 0) {
|
||||||
|
energy_full_exists = true;
|
||||||
|
energy_full = 100 * (uint64_t)energy_now / (uint64_t)capacity;
|
||||||
|
if (voltage_now != 0) {
|
||||||
|
charge_full_exists = true;
|
||||||
|
charge_full =
|
||||||
|
100 * 1000000 * (uint64_t)energy_now / (uint64_t)voltage_now / (uint64_t)capacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!power_now_exists && voltage_now_exists && current_now_exists) {
|
||||||
|
power_now_exists = true;
|
||||||
|
power_now = (uint64_t)voltage_now * (uint64_t)current_now / 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!energy_full_design_exists && voltage_now_exists && charge_full_design_exists) {
|
||||||
|
energy_full_design_exists = true;
|
||||||
|
energy_full_design = (uint64_t)voltage_now * (uint64_t)charge_full_design / 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the "smallest" status among all batteries
|
// Show the "smallest" status among all batteries
|
||||||
if (status_gt(status, _status)) {
|
if (status_gt(status, _status)) status = _status;
|
||||||
status = _status;
|
|
||||||
|
if (power_now_exists) {
|
||||||
|
total_power_exists = true;
|
||||||
|
total_power += power_now;
|
||||||
|
}
|
||||||
|
if (energy_now_exists) {
|
||||||
|
total_energy_exists = true;
|
||||||
|
total_energy += energy_now;
|
||||||
|
}
|
||||||
|
if (energy_full_exists) {
|
||||||
|
total_energy_full_exists = true;
|
||||||
|
total_energy_full += energy_full;
|
||||||
|
}
|
||||||
|
if (energy_full_design_exists) {
|
||||||
|
total_energy_full_design_exists = true;
|
||||||
|
total_energy_full_design += energy_full_design;
|
||||||
|
}
|
||||||
|
if (capacity_exists) {
|
||||||
|
total_capacity_exists = true;
|
||||||
|
total_capacity += capacity;
|
||||||
}
|
}
|
||||||
total_power += power_now;
|
|
||||||
total_energy += energy_now;
|
|
||||||
total_energy_full += energy_full;
|
|
||||||
total_energy_full_design += energy_full_design;
|
|
||||||
total_capacity += capacity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!adapter_.empty() && status == "Discharging") {
|
if (!adapter_.empty() && status == "Discharging") {
|
||||||
bool online;
|
bool online;
|
||||||
|
std::string current_status;
|
||||||
std::ifstream(adapter_ / "online") >> online;
|
std::ifstream(adapter_ / "online") >> online;
|
||||||
if (online) {
|
std::getline(std::ifstream(adapter_ / "status"), current_status);
|
||||||
status = "Plugged";
|
if (online && current_status != "Discharging") status = "Plugged";
|
||||||
|
}
|
||||||
|
|
||||||
|
float time_remaining{0.0f};
|
||||||
|
if (status == "Discharging" && total_power_exists && total_energy_exists) {
|
||||||
|
if (total_power != 0) time_remaining = (float)total_energy / total_power;
|
||||||
|
} else if (status == "Charging" && total_energy_exists && total_energy_full_exists &&
|
||||||
|
total_power_exists) {
|
||||||
|
if (total_power != 0)
|
||||||
|
time_remaining = -(float)(total_energy_full - total_energy) / total_power;
|
||||||
|
// If we've turned positive it means the battery is past 100% and so just report that as no
|
||||||
|
// time remaining
|
||||||
|
if (time_remaining > 0.0f) time_remaining = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float calculated_capacity{0.0f};
|
||||||
|
if (total_capacity_exists) {
|
||||||
|
if (total_capacity > 0.0f)
|
||||||
|
calculated_capacity = (float)total_capacity;
|
||||||
|
else if (total_energy_full_exists && total_energy_exists) {
|
||||||
|
if (total_energy_full > 0.0f)
|
||||||
|
calculated_capacity = ((float)total_energy * 100.0f / (float)total_energy_full);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float time_remaining = 0;
|
|
||||||
if (status == "Discharging" && total_power != 0) {
|
|
||||||
time_remaining = (float)total_energy / total_power;
|
|
||||||
} else if (status == "Charging" && total_power != 0) {
|
|
||||||
time_remaining = -(float)(total_energy_full - total_energy) / total_power;
|
|
||||||
if (time_remaining > 0.0f) {
|
|
||||||
// If we've turned positive it means the battery is past 100% and so
|
|
||||||
// just report that as no time remaining
|
|
||||||
time_remaining = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float capacity{0.0f};
|
|
||||||
if (total_energy_full > 0.0f) {
|
|
||||||
capacity = ((float)total_energy * 100.0f / (float)total_energy_full);
|
|
||||||
} else {
|
|
||||||
capacity = (float)total_capacity;
|
|
||||||
}
|
|
||||||
// Handle design-capacity
|
// Handle design-capacity
|
||||||
if (config_["design-capacity"].isBool() ? config_["design-capacity"].asBool() : false) {
|
if ((config_["design-capacity"].isBool() ? config_["design-capacity"].asBool() : false) &&
|
||||||
capacity = ((float)total_energy * 100.0f / (float)total_energy_full_design);
|
total_energy_exists && total_energy_full_design_exists) {
|
||||||
|
if (total_energy_full_design > 0.0f)
|
||||||
|
calculated_capacity = ((float)total_energy * 100.0f / (float)total_energy_full_design);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle full-at
|
// Handle full-at
|
||||||
if (config_["full-at"].isUInt()) {
|
if (config_["full-at"].isUInt()) {
|
||||||
auto full_at = config_["full-at"].asUInt();
|
auto full_at = config_["full-at"].asUInt();
|
||||||
if (full_at < 100) {
|
if (full_at < 100) calculated_capacity = 100.f * calculated_capacity / full_at;
|
||||||
capacity = 100.f * capacity / full_at;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (capacity > 100.f) {
|
|
||||||
// This can happen when the battery is calibrating and goes above 100%
|
|
||||||
// Handle it gracefully by clamping at 100%
|
|
||||||
capacity = 100.f;
|
|
||||||
}
|
|
||||||
uint8_t cap = round(capacity);
|
|
||||||
if (cap == 100 && status == "Charging") {
|
|
||||||
// If we've reached 100% just mark as full as some batteries can stay
|
|
||||||
// stuck reporting they're still charging but not yet done
|
|
||||||
status = "Full";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle it gracefully by clamping at 100%
|
||||||
|
// This can happen when the battery is calibrating and goes above 100%
|
||||||
|
if (calculated_capacity > 100.f) calculated_capacity = 100.f;
|
||||||
|
|
||||||
|
uint8_t cap = round(calculated_capacity);
|
||||||
|
// If we've reached 100% just mark as full as some batteries can stay stuck reporting they're
|
||||||
|
// still charging but not yet done
|
||||||
|
if (cap == 100 && status == "Charging") status = "Full";
|
||||||
|
|
||||||
return {cap, time_remaining, status, total_power / 1e6};
|
return {cap, time_remaining, status, total_power / 1e6};
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
spdlog::error("Battery: {}", e.what());
|
spdlog::error("Battery: {}", e.what());
|
||||||
@ -284,11 +465,13 @@ const std::tuple<uint8_t, float, std::string, float> waybar::modules::Battery::g
|
|||||||
const std::string waybar::modules::Battery::getAdapterStatus(uint8_t capacity) const {
|
const std::string waybar::modules::Battery::getAdapterStatus(uint8_t capacity) const {
|
||||||
if (!adapter_.empty()) {
|
if (!adapter_.empty()) {
|
||||||
bool online;
|
bool online;
|
||||||
|
std::string status;
|
||||||
std::ifstream(adapter_ / "online") >> online;
|
std::ifstream(adapter_ / "online") >> online;
|
||||||
|
std::getline(std::ifstream(adapter_ / "status"), status);
|
||||||
if (capacity == 100) {
|
if (capacity == 100) {
|
||||||
return "Full";
|
return "Full";
|
||||||
}
|
}
|
||||||
if (online) {
|
if (online && status != "Discharging") {
|
||||||
return "Plugged";
|
return "Plugged";
|
||||||
}
|
}
|
||||||
return "Discharging";
|
return "Discharging";
|
||||||
@ -309,7 +492,8 @@ const std::string waybar::modules::Battery::formatTimeRemaining(float hoursRemai
|
|||||||
format = config_["format-time"].asString();
|
format = config_["format-time"].asString();
|
||||||
}
|
}
|
||||||
std::string zero_pad_minutes = fmt::format("{:02d}", minutes);
|
std::string zero_pad_minutes = fmt::format("{:02d}", minutes);
|
||||||
return fmt::format(format, fmt::arg("H", full_hours), fmt::arg("M", minutes), fmt::arg("m", zero_pad_minutes));
|
return fmt::format(format, fmt::arg("H", full_hours), fmt::arg("M", minutes),
|
||||||
|
fmt::arg("m", zero_pad_minutes));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::modules::Battery::update() -> void {
|
auto waybar::modules::Battery::update() -> void {
|
||||||
@ -346,14 +530,14 @@ auto waybar::modules::Battery::update() -> void {
|
|||||||
} else if (config_["tooltip-format"].isString()) {
|
} else if (config_["tooltip-format"].isString()) {
|
||||||
tooltip_format = config_["tooltip-format"].asString();
|
tooltip_format = config_["tooltip-format"].asString();
|
||||||
}
|
}
|
||||||
label_.set_tooltip_text(fmt::format(tooltip_format, fmt::arg("timeTo", tooltip_text_default),
|
button_.set_tooltip_text(fmt::format(tooltip_format, fmt::arg("timeTo", tooltip_text_default),
|
||||||
fmt::arg("capacity", capacity),
|
fmt::arg("capacity", capacity),
|
||||||
fmt::arg("time", time_remaining_formatted)));
|
fmt::arg("time", time_remaining_formatted)));
|
||||||
}
|
}
|
||||||
if (!old_status_.empty()) {
|
if (!old_status_.empty()) {
|
||||||
label_.get_style_context()->remove_class(old_status_);
|
button_.get_style_context()->remove_class(old_status_);
|
||||||
}
|
}
|
||||||
label_.get_style_context()->add_class(status);
|
button_.get_style_context()->add_class(status);
|
||||||
old_status_ = status;
|
old_status_ = status;
|
||||||
if (!state.empty() && config_["format-" + status + "-" + state].isString()) {
|
if (!state.empty() && config_["format-" + status + "-" + state].isString()) {
|
||||||
format = config_["format-" + status + "-" + state].asString();
|
format = config_["format-" + status + "-" + state].asString();
|
||||||
@ -367,10 +551,10 @@ auto waybar::modules::Battery::update() -> void {
|
|||||||
} else {
|
} else {
|
||||||
event_box_.show();
|
event_box_.show();
|
||||||
auto icons = std::vector<std::string>{status + "-" + state, status, state};
|
auto icons = std::vector<std::string>{status + "-" + state, status, state};
|
||||||
label_.set_markup(fmt::format(format, fmt::arg("capacity", capacity), fmt::arg("power", power),
|
label_->set_markup(fmt::format(format, fmt::arg("capacity", capacity), fmt::arg("power", power),
|
||||||
fmt::arg("icon", getIcon(capacity, icons)),
|
fmt::arg("icon", getIcon(capacity, icons)),
|
||||||
fmt::arg("time", time_remaining_formatted)));
|
fmt::arg("time", time_remaining_formatted)));
|
||||||
}
|
}
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ auto getUcharProperty(GDBusProxy* proxy, const char* property_name) -> unsigned
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value& config)
|
waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "bluetooth", id, " {status}", 10),
|
: AButton(config, "bluetooth", id, " {status}", 10),
|
||||||
#ifdef WANT_RFKILL
|
#ifdef WANT_RFKILL
|
||||||
rfkill_{RFKILL_TYPE_BLUETOOTH},
|
rfkill_{RFKILL_TYPE_BLUETOOTH},
|
||||||
#endif
|
#endif
|
||||||
@ -189,10 +189,10 @@ auto waybar::modules::Bluetooth::update() -> void {
|
|||||||
format_.empty() ? event_box_.hide() : event_box_.show();
|
format_.empty() ? event_box_.hide() : event_box_.show();
|
||||||
|
|
||||||
auto update_style_context = [this](const std::string& style_class, bool in_next_state) {
|
auto update_style_context = [this](const std::string& style_class, bool in_next_state) {
|
||||||
if (in_next_state && !label_.get_style_context()->has_class(style_class)) {
|
if (in_next_state && !button_.get_style_context()->has_class(style_class)) {
|
||||||
label_.get_style_context()->add_class(style_class);
|
button_.get_style_context()->add_class(style_class);
|
||||||
} else if (!in_next_state && label_.get_style_context()->has_class(style_class)) {
|
} else if (!in_next_state && button_.get_style_context()->has_class(style_class)) {
|
||||||
label_.get_style_context()->remove_class(style_class);
|
button_.get_style_context()->remove_class(style_class);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
update_style_context("discoverable", cur_controller_.discoverable);
|
update_style_context("discoverable", cur_controller_.discoverable);
|
||||||
@ -204,7 +204,7 @@ auto waybar::modules::Bluetooth::update() -> void {
|
|||||||
update_style_context(state, true);
|
update_style_context(state, true);
|
||||||
state_ = state;
|
state_ = state;
|
||||||
|
|
||||||
label_.set_markup(fmt::format(
|
label_->set_markup(fmt::format(
|
||||||
format_, fmt::arg("status", state_), fmt::arg("num_connections", connected_devices_.size()),
|
format_, fmt::arg("status", state_), fmt::arg("num_connections", connected_devices_.size()),
|
||||||
fmt::arg("controller_address", cur_controller_.address),
|
fmt::arg("controller_address", cur_controller_.address),
|
||||||
fmt::arg("controller_address_type", cur_controller_.address_type),
|
fmt::arg("controller_address_type", cur_controller_.address_type),
|
||||||
@ -245,7 +245,7 @@ auto waybar::modules::Bluetooth::update() -> void {
|
|||||||
device_enumerate_.erase(0, 1);
|
device_enumerate_.erase(0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
label_.set_tooltip_text(fmt::format(
|
button_.set_tooltip_text(fmt::format(
|
||||||
tooltip_format, fmt::arg("status", state_),
|
tooltip_format, fmt::arg("status", state_),
|
||||||
fmt::arg("num_connections", connected_devices_.size()),
|
fmt::arg("num_connections", connected_devices_.size()),
|
||||||
fmt::arg("controller_address", cur_controller_.address),
|
fmt::arg("controller_address", cur_controller_.address),
|
||||||
@ -259,7 +259,7 @@ auto waybar::modules::Bluetooth::update() -> void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: only for when the org.bluez.Battery1 interface is added/removed after/before a device is
|
// NOTE: only for when the org.bluez.Battery1 interface is added/removed after/before a device is
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
using waybar::waybar_time;
|
using waybar::waybar_time;
|
||||||
|
|
||||||
waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "clock", id, "{:%H:%M}", 60, false, false, true),
|
: AButton(config, "clock", id, "{:%H:%M}", 60, false, false, true),
|
||||||
current_time_zone_idx_(0),
|
current_time_zone_idx_(0),
|
||||||
is_calendar_in_tooltip_(false),
|
is_calendar_in_tooltip_(false),
|
||||||
is_timezoned_list_in_tooltip_(false) {
|
is_timezoned_list_in_tooltip_(false) {
|
||||||
@ -107,7 +107,7 @@ auto waybar::modules::Clock::update() -> void {
|
|||||||
} else {
|
} else {
|
||||||
text = fmt::format(format_, wtime);
|
text = fmt::format(format_, wtime);
|
||||||
}
|
}
|
||||||
label_.set_markup(text);
|
label_->set_markup(text);
|
||||||
|
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
if (config_["tooltip-format"].isString()) {
|
if (config_["tooltip-format"].isString()) {
|
||||||
@ -119,12 +119,12 @@ auto waybar::modules::Clock::update() -> void {
|
|||||||
text =
|
text =
|
||||||
fmt::format(tooltip_format, wtime, fmt::arg(kCalendarPlaceholder.c_str(), calendar_lines),
|
fmt::format(tooltip_format, wtime, fmt::arg(kCalendarPlaceholder.c_str(), calendar_lines),
|
||||||
fmt::arg(KTimezonedTimeListPlaceholder.c_str(), timezoned_time_lines));
|
fmt::arg(KTimezonedTimeListPlaceholder.c_str(), timezoned_time_lines));
|
||||||
label_.set_tooltip_markup(text);
|
button_.set_tooltip_markup(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waybar::modules::Clock::handleScroll(GdkEventScroll* e) {
|
bool waybar::modules::Clock::handleScroll(GdkEventScroll* e) {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
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, "cpu", id, "{usage}%", 10) {
|
: AButton(config, "cpu", id, "{usage}%", 10) {
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
dp.emit();
|
dp.emit();
|
||||||
thread_.sleep_for(interval_);
|
thread_.sleep_for(interval_);
|
||||||
@ -23,7 +23,7 @@ auto waybar::modules::Cpu::update() -> void {
|
|||||||
auto [cpu_usage, tooltip] = getCpuUsage();
|
auto [cpu_usage, tooltip] = getCpuUsage();
|
||||||
auto [max_frequency, min_frequency, avg_frequency] = getCpuFrequency();
|
auto [max_frequency, min_frequency, avg_frequency] = getCpuFrequency();
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
label_.set_tooltip_text(tooltip);
|
button_.set_tooltip_text(tooltip);
|
||||||
}
|
}
|
||||||
auto format = format_;
|
auto format = format_;
|
||||||
auto total_usage = cpu_usage.empty() ? 0 : cpu_usage[0];
|
auto total_usage = cpu_usage.empty() ? 0 : cpu_usage[0];
|
||||||
@ -52,11 +52,11 @@ auto waybar::modules::Cpu::update() -> void {
|
|||||||
auto icon_format = fmt::format("icon{}", core_i);
|
auto icon_format = fmt::format("icon{}", core_i);
|
||||||
store.push_back(fmt::arg(icon_format.c_str(), getIcon(cpu_usage[i], icons)));
|
store.push_back(fmt::arg(icon_format.c_str(), getIcon(cpu_usage[i], icons)));
|
||||||
}
|
}
|
||||||
label_.set_markup(fmt::vformat(format, store));
|
label_->set_markup(fmt::vformat(format, store));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
double waybar::modules::Cpu::getCpuLoad() {
|
double waybar::modules::Cpu::getCpuLoad() {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
waybar::modules::Custom::Custom(const std::string& name, const std::string& id,
|
waybar::modules::Custom::Custom(const std::string& name, const std::string& id,
|
||||||
const Json::Value& config)
|
const Json::Value& config)
|
||||||
: ALabel(config, "custom-" + name, id, "{}"),
|
: AButton(config, "custom-" + name, id, "{}"),
|
||||||
name_(name),
|
name_(name),
|
||||||
id_(id),
|
id_(id),
|
||||||
percentage_(0),
|
percentage_(0),
|
||||||
@ -103,13 +103,13 @@ void waybar::modules::Custom::handleEvent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool waybar::modules::Custom::handleScroll(GdkEventScroll* e) {
|
bool waybar::modules::Custom::handleScroll(GdkEventScroll* e) {
|
||||||
auto ret = ALabel::handleScroll(e);
|
auto ret = AButton::handleScroll(e);
|
||||||
handleEvent();
|
handleEvent();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waybar::modules::Custom::handleToggle(GdkEventButton* const& e) {
|
bool waybar::modules::Custom::handleToggle(GdkEventButton* const& e) {
|
||||||
auto ret = ALabel::handleToggle(e);
|
auto ret = AButton::handleToggle(e);
|
||||||
handleEvent();
|
handleEvent();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -125,37 +125,39 @@ auto waybar::modules::Custom::update() -> void {
|
|||||||
} else {
|
} else {
|
||||||
parseOutputRaw();
|
parseOutputRaw();
|
||||||
}
|
}
|
||||||
auto str = fmt::format(format_, text_, fmt::arg("alt", alt_),
|
auto str = fmt::format(format_, Glib::Markup::escape_text(text_).raw(), 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()) {
|
if (str.empty()) {
|
||||||
event_box_.hide();
|
event_box_.hide();
|
||||||
} else {
|
} else {
|
||||||
label_.set_markup(str);
|
label_->set_markup(str);
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
if (text_ == tooltip_) {
|
if (text_ == tooltip_) {
|
||||||
if (label_.get_tooltip_markup() != str) {
|
if (button_.get_tooltip_markup() != str) {
|
||||||
label_.set_tooltip_markup(str);
|
button_.set_tooltip_markup(str);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (label_.get_tooltip_markup() != tooltip_) {
|
if (button_.get_tooltip_markup() != tooltip_) {
|
||||||
label_.set_tooltip_markup(tooltip_);
|
button_.set_tooltip_markup(tooltip_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto classes = label_.get_style_context()->list_classes();
|
auto classes = button_.get_style_context()->list_classes();
|
||||||
for (auto const& c : classes) {
|
for (auto const& c : classes) {
|
||||||
if (c == id_) continue;
|
if (c == id_) continue;
|
||||||
label_.get_style_context()->remove_class(c);
|
button_.get_style_context()->remove_class(c);
|
||||||
}
|
}
|
||||||
for (auto const& c : class_) {
|
for (auto const& c : class_) {
|
||||||
label_.get_style_context()->add_class(c);
|
button_.get_style_context()->add_class(c);
|
||||||
}
|
}
|
||||||
|
button_.get_style_context()->add_class("flat");
|
||||||
|
button_.get_style_context()->add_class("text-button");
|
||||||
event_box_.show();
|
event_box_.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Custom::parseOutputRaw() {
|
void waybar::modules::Custom::parseOutputRaw() {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
using namespace waybar::util;
|
using namespace waybar::util;
|
||||||
|
|
||||||
waybar::modules::Disk::Disk(const std::string& id, const Json::Value& config)
|
waybar::modules::Disk::Disk(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "disk", id, "{}%", 30), path_("/") {
|
: AButton(config, "disk", id, "{}%", 30), path_("/") {
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
dp.emit();
|
dp.emit();
|
||||||
thread_.sleep_for(interval_);
|
thread_.sleep_for(interval_);
|
||||||
@ -58,7 +58,7 @@ auto waybar::modules::Disk::update() -> void {
|
|||||||
event_box_.hide();
|
event_box_.hide();
|
||||||
} else {
|
} else {
|
||||||
event_box_.show();
|
event_box_.show();
|
||||||
label_.set_markup(
|
label_->set_markup(
|
||||||
fmt::format(format, stats.f_bavail * 100 / stats.f_blocks, fmt::arg("free", free),
|
fmt::format(format, stats.f_bavail * 100 / stats.f_blocks, fmt::arg("free", free),
|
||||||
fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks),
|
fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks),
|
||||||
fmt::arg("used", used), fmt::arg("percentage_used", percentage_used),
|
fmt::arg("used", used), fmt::arg("percentage_used", percentage_used),
|
||||||
@ -70,12 +70,12 @@ auto waybar::modules::Disk::update() -> void {
|
|||||||
if (config_["tooltip-format"].isString()) {
|
if (config_["tooltip-format"].isString()) {
|
||||||
tooltip_format = config_["tooltip-format"].asString();
|
tooltip_format = config_["tooltip-format"].asString();
|
||||||
}
|
}
|
||||||
label_.set_tooltip_text(
|
button_.set_tooltip_text(
|
||||||
fmt::format(tooltip_format, stats.f_bavail * 100 / stats.f_blocks, fmt::arg("free", free),
|
fmt::format(tooltip_format, stats.f_bavail * 100 / stats.f_blocks, fmt::arg("free", free),
|
||||||
fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks),
|
fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks),
|
||||||
fmt::arg("used", used), fmt::arg("percentage_used", percentage_used),
|
fmt::arg("used", used), fmt::arg("percentage_used", percentage_used),
|
||||||
fmt::arg("total", total), fmt::arg("path", path_)));
|
fmt::arg("total", total), fmt::arg("path", path_)));
|
||||||
}
|
}
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <xkbcommon/xkbregistry.h>
|
#include <xkbcommon/xkbregistry.h>
|
||||||
|
|
||||||
|
#include <util/sanitize_str.hpp>
|
||||||
|
|
||||||
#include "modules/hyprland/backend.hpp"
|
#include "modules/hyprland/backend.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::hyprland {
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
Language::Language(const std::string& id, const Bar& bar, const Json::Value& config)
|
Language::Language(const std::string& id, const Bar& bar, const Json::Value& config)
|
||||||
: ALabel(config, "language", id, "{}", 0, true), bar_(bar) {
|
: AButton(config, "language", id, "{}", 0, true), bar_(bar) {
|
||||||
modulesReady = true;
|
modulesReady = true;
|
||||||
|
|
||||||
if (!gIPC.get()) {
|
if (!gIPC.get()) {
|
||||||
@ -19,8 +21,8 @@ Language::Language(const std::string& id, const Bar& bar, const Json::Value& con
|
|||||||
// get the active layout when open
|
// get the active layout when open
|
||||||
initLanguage();
|
initLanguage();
|
||||||
|
|
||||||
label_.hide();
|
button_.hide();
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
|
|
||||||
// register for hyprland ipc
|
// register for hyprland ipc
|
||||||
gIPC->registerForIPC("activelayout", [&](const std::string& ev) { this->onEvent(ev); });
|
gIPC->registerForIPC("activelayout", [&](const std::string& ev) { this->onEvent(ev); });
|
||||||
@ -30,13 +32,13 @@ auto Language::update() -> void {
|
|||||||
std::lock_guard<std::mutex> lg(mutex_);
|
std::lock_guard<std::mutex> lg(mutex_);
|
||||||
|
|
||||||
if (!format_.empty()) {
|
if (!format_.empty()) {
|
||||||
label_.show();
|
button_.show();
|
||||||
label_.set_markup(layoutName_);
|
label_->set_markup(layoutName_);
|
||||||
} else {
|
} else {
|
||||||
label_.hide();
|
button_.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Language::onEvent(const std::string& ev) {
|
void Language::onEvent(const std::string& ev) {
|
||||||
@ -48,16 +50,6 @@ void Language::onEvent(const std::string& ev) {
|
|||||||
if (config_.isMember("keyboard-name") && keebName != config_["keyboard-name"].asString())
|
if (config_.isMember("keyboard-name") && keebName != config_["keyboard-name"].asString())
|
||||||
return; // ignore
|
return; // ignore
|
||||||
|
|
||||||
auto replaceAll = [](std::string str, const std::string& from,
|
|
||||||
const std::string& to) -> std::string {
|
|
||||||
size_t start_pos = 0;
|
|
||||||
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
|
||||||
str.replace(start_pos, from.length(), to);
|
|
||||||
start_pos += to.length();
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto BRIEFNAME = getShortFrom(layoutName);
|
const auto BRIEFNAME = getShortFrom(layoutName);
|
||||||
|
|
||||||
if (config_.isMember("format-" + BRIEFNAME)) {
|
if (config_.isMember("format-" + BRIEFNAME)) {
|
||||||
@ -67,7 +59,7 @@ void Language::onEvent(const std::string& ev) {
|
|||||||
layoutName = fmt::format(format_, layoutName);
|
layoutName = fmt::format(format_, layoutName);
|
||||||
}
|
}
|
||||||
|
|
||||||
layoutName = replaceAll(layoutName, "&", "&");
|
layoutName = waybar::util::sanitize_string(layoutName);
|
||||||
|
|
||||||
if (layoutName == layoutName_) return;
|
if (layoutName == layoutName_) return;
|
||||||
|
|
||||||
@ -128,4 +120,4 @@ std::string Language::getShortFrom(const std::string& fullName) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace waybar::modules::hyprland
|
} // namespace waybar::modules::hyprland
|
||||||
|
@ -2,13 +2,18 @@
|
|||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include <util/sanitize_str.hpp>
|
||||||
|
|
||||||
#include "modules/hyprland/backend.hpp"
|
#include "modules/hyprland/backend.hpp"
|
||||||
|
#include "util/command.hpp"
|
||||||
|
#include "util/json.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::hyprland {
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
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, "window", id, "{}", 0, true), bar_(bar) {
|
: ALabel(config, "window", id, "{}", 0, true), bar_(bar) {
|
||||||
modulesReady = true;
|
modulesReady = true;
|
||||||
|
separate_outputs = config["separate-outputs"].as<bool>();
|
||||||
|
|
||||||
if (!gIPC.get()) {
|
if (!gIPC.get()) {
|
||||||
gIPC = std::make_unique<IPC>();
|
gIPC = std::make_unique<IPC>();
|
||||||
@ -35,21 +40,41 @@ auto Window::update() -> void {
|
|||||||
ALabel::update();
|
ALabel::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint Window::getActiveWorkspaceID(std::string monitorName) {
|
||||||
|
auto cmd = waybar::util::command::exec("hyprctl monitors -j");
|
||||||
|
assert(cmd.exit_code == 0);
|
||||||
|
Json::Value json = parser_.parse(cmd.out);
|
||||||
|
assert(json.isArray());
|
||||||
|
auto monitor = std::find_if(json.begin(), json.end(), [&](Json::Value monitor){
|
||||||
|
return monitor["name"] == monitorName;
|
||||||
|
});
|
||||||
|
assert(monitor != std::end(json));
|
||||||
|
return (*monitor)["activeWorkspace"]["id"].as<uint>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Window::getLastWindowTitle(uint workspaceID) {
|
||||||
|
auto cmd = waybar::util::command::exec("hyprctl workspaces -j");
|
||||||
|
assert(cmd.exit_code == 0);
|
||||||
|
Json::Value json = parser_.parse(cmd.out);
|
||||||
|
assert(json.isArray());
|
||||||
|
auto workspace = std::find_if(json.begin(), json.end(), [&](Json::Value workspace){
|
||||||
|
return workspace["id"].as<uint>() == workspaceID;
|
||||||
|
});
|
||||||
|
assert(workspace != std::end(json));
|
||||||
|
return (*workspace)["lastwindowtitle"].as<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
void Window::onEvent(const std::string& ev) {
|
void Window::onEvent(const std::string& ev) {
|
||||||
std::lock_guard<std::mutex> lg(mutex_);
|
std::lock_guard<std::mutex> lg(mutex_);
|
||||||
auto windowName = ev.substr(ev.find_first_of(',') + 1).substr(0, 256);
|
|
||||||
|
|
||||||
auto replaceAll = [](std::string str, const std::string& from,
|
std::string windowName;
|
||||||
const std::string& to) -> std::string {
|
if (separate_outputs) {
|
||||||
size_t start_pos = 0;
|
windowName = getLastWindowTitle(getActiveWorkspaceID(this->bar_.output->name));
|
||||||
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
} else {
|
||||||
str.replace(start_pos, from.length(), to);
|
windowName = ev.substr(ev.find_first_of(',') + 1).substr(0, 256);
|
||||||
start_pos += to.length();
|
}
|
||||||
}
|
|
||||||
return str;
|
|
||||||
};
|
|
||||||
|
|
||||||
windowName = replaceAll(windowName, "&", "&");
|
windowName = waybar::util::sanitize_string(windowName);
|
||||||
|
|
||||||
if (windowName == lastView) return;
|
if (windowName == lastView) return;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ bool waybar::modules::IdleInhibitor::status = false;
|
|||||||
|
|
||||||
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, "idle_inhibitor", id, "{status}"),
|
: AButton(config, "idle_inhibitor", id, "{status}", 0, false, true),
|
||||||
bar_(bar),
|
bar_(bar),
|
||||||
idle_inhibitor_(nullptr),
|
idle_inhibitor_(nullptr),
|
||||||
pid_(-1) {
|
pid_(-1) {
|
||||||
@ -16,6 +16,11 @@ waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar&
|
|||||||
throw std::runtime_error("idle-inhibit not available");
|
throw std::runtime_error("idle-inhibit not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (waybar::modules::IdleInhibitor::modules.empty() && config_["start-activated"].isBool() &&
|
||||||
|
config_["start-activated"].asBool() != status) {
|
||||||
|
toggleStatus();
|
||||||
|
}
|
||||||
|
|
||||||
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));
|
||||||
@ -44,13 +49,13 @@ waybar::modules::IdleInhibitor::~IdleInhibitor() {
|
|||||||
auto waybar::modules::IdleInhibitor::update() -> void {
|
auto waybar::modules::IdleInhibitor::update() -> void {
|
||||||
// Check status
|
// Check status
|
||||||
if (status) {
|
if (status) {
|
||||||
label_.get_style_context()->remove_class("deactivated");
|
button_.get_style_context()->remove_class("deactivated");
|
||||||
if (idle_inhibitor_ == nullptr) {
|
if (idle_inhibitor_ == nullptr) {
|
||||||
idle_inhibitor_ = zwp_idle_inhibit_manager_v1_create_inhibitor(
|
idle_inhibitor_ = zwp_idle_inhibit_manager_v1_create_inhibitor(
|
||||||
waybar::Client::inst()->idle_inhibit_manager, bar_.surface);
|
waybar::Client::inst()->idle_inhibit_manager, bar_.surface);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
label_.get_style_context()->remove_class("activated");
|
button_.get_style_context()->remove_class("activated");
|
||||||
if (idle_inhibitor_ != nullptr) {
|
if (idle_inhibitor_ != nullptr) {
|
||||||
zwp_idle_inhibitor_v1_destroy(idle_inhibitor_);
|
zwp_idle_inhibitor_v1_destroy(idle_inhibitor_);
|
||||||
idle_inhibitor_ = nullptr;
|
idle_inhibitor_ = nullptr;
|
||||||
@ -58,11 +63,11 @@ auto waybar::modules::IdleInhibitor::update() -> void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string status_text = status ? "activated" : "deactivated";
|
std::string status_text = status ? "activated" : "deactivated";
|
||||||
label_.set_markup(fmt::format(format_, fmt::arg("status", status_text),
|
label_->set_markup(fmt::format(format_, fmt::arg("status", status_text),
|
||||||
fmt::arg("icon", getIcon(0, status_text))));
|
fmt::arg("icon", getIcon(0, status_text))));
|
||||||
label_.get_style_context()->add_class(status_text);
|
button_.get_style_context()->add_class(status_text);
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
label_.set_tooltip_markup(
|
button_.set_tooltip_markup(
|
||||||
status ? fmt::format(config_["tooltip-format-activated"].isString()
|
status ? fmt::format(config_["tooltip-format-activated"].isString()
|
||||||
? config_["tooltip-format-activated"].asString()
|
? config_["tooltip-format-activated"].asString()
|
||||||
: "{status}",
|
: "{status}",
|
||||||
@ -75,37 +80,41 @@ auto waybar::modules::IdleInhibitor::update() -> void {
|
|||||||
fmt::arg("icon", getIcon(0, status_text))));
|
fmt::arg("icon", getIcon(0, status_text))));
|
||||||
}
|
}
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::IdleInhibitor::toggleStatus() {
|
||||||
|
status = !status;
|
||||||
|
|
||||||
|
if (timeout_.connected()) {
|
||||||
|
/* cancel any already active timeout handler */
|
||||||
|
timeout_.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status && config_["timeout"].isNumeric()) {
|
||||||
|
auto timeoutMins = config_["timeout"].asDouble();
|
||||||
|
int timeoutSecs = timeoutMins * 60;
|
||||||
|
|
||||||
|
timeout_ = Glib::signal_timeout().connect_seconds(
|
||||||
|
[]() {
|
||||||
|
/* intentionally not tied to a module instance lifetime
|
||||||
|
* as the output with `this` can be disconnected
|
||||||
|
*/
|
||||||
|
spdlog::info("deactivating idle_inhibitor by timeout");
|
||||||
|
status = false;
|
||||||
|
for (auto const& module : waybar::modules::IdleInhibitor::modules) {
|
||||||
|
module->update();
|
||||||
|
}
|
||||||
|
/* disconnect */
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
timeoutSecs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) {
|
bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) {
|
||||||
if (e->button == 1) {
|
if (e->button == 1) {
|
||||||
status = !status;
|
toggleStatus();
|
||||||
|
|
||||||
if (timeout_.connected()) {
|
|
||||||
/* cancel any already active timeout handler */
|
|
||||||
timeout_.disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status && config_["timeout"].isNumeric()) {
|
|
||||||
auto timeoutMins = config_["timeout"].asDouble();
|
|
||||||
int timeoutSecs = timeoutMins * 60;
|
|
||||||
|
|
||||||
timeout_ = Glib::signal_timeout().connect_seconds(
|
|
||||||
[]() {
|
|
||||||
/* intentionally not tied to a module instance lifetime
|
|
||||||
* as the output with `this` can be disconnected
|
|
||||||
*/
|
|
||||||
spdlog::info("deactivating idle_inhibitor by timeout");
|
|
||||||
status = false;
|
|
||||||
for (auto const& module : waybar::modules::IdleInhibitor::modules) {
|
|
||||||
module->update();
|
|
||||||
}
|
|
||||||
/* disconnect */
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
timeoutSecs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make all other idle inhibitor modules update
|
// Make all other idle inhibitor modules update
|
||||||
for (auto const& module : waybar::modules::IdleInhibitor::modules) {
|
for (auto const& module : waybar::modules::IdleInhibitor::modules) {
|
||||||
@ -115,6 +124,6 @@ bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ALabel::handleToggle(e);
|
AButton::handleToggle(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ auto getInhibitors(const Json::Value& config) -> std::string {
|
|||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
Inhibitor::Inhibitor(const std::string& id, const Bar& bar, const Json::Value& config)
|
Inhibitor::Inhibitor(const std::string& id, const Bar& bar, const Json::Value& config)
|
||||||
: ALabel(config, "inhibitor", id, "{status}", true),
|
: AButton(config, "inhibitor", id, "{status}", true),
|
||||||
dbus_(::dbus()),
|
dbus_(::dbus()),
|
||||||
inhibitors_(::getInhibitors(config)) {
|
inhibitors_(::getInhibitors(config)) {
|
||||||
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
|
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
|
||||||
@ -117,16 +117,16 @@ auto Inhibitor::activated() -> bool { return handle_ != -1; }
|
|||||||
auto Inhibitor::update() -> void {
|
auto Inhibitor::update() -> void {
|
||||||
std::string status_text = activated() ? "activated" : "deactivated";
|
std::string status_text = activated() ? "activated" : "deactivated";
|
||||||
|
|
||||||
label_.get_style_context()->remove_class(activated() ? "deactivated" : "activated");
|
button_.get_style_context()->remove_class(activated() ? "deactivated" : "activated");
|
||||||
label_.set_markup(fmt::format(format_, fmt::arg("status", status_text),
|
label_->set_markup(fmt::format(format_, fmt::arg("status", status_text),
|
||||||
fmt::arg("icon", getIcon(0, status_text))));
|
fmt::arg("icon", getIcon(0, status_text))));
|
||||||
label_.get_style_context()->add_class(status_text);
|
button_.get_style_context()->add_class(status_text);
|
||||||
|
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
label_.set_tooltip_text(status_text);
|
button_.set_tooltip_text(status_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ALabel::update();
|
return AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Inhibitor::handleToggle(GdkEventButton* const& e) -> bool {
|
auto Inhibitor::handleToggle(GdkEventButton* const& e) -> bool {
|
||||||
@ -142,7 +142,7 @@ auto Inhibitor::handleToggle(GdkEventButton* const& e) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ALabel::handleToggle(e);
|
return AButton::handleToggle(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
@ -1,7 +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, "memory", id, "{}%", 30) {
|
: AButton(config, "memory", id, "{}%", 30) {
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
dp.emit();
|
dp.emit();
|
||||||
thread_.sleep_for(interval_);
|
thread_.sleep_for(interval_);
|
||||||
@ -54,7 +54,7 @@ auto waybar::modules::Memory::update() -> void {
|
|||||||
} else {
|
} else {
|
||||||
event_box_.show();
|
event_box_.show();
|
||||||
auto icons = std::vector<std::string>{state};
|
auto icons = std::vector<std::string>{state};
|
||||||
label_.set_markup(fmt::format(
|
label_->set_markup(fmt::format(
|
||||||
format, used_ram_percentage, fmt::arg("icon", getIcon(used_ram_percentage, icons)),
|
format, used_ram_percentage, fmt::arg("icon", getIcon(used_ram_percentage, icons)),
|
||||||
fmt::arg("total", total_ram_gigabytes), fmt::arg("swapTotal", total_swap_gigabytes),
|
fmt::arg("total", total_ram_gigabytes), fmt::arg("swapTotal", total_swap_gigabytes),
|
||||||
fmt::arg("percentage", used_ram_percentage),
|
fmt::arg("percentage", used_ram_percentage),
|
||||||
@ -66,7 +66,7 @@ auto waybar::modules::Memory::update() -> void {
|
|||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
if (config_["tooltip-format"].isString()) {
|
if (config_["tooltip-format"].isString()) {
|
||||||
auto tooltip_format = config_["tooltip-format"].asString();
|
auto tooltip_format = config_["tooltip-format"].asString();
|
||||||
label_.set_tooltip_text(fmt::format(
|
button_.set_tooltip_text(fmt::format(
|
||||||
tooltip_format, used_ram_percentage, fmt::arg("total", total_ram_gigabytes),
|
tooltip_format, used_ram_percentage, fmt::arg("total", total_ram_gigabytes),
|
||||||
fmt::arg("swapTotal", total_swap_gigabytes),
|
fmt::arg("swapTotal", total_swap_gigabytes),
|
||||||
fmt::arg("percentage", used_ram_percentage),
|
fmt::arg("percentage", used_ram_percentage),
|
||||||
@ -74,12 +74,12 @@ auto waybar::modules::Memory::update() -> void {
|
|||||||
fmt::arg("swapUsed", used_swap_gigabytes), fmt::arg("avail", available_ram_gigabytes),
|
fmt::arg("swapUsed", used_swap_gigabytes), fmt::arg("avail", available_ram_gigabytes),
|
||||||
fmt::arg("swapAvail", available_swap_gigabytes)));
|
fmt::arg("swapAvail", available_swap_gigabytes)));
|
||||||
} else {
|
} else {
|
||||||
label_.set_tooltip_text(fmt::format("{:.{}f}GiB used", used_ram_gigabytes, 1));
|
button_.set_tooltip_text(fmt::format("{:.{}f}GiB used", used_ram_gigabytes, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
event_box_.hide();
|
event_box_.hide();
|
||||||
}
|
}
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
#include <glibmm/ustring.h>
|
#include <glibmm/ustring.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include <util/sanitize_str.hpp>
|
||||||
|
using namespace waybar::util;
|
||||||
|
|
||||||
#include "modules/mpd/state.hpp"
|
#include "modules/mpd/state.hpp"
|
||||||
#if defined(MPD_NOINLINE)
|
#if defined(MPD_NOINLINE)
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
@ -12,7 +15,7 @@ namespace waybar::modules {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
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, "mpd", id, "{album} - {artist} - {title}", 5),
|
: AButton(config, "mpd", id, "{album} - {artist} - {title}", 5, false, true),
|
||||||
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),
|
||||||
@ -44,7 +47,7 @@ auto waybar::modules::MPD::update() -> void {
|
|||||||
context_.update();
|
context_.update();
|
||||||
|
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::MPD::queryMPD() {
|
void waybar::modules::MPD::queryMPD() {
|
||||||
@ -85,15 +88,15 @@ std::string waybar::modules::MPD::getFilename() const {
|
|||||||
|
|
||||||
void waybar::modules::MPD::setLabel() {
|
void waybar::modules::MPD::setLabel() {
|
||||||
if (connection_ == nullptr) {
|
if (connection_ == nullptr) {
|
||||||
label_.get_style_context()->add_class("disconnected");
|
button_.get_style_context()->add_class("disconnected");
|
||||||
label_.get_style_context()->remove_class("stopped");
|
button_.get_style_context()->remove_class("stopped");
|
||||||
label_.get_style_context()->remove_class("playing");
|
button_.get_style_context()->remove_class("playing");
|
||||||
label_.get_style_context()->remove_class("paused");
|
button_.get_style_context()->remove_class("paused");
|
||||||
|
|
||||||
auto format = config_["format-disconnected"].isString()
|
auto format = config_["format-disconnected"].isString()
|
||||||
? config_["format-disconnected"].asString()
|
? config_["format-disconnected"].asString()
|
||||||
: "disconnected";
|
: "disconnected";
|
||||||
label_.set_markup(format);
|
label_->set_markup(format);
|
||||||
|
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
std::string tooltip_format;
|
std::string tooltip_format;
|
||||||
@ -101,11 +104,11 @@ void waybar::modules::MPD::setLabel() {
|
|||||||
? config_["tooltip-format-disconnected"].asString()
|
? config_["tooltip-format-disconnected"].asString()
|
||||||
: "MPD (disconnected)";
|
: "MPD (disconnected)";
|
||||||
// Nothing to format
|
// Nothing to format
|
||||||
label_.set_tooltip_text(tooltip_format);
|
button_.set_tooltip_text(tooltip_format);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
label_.get_style_context()->remove_class("disconnected");
|
button_.get_style_context()->remove_class("disconnected");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto format = format_;
|
auto format = format_;
|
||||||
@ -118,29 +121,29 @@ void waybar::modules::MPD::setLabel() {
|
|||||||
if (stopped()) {
|
if (stopped()) {
|
||||||
format =
|
format =
|
||||||
config_["format-stopped"].isString() ? config_["format-stopped"].asString() : "stopped";
|
config_["format-stopped"].isString() ? config_["format-stopped"].asString() : "stopped";
|
||||||
label_.get_style_context()->add_class("stopped");
|
button_.get_style_context()->add_class("stopped");
|
||||||
label_.get_style_context()->remove_class("playing");
|
button_.get_style_context()->remove_class("playing");
|
||||||
label_.get_style_context()->remove_class("paused");
|
button_.get_style_context()->remove_class("paused");
|
||||||
} else {
|
} else {
|
||||||
label_.get_style_context()->remove_class("stopped");
|
button_.get_style_context()->remove_class("stopped");
|
||||||
if (playing()) {
|
if (playing()) {
|
||||||
label_.get_style_context()->add_class("playing");
|
button_.get_style_context()->add_class("playing");
|
||||||
label_.get_style_context()->remove_class("paused");
|
button_.get_style_context()->remove_class("paused");
|
||||||
} else if (paused()) {
|
} else if (paused()) {
|
||||||
format = config_["format-paused"].isString() ? config_["format-paused"].asString()
|
format = config_["format-paused"].isString() ? config_["format-paused"].asString()
|
||||||
: config_["format"].asString();
|
: config_["format"].asString();
|
||||||
label_.get_style_context()->add_class("paused");
|
button_.get_style_context()->add_class("paused");
|
||||||
label_.get_style_context()->remove_class("playing");
|
button_.get_style_context()->remove_class("playing");
|
||||||
}
|
}
|
||||||
|
|
||||||
stateIcon = getStateIcon();
|
stateIcon = getStateIcon();
|
||||||
|
|
||||||
artist = getTag(MPD_TAG_ARTIST);
|
artist = sanitize_string(getTag(MPD_TAG_ARTIST));
|
||||||
album_artist = getTag(MPD_TAG_ALBUM_ARTIST);
|
album_artist = sanitize_string(getTag(MPD_TAG_ALBUM_ARTIST));
|
||||||
album = getTag(MPD_TAG_ALBUM);
|
album = sanitize_string(getTag(MPD_TAG_ALBUM));
|
||||||
title = getTag(MPD_TAG_TITLE);
|
title = sanitize_string(getTag(MPD_TAG_TITLE));
|
||||||
date = getTag(MPD_TAG_DATE);
|
date = sanitize_string(getTag(MPD_TAG_DATE));
|
||||||
filename = getFilename();
|
filename = sanitize_string(getFilename());
|
||||||
song_pos = mpd_status_get_song_pos(status_.get()) + 1;
|
song_pos = mpd_status_get_song_pos(status_.get()) + 1;
|
||||||
volume = mpd_status_get_volume(status_.get());
|
volume = mpd_status_get_volume(status_.get());
|
||||||
if (volume < 0) {
|
if (volume < 0) {
|
||||||
@ -166,7 +169,7 @@ void waybar::modules::MPD::setLabel() {
|
|||||||
if (config_["title-len"].isInt()) title = title.substr(0, config_["title-len"].asInt());
|
if (config_["title-len"].isInt()) title = title.substr(0, config_["title-len"].asInt());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
label_.set_markup(fmt::format(
|
label_->set_markup(fmt::format(
|
||||||
format, fmt::arg("artist", Glib::Markup::escape_text(artist).raw()),
|
format, fmt::arg("artist", Glib::Markup::escape_text(artist).raw()),
|
||||||
fmt::arg("albumArtist", Glib::Markup::escape_text(album_artist).raw()),
|
fmt::arg("albumArtist", Glib::Markup::escape_text(album_artist).raw()),
|
||||||
fmt::arg("album", Glib::Markup::escape_text(album).raw()),
|
fmt::arg("album", Glib::Markup::escape_text(album).raw()),
|
||||||
@ -195,7 +198,7 @@ void waybar::modules::MPD::setLabel() {
|
|||||||
fmt::arg("queueLength", queue_length), fmt::arg("stateIcon", stateIcon),
|
fmt::arg("queueLength", queue_length), fmt::arg("stateIcon", stateIcon),
|
||||||
fmt::arg("consumeIcon", consumeIcon), fmt::arg("randomIcon", randomIcon),
|
fmt::arg("consumeIcon", consumeIcon), fmt::arg("randomIcon", randomIcon),
|
||||||
fmt::arg("repeatIcon", repeatIcon), fmt::arg("singleIcon", singleIcon));
|
fmt::arg("repeatIcon", repeatIcon), fmt::arg("singleIcon", singleIcon));
|
||||||
label_.set_tooltip_text(tooltip_text);
|
button_.set_tooltip_text(tooltip_text);
|
||||||
} catch (fmt::format_error const& e) {
|
} catch (fmt::format_error const& e) {
|
||||||
spdlog::warn("mpd: format error (tooltip): {}", e.what());
|
spdlog::warn("mpd: format error (tooltip): {}", e.what());
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ waybar::modules::Network::readBandwidthUsage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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, "network", id, DEFAULT_FORMAT, 60),
|
: AButton(config, "network", id, DEFAULT_FORMAT, 60),
|
||||||
ifid_(-1),
|
ifid_(-1),
|
||||||
family_(config["family"] == "ipv6" ? AF_INET6 : AF_INET),
|
family_(config["family"] == "ipv6" ? AF_INET6 : AF_INET),
|
||||||
efd_(-1),
|
efd_(-1),
|
||||||
@ -95,11 +95,11 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf
|
|||||||
#endif
|
#endif
|
||||||
frequency_(0.0) {
|
frequency_(0.0) {
|
||||||
|
|
||||||
// Start with some "text" in the module's label_, update() will then
|
// Start with some "text" in the module's label_-> update() will then
|
||||||
// update it. Since the text should be different, update() will be able
|
// update it. Since the text should be different, update() will be able
|
||||||
// to show or hide the event_box_. This is to work around the case where
|
// to show or hide the event_box_. This is to work around the case where
|
||||||
// the module start with no text, but the the event_box_ is shown.
|
// the module start with no text, but the the event_box_ is shown.
|
||||||
label_.set_markup("<s></s>");
|
label_->set_markup("<s></s>");
|
||||||
|
|
||||||
auto bandwidth = readBandwidthUsage();
|
auto bandwidth = readBandwidthUsage();
|
||||||
if (bandwidth.has_value()) {
|
if (bandwidth.has_value()) {
|
||||||
@ -309,8 +309,8 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
|
|
||||||
if (!alt_) {
|
if (!alt_) {
|
||||||
auto state = getNetworkState();
|
auto state = getNetworkState();
|
||||||
if (!state_.empty() && label_.get_style_context()->has_class(state_)) {
|
if (!state_.empty() && button_.get_style_context()->has_class(state_)) {
|
||||||
label_.get_style_context()->remove_class(state_);
|
button_.get_style_context()->remove_class(state_);
|
||||||
}
|
}
|
||||||
if (config_["format-" + state].isString()) {
|
if (config_["format-" + state].isString()) {
|
||||||
default_format_ = config_["format-" + state].asString();
|
default_format_ = config_["format-" + state].asString();
|
||||||
@ -322,8 +322,8 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
if (config_["tooltip-format-" + state].isString()) {
|
if (config_["tooltip-format-" + state].isString()) {
|
||||||
tooltip_format = config_["tooltip-format-" + state].asString();
|
tooltip_format = config_["tooltip-format-" + state].asString();
|
||||||
}
|
}
|
||||||
if (!label_.get_style_context()->has_class(state)) {
|
if (!button_.get_style_context()->has_class(state)) {
|
||||||
label_.get_style_context()->add_class(state);
|
button_.get_style_context()->add_class(state);
|
||||||
}
|
}
|
||||||
format_ = default_format_;
|
format_ = default_format_;
|
||||||
state_ = state;
|
state_ = state;
|
||||||
@ -349,8 +349,8 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
fmt::arg("bandwidthUpBytes", pow_format(bandwidth_up / interval_.count(), "B/s")),
|
fmt::arg("bandwidthUpBytes", pow_format(bandwidth_up / interval_.count(), "B/s")),
|
||||||
fmt::arg("bandwidthTotalBytes",
|
fmt::arg("bandwidthTotalBytes",
|
||||||
pow_format((bandwidth_up + bandwidth_down) / interval_.count(), "B/s")));
|
pow_format((bandwidth_up + bandwidth_down) / interval_.count(), "B/s")));
|
||||||
if (text.compare(label_.get_label()) != 0) {
|
if (text.compare(label_->get_label()) != 0) {
|
||||||
label_.set_markup(text);
|
label_->set_markup(text);
|
||||||
if (text.empty()) {
|
if (text.empty()) {
|
||||||
event_box_.hide();
|
event_box_.hide();
|
||||||
} else {
|
} else {
|
||||||
@ -382,16 +382,16 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
fmt::arg("bandwidthUpBytes", pow_format(bandwidth_up / interval_.count(), "B/s")),
|
fmt::arg("bandwidthUpBytes", pow_format(bandwidth_up / interval_.count(), "B/s")),
|
||||||
fmt::arg("bandwidthTotalBytes",
|
fmt::arg("bandwidthTotalBytes",
|
||||||
pow_format((bandwidth_up + bandwidth_down) / interval_.count(), "B/s")));
|
pow_format((bandwidth_up + bandwidth_down) / interval_.count(), "B/s")));
|
||||||
if (label_.get_tooltip_text() != tooltip_text) {
|
if (button_.get_tooltip_text() != tooltip_text) {
|
||||||
label_.set_tooltip_markup(tooltip_text);
|
button_.set_tooltip_markup(tooltip_text);
|
||||||
}
|
}
|
||||||
} else if (label_.get_tooltip_text() != text) {
|
} else if (button_.get_tooltip_text() != text) {
|
||||||
label_.set_tooltip_markup(text);
|
button_.set_tooltip_markup(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waybar::modules::Network::checkInterface(std::string name) {
|
bool waybar::modules::Network::checkInterface(std::string name) {
|
||||||
|
@ -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, "pulseaudio", id, "{volume}%"),
|
: AButton(config, "pulseaudio", id, "{volume}%"),
|
||||||
mainloop_(nullptr),
|
mainloop_(nullptr),
|
||||||
mainloop_api_(nullptr),
|
mainloop_api_(nullptr),
|
||||||
context_(nullptr),
|
context_(nullptr),
|
||||||
@ -91,19 +91,31 @@ bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) {
|
|||||||
pa_volume_t change = volume_tick;
|
pa_volume_t change = volume_tick;
|
||||||
pa_cvolume pa_volume = pa_volume_;
|
pa_cvolume pa_volume = pa_volume_;
|
||||||
int max_volume = 100;
|
int max_volume = 100;
|
||||||
|
double step = 1;
|
||||||
// isDouble returns true for integers as well, just in case
|
// isDouble returns true for integers as well, just in case
|
||||||
if (config_["scroll-step"].isDouble()) {
|
if (config_["scroll-step"].isDouble()) {
|
||||||
change = round(config_["scroll-step"].asDouble() * volume_tick);
|
step = config_["scroll-step"].asDouble();
|
||||||
}
|
}
|
||||||
if (config_["max-volume"].isInt()) {
|
if (config_["max-volume"].isInt()) {
|
||||||
max_volume = std::min(0, config_["max-volume"].asInt());
|
max_volume = std::min(config_["max-volume"].asInt(), static_cast<int>(PA_VOLUME_UI_MAX));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dir == SCROLL_DIR::UP) {
|
if (dir == SCROLL_DIR::UP) {
|
||||||
if (volume_ + 1 <= max_volume) {
|
if (volume_ < max_volume) {
|
||||||
|
if (volume_ + step > max_volume) {
|
||||||
|
change = round((max_volume - volume_) * volume_tick);
|
||||||
|
} else {
|
||||||
|
change = round(step * volume_tick);
|
||||||
|
}
|
||||||
pa_cvolume_inc(&pa_volume, change);
|
pa_cvolume_inc(&pa_volume, change);
|
||||||
}
|
}
|
||||||
} else if (dir == SCROLL_DIR::DOWN) {
|
} else if (dir == SCROLL_DIR::DOWN) {
|
||||||
if (volume_ - 1 >= 0) {
|
if (volume_ > 0) {
|
||||||
|
if (volume_ - step < 0) {
|
||||||
|
change = round(volume_ * volume_tick);
|
||||||
|
} else {
|
||||||
|
change = round(step * volume_tick);
|
||||||
|
}
|
||||||
pa_cvolume_dec(&pa_volume, change);
|
pa_cvolume_dec(&pa_volume, change);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,6 +182,15 @@ void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, const pa_
|
|||||||
if (i == nullptr) return;
|
if (i == nullptr) return;
|
||||||
|
|
||||||
auto pa = static_cast<waybar::modules::Pulseaudio *>(data);
|
auto pa = static_cast<waybar::modules::Pulseaudio *>(data);
|
||||||
|
|
||||||
|
if (pa->config_["ignored-sinks"].isArray()) {
|
||||||
|
for (const auto &ignored_sink : pa->config_["ignored-sinks"]) {
|
||||||
|
if (ignored_sink.asString() == i->description) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pa->current_sink_name_ == i->name) {
|
if (pa->current_sink_name_ == i->name) {
|
||||||
if (i->state != PA_SINK_RUNNING) {
|
if (i->state != PA_SINK_RUNNING) {
|
||||||
pa->current_sink_running_ = false;
|
pa->current_sink_running_ = false;
|
||||||
@ -240,9 +261,9 @@ auto waybar::modules::Pulseaudio::update() -> void {
|
|||||||
if (monitor_.find("a2dp_sink") != std::string::npos || // PulseAudio
|
if (monitor_.find("a2dp_sink") != std::string::npos || // PulseAudio
|
||||||
monitor_.find("a2dp-sink") != std::string::npos) { // PipeWire
|
monitor_.find("a2dp-sink") != std::string::npos) { // PipeWire
|
||||||
format_name = format_name + "-bluetooth";
|
format_name = format_name + "-bluetooth";
|
||||||
label_.get_style_context()->add_class("bluetooth");
|
button_.get_style_context()->add_class("bluetooth");
|
||||||
} else {
|
} else {
|
||||||
label_.get_style_context()->remove_class("bluetooth");
|
button_.get_style_context()->remove_class("bluetooth");
|
||||||
}
|
}
|
||||||
if (muted_) {
|
if (muted_) {
|
||||||
// Check muted bluetooth format exist, otherwise fallback to default muted format
|
// Check muted bluetooth format exist, otherwise fallback to default muted format
|
||||||
@ -250,29 +271,29 @@ auto waybar::modules::Pulseaudio::update() -> void {
|
|||||||
format_name = "format";
|
format_name = "format";
|
||||||
}
|
}
|
||||||
format_name = format_name + "-muted";
|
format_name = format_name + "-muted";
|
||||||
label_.get_style_context()->add_class("muted");
|
button_.get_style_context()->add_class("muted");
|
||||||
label_.get_style_context()->add_class("sink-muted");
|
button_.get_style_context()->add_class("sink-muted");
|
||||||
} else {
|
} else {
|
||||||
label_.get_style_context()->remove_class("muted");
|
button_.get_style_context()->remove_class("muted");
|
||||||
label_.get_style_context()->remove_class("sink-muted");
|
button_.get_style_context()->remove_class("sink-muted");
|
||||||
}
|
}
|
||||||
format = config_[format_name].isString() ? config_[format_name].asString() : format;
|
format = config_[format_name].isString() ? config_[format_name].asString() : format;
|
||||||
}
|
}
|
||||||
// TODO: find a better way to split source/sink
|
// TODO: find a better way to split source/sink
|
||||||
std::string format_source = "{volume}%";
|
std::string format_source = "{volume}%";
|
||||||
if (source_muted_) {
|
if (source_muted_) {
|
||||||
label_.get_style_context()->add_class("source-muted");
|
button_.get_style_context()->add_class("source-muted");
|
||||||
if (config_["format-source-muted"].isString()) {
|
if (config_["format-source-muted"].isString()) {
|
||||||
format_source = config_["format-source-muted"].asString();
|
format_source = config_["format-source-muted"].asString();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
label_.get_style_context()->remove_class("source-muted");
|
button_.get_style_context()->remove_class("source-muted");
|
||||||
if (config_["format-source-muted"].isString()) {
|
if (config_["format-source-muted"].isString()) {
|
||||||
format_source = config_["format-source"].asString();
|
format_source = config_["format-source"].asString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
format_source = fmt::format(format_source, fmt::arg("volume", source_volume_));
|
format_source = fmt::format(format_source, fmt::arg("volume", source_volume_));
|
||||||
label_.set_markup(fmt::format(
|
label_->set_markup(fmt::format(
|
||||||
format, fmt::arg("desc", desc_), fmt::arg("volume", volume_),
|
format, fmt::arg("desc", desc_), fmt::arg("volume", volume_),
|
||||||
fmt::arg("format_source", format_source), fmt::arg("source_volume", source_volume_),
|
fmt::arg("format_source", format_source), fmt::arg("source_volume", source_volume_),
|
||||||
fmt::arg("source_desc", source_desc_), fmt::arg("icon", getIcon(volume_, getPulseIcon()))));
|
fmt::arg("source_desc", source_desc_), fmt::arg("icon", getIcon(volume_, getPulseIcon()))));
|
||||||
@ -283,16 +304,16 @@ auto waybar::modules::Pulseaudio::update() -> void {
|
|||||||
tooltip_format = config_["tooltip-format"].asString();
|
tooltip_format = config_["tooltip-format"].asString();
|
||||||
}
|
}
|
||||||
if (!tooltip_format.empty()) {
|
if (!tooltip_format.empty()) {
|
||||||
label_.set_tooltip_text(fmt::format(
|
button_.set_tooltip_text(fmt::format(
|
||||||
tooltip_format, fmt::arg("desc", desc_), fmt::arg("volume", volume_),
|
tooltip_format, fmt::arg("desc", desc_), fmt::arg("volume", volume_),
|
||||||
fmt::arg("format_source", format_source), fmt::arg("source_volume", source_volume_),
|
fmt::arg("format_source", format_source), fmt::arg("source_volume", source_volume_),
|
||||||
fmt::arg("source_desc", source_desc_),
|
fmt::arg("source_desc", source_desc_),
|
||||||
fmt::arg("icon", getIcon(volume_, getPulseIcon()))));
|
fmt::arg("icon", getIcon(volume_, getPulseIcon()))));
|
||||||
} else {
|
} else {
|
||||||
label_.set_tooltip_text(desc_);
|
button_.set_tooltip_text(desc_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "clock", id, "{:%H:%M}", 60) {
|
: AButton(config, "clock", id, "{:%H:%M}", 60) {
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
dp.emit();
|
dp.emit();
|
||||||
auto now = std::chrono::system_clock::now();
|
auto now = std::chrono::system_clock::now();
|
||||||
@ -19,17 +19,17 @@ auto waybar::modules::Clock::update() -> void {
|
|||||||
auto now = std::chrono::system_clock::now();
|
auto now = std::chrono::system_clock::now();
|
||||||
auto localtime = fmt::localtime(std::chrono::system_clock::to_time_t(now));
|
auto localtime = fmt::localtime(std::chrono::system_clock::to_time_t(now));
|
||||||
auto text = fmt::format(format_, localtime);
|
auto text = fmt::format(format_, localtime);
|
||||||
label_.set_markup(text);
|
label_->set_markup(text);
|
||||||
|
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
if (config_["tooltip-format"].isString()) {
|
if (config_["tooltip-format"].isString()) {
|
||||||
auto tooltip_format = config_["tooltip-format"].asString();
|
auto tooltip_format = config_["tooltip-format"].asString();
|
||||||
auto tooltip_text = fmt::format(tooltip_format, localtime);
|
auto tooltip_text = fmt::format(tooltip_format, localtime);
|
||||||
label_.set_tooltip_text(tooltip_text);
|
button_.set_tooltip_text(tooltip_text);
|
||||||
} else {
|
} else {
|
||||||
label_.set_tooltip_text(text);
|
button_.set_tooltip_text(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ auto Sndio::connect_to_sndio() -> void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Sndio::Sndio(const std::string &id, const Json::Value &config)
|
Sndio::Sndio(const std::string &id, const Json::Value &config)
|
||||||
: ALabel(config, "sndio", id, "{volume}%", 1),
|
: AButton(config, "sndio", id, "{volume}%", 1, false, true),
|
||||||
hdl_(nullptr),
|
hdl_(nullptr),
|
||||||
pfds_(0),
|
pfds_(0),
|
||||||
addr_(0),
|
addr_(0),
|
||||||
@ -105,14 +105,14 @@ auto Sndio::update() -> void {
|
|||||||
unsigned int vol = 100. * static_cast<double>(volume_) / static_cast<double>(maxval_);
|
unsigned int vol = 100. * static_cast<double>(volume_) / static_cast<double>(maxval_);
|
||||||
|
|
||||||
if (volume_ == 0) {
|
if (volume_ == 0) {
|
||||||
label_.get_style_context()->add_class("muted");
|
button_.get_style_context()->add_class("muted");
|
||||||
} else {
|
} else {
|
||||||
label_.get_style_context()->remove_class("muted");
|
button_.get_style_context()->remove_class("muted");
|
||||||
}
|
}
|
||||||
|
|
||||||
label_.set_markup(fmt::format(format, fmt::arg("volume", vol), fmt::arg("raw_value", volume_)));
|
label_->set_markup(fmt::format(format, fmt::arg("volume", vol), fmt::arg("raw_value", volume_)));
|
||||||
|
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Sndio::set_desc(struct sioctl_desc *d, unsigned int val) -> void {
|
auto Sndio::set_desc(struct sioctl_desc *d, unsigned int val) -> void {
|
||||||
|
@ -18,7 +18,7 @@ const std::string Language::XKB_LAYOUT_NAMES_KEY = "xkb_layout_names";
|
|||||||
const std::string Language::XKB_ACTIVE_LAYOUT_NAME_KEY = "xkb_active_layout_name";
|
const std::string Language::XKB_ACTIVE_LAYOUT_NAME_KEY = "xkb_active_layout_name";
|
||||||
|
|
||||||
Language::Language(const std::string& id, const Json::Value& config)
|
Language::Language(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "language", id, "{}", 0, true) {
|
: AButton(config, "language", id, "{}", 0, true) {
|
||||||
is_variant_displayed = format_.find("{variant}") != std::string::npos;
|
is_variant_displayed = format_.find("{variant}") != std::string::npos;
|
||||||
if (format_.find("{}") != std::string::npos || format_.find("{short}") != std::string::npos) {
|
if (format_.find("{}") != std::string::npos || format_.find("{short}") != std::string::npos) {
|
||||||
displayed_short_flag |= static_cast<std::byte>(DispayedShortFlag::ShortName);
|
displayed_short_flag |= static_cast<std::byte>(DispayedShortFlag::ShortName);
|
||||||
@ -99,7 +99,7 @@ auto Language::update() -> void {
|
|||||||
format_, fmt::arg("short", layout_.short_name),
|
format_, fmt::arg("short", layout_.short_name),
|
||||||
fmt::arg("shortDescription", layout_.short_description), fmt::arg("long", layout_.full_name),
|
fmt::arg("shortDescription", layout_.short_description), fmt::arg("long", layout_.full_name),
|
||||||
fmt::arg("variant", layout_.variant), fmt::arg("flag", layout_.country_flag())));
|
fmt::arg("variant", layout_.variant), fmt::arg("flag", layout_.country_flag())));
|
||||||
label_.set_markup(display_layout);
|
label_->set_markup(display_layout);
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
if (tooltip_format_ != "") {
|
if (tooltip_format_ != "") {
|
||||||
auto tooltip_display_layout = trim(
|
auto tooltip_display_layout = trim(
|
||||||
@ -107,22 +107,22 @@ auto Language::update() -> void {
|
|||||||
fmt::arg("shortDescription", layout_.short_description),
|
fmt::arg("shortDescription", layout_.short_description),
|
||||||
fmt::arg("long", layout_.full_name), fmt::arg("variant", layout_.variant),
|
fmt::arg("long", layout_.full_name), fmt::arg("variant", layout_.variant),
|
||||||
fmt::arg("flag", layout_.country_flag())));
|
fmt::arg("flag", layout_.country_flag())));
|
||||||
label_.set_tooltip_markup(tooltip_display_layout);
|
button_.set_tooltip_markup(tooltip_display_layout);
|
||||||
} else {
|
} else {
|
||||||
label_.set_tooltip_markup(display_layout);
|
button_.set_tooltip_markup(display_layout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event_box_.show();
|
event_box_.show();
|
||||||
|
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Language::set_current_layout(std::string current_layout) -> void {
|
auto Language::set_current_layout(std::string current_layout) -> void {
|
||||||
label_.get_style_context()->remove_class(layout_.short_name);
|
button_.get_style_context()->remove_class(layout_.short_name);
|
||||||
layout_ = layouts_map_[current_layout];
|
layout_ = layouts_map_[current_layout];
|
||||||
label_.get_style_context()->add_class(layout_.short_name);
|
button_.get_style_context()->add_class(layout_.short_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Language::init_layouts_map(const std::vector<std::string>& used_layouts) -> void {
|
auto Language::init_layouts_map(const std::vector<std::string>& used_layouts) -> void {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
Mode::Mode(const std::string& id, const Json::Value& config)
|
Mode::Mode(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "mode", id, "{}", 0, true) {
|
: AButton(config, "mode", id, "{}", 0, true) {
|
||||||
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
|
||||||
@ -42,14 +42,14 @@ auto Mode::update() -> void {
|
|||||||
if (mode_.empty()) {
|
if (mode_.empty()) {
|
||||||
event_box_.hide();
|
event_box_.hide();
|
||||||
} else {
|
} else {
|
||||||
label_.set_markup(fmt::format(format_, mode_));
|
label_->set_markup(fmt::format(format_, mode_));
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
label_.set_tooltip_text(mode_);
|
button_.set_tooltip_text(mode_);
|
||||||
}
|
}
|
||||||
event_box_.show();
|
event_box_.show();
|
||||||
}
|
}
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace waybar::modules::sway
|
} // namespace waybar::modules::sway
|
||||||
|
@ -3,15 +3,11 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
// clang-format off
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
// clang-format on
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
waybar::modules::Temperature::Temperature(const std::string& id, const Json::Value& config)
|
waybar::modules::Temperature::Temperature(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "temperature", id, "{temperatureC}°C", 10) {
|
: AButton(config, "temperature", id, "{temperatureC}°C", 10) {
|
||||||
|
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
// try to read sysctl?
|
// try to read sysctl?
|
||||||
#else
|
#else
|
||||||
@ -46,9 +42,9 @@ auto waybar::modules::Temperature::update() -> void {
|
|||||||
auto format = format_;
|
auto format = format_;
|
||||||
if (critical) {
|
if (critical) {
|
||||||
format = config_["format-critical"].isString() ? config_["format-critical"].asString() : format;
|
format = config_["format-critical"].isString() ? config_["format-critical"].asString() : format;
|
||||||
label_.get_style_context()->add_class("critical");
|
button_.get_style_context()->add_class("critical");
|
||||||
} else {
|
} else {
|
||||||
label_.get_style_context()->remove_class("critical");
|
button_.get_style_context()->remove_class("critical");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format.empty()) {
|
if (format.empty()) {
|
||||||
@ -59,21 +55,21 @@ auto waybar::modules::Temperature::update() -> void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto max_temp = config_["critical-threshold"].isInt() ? config_["critical-threshold"].asInt() : 0;
|
auto max_temp = config_["critical-threshold"].isInt() ? config_["critical-threshold"].asInt() : 0;
|
||||||
label_.set_markup(fmt::format(format, fmt::arg("temperatureC", temperature_c),
|
label_->set_markup(fmt::format(format, fmt::arg("temperatureC", temperature_c),
|
||||||
fmt::arg("temperatureF", temperature_f),
|
fmt::arg("temperatureF", temperature_f),
|
||||||
fmt::arg("temperatureK", temperature_k),
|
fmt::arg("temperatureK", temperature_k),
|
||||||
fmt::arg("icon", getIcon(temperature_c, "", max_temp))));
|
fmt::arg("icon", getIcon(temperature_c, "", max_temp))));
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
std::string tooltip_format = "{temperatureC}°C";
|
std::string tooltip_format = "{temperatureC}°C";
|
||||||
if (config_["tooltip-format"].isString()) {
|
if (config_["tooltip-format"].isString()) {
|
||||||
tooltip_format = config_["tooltip-format"].asString();
|
tooltip_format = config_["tooltip-format"].asString();
|
||||||
}
|
}
|
||||||
label_.set_tooltip_text(fmt::format(tooltip_format, fmt::arg("temperatureC", temperature_c),
|
button_.set_tooltip_text(fmt::format(tooltip_format, fmt::arg("temperatureC", temperature_c),
|
||||||
fmt::arg("temperatureF", temperature_f),
|
fmt::arg("temperatureF", temperature_f),
|
||||||
fmt::arg("temperatureK", temperature_k)));
|
fmt::arg("temperatureK", temperature_k)));
|
||||||
}
|
}
|
||||||
// Call parent update
|
// Call parent update
|
||||||
ALabel::update();
|
AButton::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
float waybar::modules::Temperature::getTemperature() {
|
float waybar::modules::Temperature::getTemperature() {
|
||||||
@ -81,13 +77,17 @@ float waybar::modules::Temperature::getTemperature() {
|
|||||||
int temp;
|
int temp;
|
||||||
size_t size = sizeof temp;
|
size_t size = sizeof temp;
|
||||||
|
|
||||||
|
auto zone = config_["thermal-zone"].isInt() ? config_["thermal-zone"].asInt() : 0;
|
||||||
|
auto sysctl_thermal = fmt::format("hw.acpi.thermal.tz{}.temperature", zone);
|
||||||
|
|
||||||
if (sysctlbyname("hw.acpi.thermal.tz0.temperature", &temp, &size, NULL, 0) != 0) {
|
if (sysctlbyname("hw.acpi.thermal.tz0.temperature", &temp, &size, NULL, 0) != 0) {
|
||||||
throw std::runtime_error("sysctl hw.acpi.thermal.tz0.temperature or dev.cpu.0.temperature failed");
|
throw std::runtime_error(
|
||||||
|
"sysctl hw.acpi.thermal.tz0.temperature or dev.cpu.0.temperature failed");
|
||||||
}
|
}
|
||||||
auto temperature_c = ((float)temp-2732)/10;
|
auto temperature_c = ((float)temp - 2732) / 10;
|
||||||
return temperature_c;
|
return temperature_c;
|
||||||
|
|
||||||
#else // Linux
|
#else // Linux
|
||||||
std::ifstream temp(file_path_);
|
std::ifstream temp(file_path_);
|
||||||
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_);
|
||||||
|
24
src/util/sanitize_str.cpp
Normal file
24
src/util/sanitize_str.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
#include <util/sanitize_str.hpp>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace waybar::util {
|
||||||
|
// replaces ``<>&"'`` with their encoded counterparts
|
||||||
|
std::string sanitize_string(std::string str) {
|
||||||
|
// note: it's important that '&' is replaced first; therefor we *can't* use std::map
|
||||||
|
const std::pair<char, std::string> replacement_table[] = {
|
||||||
|
{'&', "&"}, {'<', "<"}, {'>', ">"}, {'"', """}, {'\'', "'"}};
|
||||||
|
size_t startpoint;
|
||||||
|
for (size_t i = 0; i < (sizeof(replacement_table) / sizeof(replacement_table[0])); ++i) {
|
||||||
|
startpoint = 0;
|
||||||
|
std::pair pair = replacement_table[i];
|
||||||
|
while ((startpoint = str.find(pair.first, startpoint)) != std::string::npos) {
|
||||||
|
str.replace(startpoint, 1, pair.second);
|
||||||
|
startpoint += pair.second.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
} // namespace waybar::util
|
Loading…
Reference in New Issue
Block a user