Merge branch 'master' into output-exclusion

pull/596/head
Alex 2020-04-17 23:42:58 +02:00 committed by GitHub
commit 774d8ffdba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 555 additions and 70 deletions

View File

@ -11,6 +11,7 @@ env:
- distro: archlinux - distro: archlinux
- distro: fedora - distro: fedora
- distro: alpine - distro: alpine
- distro: opensuse
before_install: before_install:
- docker pull alexays/waybar:${distro} - docker pull alexays/waybar:${distro}

View File

@ -2,4 +2,4 @@
FROM alpine:latest FROM alpine:latest
RUN apk add --no-cache git meson alpine-sdk libinput-dev wayland-dev wayland-protocols mesa-dev libxkbcommon-dev eudev-dev pixman-dev gtkmm3-dev jsoncpp-dev libnl3-dev pulseaudio-dev libmpdclient-dev scdoc RUN apk add --no-cache git meson alpine-sdk libinput-dev wayland-dev wayland-protocols mesa-dev libxkbcommon-dev eudev-dev pixman-dev gtkmm3-dev jsoncpp-dev pugixml libnl3-dev pulseaudio-dev libmpdclient-dev scdoc

View File

@ -3,4 +3,4 @@
FROM archlinux/base:latest FROM archlinux/base:latest
RUN pacman -Syu --noconfirm && \ RUN pacman -Syu --noconfirm && \
pacman -S git meson base-devel libinput wayland wayland-protocols pixman libxkbcommon mesa gtkmm3 jsoncpp scdoc --noconfirm pacman -S git meson base-devel libinput wayland wayland-protocols pixman libxkbcommon mesa gtkmm3 jsoncpp pugixml scdoc --noconfirm

View File

@ -3,5 +3,5 @@
FROM debian:sid FROM debian:sid
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y build-essential meson ninja-build git pkg-config libinput10 libinput-dev wayland-protocols libwayland-client0 libwayland-cursor0 libwayland-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libxkbcommon-dev libudev-dev libpixman-1-dev libgtkmm-3.0-dev libjsoncpp-dev scdoc && \ apt-get install -y build-essential meson ninja-build git pkg-config libinput10 libpugixml-dev libinput-dev wayland-protocols libwayland-client0 libwayland-cursor0 libwayland-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libxkbcommon-dev libudev-dev libpixman-1-dev libgtkmm-3.0-dev libjsoncpp-dev scdoc && \
apt-get clean apt-get clean

View File

@ -1,7 +1,7 @@
# vim: ft=Dockerfile # vim: ft=Dockerfile
FROM fedora:30 FROM fedora:32
RUN dnf install sway meson git libinput-devel wayland-devel wayland-protocols-devel egl-wayland-devel mesa-libEGL-devel mesa-libGLES-devel mesa-libgbm-devel libxkbcommon-devel libudev-devel pixman-devel gtkmm30-devel jsoncpp-devel scdoc -y && \ RUN dnf install sway meson git libinput-devel wayland-devel wayland-protocols-devel pugixml-devel egl-wayland-devel mesa-libEGL-devel mesa-libGLES-devel mesa-libgbm-devel libxkbcommon-devel libudev-devel pixman-devel gtkmm30-devel jsoncpp-devel scdoc -y && \
dnf group install "C Development Tools and Libraries" -y && \ dnf group install "C Development Tools and Libraries" -y && \
dnf clean all -y dnf clean all -y

View File

@ -4,4 +4,4 @@ FROM opensuse/tumbleweed:latest
RUN zypper -n up && \ RUN zypper -n up && \
zypper -n install -t pattern devel_C_C++ && \ zypper -n install -t pattern devel_C_C++ && \
zypper -n install git meson clang libinput10 libinput-devel libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel scdoc zypper -n install git meson clang libinput10 libinput-devel libpugixml1 libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel scdoc

View File

@ -1,6 +1,6 @@
.PHONY: build build-debug run clean default install .PHONY: build build-debug run clean default install
default: run default: build
build: build:
meson build meson build

View File

@ -11,6 +11,7 @@
- Local time - Local time
- Battery - Battery
- Network - Network
- Bluetooth
- Pulseaudio - Pulseaudio
- Disk - Disk
- Memory - Memory
@ -62,7 +63,24 @@ libmpdclient [MPD module]
On Ubuntu 19.10 you can install all the relevant dependencies using this command: On Ubuntu 19.10 you can install all the relevant dependencies using this command:
``` ```
sudo apt install libgtkmm-3.0-dev libjsoncpp-dev libinput-dev libsigc++-2.0-dev libpulse-dev libnl-3-dev libdbusmenu-gtk3-dev libnl-genl-3-dev libfmt-dev clang-tidy libmpdclient-dev libwayland-dev libgtk-3-dev gobject-introspection libgirepository1.0-dev scdoc sudo apt install \
clang-tidy \
gobject-introspection \
libdbusmenu-gtk3-dev \
libfmt-dev \
libgirepository1.0-dev \
libgtk-3-dev \
libgtkmm-3.0-dev \
libinput-dev \
libjsoncpp-dev \
libmpdclient-dev \
libnl-3-dev \
libnl-genl-3-dev \
libpulse-dev \
libsigc++-2.0-dev \
libspdlog-dev \
libwayland-dev \
scdoc
``` ```

View File

