mirror of
https://github.com/rad4day/Waybar.git
synced 2023-12-21 10:22:59 +01:00
Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
f700319d7f | |||
418767c405 | |||
1f924c9c06 | |||
38fa7ceab1 | |||
22cddc5e26 | |||
1ccf372f8e | |||
3257968a28 | |||
6fc06fe9db | |||
75afcd3ad1 | |||
9ad80849b1 | |||
492d151079 | |||
00176c9514 | |||
6d2dcd8ac7 | |||
7d6079bb06 | |||
c820ed3495 | |||
0314bf70b3 | |||
7ae549dc9e | |||
cd13180199 | |||
8d6d8e8210 | |||
2995da845d | |||
973cec1713 | |||
94d7b083c5 | |||
ef88f0a223 | |||
ab0dcbfb2e | |||
1974766125 | |||
9c0c0d262e | |||
768e57dd37 | |||
67c756b28e | |||
584750d0fe | |||
80ef63791d | |||
a9f680b06e | |||
7e4fed8218 | |||
737da3615f | |||
d0f56b7bdd |
@ -2,7 +2,7 @@
|
|||||||
**Proof of concept**
|
**Proof of concept**
|
||||||
|
|
||||||
> Highly customizable Wayland bar for Sway and Wlroots based compositors.<br>
|
> Highly customizable Wayland bar for Sway and Wlroots based compositors.<br>
|
||||||
> Available on [AUR](https://aur.archlinux.org/packages/waybar-git/)
|
> Available on [AUR](https://aur.archlinux.org/packages/waybar-git/) and [openSUSE](https://build.opensuse.org/package/show/X11:Wayland/waybar)
|
||||||
|
|
||||||
**Current features**
|
**Current features**
|
||||||
- Sway (Workspaces, Binding mode, Focused window name)
|
- Sway (Workspaces, Binding mode, Focused window name)
|
||||||
@ -13,6 +13,7 @@
|
|||||||
- Pulseaudio
|
- Pulseaudio
|
||||||
- Memory
|
- Memory
|
||||||
- Cpu load average
|
- Cpu load average
|
||||||
|
- Temperature
|
||||||
- Custom scripts
|
- Custom scripts
|
||||||
- Multiple output configuration
|
- Multiple output configuration
|
||||||
- And much more customizations
|
- And much more customizations
|
||||||
|
@ -28,9 +28,8 @@ protected:
|
|||||||
bool alt_ = false;
|
bool alt_ = false;
|
||||||
std::string default_format_;
|
std::string default_format_;
|
||||||
|
|
||||||
private:
|
virtual bool handleToggle(GdkEventButton *const &ev);
|
||||||
bool handleToggle(GdkEventButton *const &ev);
|
virtual bool handleScroll(GdkEventScroll *);
|
||||||
bool handleScroll(GdkEventScroll *);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
@ -22,6 +22,7 @@ class Bar {
|
|||||||
~Bar() = default;
|
~Bar() = default;
|
||||||
|
|
||||||
auto toggle() -> void;
|
auto toggle() -> void;
|
||||||
|
void handleSignal(int);
|
||||||
|
|
||||||
const Client& client;
|
const Client& client;
|
||||||
Gtk::Window window;
|
Gtk::Window window;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#ifdef HAVE_LIBPULSE
|
#ifdef HAVE_LIBPULSE
|
||||||
#include "modules/pulseaudio.hpp"
|
#include "modules/pulseaudio.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
#include "modules/temperature.hpp"
|
||||||
#include "modules/custom.hpp"
|
#include "modules/custom.hpp"
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <csignal>
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
#include "util/command.hpp"
|
#include "util/command.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
@ -14,6 +15,7 @@ class Custom : public ALabel {
|
|||||||
Custom(const std::string&, const Json::Value&);
|
Custom(const std::string&, const Json::Value&);
|
||||||
~Custom();
|
~Custom();
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
|
void refresh(int /*signal*/);
|
||||||
private:
|
private:
|
||||||
void delayWorker();
|
void delayWorker();
|
||||||
void continuousWorker();
|
void continuousWorker();
|
||||||
|
@ -13,7 +13,7 @@ class IdleInhibitor: public ALabel {
|
|||||||
~IdleInhibitor();
|
~IdleInhibitor();
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
bool onClick(GdkEventButton* const& ev);
|
bool handleToggle(GdkEventButton* const& e);
|
||||||
|
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
std::string status_;
|
std::string status_;
|
||||||
|
@ -21,8 +21,8 @@ class Network : public ALabel {
|
|||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
static const uint8_t MAX_RETRY = 5;
|
static const uint8_t MAX_RETRY = 5;
|
||||||
|
static const uint8_t EPOLL_MAX = 255;
|
||||||
|
|
||||||
static int handleEvents(struct nl_msg*, void*);
|
|
||||||
static int handleScan(struct nl_msg*, void*);
|
static int handleScan(struct nl_msg*, void*);
|
||||||
|
|
||||||
void worker();
|
void worker();
|
||||||
@ -31,6 +31,7 @@ class Network : public ALabel {
|
|||||||
void createEventSocket();
|
void createEventSocket();
|
||||||
int getExternalInterface();
|
int getExternalInterface();
|
||||||
void getInterfaceAddress();
|
void getInterfaceAddress();
|
||||||
|
void handleEvents();
|
||||||
int netlinkRequest(void*, uint32_t, uint32_t groups = 0);
|
int netlinkRequest(void*, uint32_t, uint32_t groups = 0);
|
||||||
int netlinkResponse(void*, uint32_t, uint32_t groups = 0);
|
int netlinkResponse(void*, uint32_t, uint32_t groups = 0);
|
||||||
void parseEssid(struct nlattr**);
|
void parseEssid(struct nlattr**);
|
||||||
@ -44,7 +45,7 @@ class Network : public ALabel {
|
|||||||
sa_family_t family_;
|
sa_family_t family_;
|
||||||
struct sockaddr_nl nladdr_ = {0};
|
struct sockaddr_nl nladdr_ = {0};
|
||||||
struct nl_sock* sk_ = nullptr;
|
struct nl_sock* sk_ = nullptr;
|
||||||
struct nl_sock* info_sock_ = nullptr;
|
int info_sock_;
|
||||||
int efd_;
|
int efd_;
|
||||||
int ev_fd_;
|
int ev_fd_;
|
||||||
int nl80211_id_;
|
int nl80211_id_;
|
||||||
|
@ -20,11 +20,11 @@ class Workspaces : public IModule {
|
|||||||
private:
|
private:
|
||||||
void worker();
|
void worker();
|
||||||
void addWorkspace(const Json::Value&);
|
void addWorkspace(const Json::Value&);
|
||||||
|
void onButtonReady(const Json::Value&, Gtk::Button&);
|
||||||
std::string getIcon(const std::string&, const Json::Value&);
|
std::string getIcon(const std::string&, const Json::Value&);
|
||||||
bool handleScroll(GdkEventScroll*);
|
bool handleScroll(GdkEventScroll*);
|
||||||
std::string getPrevWorkspace();
|
const std::string getCycleWorkspace(uint8_t current, bool prev) const;
|
||||||
std::string getNextWorkspace();
|
uint16_t getWorkspaceIndex(const std::string &name) const;
|
||||||
uint16_t getWorkspaceIndex(const std::string &name);
|
|
||||||
std::string trimWorkspaceName(std::string);
|
std::string trimWorkspaceName(std::string);
|
||||||
|
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
|
23
include/modules/temperature.hpp
Normal file
23
include/modules/temperature.hpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class Temperature : public ALabel {
|
||||||
|
public:
|
||||||
|
Temperature(const std::string&, const Json::Value&);
|
||||||
|
~Temperature() = default;
|
||||||
|
auto update() -> void;
|
||||||
|
private:
|
||||||
|
std::tuple<uint16_t, uint16_t> getTemperature();
|
||||||
|
bool isCritical(uint16_t);
|
||||||
|
|
||||||
|
std::string file_path_;
|
||||||
|
waybar::util::SleeperThread thread_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -21,7 +21,10 @@ public:
|
|||||||
SleeperThread& operator=(std::function<void()> func)
|
SleeperThread& operator=(std::function<void()> func)
|
||||||
{
|
{
|
||||||
thread_ = std::thread([this, func] {
|
thread_ = std::thread([this, func] {
|
||||||
while (do_run_) func();
|
while (do_run_) {
|
||||||
|
signal_ = false;
|
||||||
|
func();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -34,18 +37,19 @@ public:
|
|||||||
auto sleep_for(std::chrono::system_clock::duration dur)
|
auto sleep_for(std::chrono::system_clock::duration dur)
|
||||||
{
|
{
|
||||||
std::unique_lock lk(mutex_);
|
std::unique_lock lk(mutex_);
|
||||||
return condvar_.wait_for(lk, dur, [this] { return !do_run_; });
|
return condvar_.wait_for(lk, dur, [this] { return signal_ || !do_run_; });
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sleep_until(std::chrono::time_point<std::chrono::system_clock,
|
auto sleep_until(std::chrono::time_point<std::chrono::system_clock,
|
||||||
std::chrono::system_clock::duration> time_point)
|
std::chrono::system_clock::duration> time_point)
|
||||||
{
|
{
|
||||||
std::unique_lock lk(mutex_);
|
std::unique_lock lk(mutex_);
|
||||||
return condvar_.wait_until(lk, time_point, [this] { return !do_run_; });
|
return condvar_.wait_until(lk, time_point, [this] { return signal_ || !do_run_; });
|
||||||
}
|
}
|
||||||
|
|
||||||
auto wake_up()
|
auto wake_up()
|
||||||
{
|
{
|
||||||
|
signal_ = true;
|
||||||
condvar_.notify_all();
|
condvar_.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +57,7 @@ public:
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lck(mutex_);
|
std::lock_guard<std::mutex> lck(mutex_);
|
||||||
|
signal_ = true;
|
||||||
do_run_ = false;
|
do_run_ = false;
|
||||||
}
|
}
|
||||||
condvar_.notify_all();
|
condvar_.notify_all();
|
||||||
@ -71,6 +76,7 @@ private:
|
|||||||
std::condition_variable condvar_;
|
std::condition_variable condvar_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
bool do_run_ = true;
|
bool do_run_ = true;
|
||||||
|
bool signal_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
project(
|
project(
|
||||||
'waybar', 'cpp', 'c',
|
'waybar', 'cpp', 'c',
|
||||||
version: '0.4.0',
|
version: '0.5.0',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
default_options : [
|
default_options : [
|
||||||
'cpp_std=c++17',
|
'cpp_std=c++17',
|
||||||
@ -66,6 +66,7 @@ src_files = files(
|
|||||||
'src/modules/custom.cpp',
|
'src/modules/custom.cpp',
|
||||||
'src/modules/cpu.cpp',
|
'src/modules/cpu.cpp',
|
||||||
'src/modules/idle_inhibitor.cpp',
|
'src/modules/idle_inhibitor.cpp',
|
||||||
|
'src/modules/temperature.cpp',
|
||||||
'src/main.cpp',
|
'src/main.cpp',
|
||||||
'src/bar.cpp',
|
'src/bar.cpp',
|
||||||
'src/client.cpp'
|
'src/client.cpp'
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
// Choose the order of the modules
|
// Choose the order of the modules
|
||||||
"modules-left": ["sway/workspaces", "sway/mode", "custom/spotify"],
|
"modules-left": ["sway/workspaces", "sway/mode", "custom/spotify"],
|
||||||
"modules-center": ["sway/window"],
|
"modules-center": ["sway/window"],
|
||||||
"modules-right": ["idle_inhibitor", "pulseaudio", "network", "cpu", "memory", "backlight", "battery", "battery#bat2", "clock", "tray"],
|
"modules-right": ["idle_inhibitor", "pulseaudio", "network", "cpu", "memory", "temperature", "backlight", "battery", "battery#bat2", "clock", "tray"],
|
||||||
// Modules configuration
|
// Modules configuration
|
||||||
// "sway/workspaces": {
|
// "sway/workspaces": {
|
||||||
// "disable-scroll": true,
|
// "disable-scroll": true,
|
||||||
@ -47,6 +47,13 @@
|
|||||||
"memory": {
|
"memory": {
|
||||||
"format": "{}% "
|
"format": "{}% "
|
||||||
},
|
},
|
||||||
|
"temperature": {
|
||||||
|
// "thermal-zone": 2,
|
||||||
|
// "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
|
||||||
|
"critical-threshold": 80,
|
||||||
|
// "format-critical": "{temperatureC}°C ",
|
||||||
|
"format": "{temperatureC}°C "
|
||||||
|
},
|
||||||
"backlight": {
|
"backlight": {
|
||||||
// "device": "acpi_video1",
|
// "device": "acpi_video1",
|
||||||
"format": "{percent}% {icon}",
|
"format": "{percent}% {icon}",
|
||||||
|
@ -9,28 +9,28 @@
|
|||||||
window#waybar {
|
window#waybar {
|
||||||
background: rgba(43, 48, 59, 0.5);
|
background: rgba(43, 48, 59, 0.5);
|
||||||
border-bottom: 3px solid rgba(100, 114, 125, 0.5);
|
border-bottom: 3px solid rgba(100, 114, 125, 0.5);
|
||||||
color: white;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
||||||
#workspaces button {
|
#workspaces button {
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: white;
|
color: #ffffff;
|
||||||
border-bottom: 3px solid transparent;
|
border-bottom: 3px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#workspaces button.focused {
|
#workspaces button.focused {
|
||||||
background: #64727D;
|
background: #64727D;
|
||||||
border-bottom: 3px solid white;
|
border-bottom: 3px solid #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mode {
|
#mode {
|
||||||
background: #64727D;
|
background: #64727D;
|
||||||
border-bottom: 3px solid white;
|
border-bottom: 3px solid #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#clock, #battery, #cpu, #memory, #backlight, #network, #pulseaudio, #custom-spotify, #tray, #mode, #idle_inhibitor {
|
#clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #custom-spotify, #tray, #mode, #idle_inhibitor {
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
}
|
}
|
||||||
@ -41,24 +41,24 @@ window#waybar {
|
|||||||
|
|
||||||
#battery {
|
#battery {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
color: black;
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#battery.charging {
|
#battery.charging {
|
||||||
color: white;
|
color: #ffffff;
|
||||||
background-color: #26A65B;
|
background-color: #26A65B;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes blink {
|
@keyframes blink {
|
||||||
to {
|
to {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
color: black;
|
color: #000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#battery.critical:not(.charging) {
|
#battery.critical:not(.charging) {
|
||||||
background: #f53c3c;
|
background: #f53c3c;
|
||||||
color: white;
|
color: #ffffff;
|
||||||
animation-name: blink;
|
animation-name: blink;
|
||||||
animation-duration: 0.5s;
|
animation-duration: 0.5s;
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
@ -89,7 +89,7 @@ window#waybar {
|
|||||||
|
|
||||||
#pulseaudio {
|
#pulseaudio {
|
||||||
background: #f1c40f;
|
background: #f1c40f;
|
||||||
color: black;
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pulseaudio.muted {
|
#pulseaudio.muted {
|
||||||
@ -102,6 +102,14 @@ window#waybar {
|
|||||||
color: #2a5c45;
|
color: #2a5c45;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#temperature {
|
||||||
|
background: #f0932b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#temperature.critical {
|
||||||
|
background: #eb4d4b;
|
||||||
|
}
|
||||||
|
|
||||||
#tray {
|
#tray {
|
||||||
background-color: #2980b9;
|
background-color: #2980b9;
|
||||||
}
|
}
|
||||||
@ -109,3 +117,8 @@ window#waybar {
|
|||||||
#idle_inhibitor {
|
#idle_inhibitor {
|
||||||
background-color: #2d3436;
|
background-color: #2d3436;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#idle_inhibitor.activated {
|
||||||
|
background-color: #ecf0f1;
|
||||||
|
color: #2d3436;
|
||||||
|
}
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
waybar::ALabel::ALabel(const Json::Value& config, const std::string format, uint16_t interval)
|
waybar::ALabel::ALabel(const Json::Value& config, const std::string format, uint16_t interval)
|
||||||
: config_(config),
|
: config_(config),
|
||||||
format_(config_["format"].isString() ? config_["format"].asString() : format),
|
format_(config_["format"].isString() ? config_["format"].asString() : format),
|
||||||
interval_(std::chrono::seconds(config_["interval"].isUInt()
|
interval_(config_["interval"] == "once" ? std::chrono::seconds(100000000) :
|
||||||
? config_["interval"].asUInt() : interval)), default_format_(format_)
|
std::chrono::seconds(config_["interval"].isUInt() ?
|
||||||
|
config_["interval"].asUInt() : interval)), default_format_(format_)
|
||||||
{
|
{
|
||||||
event_box_.add(label_);
|
event_box_.add(label_);
|
||||||
if (config_["max-length"].isUInt()) {
|
if (config_["max-length"].isUInt()) {
|
||||||
@ -40,11 +41,20 @@ auto waybar::ALabel::update() -> void {
|
|||||||
bool waybar::ALabel::handleToggle(GdkEventButton* const& e) {
|
bool waybar::ALabel::handleToggle(GdkEventButton* const& e) {
|
||||||
if (config_["on-click"].isString() && e->button == 1) {
|
if (config_["on-click"].isString() && e->button == 1) {
|
||||||
waybar::util::command::forkExec(config_["on-click"].asString());
|
waybar::util::command::forkExec(config_["on-click"].asString());
|
||||||
|
} else if (config_["on-click-middle"].isString() && e->button == 2) {
|
||||||
|
waybar::util::command::forkExec(config_["on-click-middle"].asString());
|
||||||
} else if (config_["on-click-right"].isString() && e->button == 3) {
|
} else if (config_["on-click-right"].isString() && e->button == 3) {
|
||||||
waybar::util::command::forkExec(config_["on-click-right"].asString());
|
waybar::util::command::forkExec(config_["on-click-right"].asString());
|
||||||
} else {
|
} else if (config_["on-click-forward"].isString() && e->button == 8) {
|
||||||
|
waybar::util::command::forkExec(config_["on-click-backward"].asString());
|
||||||
|
} else if (config_["on-click-backward"].isString() && e->button == 9) {
|
||||||
|
waybar::util::command::forkExec(config_["on-click-forward"].asString());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
if (config_["format-alt-click"].isUInt() && e->button == config_["format-alt-click"].asUInt()) {
|
||||||
alt_ = !alt_;
|
alt_ = !alt_;
|
||||||
if (alt_) {
|
if (alt_ && config_["format-alt"].isString()) {
|
||||||
format_ = config_["format-alt"].asString();
|
format_ = config_["format-alt"].asString();
|
||||||
} else {
|
} else {
|
||||||
format_ = default_format_;
|
format_ = default_format_;
|
||||||
|
66
src/bar.cpp
66
src/bar.cpp
@ -37,7 +37,54 @@ waybar::Bar::Bar(const Client& client,
|
|||||||
|
|
||||||
void waybar::Bar::initBar()
|
void waybar::Bar::initBar()
|
||||||
{
|
{
|
||||||
std::size_t layer_top = config_["layer"] == "top"
|
// Converting string to button code rn as to avoid doing it later
|
||||||
|
auto setupAltFormatKeyForModule = [this](const std::string& module_name){
|
||||||
|
if (config_.isMember(module_name)) {
|
||||||
|
Json::Value& module = config_[module_name];
|
||||||
|
if (module.isMember("format-alt")) {
|
||||||
|
if (module.isMember("format-alt-click")) {
|
||||||
|
Json::Value& click = module["format-alt-click"];
|
||||||
|
if (click.isString()) {
|
||||||
|
std::string str_click = click.asString();
|
||||||
|
|
||||||
|
if (str_click == "click-right") {
|
||||||
|
module["format-alt-click"] = 3u;
|
||||||
|
} else if (str_click == "click-middle") {
|
||||||
|
module["format-alt-click"] = 2u;
|
||||||
|
} else if (str_click == "click-backward") {
|
||||||
|
module["format-alt-click"] = 8u;
|
||||||
|
} else if (str_click == "click-forward") {
|
||||||
|
module["format-alt-click"] = 9u;
|
||||||
|
} else {
|
||||||
|
module["format-alt-click"] = 1u; // default click-left
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
module["format-alt-click"] = 1u;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
module["format-alt-click"] = 1u;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto setupAltFormatKeyForModuleList = [this, &setupAltFormatKeyForModule](const char* module_list_name) {
|
||||||
|
if (config_.isMember(module_list_name)) {
|
||||||
|
Json::Value& modules = config_[module_list_name];
|
||||||
|
for (const Json::Value& module_name : modules) {
|
||||||
|
if (module_name.isString()) {
|
||||||
|
setupAltFormatKeyForModule(module_name.asString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert to button code for every module that is used.
|
||||||
|
setupAltFormatKeyForModuleList("modules-left");
|
||||||
|
setupAltFormatKeyForModuleList("modules-right");
|
||||||
|
setupAltFormatKeyForModuleList("modules-center");
|
||||||
|
std::size_t layer_top = config_["layer"] == "top"
|
||||||
? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
|
? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
|
||||||
layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
||||||
client.layer_shell, surface, *output, layer_top, "waybar");
|
client.layer_shell, surface, *output, layer_top, "waybar");
|
||||||
@ -138,6 +185,22 @@ void waybar::Bar::handleDescription(void* /*data*/,
|
|||||||
// Nothing here
|
// Nothing here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void waybar::Bar::handleSignal(int signal)
|
||||||
|
{
|
||||||
|
for (auto& module : modules_left_) {
|
||||||
|
auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get());
|
||||||
|
if(custom) custom->refresh(signal);
|
||||||
|
}
|
||||||
|
for (auto& module : modules_center_) {
|
||||||
|
auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get());
|
||||||
|
if(custom) custom->refresh(signal);
|
||||||
|
}
|
||||||
|
for (auto& module : modules_right_) {
|
||||||
|
auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get());
|
||||||
|
if(custom) custom->refresh(signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void waybar::Bar::layerSurfaceHandleConfigure(void* data,
|
void waybar::Bar::layerSurfaceHandleConfigure(void* data,
|
||||||
struct zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width,
|
struct zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width,
|
||||||
uint32_t height)
|
uint32_t height)
|
||||||
@ -169,7 +232,6 @@ void waybar::Bar::layerSurfaceHandleClosed(void* data,
|
|||||||
struct zwlr_layer_surface_v1* /*surface*/)
|
struct zwlr_layer_surface_v1* /*surface*/)
|
||||||
{
|
{
|
||||||
auto o = static_cast<waybar::Bar *>(data);
|
auto o = static_cast<waybar::Bar *>(data);
|
||||||
std::cout << "Bar removed from output: " + o->output_name << std::endl;
|
|
||||||
zwlr_layer_surface_v1_destroy(o->layer_surface);
|
zwlr_layer_surface_v1_destroy(o->layer_surface);
|
||||||
wl_output_destroy(*o->output);
|
wl_output_destroy(*o->output);
|
||||||
zxdg_output_v1_destroy(o->xdg_output_);
|
zxdg_output_v1_destroy(o->xdg_output_);
|
||||||
|
@ -67,8 +67,10 @@ void waybar::Client::handleGlobalRemove(void* data,
|
|||||||
{
|
{
|
||||||
auto o = static_cast<waybar::Client *>(data);
|
auto o = static_cast<waybar::Client *>(data);
|
||||||
for (auto it = o->bars.begin(); it != o->bars.end(); ++it) {
|
for (auto it = o->bars.begin(); it != o->bars.end(); ++it) {
|
||||||
if ((**it).wl_name == name) {
|
if ((*it)->wl_name == name) {
|
||||||
|
auto output_name = (*it)->output_name;
|
||||||
o->bars.erase(it);
|
o->bars.erase(it);
|
||||||
|
std::cout << "Bar removed from output: " + output_name << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,9 @@ waybar::IModule* waybar::Factory::makeModule(const std::string &name) const
|
|||||||
return new waybar::modules::Pulseaudio(id, config_[name]);
|
return new waybar::modules::Pulseaudio(id, config_[name]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (ref == "temperature") {
|
||||||
|
return new waybar::modules::Temperature(id, config_[name]);
|
||||||
|
}
|
||||||
if (ref.compare(0, 7, "custom/") == 0 && ref.size() > 7) {
|
if (ref.compare(0, 7, "custom/") == 0 && ref.size() > 7) {
|
||||||
return new waybar::modules::Custom(ref.substr(7), config_[name]);
|
return new waybar::modules::Custom(ref.substr(7), config_[name]);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,14 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (int sig = SIGRTMIN + 1; sig <= SIGRTMAX; ++sig) {
|
||||||
|
std::signal(sig, [] (int sig/*signal*/) {
|
||||||
|
for (auto& bar : waybar::client->bars) {
|
||||||
|
bar->handleSignal(sig);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return c.main(argc, argv);
|
return c.main(argc, argv);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
|
@ -8,13 +8,14 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
|||||||
label_.get_style_context()->add_class(id);
|
label_.get_style_context()->add_class(id);
|
||||||
}
|
}
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
auto now = std::chrono::system_clock::now();
|
|
||||||
dp.emit();
|
dp.emit();
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
auto timeout = std::chrono::floor<std::chrono::seconds>(now + interval_);
|
auto timeout = std::chrono::floor<std::chrono::seconds>(now + interval_);
|
||||||
auto time_s = std::chrono::time_point_cast<std::chrono::seconds>(timeout);
|
auto time_s = std::chrono::time_point_cast<std::chrono::seconds>(timeout);
|
||||||
auto sub_m =
|
auto sub_m =
|
||||||
std::chrono::duration_cast<std::chrono::seconds>(time_s.time_since_epoch()).count() % interval_.count();
|
std::chrono::duration_cast<std::chrono::seconds>(time_s.time_since_epoch()).count() % interval_.count();
|
||||||
thread_.sleep_until(timeout - std::chrono::seconds(sub_m - 1));
|
if (sub_m > 0) thread_.sleep_until(timeout - std::chrono::seconds(sub_m - 1));
|
||||||
|
else thread_.sleep_until(timeout - std::chrono::seconds(sub_m));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,6 @@ void waybar::modules::Custom::continuousWorker()
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string output = buff;
|
std::string output = buff;
|
||||||
|
|
||||||
// Remove last newline
|
// Remove last newline
|
||||||
@ -78,6 +77,13 @@ void waybar::modules::Custom::continuousWorker()
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void waybar::modules::Custom::refresh(int sig /*signal*/)
|
||||||
|
{
|
||||||
|
if(sig == SIGRTMIN + config_["signal"].asInt()) {
|
||||||
|
thread_.wake_up();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto waybar::modules::Custom::update() -> void
|
auto waybar::modules::Custom::update() -> void
|
||||||
{
|
{
|
||||||
// Hide label if output is empty
|
// Hide label if output is empty
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "modules/idle_inhibitor.hpp"
|
#include "modules/idle_inhibitor.hpp"
|
||||||
|
#include "util/command.hpp"
|
||||||
|
|
||||||
waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar, const Json::Value& config)
|
waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar, const Json::Value& config)
|
||||||
: ALabel(config, "{status}"), bar_(bar), status_("deactivated"), idle_inhibitor_(nullptr)
|
: ALabel(config, "{status}"), bar_(bar), status_("deactivated"), idle_inhibitor_(nullptr)
|
||||||
@ -10,7 +10,7 @@ waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar&
|
|||||||
}
|
}
|
||||||
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::onClick));
|
sigc::mem_fun(*this, &IdleInhibitor::handleToggle));
|
||||||
dp.emit();
|
dp.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,14 +27,15 @@ auto waybar::modules::IdleInhibitor::update() -> void
|
|||||||
label_.set_markup(
|
label_.set_markup(
|
||||||
fmt::format(format_, fmt::arg("status", status_),
|
fmt::format(format_, fmt::arg("status", status_),
|
||||||
fmt::arg("icon", getIcon(0, status_))));
|
fmt::arg("icon", getIcon(0, status_))));
|
||||||
|
label_.get_style_context()->add_class(status_);
|
||||||
if(tooltipEnabled()) {
|
if(tooltipEnabled()) {
|
||||||
label_.set_tooltip_text(status_);
|
label_.set_tooltip_text(status_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waybar::modules::IdleInhibitor::onClick(GdkEventButton* const& e)
|
bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) {
|
||||||
{
|
if (e->button == 1) {
|
||||||
if(e->button == 1) {
|
label_.get_style_context()->remove_class(status_);
|
||||||
if (idle_inhibitor_) {
|
if (idle_inhibitor_) {
|
||||||
zwp_idle_inhibitor_v1_destroy(idle_inhibitor_);
|
zwp_idle_inhibitor_v1_destroy(idle_inhibitor_);
|
||||||
idle_inhibitor_ = nullptr;
|
idle_inhibitor_ = nullptr;
|
||||||
@ -44,7 +45,13 @@ bool waybar::modules::IdleInhibitor::onClick(GdkEventButton* const& e)
|
|||||||
bar_.client.idle_inhibit_manager, bar_.surface);
|
bar_.client.idle_inhibit_manager, bar_.surface);
|
||||||
status_ = "activated";
|
status_ = "activated";
|
||||||
}
|
}
|
||||||
|
if (config_["on-click"].isString() && e->button == 1) {
|
||||||
|
waybar::util::command::forkExec(config_["on-click"].asString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ALabel::handleToggle(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
dp.emit();
|
dp.emit();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
#include "modules/network.hpp"
|
#include "modules/network.hpp"
|
||||||
|
|
||||||
waybar::modules::Network::Network(const std::string& id, const Json::Value& config)
|
waybar::modules::Network::Network(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "{ifname}", 60), family_(AF_INET), efd_(-1), ev_fd_(-1),
|
: ALabel(config, "{ifname}", 60), family_(AF_INET), info_sock_(-1), efd_(-1),
|
||||||
cidr_(-1), signal_strength_dbm_(0), signal_strength_(0)
|
ev_fd_(-1), cidr_(-1), signal_strength_dbm_(0), signal_strength_(0)
|
||||||
{
|
{
|
||||||
label_.set_name("network");
|
label_.set_name("network");
|
||||||
if (!id.empty()) {
|
if (!id.empty()) {
|
||||||
@ -39,11 +39,8 @@ waybar::modules::Network::~Network()
|
|||||||
if (efd_ > -1) {
|
if (efd_ > -1) {
|
||||||
close(efd_);
|
close(efd_);
|
||||||
}
|
}
|
||||||
if (info_sock_ != nullptr) {
|
if (info_sock_ != -1) {
|
||||||
nl_socket_drop_membership(info_sock_, RTMGRP_LINK);
|
close(info_sock_);
|
||||||
nl_socket_drop_membership(info_sock_, RTMGRP_IPV4_IFADDR);
|
|
||||||
nl_close(info_sock_);
|
|
||||||
nl_socket_free(info_sock_);
|
|
||||||
}
|
}
|
||||||
if (sk_ != nullptr) {
|
if (sk_ != nullptr) {
|
||||||
nl_close(sk_);
|
nl_close(sk_);
|
||||||
@ -53,19 +50,18 @@ waybar::modules::Network::~Network()
|
|||||||
|
|
||||||
void waybar::modules::Network::createInfoSocket()
|
void waybar::modules::Network::createInfoSocket()
|
||||||
{
|
{
|
||||||
info_sock_ = nl_socket_alloc();
|
struct sockaddr_nl sa;
|
||||||
if (nl_connect(info_sock_, NETLINK_ROUTE) != 0) {
|
info_sock_ = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||||
throw std::runtime_error("Can't connect network socket");
|
if (info_sock_ < 0) {
|
||||||
}
|
throw std::runtime_error("Can't connect network socket");
|
||||||
if (nl_socket_add_membership(info_sock_, RTMGRP_LINK) != 0) {
|
}
|
||||||
|
sa.nl_family = AF_NETLINK;
|
||||||
|
sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE
|
||||||
|
| RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE;
|
||||||
|
auto ret = bind(info_sock_, (struct sockaddr *)&sa, sizeof(sa));
|
||||||
|
if (ret < 0) {
|
||||||
throw std::runtime_error("Can't add membership");
|
throw std::runtime_error("Can't add membership");
|
||||||
}
|
}
|
||||||
if (nl_socket_add_membership(info_sock_, RTMGRP_IPV4_IFADDR) != 0) {
|
|
||||||
throw std::runtime_error("Can't add membership");
|
|
||||||
}
|
|
||||||
nl_socket_disable_seq_check(info_sock_);
|
|
||||||
nl_socket_set_nonblocking(info_sock_);
|
|
||||||
nl_socket_modify_cb(info_sock_, NL_CB_VALID, NL_CB_CUSTOM, handleEvents, this);
|
|
||||||
efd_ = epoll_create1(0);
|
efd_ = epoll_create1(0);
|
||||||
if (efd_ < 0) {
|
if (efd_ < 0) {
|
||||||
throw std::runtime_error("Can't create epoll");
|
throw std::runtime_error("Can't create epoll");
|
||||||
@ -80,11 +76,10 @@ void waybar::modules::Network::createInfoSocket()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto fd = nl_socket_get_fd(info_sock_);
|
|
||||||
struct epoll_event event;
|
struct epoll_event event;
|
||||||
event.events = EPOLLIN | EPOLLET | EPOLLRDHUP;
|
event.events = EPOLLIN | EPOLLET;
|
||||||
event.data.fd = fd;
|
event.data.fd = info_sock_;
|
||||||
if (epoll_ctl(efd_, EPOLL_CTL_ADD, fd, &event) == -1) {
|
if (epoll_ctl(efd_, EPOLL_CTL_ADD, info_sock_, &event) == -1) {
|
||||||
throw std::runtime_error("Can't add epoll event");
|
throw std::runtime_error("Can't add epoll event");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,7 +88,7 @@ void waybar::modules::Network::createInfoSocket()
|
|||||||
void waybar::modules::Network::createEventSocket()
|
void waybar::modules::Network::createEventSocket()
|
||||||
{
|
{
|
||||||
sk_ = nl_socket_alloc();
|
sk_ = nl_socket_alloc();
|
||||||
if (genl_connect(sk_) != 0) {
|
if (genl_connect(sk_) != 0) {
|
||||||
throw std::runtime_error("Can't connect to netlink socket");
|
throw std::runtime_error("Can't connect to netlink socket");
|
||||||
}
|
}
|
||||||
if (nl_socket_modify_cb(sk_, NL_CB_VALID, NL_CB_CUSTOM, handleScan, this) < 0) {
|
if (nl_socket_modify_cb(sk_, NL_CB_VALID, NL_CB_CUSTOM, handleScan, this) < 0) {
|
||||||
@ -114,16 +109,15 @@ void waybar::modules::Network::worker()
|
|||||||
}
|
}
|
||||||
thread_timer_.sleep_for(interval_);
|
thread_timer_.sleep_for(interval_);
|
||||||
};
|
};
|
||||||
thread_ = [this] {
|
struct epoll_event events[EPOLL_MAX] = {0};
|
||||||
struct epoll_event events[16];
|
thread_ = [this, &events] {
|
||||||
int ec = epoll_wait(efd_, events, 16, -1);
|
int ec = epoll_wait(efd_, events, EPOLL_MAX, -1);
|
||||||
if (ec > 0) {
|
if (ec > 0) {
|
||||||
for (auto i = 0; i < ec; i++) {
|
for (auto i = 0; i < ec; i++) {
|
||||||
if (events[i].data.fd == nl_socket_get_fd(info_sock_)) {
|
if (events[i].data.fd == ev_fd_) {
|
||||||
nl_recvmsgs_default(info_sock_);
|
|
||||||
} else {
|
|
||||||
thread_.stop();
|
thread_.stop();
|
||||||
break;
|
} else if (events[i].events & EPOLLIN) {
|
||||||
|
handleEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ec == -1) {
|
} else if (ec == -1) {
|
||||||
@ -135,10 +129,17 @@ void waybar::modules::Network::worker()
|
|||||||
auto waybar::modules::Network::update() -> void
|
auto waybar::modules::Network::update() -> void
|
||||||
{
|
{
|
||||||
std::string connectiontype;
|
std::string connectiontype;
|
||||||
|
std::string tooltip_format = "";
|
||||||
|
if (config_["tooltip-format"].isString()) {
|
||||||
|
tooltip_format = config_["tooltip-format"].asString();
|
||||||
|
}
|
||||||
if (ifid_ <= 0 || ipaddr_.empty()) {
|
if (ifid_ <= 0 || ipaddr_.empty()) {
|
||||||
if (config_["format-disconnected"].isString()) {
|
if (config_["format-disconnected"].isString()) {
|
||||||
default_format_ = config_["format-disconnected"].asString();
|
default_format_ = config_["format-disconnected"].asString();
|
||||||
}
|
}
|
||||||
|
if (config_["tooltip-format-disconnected"].isString()) {
|
||||||
|
tooltip_format = config_["tooltip-format-disconnected"].asString();
|
||||||
|
}
|
||||||
label_.get_style_context()->add_class("disconnected");
|
label_.get_style_context()->add_class("disconnected");
|
||||||
connectiontype = "disconnected";
|
connectiontype = "disconnected";
|
||||||
} else {
|
} else {
|
||||||
@ -146,11 +147,17 @@ auto waybar::modules::Network::update() -> void
|
|||||||
if (config_["format-ethernet"].isString()) {
|
if (config_["format-ethernet"].isString()) {
|
||||||
default_format_ = config_["format-ethernet"].asString();
|
default_format_ = config_["format-ethernet"].asString();
|
||||||
}
|
}
|
||||||
|
if (config_["tooltip-format-ethernet"].isString()) {
|
||||||
|
tooltip_format = config_["tooltip-format-ethernet"].asString();
|
||||||
|
}
|
||||||
connectiontype = "ethernet";
|
connectiontype = "ethernet";
|
||||||
} else {
|
} else {
|
||||||
if (config_["format-wifi"].isString()) {
|
if (config_["format-wifi"].isString()) {
|
||||||
default_format_ = config_["format-wifi"].asString();
|
default_format_ = config_["format-wifi"].asString();
|
||||||
}
|
}
|
||||||
|
if (config_["tooltip-format-wifi"].isString()) {
|
||||||
|
tooltip_format = config_["tooltip-format-wifi"].asString();
|
||||||
|
}
|
||||||
connectiontype = "wifi";
|
connectiontype = "wifi";
|
||||||
}
|
}
|
||||||
label_.get_style_context()->remove_class("disconnected");
|
label_.get_style_context()->remove_class("disconnected");
|
||||||
@ -158,7 +165,7 @@ auto waybar::modules::Network::update() -> void
|
|||||||
if (!alt_) {
|
if (!alt_) {
|
||||||
format_ = default_format_;
|
format_ = default_format_;
|
||||||
}
|
}
|
||||||
label_.set_markup(fmt::format(format_,
|
auto text = fmt::format(format_,
|
||||||
fmt::arg("essid", essid_),
|
fmt::arg("essid", essid_),
|
||||||
fmt::arg("signaldBm", signal_strength_dbm_),
|
fmt::arg("signaldBm", signal_strength_dbm_),
|
||||||
fmt::arg("signalStrength", signal_strength_),
|
fmt::arg("signalStrength", signal_strength_),
|
||||||
@ -167,7 +174,25 @@ auto waybar::modules::Network::update() -> void
|
|||||||
fmt::arg("ipaddr", ipaddr_),
|
fmt::arg("ipaddr", ipaddr_),
|
||||||
fmt::arg("cidr", cidr_),
|
fmt::arg("cidr", cidr_),
|
||||||
fmt::arg("icon", getIcon(signal_strength_, connectiontype))
|
fmt::arg("icon", getIcon(signal_strength_, connectiontype))
|
||||||
));
|
);
|
||||||
|
label_.set_markup(text);
|
||||||
|
if (tooltipEnabled()) {
|
||||||
|
if (!tooltip_format.empty()) {
|
||||||
|
auto tooltip_text = fmt::format(tooltip_format,
|
||||||
|
fmt::arg("essid", essid_),
|
||||||
|
fmt::arg("signaldBm", signal_strength_dbm_),
|
||||||
|
fmt::arg("signalStrength", signal_strength_),
|
||||||
|
fmt::arg("ifname", ifname_),
|
||||||
|
fmt::arg("netmask", netmask_),
|
||||||
|
fmt::arg("ipaddr", ipaddr_),
|
||||||
|
fmt::arg("cidr", cidr_),
|
||||||
|
fmt::arg("icon", getIcon(signal_strength_, connectiontype))
|
||||||
|
);
|
||||||
|
label_.set_tooltip_text(tooltip_text);
|
||||||
|
} else {
|
||||||
|
label_.set_tooltip_text(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Network::disconnected()
|
void waybar::modules::Network::disconnected()
|
||||||
@ -346,7 +371,7 @@ int waybar::modules::Network::netlinkRequest(void *req,
|
|||||||
sa.nl_groups = groups;
|
sa.nl_groups = groups;
|
||||||
struct iovec iov = { req, reqlen };
|
struct iovec iov = { req, reqlen };
|
||||||
struct msghdr msg = { &sa, sizeof(sa), &iov, 1, nullptr, 0, 0 };
|
struct msghdr msg = { &sa, sizeof(sa), &iov, 1, nullptr, 0, 0 };
|
||||||
return sendmsg(nl_socket_get_fd(info_sock_), &msg, 0);
|
return sendmsg(info_sock_, &msg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int waybar::modules::Network::netlinkResponse(void *resp,
|
int waybar::modules::Network::netlinkResponse(void *resp,
|
||||||
@ -357,53 +382,64 @@ int waybar::modules::Network::netlinkResponse(void *resp,
|
|||||||
sa.nl_groups = groups;
|
sa.nl_groups = groups;
|
||||||
struct iovec iov = { resp, resplen };
|
struct iovec iov = { resp, resplen };
|
||||||
struct msghdr msg = { &sa, sizeof(sa), &iov, 1, nullptr, 0, 0 };
|
struct msghdr msg = { &sa, sizeof(sa), &iov, 1, nullptr, 0, 0 };
|
||||||
auto ret = recvmsg(nl_socket_get_fd(info_sock_), &msg, 0);
|
auto ret = recvmsg(info_sock_, &msg, 0);
|
||||||
if (msg.msg_flags & MSG_TRUNC) {
|
if (msg.msg_flags & MSG_TRUNC) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) {
|
void waybar::modules::Network::handleEvents() {
|
||||||
auto net = static_cast<waybar::modules::Network *>(data);
|
struct sockaddr_nl addr;
|
||||||
bool need_update = false;
|
char buff[2048] = {0};
|
||||||
nlmsghdr *nh = nlmsg_hdr(msg);
|
socklen_t len = 0;
|
||||||
if (nh->nlmsg_type == RTM_NEWADDR) {
|
|
||||||
need_update = true;
|
while (true) {
|
||||||
}
|
len = sizeof(addr);
|
||||||
if (nh->nlmsg_type < RTM_NEWADDR) {
|
auto ret = recvfrom(info_sock_, (void *)buff, sizeof(buff), 0,
|
||||||
auto rtif = static_cast<struct ifinfomsg *>(NLMSG_DATA(nh));
|
(struct sockaddr *)&addr, &len);
|
||||||
if (rtif->ifi_index == static_cast<int>(net->ifid_)) {
|
auto nh = (struct nlmsghdr *)buff;
|
||||||
need_update = true;
|
for(; NLMSG_OK(nh, ret); nh = NLMSG_NEXT(nh, ret)) {
|
||||||
if (!(rtif->ifi_flags & IFF_RUNNING)) {
|
bool need_update = false;
|
||||||
net->disconnected();
|
if (nh->nlmsg_type == RTM_NEWADDR) {
|
||||||
net->dp.emit();
|
need_update = true;
|
||||||
}
|
}
|
||||||
}
|
if (nh->nlmsg_type < RTM_NEWADDR) {
|
||||||
}
|
auto rtif = static_cast<struct ifinfomsg *>(NLMSG_DATA(nh));
|
||||||
if (net->ifid_ <= 0 && !net->config_["interface"].isString()) {
|
if (rtif->ifi_index == static_cast<int>(ifid_)) {
|
||||||
for (uint8_t i = 0; i < MAX_RETRY; i += 1) {
|
need_update = true;
|
||||||
net->ifid_ = net->getExternalInterface();
|
if (!(rtif->ifi_flags & IFF_RUNNING)) {
|
||||||
if (net->ifid_ > 0) {
|
disconnected();
|
||||||
break;
|
dp.emit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Need to wait before get external interface
|
if (ifid_ <= 0 && !config_["interface"].isString()) {
|
||||||
net->thread_.sleep_for(std::chrono::seconds(1));
|
for (uint8_t i = 0; i < MAX_RETRY; i += 1) {
|
||||||
}
|
ifid_ = getExternalInterface();
|
||||||
if (net->ifid_ > 0) {
|
if (ifid_ > 0) {
|
||||||
char ifname[IF_NAMESIZE];
|
break;
|
||||||
if_indextoname(net->ifid_, ifname);
|
}
|
||||||
net->ifname_ = ifname;
|
// Need to wait before get external interface
|
||||||
need_update = true;
|
thread_.sleep_for(std::chrono::seconds(1));
|
||||||
|
}
|
||||||
|
if (ifid_ > 0) {
|
||||||
|
char ifname[IF_NAMESIZE];
|
||||||
|
if_indextoname(ifid_, ifname);
|
||||||
|
ifname_ = ifname;
|
||||||
|
need_update = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (need_update) {
|
||||||
|
if (ifid_ > 0) {
|
||||||
|
getInfo();
|
||||||
|
}
|
||||||
|
dp.emit();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (need_update) {
|
|
||||||
if (net->ifid_ > 0) {
|
|
||||||
net->getInfo();
|
|
||||||
}
|
|
||||||
net->dp.emit();
|
|
||||||
}
|
|
||||||
return NL_SKIP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) {
|
int waybar::modules::Network::handleScan(struct nl_msg *msg, void *data) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "modules/pulseaudio.hpp"
|
#include "modules/pulseaudio.hpp"
|
||||||
|
#include <array>
|
||||||
|
|
||||||
waybar::modules::Pulseaudio::Pulseaudio(const std::string& id, const Json::Value &config)
|
waybar::modules::Pulseaudio::Pulseaudio(const std::string& id, const Json::Value &config)
|
||||||
: ALabel(config, "{volume}%"),
|
: ALabel(config, "{volume}%"),
|
||||||
@ -63,13 +64,13 @@ void waybar::modules::Pulseaudio::contextStateCb(pa_context *c, void *data)
|
|||||||
pa_context_set_subscribe_callback(c, subscribeCb, data);
|
pa_context_set_subscribe_callback(c, subscribeCb, data);
|
||||||
pa_context_subscribe(c, PA_SUBSCRIPTION_MASK_SINK, nullptr, nullptr);
|
pa_context_subscribe(c, PA_SUBSCRIPTION_MASK_SINK, nullptr, nullptr);
|
||||||
break;
|
break;
|
||||||
|
case PA_CONTEXT_FAILED:
|
||||||
|
pa->mainloop_api_->quit(pa->mainloop_api_, 1);
|
||||||
|
break;
|
||||||
case PA_CONTEXT_CONNECTING:
|
case PA_CONTEXT_CONNECTING:
|
||||||
case PA_CONTEXT_AUTHORIZING:
|
case PA_CONTEXT_AUTHORIZING:
|
||||||
case PA_CONTEXT_SETTING_NAME:
|
case PA_CONTEXT_SETTING_NAME:
|
||||||
break;
|
|
||||||
case PA_CONTEXT_FAILED:
|
|
||||||
default:
|
default:
|
||||||
pa->mainloop_api_->quit(pa->mainloop_api_, 1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,21 +175,24 @@ void waybar::modules::Pulseaudio::serverInfoCb(pa_context *context,
|
|||||||
sinkInfoCb, data);
|
sinkInfoCb, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const std::array<std::string, 9> ports = {
|
||||||
|
"headphones",
|
||||||
|
"speaker",
|
||||||
|
"hdmi",
|
||||||
|
"headset",
|
||||||
|
"handsfree",
|
||||||
|
"portable",
|
||||||
|
"car",
|
||||||
|
"hifi",
|
||||||
|
"phone",
|
||||||
|
};
|
||||||
|
|
||||||
const std::string waybar::modules::Pulseaudio::getPortIcon() const
|
const std::string waybar::modules::Pulseaudio::getPortIcon() const
|
||||||
{
|
{
|
||||||
std::vector<std::string> ports = {
|
std::string nameLC = port_name_;
|
||||||
"headphones",
|
std::transform(nameLC.begin(), nameLC.end(), nameLC.begin(), ::tolower);
|
||||||
"speaker",
|
|
||||||
"hdmi",
|
|
||||||
"headset",
|
|
||||||
"handsfree",
|
|
||||||
"portable",
|
|
||||||
"car",
|
|
||||||
"hifi",
|
|
||||||
"phone",
|
|
||||||
};
|
|
||||||
for (auto const& port : ports) {
|
for (auto const& port : ports) {
|
||||||
if (port_name_.find(port) != std::string::npos) {
|
if (nameLC.find(port) != std::string::npos) {
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ struct waybar::modules::sway::Ipc::ipc_response
|
|||||||
waybar::modules::sway::Ipc::recv(int fd) const
|
waybar::modules::sway::Ipc::recv(int fd) const
|
||||||
{
|
{
|
||||||
std::string header;
|
std::string header;
|
||||||
header.reserve(ipc_header_size_);
|
header.resize(ipc_header_size_);
|
||||||
auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic_.size());
|
auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic_.size());
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ struct waybar::modules::sway::Ipc::ipc_response
|
|||||||
|
|
||||||
total = 0;
|
total = 0;
|
||||||
std::string payload;
|
std::string payload;
|
||||||
payload.reserve(data32[0] + 1);
|
payload.resize(data32[0]);
|
||||||
while (total < data32[0]) {
|
while (total < data32[0]) {
|
||||||
auto res = ::recv(fd, payload.data() + total, data32[0] - total, 0);
|
auto res = ::recv(fd, payload.data() + total, data32[0] - total, 0);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
@ -91,7 +91,6 @@ struct waybar::modules::sway::Ipc::ipc_response
|
|||||||
}
|
}
|
||||||
total += res;
|
total += res;
|
||||||
}
|
}
|
||||||
payload[data32[0]] = 0;
|
|
||||||
return { data32[0], data32[1], &payload.front() };
|
return { data32[0], data32[1], &payload.front() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +99,7 @@ struct waybar::modules::sway::Ipc::ipc_response
|
|||||||
const std::string& payload) const
|
const std::string& payload) const
|
||||||
{
|
{
|
||||||
std::string header;
|
std::string header;
|
||||||
header.reserve(ipc_header_size_);
|
header.resize(ipc_header_size_);
|
||||||
auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic_.size());
|
auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic_.size());
|
||||||
memcpy(header.data(), ipc_magic_.c_str(), ipc_magic_.size());
|
memcpy(header.data(), ipc_magic_.c_str(), ipc_magic_.size());
|
||||||
data32[0] = payload.size();
|
data32[0] = payload.size();
|
||||||
|
@ -87,7 +87,7 @@ auto waybar::modules::sway::Workspaces::update() -> void
|
|||||||
} else {
|
} else {
|
||||||
button.set_label(icon);
|
button.set_label(icon);
|
||||||
}
|
}
|
||||||
button.show();
|
onButtonReady(node, button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (scrolling_) {
|
if (scrolling_) {
|
||||||
@ -116,8 +116,8 @@ void waybar::modules::sway::Workspaces::addWorkspace(const Json::Value &node)
|
|||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
button.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
|
||||||
if (!config_["disable-scroll"].asBool()) {
|
if (!config_["disable-scroll"].asBool()) {
|
||||||
|
button.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
||||||
button.signal_scroll_event()
|
button.signal_scroll_event()
|
||||||
.connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
.connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
||||||
}
|
}
|
||||||
@ -131,7 +131,8 @@ void waybar::modules::sway::Workspaces::addWorkspace(const Json::Value &node)
|
|||||||
if (node["urgent"].asBool()) {
|
if (node["urgent"].asBool()) {
|
||||||
button.get_style_context()->add_class("urgent");
|
button.get_style_context()->add_class("urgent");
|
||||||
}
|
}
|
||||||
button.show();
|
|
||||||
|
onButtonReady(node, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string waybar::modules::sway::Workspaces::getIcon(const std::string &name,
|
std::string waybar::modules::sway::Workspaces::getIcon(const std::string &name,
|
||||||
@ -156,86 +157,78 @@ bool waybar::modules::sway::Workspaces::handleScroll(GdkEventScroll *e)
|
|||||||
if (scrolling_) {
|
if (scrolling_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
uint8_t idx;
|
||||||
scrolling_ = true;
|
scrolling_ = true;
|
||||||
std::string name;
|
for (idx = 0; idx < workspaces_.size(); idx += 1) {
|
||||||
uint16_t idx = 0;
|
if (workspaces_[idx]["focused"].asBool()) {
|
||||||
{
|
break;
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
|
||||||
for (; idx < workspaces_.size(); idx += 1) {
|
|
||||||
if (workspaces_[idx]["focused"].asBool()) {
|
|
||||||
name = workspaces_[idx]["name"].asString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name.empty()) {
|
if (idx == workspaces_.size()) {
|
||||||
scrolling_ = false;
|
scrolling_ = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
std::string name;
|
||||||
if (e->direction == GDK_SCROLL_UP) {
|
if (e->direction == GDK_SCROLL_UP) {
|
||||||
name = getNextWorkspace();
|
name = getCycleWorkspace(idx, false);
|
||||||
}
|
}
|
||||||
if (e->direction == GDK_SCROLL_DOWN) {
|
if (e->direction == GDK_SCROLL_DOWN) {
|
||||||
name = getPrevWorkspace();
|
name = getCycleWorkspace(idx, true);
|
||||||
}
|
}
|
||||||
if (e->direction == GDK_SCROLL_SMOOTH) {
|
if (e->direction == GDK_SCROLL_SMOOTH) {
|
||||||
gdouble delta_x, delta_y;
|
gdouble delta_x, delta_y;
|
||||||
gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e),
|
gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e),
|
||||||
&delta_x, &delta_y);
|
&delta_x, &delta_y);
|
||||||
if (delta_y < 0) {
|
if (delta_y < 0) {
|
||||||
name = getNextWorkspace();
|
name = getCycleWorkspace(idx, false);
|
||||||
} else if (delta_y > 0) {
|
} else if (delta_y > 0) {
|
||||||
name = getPrevWorkspace();
|
name = getCycleWorkspace(idx, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!name.empty()) {
|
if (name.empty() || name == workspaces_[idx]["name"].asString()) {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
scrolling_ = false;
|
||||||
if (name == workspaces_[idx]["name"].asString()) {
|
return false;
|
||||||
scrolling_ = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"", name));
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(150));
|
|
||||||
}
|
}
|
||||||
|
ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"", name));
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(150));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string waybar::modules::sway::Workspaces::getPrevWorkspace()
|
const std::string waybar::modules::sway::Workspaces::getCycleWorkspace(
|
||||||
|
uint8_t focused_workspace, bool prev) const
|
||||||
{
|
{
|
||||||
for (uint16_t i = 0; i < workspaces_.size(); i += 1) {
|
auto inc = prev ? -1 : 1;
|
||||||
if (workspaces_[i]["focused"].asBool()) {
|
int size = workspaces_.size();
|
||||||
if (i > 0) {
|
uint8_t idx = 0;
|
||||||
return workspaces_[i - 1]["name"].asString();
|
for (int i = focused_workspace; i < size && i >= 0; i += inc) {
|
||||||
}
|
bool same_output = (workspaces_[i]["output"].asString() == bar_.output_name
|
||||||
return workspaces_[workspaces_.size() - 1]["name"].asString();
|
&& !config_["all-outputs"].asBool()) || config_["all-outputs"].asBool();
|
||||||
|
bool same_name =
|
||||||
|
workspaces_[i]["name"].asString() == workspaces_[focused_workspace]["name"].asString();
|
||||||
|
if (same_output && !same_name) {
|
||||||
|
return workspaces_[i]["name"].asString();
|
||||||
}
|
}
|
||||||
|
if (prev && i - 1 < 0) {
|
||||||
|
i = size;
|
||||||
|
} else if (!prev && i + 1 >= size) {
|
||||||
|
i = -1;
|
||||||
|
} else if (idx >= workspaces_.size()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
idx += 1;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string waybar::modules::sway::Workspaces::getNextWorkspace()
|
uint16_t waybar::modules::sway::Workspaces::getWorkspaceIndex(const std::string &name) const
|
||||||
{
|
|
||||||
for (uint16_t i = 0; i < workspaces_.size(); i += 1) {
|
|
||||||
if (workspaces_[i]["focused"].asBool()) {
|
|
||||||
if (i + 1U < workspaces_.size()) {
|
|
||||||
return workspaces_[i + 1]["name"].asString();
|
|
||||||
}
|
|
||||||
return workspaces_[0]["String"].asString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t waybar::modules::sway::Workspaces::getWorkspaceIndex(const std::string &name)
|
|
||||||
{
|
{
|
||||||
uint16_t idx = 0;
|
uint16_t idx = 0;
|
||||||
for (const auto &workspace : workspaces_) {
|
for (const auto &workspace : workspaces_) {
|
||||||
if (workspace["name"].asString() == name) {
|
if (workspace["name"].asString() == name) {
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
if (!config_["all-outputs"].asBool() && workspace["output"].asString() != bar_.output_name) {
|
if (!(!config_["all-outputs"].asBool() && workspace["output"].asString() != bar_.output_name)) {
|
||||||
// Nothing here
|
|
||||||
} else {
|
|
||||||
idx += 1;
|
idx += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,6 +244,19 @@ std::string waybar::modules::sway::Workspaces::trimWorkspaceName(std::string nam
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void waybar::modules::sway::Workspaces::onButtonReady(const Json::Value& node, Gtk::Button& button)
|
||||||
|
{
|
||||||
|
if (config_["current-only"].asBool()) {
|
||||||
|
if (node["focused"].asBool()) {
|
||||||
|
button.show();
|
||||||
|
} else {
|
||||||
|
button.hide();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
button.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
waybar::modules::sway::Workspaces::operator Gtk::Widget &() {
|
waybar::modules::sway::Workspaces::operator Gtk::Widget &() {
|
||||||
return box_;
|
return box_;
|
||||||
}
|
}
|
||||||
|
60
src/modules/temperature.cpp
Normal file
60
src/modules/temperature.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "modules/temperature.hpp"
|
||||||
|
|
||||||
|
waybar::modules::Temperature::Temperature(const std::string& id, const Json::Value& config)
|
||||||
|
: ALabel(config, "{temperatureC}°C", 10)
|
||||||
|
{
|
||||||
|
if (config_["hwmon-path"].isString()) {
|
||||||
|
file_path_ = config_["hwmon-path"].asString();
|
||||||
|
} else {
|
||||||
|
auto zone =
|
||||||
|
config_["thermal-zone"].isInt() ? config_["thermal-zone"].asInt() : 0;
|
||||||
|
file_path_ = fmt::format("/sys/class/thermal/thermal_zone{}/temp", zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
label_.set_name("temperature");
|
||||||
|
if (!id.empty()) {
|
||||||
|
label_.get_style_context()->add_class(id);
|
||||||
|
}
|
||||||
|
thread_ = [this] {
|
||||||
|
dp.emit();
|
||||||
|
thread_.sleep_for(interval_);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto waybar::modules::Temperature::update() -> void
|
||||||
|
{
|
||||||
|
auto [temperature_c, temperature_f] = getTemperature();
|
||||||
|
auto critical = isCritical(temperature_c);
|
||||||
|
auto format = format_;
|
||||||
|
if (critical) {
|
||||||
|
format =
|
||||||
|
config_["format-critical"].isString() ? config_["format-critical"].asString() : format;
|
||||||
|
label_.get_style_context()->add_class("critical");
|
||||||
|
} else {
|
||||||
|
label_.get_style_context()->remove_class("critical");
|
||||||
|
}
|
||||||
|
label_.set_markup(fmt::format(format,
|
||||||
|
fmt::arg("temperatureC", temperature_c), fmt::arg("temperatureF", temperature_f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<uint16_t, uint16_t> waybar::modules::Temperature::getTemperature()
|
||||||
|
{
|
||||||
|
std::ifstream temp(file_path_);
|
||||||
|
if (!temp.is_open()) {
|
||||||
|
throw std::runtime_error("Can't open " + file_path_);
|
||||||
|
}
|
||||||
|
std::string line;
|
||||||
|
if (temp.good()) {
|
||||||
|
getline(temp, line);
|
||||||
|
}
|
||||||
|
temp.close();
|
||||||
|
auto temperature_c = std::strtol(line.c_str(), nullptr, 10) / 1000.0;
|
||||||
|
auto temperature_f = temperature_c * 1.8 + 32;
|
||||||
|
std::tuple<uint16_t, uint16_t> temperatures(std::round(temperature_c), std::round(temperature_f));
|
||||||
|
return temperatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool waybar::modules::Temperature::isCritical(uint16_t temperature_c)
|
||||||
|
{
|
||||||
|
return config_["critical-threshold"].isInt() && temperature_c >= config_["critical-threshold"].asInt();
|
||||||
|
}
|
Reference in New Issue
Block a user