@ -32,6 +32,7 @@
#include "bar.hpp" #include "bar.hpp"
#include "modules/custom.hpp" #include "modules/custom.hpp"
#include "modules/temperature.hpp" #include "modules/temperature.hpp"
#include "modules/bluetooth.hpp"
namespace waybar { namespace waybar {

View File

@ -0,0 +1,26 @@
#pragma once
#include <fmt/format.h>
#include "ALabel.hpp"
#include <fmt/chrono.h>
#include "util/sleeper_thread.hpp"
#include "util/rfkill.hpp"
namespace waybar::modules {
class Bluetooth : public ALabel {
public:
Bluetooth(const std::string&, const Json::Value&);
~Bluetooth() = default;
auto update() -> void;
private:
std::string status_;
util::SleeperThread thread_;
util::SleeperThread intervall_thread_;
util::Rfkill rfkill_;
};
} // namespace waybar::modules

View File

@ -2,6 +2,7 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <fstream> #include <fstream>
#include <unordered_map>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
@ -17,8 +18,7 @@ class Memory : public ALabel {
static inline const std::string data_dir_ = "/proc/meminfo"; static inline const std::string data_dir_ = "/proc/meminfo";
void parseMeminfo(); void parseMeminfo();
unsigned long memtotal_; std::unordered_map<std::string, unsigned long> meminfo_;
unsigned long memfree_;
util::SleeperThread thread_; util::SleeperThread thread_;
}; };

View File

@ -11,6 +11,7 @@
#include <sys/epoll.h> #include <sys/epoll.h>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
#include "util/rfkill.hpp"
namespace waybar::modules { namespace waybar::modules {
@ -71,6 +72,9 @@ class Network : public ALabel {
util::SleeperThread thread_; util::SleeperThread thread_;
util::SleeperThread thread_timer_; util::SleeperThread thread_timer_;
util::SleeperThread thread_rfkill_;
util::Rfkill rfkill_;
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@ -72,8 +72,11 @@ inline struct res exec(std::string cmd) {
if (!fp) return {-1, ""}; if (!fp) return {-1, ""};
auto output = command::read(fp); auto output = command::read(fp);
auto stat = command::close(fp, pid); auto stat = command::close(fp, pid);
if (WIFEXITED(stat)) {
return {WEXITSTATUS(stat), output}; return {WEXITSTATUS(stat), output};
} }
return {-1, output};
}
inline int32_t forkExec(std::string cmd) { inline int32_t forkExec(std::string cmd) {
if (cmd == "") return -1; if (cmd == "") return -1;
@ -88,6 +91,7 @@ inline int32_t forkExec(std::string cmd) {
// Child executes the command // Child executes the command
if (!pid) { if (!pid) {
setpgid(pid, pid); setpgid(pid, pid);
signal(SIGCHLD, SIG_DFL);
execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0); execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
exit(0); exit(0);
} else { } else {

View File

@ -0,0 +1,19 @@
#pragma once
#include <linux/rfkill.h>
namespace waybar::util {
class Rfkill {
public:;
Rfkill(enum rfkill_type rfkill_type);
~Rfkill() = default;
void waitForEvent();
bool getState() const;
private:
enum rfkill_type rfkill_type_;
int state_ = 0;
};
} // namespace waybar::util

View File

@ -10,29 +10,29 @@ The *backlight* module displays the current backlight level.
# CONFIGURATION # CONFIGURATION
*interval* ++ *interval*: ++
typeof: integer ++ typeof: integer ++
default: 2 ++ default: 2 ++
The interval in which information gets polled. The interval in which information gets polled.
*format* ++ *format*: ++
typeof: string ++ typeof: string ++
default: {percent}% ++ default: {percent}% ++
The format, how information should be displayed. On {} data gets inserted. The format, how information should be displayed. On {} data gets inserted.
*max-length* ++ *max-length*: ++
typeof: integer ++ typeof: integer ++
The maximum length in characters the module should display. The maximum length in characters the module should display.
*rotate* ++ *rotate*: ++
typeof: integer ++ typeof: integer ++
Positive value to rotate the text label. Positive value to rotate the text label.
*states* ++ *states*: ++
typeof: array ++ typeof: array ++
A number of backlight states which get activated on certain brightness levels. A number of backlight states which get activated on certain brightness levels.
*on-click* ++ *on-click*: ++
typeof: string ++ typeof: string ++
Command to execute when the module is clicked. Command to execute when the module is clicked.
@ -40,19 +40,23 @@ The *backlight* module displays the current backlight level.
typeof: string ++ typeof: string ++
Command to execute when middle-clicked on the module using mousewheel. Command to execute when middle-clicked on the module using mousewheel.
*on-click-right* ++ *on-click-right*: ++
typeof: string ++ typeof: string ++
Command to execute when the module is right clicked. Command to execute when the module is right clicked.
*on-scroll-up* ++ *on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when performing a scroll up on the module. Command to execute when performing a scroll up on the module.
*on-scroll-down* ++ *on-scroll-down*: ++
typeof: string typeof: string
Command to execute when performing a scroll down on the module. Command to execute when performing a scroll down on the module.
*smooth-scrolling-threshold* ++ *smooth-scrolling-threshold*: ++
typeof: double typeof: double
Threshold to be used when scrolling. Threshold to be used when scrolling.

View File

@ -10,29 +10,33 @@ The *battery* module displays the current capacity and state (eg. charging) of y
# CONFIGURATION # CONFIGURATION
*bat* ++ *bat*: ++
typeof: string ++ typeof: string ++
The battery to monitor, as in /sys/class/power_supply/ instead of auto detect. The battery to monitor, as in /sys/class/power_supply/ instead of auto detect.
*adapter* ++ *adapter*: ++
typeof: string ++ typeof: string ++
The adapter to monitor, as in /sys/class/power_supply/ instead of auto detect. The adapter to monitor, as in /sys/class/power_supply/ instead of auto detect.
*interval* ++ *full-at*: ++
typeof: integer ++
Define the max percentage of the battery, usefull for an old battery, e.g. 96
*interval*: ++
typeof: integer ++ typeof: integer ++
default: 60 ++ default: 60 ++
The interval in which the information gets polled. The interval in which the information gets polled.
*states* ++ *states*: ++
typeof: array ++ typeof: array ++
A number of battery states which get activated on certain capacity levels. See *waybar-states(5)*. A number of battery states which get activated on certain capacity levels. See *waybar-states(5)*.
*format* ++ *format*: ++
typeof: string ++ typeof: string ++
default: {capacity}% ++ default: {capacity}% ++
The format, how the time should be displayed. The format, how the time should be displayed.
*format-time* ++ *format-time*: ++
typeof: string ++ typeof: string ++
default: {H} h {M} min ++ default: {H} h {M} min ++
The format, how the time should be displayed. The format, how the time should be displayed.
@ -58,10 +62,14 @@ The *battery* module displays the current capacity and state (eg. charging) of y
typeof: string ++ typeof: string ++
Command to execute when middle-clicked on the module using mousewheel. Command to execute when middle-clicked on the module using mousewheel.
*on-click-right* ++ *on-click-right*: ++
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.
@ -70,11 +78,11 @@ The *battery* module displays the current capacity and state (eg. charging) of y
typeof: string ++ typeof: string ++
Command to execute when scrolling down on the module. Command to execute when scrolling down on the module.
*smooth-scrolling-threshold* ++ *smooth-scrolling-threshold*: ++
typeof: double ++ typeof: double ++
Threshold to be used when scrolling. Threshold to be used when scrolling.
*tooltip* ++ *tooltip*: ++
typeof: bool ++ typeof: bool ++
default: true ++ default: true ++
Option to disable tooltip on hover. Option to disable tooltip on hover.

View File

@ -0,0 +1,94 @@
waybar-bluetooth(5)
# NAME
waybar - bluetooth module
# DESCRIPTION
The *bluetooth* module displays information about the status of the device's bluetooth device.
# CONFIGURATION
Addressed by *bluetooth*
*interval*: ++
typeof: integer ++
default: 60 ++
The interval in which the bluetooth state gets updated.
*format*: ++
typeof: string ++
default: *{icon}* ++
The format, how information should be displayed. This format is used when other formats aren't specified.
*format-icons*: ++
typeof: array/object ++
Based on the device status, the corresponding icon gets selected. ++
The order is *low* to *high*. Or by the state if it is an object.
*rotate*: ++
typeof: integer ++
Positive value to rotate the text label.
*max-length*: ++
typeof: integer ++
The maximum length in character the module should display.
*on-click*: ++
typeof: string ++
Command to execute when clicked on the module.
*on-click-middle*: ++
typeof: string ++
Command to execute when middle-clicked on the module using mousewheel.
*on-click-right*: ++
typeof: string ++
Command to execute when you right clicked on the module.
*on-scroll-up*: ++
typeof: string ++
Command to execute when scrolling up on the module.
*on-scroll-down*: ++
typeof: string ++
Command to execute when scrolling down on the module.
*smooth-scrolling-threshold*: ++
typeof: double ++
Threshold to be used when scrolling.
*tooltip*: ++
typeof: bool ++
default: *true* ++
Option to disable tooltip on hover.
*tooltip-format*: ++
typeof: string ++
The format, how information should be displayed in the tooltip. This format is used when other formats aren't specified.
# FORMAT REPLACEMENTS
*{status}*: Status of the bluetooth device.
*{icon}*: Icon, as defined in *format-icons*.
# EXAMPLES
```
"bluetooth": {
"format": "{icon}",
"format-alt": "bluetooth: {status}",
"interval": 30,
"format-icons": {
"enabled": "",
"disabled": ""
}
"tooltip-format": "{status}"
}
```
# STYLE
- *#bluetooth*

View File

@ -51,6 +51,10 @@ The *clock* module displays the current date and time.
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.

View File

@ -44,6 +44,10 @@ The *cpu* module displays the current cpu utilization.
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.

View File

@ -33,6 +33,12 @@ Addressed by *custom/<name>*
You can update it manually with a signal. If no *interval* is defined, You can update it manually with a signal. If no *interval* is defined,
it is assumed that the out script loops it self. it is assumed that the out script loops it self.
*restart-interval*: ++
typeof: integer ++
The restart interval (in seconds).
Can't be used with the *interval* option, so only with continuous scripts.
Once the script exit, it'll be re-executed after the *restart-interval*.
*signal*: ++ *signal*: ++
typeof: integer ++ typeof: integer ++
The signal number used to update the module. The signal number used to update the module.
@ -67,6 +73,10 @@ Addressed by *custom/<name>*
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.

View File

@ -47,6 +47,10 @@ Addressed by *disk*
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.

View File

@ -39,6 +39,10 @@ screensaving, also known as "presentation mode".
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.

View File

@ -46,6 +46,10 @@ Addressed by *memory*
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.

View File

@ -89,6 +89,10 @@ Addressed by *mpd*
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.

View File

@ -47,6 +47,10 @@ Addressed by *network*
typeof: string ++ typeof: string ++
This format is used when the displayed interface is disconnected. This format is used when the displayed interface is disconnected.
*format-disabled*: ++
typeof: string ++
This format is used when the displayed interface is disabled.
*format-icons*: ++ *format-icons*: ++
typeof: array/object ++ typeof: array/object ++
Based on the current signal strength, the corresponding icon gets selected. ++ Based on the current signal strength, the corresponding icon gets selected. ++
@ -72,6 +76,10 @@ Addressed by *network*
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.
@ -105,6 +113,10 @@ Addressed by *network*
typeof: string ++ typeof: string ++
This format is used when the displayed interface is disconnected. This format is used when the displayed interface is disconnected.
*tooltip-format-disabled*: ++
typeof: string ++
This format is used when the displayed interface is disabled.
# FORMAT REPLACEMENTS # FORMAT REPLACEMENTS
*{ifname}*: Name of the network interface. *{ifname}*: Name of the network interface.
@ -142,6 +154,7 @@ Addressed by *network*
"format-wifi": "{essid} ({signalStrength}%) ", "format-wifi": "{essid} ({signalStrength}%) ",
"format-ethernet": "{ifname} ", "format-ethernet": "{ifname} ",
"format-disconnected": "", //An empty format will hide the module. "format-disconnected": "", //An empty format will hide the module.
"format-disconnected": "",
"tooltip-format": "{ifname}", "tooltip-format": "{ifname}",
"tooltip-format-wifi": "{essid} ({signalStrength}%) ", "tooltip-format-wifi": "{essid} ({signalStrength}%) ",
"tooltip-format-ethernet": "{ifname} ", "tooltip-format-ethernet": "{ifname} ",
@ -154,6 +167,7 @@ Addressed by *network*
- *#network* - *#network*
- *#network.disconnected* - *#network.disconnected*
- *#network.disabled*
- *#network.linked* - *#network.linked*
- *#network.ethernet* - *#network.ethernet*
- *#network.wifi* - *#network.wifi*

View File

@ -67,6 +67,10 @@ Additionally you can control the volume by scrolling *up* or *down* while the cu
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. This replaces the default behaviour of volume control. Command to execute when scrolling up on the module. This replaces the default behaviour of volume control.

View File

@ -37,6 +37,10 @@ Addressed by *sway/mode*
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.

View File

@ -37,6 +37,10 @@ Addressed by *sway/window*
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.

View File

@ -19,7 +19,7 @@ Addressed by *sway/workspaces*
*format*: ++ *format*: ++
typeof: string ++ typeof: string ++
default: {name} ++ default: {value} ++
The format, how information should be displayed. The format, how information should be displayed.
*format-icons*: ++ *format-icons*: ++
@ -60,9 +60,15 @@ Addressed by *sway/workspaces*
default: empty ++ default: empty ++
Lists workspaces that should always be shown, even when non existent Lists workspaces that should always be shown, even when non existent
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
# FORMAT REPLACEMENTS # FORMAT REPLACEMENTS
*{name}*: Name of the workspace, as defined by sway. *{value}*: Name of the workspace, as defined by sway.
*{name}*: Number stripped from workspace value.
*{icon}*: Icon, as defined in *format-icons*. *{icon}*: Icon, as defined in *format-icons*.
@ -75,6 +81,7 @@ Additional to workspace name matching, the following *format-icons* can be set.
- *default*: Will be shown, when no string matches is found. - *default*: Will be shown, when no string matches is found.
- *urgent*: Will be shown, when workspace is flagged as urgent - *urgent*: Will be shown, when workspace is flagged as urgent
- *focused*: Will be shown, when workspace is focused - *focused*: Will be shown, when workspace is focused
- *persistent*: Will be shown, when workspace is persistent one.
# PERSISTENT WORKSPACES # PERSISTENT WORKSPACES

View File

@ -20,6 +20,14 @@ Addressed by *temperature*
typeof: string ++ typeof: string ++
The temperature path to use, e.g. */sys/class/hwmon/hwmon2/temp1_input* instead of one in */sys/class/thermal/*. The temperature path to use, e.g. */sys/class/hwmon/hwmon2/temp1_input* instead of one in */sys/class/thermal/*.
*hwmon-path-abs*: ++
typeof: string ++
The path of the hwmon-directory of the device, e.g. */sys/devices/pci0000:00/0000:00:18.3/hwmon*. (Note that the subdirectory *hwmon/hwmon#*, where *#* is a number is not part of the path!) Has to be used together with *input-filename*.
*input-filename*: ++
typeof: string ++
The temperature filename of your *hwmon-path-abs*, e.g. *temp1_input*
*critical-threshold*: ++ *critical-threshold*: ++
typeof: integer ++ typeof: integer ++
The threshold before it is considered critical (Celsius). The threshold before it is considered critical (Celsius).
@ -62,6 +70,10 @@ Addressed by *temperature*
typeof: string ++ typeof: string ++
Command to execute when you right clicked on the module. Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when scrolling up on the module. Command to execute when scrolling up on the module.

View File

@ -20,6 +20,10 @@ Addressed by *tray*
typeof: integer ++ typeof: integer ++
Defines the spacing between the tray icons. Defines the spacing between the tray icons.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
# EXAMPLES # EXAMPLES
``` ```

View File

@ -1,6 +1,6 @@
project( project(
'waybar', 'cpp', 'c', 'waybar', 'cpp', 'c',
version: '0.9.1', version: '0.9.2',
license: 'MIT', license: 'MIT',
default_options : [ default_options : [
'cpp_std=c++17', 'cpp_std=c++17',
@ -25,7 +25,7 @@ else
cpp_link_args += ['-lstdc++fs'] cpp_link_args += ['-lstdc++fs']
endif endif
git = find_program('git', required: false) git = find_program('git', native: true, required: false)
if not git.found() if not git.found()
add_project_arguments('-DVERSION="@0@"'.format(meson.project_version()), language: 'cpp') add_project_arguments('-DVERSION="@0@"'.format(meson.project_version()), language: 'cpp')
@ -108,6 +108,7 @@ src_files = files(
'src/ALabel.cpp', 'src/ALabel.cpp',
'src/modules/memory.cpp', 'src/modules/memory.cpp',
'src/modules/battery.cpp', 'src/modules/battery.cpp',
'src/modules/bluetooth.cpp',
'src/modules/clock.cpp', 'src/modules/clock.cpp',
'src/modules/custom.cpp', 'src/modules/custom.cpp',
'src/modules/cpu.cpp', 'src/modules/cpu.cpp',
@ -116,7 +117,8 @@ src_files = files(
'src/modules/temperature.cpp', 'src/modules/temperature.cpp',
'src/main.cpp', 'src/main.cpp',
'src/bar.cpp', 'src/bar.cpp',
'src/client.cpp' 'src/client.cpp',
'src/util/rfkill.cpp'
) )
if true # find_program('sway', required : false).found() if true # find_program('sway', required : false).found()

View File

@ -1,5 +1,5 @@
{ {
"layer": "top", // Waybar at top layer // "layer": "top", // Waybar at top layer
// "position": "bottom", // Waybar position (top|bottom|left|right) // "position": "bottom", // Waybar position (top|bottom|left|right)
"height": 30, // Waybar height (to be removed for auto height) "height": 30, // Waybar height (to be removed for auto height)
// "width": 1280, // Waybar width // "width": 1280, // Waybar width

View File

@ -2,6 +2,7 @@
Description=Highly customizable Wayland bar for Sway and Wlroots based compositors. Description=Highly customizable Wayland bar for Sway and Wlroots based compositors.
Documentation=https://github.com/Alexays/Waybar/wiki/ Documentation=https://github.com/Alexays/Waybar/wiki/
PartOf=wayland-session.target PartOf=wayland-session.target
After=wayland-session.target
[Service] [Service]
Type=dbus Type=dbus

View File

@ -31,7 +31,7 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
} }
auto ALabel::update() -> void { auto ALabel::update() -> void {
// Nothing here AModule::update();
} }
std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_t max) { std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_t max) {

View File

@ -29,7 +29,10 @@ AModule::~AModule() {
} }
auto AModule::update() -> void { auto AModule::update() -> void {
// Nothing here // Run user-provided update handler if configured
if (config_["on-update"].isString()) {
pid_.push_back(util::command::forkExec(config_["on-update"].asString()));
}
} }
bool AModule::handleToggle(GdkEventButton* const& e) { bool AModule::handleToggle(GdkEventButton* const& e) {

View File

@ -175,6 +175,11 @@ void waybar::Bar::initGtkLayerShell() {
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, margins_.right); gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, margins_.right);
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_TOP, margins_.top); gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_TOP, margins_.top);
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_BOTTOM, margins_.bottom); gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_BOTTOM, margins_.bottom);
if (width_ > 1 && height_ > 1) {
/* configure events are not emitted if the bar is using initial size */
setExclusiveZone(width_, height_);
}
} }
#endif #endif

View File

@ -66,6 +66,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const {
if (ref == "temperature") { if (ref == "temperature") {
return new waybar::modules::Temperature(id, config_[name]); return new waybar::modules::Temperature(id, config_[name]);
} }
if (ref == "bluetooth") {
return new waybar::modules::Bluetooth(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), id, config_[name]); return new waybar::modules::Custom(ref.substr(7), id, config_[name]);
} }

View File

@ -187,6 +187,8 @@ auto waybar::modules::Backlight::update() -> void {
} }
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
ALabel::update();
} }
template <class ForwardIt> template <class ForwardIt>

View File

@ -115,6 +115,16 @@ const std::tuple<uint8_t, float, std::string> waybar::modules::Battery::getInfos
time_remaining = -(float)(total_energy_full - total_energy) / total_power; time_remaining = -(float)(total_energy_full - total_energy) / total_power;
} }
uint16_t capacity = total / batteries_.size(); uint16_t capacity = total / batteries_.size();
// Handle full-at
if (config_["full-at"].isUInt()) {
auto full_at = config_["full-at"].asUInt();
if (full_at < 100) {
capacity = static_cast<float>(capacity / full_at) * 100;
if (capacity > full_at) {
capacity = full_at;
}
}
}
return {capacity, time_remaining, status}; return {capacity, time_remaining, status};
} catch (const std::exception& e) { } catch (const std::exception& e) {
spdlog::error("Battery: {}", e.what()); spdlog::error("Battery: {}", e.what());
@ -192,4 +202,6 @@ auto waybar::modules::Battery::update() -> void {
fmt::arg("icon", getIcon(capacity, state)), fmt::arg("icon", getIcon(capacity, state)),
fmt::arg("time", formatTimeRemaining(time_remaining)))); fmt::arg("time", formatTimeRemaining(time_remaining))));
} }
// Call parent update
ALabel::update();
} }

View File

@ -0,0 +1,45 @@
#include "modules/bluetooth.hpp"
#include "util/rfkill.hpp"
#include <linux/rfkill.h>
#include <time.h>
waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value& config)
: ALabel(config, "bluetooth", id, "{icon}", 10),
status_("disabled"),
rfkill_{RFKILL_TYPE_BLUETOOTH} {
thread_ = [this] {
dp.emit();
rfkill_.waitForEvent();
};
intervall_thread_ = [this] {
auto now = std::chrono::system_clock::now();
auto timeout = std::chrono::floor<std::chrono::seconds>(now + interval_);
auto diff = std::chrono::seconds(timeout.time_since_epoch().count() % interval_.count());
thread_.sleep_until(timeout - diff);
dp.emit();
};
}
auto waybar::modules::Bluetooth::update() -> void {
if (rfkill_.getState()) {
status_ = "disabled";
} else {
status_ = "enabled";
}
label_.set_markup(
fmt::format(
format_,
fmt::arg("status", status_),
fmt::arg("icon", getIcon(0, status_))));
if (tooltipEnabled()) {
if (config_["tooltip-format"].isString()) {
auto tooltip_format = config_["tooltip-format"].asString();
auto tooltip_text = fmt::format(tooltip_format, status_);
label_.set_tooltip_text(tooltip_text);
} else {
label_.set_tooltip_text(status_);
}
}
}

View File

@ -54,6 +54,8 @@ auto waybar::modules::Clock::update() -> void {
label_.set_tooltip_markup(text); label_.set_tooltip_markup(text);
} }
} }
// Call parent update
ALabel::update();
} }
auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::string { auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::string {

View File

@ -18,6 +18,8 @@ auto waybar::modules::Cpu::update() -> void {
} }
label_.set_markup(fmt::format(format_, fmt::arg("load", cpu_load), fmt::arg("usage", cpu_usage))); label_.set_markup(fmt::format(format_, fmt::arg("load", cpu_load), fmt::arg("usage", cpu_usage)));
getState(cpu_usage); getState(cpu_usage);
// Call parent update
ALabel::update();
} }
uint16_t waybar::modules::Cpu::getCpuLoad() { uint16_t waybar::modules::Cpu::getCpuLoad() {

View File

@ -49,20 +49,25 @@ void waybar::modules::Custom::continuousWorker() {
thread_ = [&] { thread_ = [&] {
char* buff = nullptr; char* buff = nullptr;
size_t len = 0; size_t len = 0;
bool restart = false;
if (getline(&buff, &len, fp_) == -1) { if (getline(&buff, &len, fp_) == -1) {
int exit_code = 1; int exit_code = 1;
if (fp_) { if (fp_) {
exit_code = WEXITSTATUS(util::command::close(fp_, pid_)); exit_code = WEXITSTATUS(util::command::close(fp_, pid_));
fp_ = nullptr; fp_ = nullptr;
} }
thread_.stop();
if (exit_code != 0) { if (exit_code != 0) {
output_ = {exit_code, ""}; output_ = {exit_code, ""};
dp.emit(); dp.emit();
spdlog::error("{} stopped unexpectedly, is it endless?", name_); spdlog::error("{} stopped unexpectedly, is it endless?", name_);
} }
if (config_["restart-interval"].isUInt()) {
restart = true;
} else {
thread_.stop();
return; return;
} }
}
std::string output = buff; std::string output = buff;
// Remove last newline // Remove last newline
@ -71,6 +76,14 @@ void waybar::modules::Custom::continuousWorker() {
} }
output_ = {0, output}; output_ = {0, output};
dp.emit(); dp.emit();
if (restart) {
pid_ = -1;
fp_ = util::command::open(cmd, pid_);
if (!fp_) {
throw std::runtime_error("Unable to open " + cmd);
}
thread_.sleep_for(std::chrono::seconds(config_["restart-interval"].asUInt()));
}
}; };
} }
@ -128,6 +141,8 @@ auto waybar::modules::Custom::update() -> void {
event_box_.show(); event_box_.show();
} }
} }
// Call parent update
ALabel::update();
} }
void waybar::modules::Custom::parseOutputRaw() { void waybar::modules::Custom::parseOutputRaw() {

View File

@ -73,4 +73,6 @@ auto waybar::modules::Disk::update() -> void {
)); ));
} }
event_box_.show(); event_box_.show();
// Call parent update
ALabel::update();
} }

View File

@ -32,6 +32,8 @@ auto waybar::modules::IdleInhibitor::update() -> void {
if (tooltipEnabled()) { if (tooltipEnabled()) {
label_.set_tooltip_text(status_); label_.set_tooltip_text(status_);
} }
// Call parent update
ALabel::update();
} }
bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) { bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) {

View File

@ -10,11 +10,23 @@ waybar::modules::Memory::Memory(const std::string& id, const Json::Value& config
auto waybar::modules::Memory::update() -> void { auto waybar::modules::Memory::update() -> void {
parseMeminfo(); parseMeminfo();
if (memtotal_ > 0 && memfree_ >= 0) {
auto total_ram_gigabytes = memtotal_ / std::pow(1024, 2); unsigned long memtotal = meminfo_["MemTotal"];
int used_ram_percentage = 100 * (memtotal_ - memfree_) / memtotal_; unsigned long memfree;
auto used_ram_gigabytes = (memtotal_ - memfree_) / std::pow(1024, 2); if (meminfo_.count("MemAvailable")) {
auto available_ram_gigabytes = memfree_ / std::pow(1024, 2); // New kernels (3.4+) have an accurate available memory field.
memfree = meminfo_["MemAvailable"];
} else {
// Old kernel; give a best-effort approximation of available memory.
memfree = meminfo_["MemFree"] + meminfo_["Buffers"] + meminfo_["Cached"] +
meminfo_["SReclaimable"] - meminfo_["Shmem"];
}
if (memtotal > 0 && memfree >= 0) {
auto total_ram_gigabytes = memtotal / std::pow(1024, 2);
int used_ram_percentage = 100 * (memtotal - memfree) / memtotal;
auto used_ram_gigabytes = (memtotal - memfree) / std::pow(1024, 2);
auto available_ram_gigabytes = memfree / std::pow(1024, 2);
getState(used_ram_percentage); getState(used_ram_percentage);
label_.set_markup(fmt::format(format_, label_.set_markup(fmt::format(format_,
@ -30,10 +42,11 @@ auto waybar::modules::Memory::update() -> void {
} else { } else {
event_box_.hide(); event_box_.hide();
} }
// Call parent update
ALabel::update();
} }
void waybar::modules::Memory::parseMeminfo() { void waybar::modules::Memory::parseMeminfo() {
int64_t memfree = -1, membuffer = -1, memcache = -1, memavail = -1;
std::ifstream info(data_dir_); std::ifstream info(data_dir_);
if (!info.is_open()) { if (!info.is_open()) {
throw std::runtime_error("Can't open " + data_dir_); throw std::runtime_error("Can't open " + data_dir_);
@ -44,23 +57,9 @@ void waybar::modules::Memory::parseMeminfo() {
if (posDelim == std::string::npos) { if (posDelim == std::string::npos) {
continue; continue;
} }
std::string name = line.substr(0, posDelim); std::string name = line.substr(0, posDelim);
int64_t value = std::stol(line.substr(posDelim + 1)); int64_t value = std::stol(line.substr(posDelim + 1));
meminfo_[name] = value;
if (name.compare("MemTotal") == 0) {
memtotal_ = value;
} else if (name.compare("MemAvailable") == 0) {
memavail = value;
} else if (name.compare("MemFree") == 0) {
memfree = value;
} else if (name.compare("Buffers") == 0) {
membuffer = value;
} else if (name.compare("Cached") == 0) {
memcache = value;
}
if (memtotal_ > 0 && (memavail >= 0 || (memfree > -1 && membuffer > -1 && memcache > -1))) {
break;
} }
} }
memfree_ = memavail >= 0 ? memavail : memfree + membuffer + memcache;
}

View File

@ -56,6 +56,9 @@ auto waybar::modules::MPD::update() -> void {
} }
setLabel(); setLabel();
// Call parent update
ALabel::update();
} }
std::thread waybar::modules::MPD::event_listener() { std::thread waybar::modules::MPD::event_listener() {

View File

@ -4,7 +4,7 @@
#include <fstream> #include <fstream>
#include <cassert> #include <cassert>
#include "util/format.hpp" #include "util/format.hpp"
#include "util/rfkill.hpp"
namespace { namespace {
@ -86,7 +86,8 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf
cidr_(-1), cidr_(-1),
signal_strength_dbm_(0), signal_strength_dbm_(0),
signal_strength_(0), signal_strength_(0),
frequency_(0) { frequency_(0),
rfkill_{RFKILL_TYPE_WLAN} {
auto down_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_DOWN_TOTAL_KEY); auto down_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_DOWN_TOTAL_KEY);
auto up_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_UP_TOTAL_KEY); auto up_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_UP_TOTAL_KEY);
if (down_octets) { if (down_octets) {
@ -196,6 +197,7 @@ void waybar::modules::Network::createInfoSocket() {
} }
void waybar::modules::Network::worker() { void waybar::modules::Network::worker() {
// update via here not working
thread_timer_ = [this] { thread_timer_ = [this] {
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
@ -206,6 +208,16 @@ void waybar::modules::Network::worker() {
} }
thread_timer_.sleep_for(interval_); thread_timer_.sleep_for(interval_);
}; };
thread_rfkill_ = [this] {
rfkill_.waitForEvent();
{
std::lock_guard<std::mutex> lock(mutex_);
if (ifid_ > 0) {
getInfo();
dp.emit();
}
}
};
thread_ = [this] { thread_ = [this] {
std::array<struct epoll_event, EPOLL_MAX> events{}; std::array<struct epoll_event, EPOLL_MAX> events{};
@ -222,7 +234,11 @@ void waybar::modules::Network::worker() {
} }
const std::string waybar::modules::Network::getNetworkState() const { const std::string waybar::modules::Network::getNetworkState() const {
if (ifid_ == -1) return "disconnected"; if (ifid_ == -1) {
if (rfkill_.getState())
return "disabled";
return "disconnected";
}
if (ipaddr_.empty()) return "linked"; if (ipaddr_.empty()) return "linked";
if (essid_.empty()) return "ethernet"; if (essid_.empty()) return "ethernet";
return "wifi"; return "wifi";
@ -315,6 +331,9 @@ auto waybar::modules::Network::update() -> void {
label_.set_tooltip_text(text); label_.set_tooltip_text(text);
} }
} }
// Call parent update
ALabel::update();
} }
// Based on https://gist.github.com/Yawning/c70d804d4b8ae78cc698 // Based on https://gist.github.com/Yawning/c70d804d4b8ae78cc698

View File

@ -21,7 +21,7 @@ waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value
if (context_ == nullptr) { if (context_ == nullptr) {
throw std::runtime_error("pa_context_new() failed."); throw std::runtime_error("pa_context_new() failed.");
} }
if (pa_context_connect(context_, nullptr, PA_CONTEXT_NOAUTOSPAWN, nullptr) < 0) { if (pa_context_connect(context_, nullptr, PA_CONTEXT_NOFAIL, nullptr) < 0) {
auto err = auto err =
fmt::format("pa_context_connect() failed: {}", pa_strerror(pa_context_errno(context_))); fmt::format("pa_context_connect() failed: {}", pa_strerror(pa_context_errno(context_)));
throw std::runtime_error(err); throw std::runtime_error(err);
@ -216,6 +216,10 @@ auto waybar::modules::Pulseaudio::update() -> void {
label_.get_style_context()->remove_class("bluetooth"); label_.get_style_context()->remove_class("bluetooth");
} }
if (muted_) { if (muted_) {
// Check muted bluetooth format exist, otherwise fallback to default muted format
if (format_name != "format" && !config_[format_name + "-muted"].isString()) {
format_name = "format";
}
format_name = format_name + "-muted"; format_name = format_name + "-muted";
label_.get_style_context()->add_class("muted"); label_.get_style_context()->add_class("muted");
} else { } else {
@ -241,4 +245,7 @@ auto waybar::modules::Pulseaudio::update() -> void {
if (tooltipEnabled()) { if (tooltipEnabled()) {
label_.set_tooltip_text(desc_); label_.set_tooltip_text(desc_);
} }
// Call parent update
ALabel::update();
} }

View File

@ -40,6 +40,8 @@ auto Tray::update() -> void {
} else { } else {
box_.show_all(); box_.show_all();
} }
// Call parent update
AModule::update();
} }
} // namespace waybar::modules::SNI } // namespace waybar::modules::SNI

View File

@ -47,6 +47,8 @@ auto Mode::update() -> void {
} }
event_box_.show(); event_box_.show();
} }
// Call parent update
ALabel::update();
} }
} // namespace waybar::modules::sway } // namespace waybar::modules::sway

View File

@ -60,6 +60,8 @@ auto Window::update() -> void {
if (tooltipEnabled()) { if (tooltipEnabled()) {
label_.set_tooltip_text(window_); label_.set_tooltip_text(window_);
} }
// Call parent update
ALabel::update();
} }
std::tuple<std::size_t, int, std::string, std::string> Window::getFocusedNode( std::tuple<std::size_t, int, std::string, std::string> Window::getFocusedNode(

View File

@ -157,12 +157,13 @@ auto Workspaces::update() -> void {
if (needReorder) { if (needReorder) {
box_.reorder_child(button, it - workspaces_.begin()); box_.reorder_child(button, it - workspaces_.begin());
} }
std::string output = getIcon((*it)["name"].asString(), *it); std::string output = (*it)["name"].asString();
if (config_["format"].isString()) { if (config_["format"].isString()) {
auto format = config_["format"].asString(); auto format = config_["format"].asString();
output = fmt::format(format, output = fmt::format(format,
fmt::arg("icon", output), fmt::arg("icon", getIcon(output, *it)),
fmt::arg("name", trimWorkspaceName((*it)["name"].asString())), fmt::arg("value", output),
fmt::arg("name", trimWorkspaceName(output)),
fmt::arg("index", (*it)["num"].asString())); fmt::arg("index", (*it)["num"].asString()));
} }
if (!config_["disable-markup"].asBool()) { if (!config_["disable-markup"].asBool()) {
@ -172,6 +173,8 @@ auto Workspaces::update() -> void {
} }
onButtonReady(*it, button); onButtonReady(*it, button);
} }
// Call parent update
AModule::update();
} }
Gtk::Button &Workspaces::addButton(const Json::Value &node) { Gtk::Button &Workspaces::addButton(const Json::Value &node) {
@ -205,6 +208,8 @@ std::string Workspaces::getIcon(const std::string &name, const Json::Value &node
if (config_["format-icons"][key].isString() && node[key].asBool()) { if (config_["format-icons"][key].isString() && node[key].asBool()) {
return config_["format-icons"][key].asString(); return config_["format-icons"][key].asString();
} }
} else if (config_["format_icons"]["persistent"].isString() && node["target_output"].isString()) {
return config_["format-icons"]["persistent"].asString();
} else if (config_["format-icons"][key].isString()) { } else if (config_["format-icons"][key].isString()) {
return config_["format-icons"][key].asString(); return config_["format-icons"][key].asString();
} }

View File

@ -1,9 +1,12 @@
#include "modules/temperature.hpp" #include "modules/temperature.hpp"
#include <filesystem>
waybar::modules::Temperature::Temperature(const std::string& id, const Json::Value& config) waybar::modules::Temperature::Temperature(const std::string& id, const Json::Value& config)
: ALabel(config, "temperature", id, "{temperatureC}°C", 10) { : ALabel(config, "temperature", id, "{temperatureC}°C", 10) {
if (config_["hwmon-path"].isString()) { if (config_["hwmon-path"].isString()) {
file_path_ = config_["hwmon-path"].asString(); file_path_ = config_["hwmon-path"].asString();
} else if (config_["hwmon-path-abs"].isString() && config_["input-filename"].isString()) {
file_path_ = (*std::filesystem::directory_iterator(config_["hwmon-path-abs"].asString())).path().u8string() + "/" + config_["input-filename"].asString();
} else { } else {
auto zone = config_["thermal-zone"].isInt() ? config_["thermal-zone"].asInt() : 0; auto zone = config_["thermal-zone"].isInt() ? config_["thermal-zone"].asInt() : 0;
file_path_ = fmt::format("/sys/class/thermal/thermal_zone{}/temp", zone); file_path_ = fmt::format("/sys/class/thermal/thermal_zone{}/temp", zone);
@ -33,6 +36,8 @@ auto waybar::modules::Temperature::update() -> void {
fmt::arg("temperatureC", temperature_c), fmt::arg("temperatureC", temperature_c),
fmt::arg("temperatureF", temperature_f), fmt::arg("temperatureF", temperature_f),
fmt::arg("icon", getIcon(temperature_c, "", max_temp)))); fmt::arg("icon", getIcon(temperature_c, "", max_temp))));
// Call parent update
ALabel::update();
} }
std::tuple<uint16_t, uint16_t> waybar::modules::Temperature::getTemperature() { std::tuple<uint16_t, uint16_t> waybar::modules::Temperature::getTemperature() {

View File

@ -0,0 +1,83 @@
/* https://git.kernel.org/pub/scm/linux/kernel/git/jberg/rfkill.git/
*
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2009 Marcel Holtmann <marcel@holtmann.org>
* Copyright 2009 Tim Gardner <tim.gardner@canonical.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include "util/rfkill.hpp"
#include <linux/rfkill.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstring>
#include <fcntl.h>
#include <sys/poll.h>
#include <cerrno>
#include <stdexcept>
waybar::util::Rfkill::Rfkill(const enum rfkill_type rfkill_type)
: rfkill_type_(rfkill_type) {
}
void waybar::util::Rfkill::waitForEvent() {
struct rfkill_event event;
struct pollfd p;
ssize_t len;
int fd, n;
fd = open("/dev/rfkill", O_RDONLY);
if (fd < 0) {
throw std::runtime_error("Can't open RFKILL control device");
return;
}
memset(&p, 0, sizeof(p));
p.fd = fd;
p.events = POLLIN | POLLHUP;
while (1) {
n = poll(&p, 1, -1);
if (n < 0) {
throw std::runtime_error("Failed to poll RFKILL control device");
break;
}
if (n == 0)
continue;
len = read(fd, &event, sizeof(event));
if (len < 0) {
throw std::runtime_error("Reading of RFKILL events failed");
break;
}
if (len != RFKILL_EVENT_SIZE_V1) {
throw std::runtime_error("Wrong size of RFKILL event");
continue;
}
if(event.type == rfkill_type_ && event.op == RFKILL_OP_CHANGE) {
state_ = event.soft || event.hard;
break;
}
}
close(fd);
return;
}
bool waybar::util::Rfkill::getState() const {
return state_;
}