mirror of
https://github.com/rad4day/Waybar.git
synced 2023-12-21 10:22:59 +01:00
Compare commits
71 Commits
Author | SHA1 | Date | |
---|---|---|---|
aae105c998 | |||
b719569243 | |||
e70f8d8730 | |||
e1215a6d17 | |||
119446d538 | |||
d1f427618f | |||
3c268d83c2 | |||
ae6ca36fa7 | |||
83b12fc8a7 | |||
f107aaddc3 | |||
cd2db19267 | |||
4c40f9c635 | |||
84e5b0e8c2 | |||
34a710cce3 | |||
218bb3bc2b | |||
f6b2005687 | |||
ea9591baea | |||
af2528952b | |||
414bf741f3 | |||
527fa982d2 | |||
8e05aab4d9 | |||
e9b0365327 | |||
97554b3532 | |||
1e969a48ae | |||
84b671f6b2 | |||
6e30b7af3c | |||
3130a57622 | |||
a555a72d7f | |||
99dde1aff8 | |||
d5875c468f | |||
9e877d3f57 | |||
f80270519b | |||
8fb3211594 | |||
b9cd51a9cc | |||
569f40de9b | |||
9c8d0865d1 | |||
129713fe1b | |||
e66c3bc965 | |||
75c6e2e7d5 | |||
d294352845 | |||
35f7fdf684 | |||
33798c31d0 | |||
ee0db26021 | |||
abcac464fa | |||
9602360d28 | |||
1d087f96bd | |||
01b8527333 | |||
abeb406166 | |||
443281f0bc | |||
de3be8b2ab | |||
4d7e19ae66 | |||
e8f2bd3ad1 | |||
c41cedd407 | |||
f6864e4a43 | |||
a833c51a28 | |||
1145788ab3 | |||
c0d4867421 | |||
d18ece13f2 | |||
1f379fa5f6 | |||
1125119dc6 | |||
173a7bb8cd | |||
4836333bff | |||
f01ddb9ab3 | |||
2f6a70f34e | |||
def4466953 | |||
db1136d647 | |||
c8821a5e7f | |||
d40cc6f23a | |||
c885be369e | |||
631695ec74 | |||
50275ae529 |
@ -49,6 +49,9 @@ libsigc++
|
||||
fmt
|
||||
wayland
|
||||
wlroots
|
||||
libgtk-3-dev [gtk-layer-shell]
|
||||
gobject-introspection [gtk-layer-shell]
|
||||
libgirepository1.0-dev [gtk-layer-shell]
|
||||
libpulse [Pulseaudio module]
|
||||
libnl [Network module]
|
||||
sway [Sway modules]
|
||||
@ -59,7 +62,7 @@ libmpdclient [MPD module]
|
||||
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 scdoc libmpdclient-dev
|
||||
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
|
||||
```
|
||||
|
||||
|
||||
|
@ -30,12 +30,12 @@ class Client {
|
||||
const std::string &style) const;
|
||||
void bindInterfaces();
|
||||
const std::string getValidPath(const std::vector<std::string> &paths) const;
|
||||
void handleOutput(std::unique_ptr<struct waybar_output> &output);
|
||||
bool isValidOutput(const Json::Value &config, std::unique_ptr<struct waybar_output> &output);
|
||||
void handleOutput(struct waybar_output &output);
|
||||
bool isValidOutput(const Json::Value &config, struct waybar_output &output);
|
||||
auto setupConfig(const std::string &config_file) -> void;
|
||||
auto setupCss(const std::string &css_file) -> void;
|
||||
std::unique_ptr<struct waybar_output> &getOutput(void *);
|
||||
std::vector<Json::Value> getOutputConfigs(std::unique_ptr<struct waybar_output> &output);
|
||||
struct waybar_output &getOutput(void *);
|
||||
std::vector<Json::Value> getOutputConfigs(struct waybar_output &output);
|
||||
|
||||
static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
|
||||
const char *interface, uint32_t version);
|
||||
@ -44,10 +44,10 @@ class Client {
|
||||
void handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor);
|
||||
void handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor);
|
||||
|
||||
Json::Value config_;
|
||||
Glib::RefPtr<Gtk::StyleContext> style_context_;
|
||||
Glib::RefPtr<Gtk::CssProvider> css_provider_;
|
||||
std::vector<std::unique_ptr<struct waybar_output>> outputs_;
|
||||
Json::Value config_;
|
||||
Glib::RefPtr<Gtk::StyleContext> style_context_;
|
||||
Glib::RefPtr<Gtk::CssProvider> css_provider_;
|
||||
std::list<struct waybar_output> outputs_;
|
||||
};
|
||||
|
||||
} // namespace waybar
|
||||
|
@ -6,11 +6,17 @@
|
||||
#else
|
||||
#include <fmt/chrono.h>
|
||||
#endif
|
||||
#include <date/tz.h>
|
||||
#include "ALabel.hpp"
|
||||
#include "util/sleeper_thread.hpp"
|
||||
|
||||
namespace waybar::modules {
|
||||
|
||||
struct waybar_time {
|
||||
std::locale locale;
|
||||
date::zoned_seconds ztime;
|
||||
};
|
||||
|
||||
class Clock : public ALabel {
|
||||
public:
|
||||
Clock(const std::string&, const Json::Value&);
|
||||
@ -19,6 +25,15 @@ class Clock : public ALabel {
|
||||
|
||||
private:
|
||||
util::SleeperThread thread_;
|
||||
std::locale locale_;
|
||||
const date::time_zone* time_zone_;
|
||||
bool fixed_time_zone_;
|
||||
date::year_month_day cached_calendar_ymd_;
|
||||
std::string cached_calendar_text_;
|
||||
|
||||
auto calendar_text(const waybar_time& wtime) -> std::string;
|
||||
auto weekdays_header(const date::weekday& first_dow, std::ostream& os) -> void;
|
||||
auto first_day_of_week() -> date::weekday;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules
|
||||
|
@ -36,6 +36,7 @@ class MPD : public ALabel {
|
||||
|
||||
bool stopped();
|
||||
bool playing();
|
||||
bool paused();
|
||||
|
||||
const std::string module_name_;
|
||||
|
||||
|
@ -34,6 +34,7 @@ class Pulseaudio : public ALabel {
|
||||
pa_cvolume pa_volume_;
|
||||
bool muted_;
|
||||
std::string port_name_;
|
||||
std::string form_factor_;
|
||||
std::string desc_;
|
||||
std::string monitor_;
|
||||
// SOURCE
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include "ipc.hpp"
|
||||
#include "util/sleeper_thread.hpp"
|
||||
|
||||
namespace waybar::modules::sway {
|
||||
|
||||
@ -28,6 +29,7 @@ class Ipc {
|
||||
void sendCmd(uint32_t type, const std::string &payload = "");
|
||||
void subscribe(const std::string &payload);
|
||||
void handleEvent();
|
||||
void setWorker(std::function<void()> &&func);
|
||||
|
||||
protected:
|
||||
static inline const std::string ipc_magic_ = "i3-ipc";
|
||||
@ -38,9 +40,10 @@ class Ipc {
|
||||
struct ipc_response send(int fd, uint32_t type, const std::string &payload = "");
|
||||
struct ipc_response recv(int fd);
|
||||
|
||||
int fd_;
|
||||
int fd_event_;
|
||||
std::mutex mutex_;
|
||||
int fd_;
|
||||
int fd_event_;
|
||||
std::mutex mutex_;
|
||||
util::SleeperThread thread_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::sway
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "client.hpp"
|
||||
#include "modules/sway/ipc/client.hpp"
|
||||
#include "util/json.hpp"
|
||||
#include "util/sleeper_thread.hpp"
|
||||
|
||||
namespace waybar::modules::sway {
|
||||
|
||||
@ -18,14 +17,11 @@ class Mode : public ALabel, public sigc::trackable {
|
||||
|
||||
private:
|
||||
void onEvent(const struct Ipc::ipc_response&);
|
||||
void worker();
|
||||
|
||||
std::string mode_;
|
||||
util::JsonParser parser_;
|
||||
std::mutex mutex_;
|
||||
|
||||
util::SleeperThread thread_;
|
||||
Ipc ipc_;
|
||||
Ipc ipc_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::sway
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "client.hpp"
|
||||
#include "modules/sway/ipc/client.hpp"
|
||||
#include "util/json.hpp"
|
||||
#include "util/sleeper_thread.hpp"
|
||||
|
||||
namespace waybar::modules::sway {
|
||||
|
||||
@ -20,7 +19,6 @@ class Window : public ALabel, public sigc::trackable {
|
||||
private:
|
||||
void onEvent(const struct Ipc::ipc_response&);
|
||||
void onCmd(const struct Ipc::ipc_response&);
|
||||
void worker();
|
||||
std::tuple<std::size_t, int, std::string, std::string> getFocusedNode(const Json::Value& nodes,
|
||||
std::string& output);
|
||||
void getTree();
|
||||
@ -33,9 +31,7 @@ class Window : public ALabel, public sigc::trackable {
|
||||
std::size_t app_nb_;
|
||||
util::JsonParser parser_;
|
||||
std::mutex mutex_;
|
||||
|
||||
util::SleeperThread thread_;
|
||||
Ipc ipc_;
|
||||
Ipc ipc_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::sway
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "client.hpp"
|
||||
#include "modules/sway/ipc/client.hpp"
|
||||
#include "util/json.hpp"
|
||||
#include "util/sleeper_thread.hpp"
|
||||
|
||||
namespace waybar::modules::sway {
|
||||
|
||||
@ -21,7 +20,6 @@ class Workspaces : public AModule, public sigc::trackable {
|
||||
private:
|
||||
void onCmd(const struct Ipc::ipc_response&);
|
||||
void onEvent(const struct Ipc::ipc_response&);
|
||||
void worker();
|
||||
bool filterButtons();
|
||||
Gtk::Button& addButton(const Json::Value&);
|
||||
void onButtonReady(const Json::Value&, Gtk::Button&);
|
||||
@ -38,9 +36,7 @@ class Workspaces : public AModule, public sigc::trackable {
|
||||
util::JsonParser parser_;
|
||||
std::unordered_map<std::string, Gtk::Button> buttons_;
|
||||
std::mutex mutex_;
|
||||
|
||||
util::SleeperThread thread_;
|
||||
Ipc ipc_;
|
||||
Ipc ipc_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::sway
|
||||
|
@ -36,6 +36,10 @@ The *backlight* module displays the current backlight level.
|
||||
typeof: string ++
|
||||
Command to execute when the module is clicked.
|
||||
|
||||
*on-click-middle*: ++
|
||||
typeof: string ++
|
||||
Command to execute when middle-clicked on the module using mousewheel.
|
||||
|
||||
*on-click-right* ++
|
||||
typeof: string ++
|
||||
Command to execute when the module is right clicked.
|
||||
|
@ -37,32 +37,36 @@ The *battery* module displays the current capacity and state (eg. charging) of y
|
||||
default: {H} h {M} min ++
|
||||
The format, how the time should be displayed.
|
||||
|
||||
*format-icons*
|
||||
typeof: array/object
|
||||
*format-icons*: ++
|
||||
typeof: array/object ++
|
||||
Based on the current capacity, the corresponding icon gets selected. ++
|
||||
The order is *low* to *high*. Or by the state if it is an object.
|
||||
|
||||
*max-length* ++
|
||||
*max-length*: ++
|
||||
typeof: integer++
|
||||
The maximum length in character the module should display.
|
||||
|
||||
*rotate* ++
|
||||
*rotate*: ++
|
||||
typeof: integer++
|
||||
Positive value to rotate the text label.
|
||||
|
||||
*on-click* ++
|
||||
*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* ++
|
||||
*on-scroll-up*: ++
|
||||
typeof: string ++
|
||||
Command to execute when scrolling up on the module.
|
||||
|
||||
*on-scroll-down* ++
|
||||
*on-scroll-down*: ++
|
||||
typeof: string ++
|
||||
Command to execute when scrolling down on the module.
|
||||
|
||||
|
@ -18,7 +18,18 @@ The *clock* module displays the current date and time.
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: {:%H:%M} ++
|
||||
The format, how the date and time should be displayed.
|
||||
The format, how the date and time should be displayed. ++
|
||||
It uses the format of the date library. See https://howardhinnant.github.io/date/date.html#to_stream_formatting for details.
|
||||
|
||||
*timezone*: ++
|
||||
typeof: string ++
|
||||
default: inferred local timezone ++
|
||||
The timezone to display the time in, e.g. America/New_York.
|
||||
|
||||
*locale*: ++
|
||||
typeof: string ++
|
||||
default: inferred from current locale ++
|
||||
A locale to be used to display the time. Intended to render times in custom timezones with the proper language and format.
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@ -32,6 +43,10 @@ The *clock* module displays the current date and time.
|
||||
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.
|
||||
@ -50,6 +65,10 @@ The *clock* module displays the current date and time.
|
||||
|
||||
View all valid format options in *strftime(3)*.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{calendar}*: Current month calendar
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
@ -36,6 +36,10 @@ The *cpu* module displays the current cpu utilization.
|
||||
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.
|
||||
|
@ -59,6 +59,10 @@ Addressed by *custom/<name>*
|
||||
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.
|
||||
|
@ -39,6 +39,10 @@ Addressed by *disk*
|
||||
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.
|
||||
|
@ -31,6 +31,10 @@ screensaving, also known as "presentation mode".
|
||||
typeof: string ++
|
||||
Command to execute when clicked on the module. A click also toggles the state
|
||||
|
||||
*on-click-middle*: ++
|
||||
typeof: string ++
|
||||
Command to execute when middle-clicked on the module using mousewheel.
|
||||
|
||||
*on-click-right*: ++
|
||||
typeof: string ++
|
||||
Command to execute when you right clicked on the module.
|
||||
|
@ -38,6 +38,10 @@ Addressed by *memory*
|
||||
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.
|
||||
|
@ -13,110 +13,118 @@ The *mpd* module displays information about a running "Music Player Daemon" inst
|
||||
Addressed by *mpd*
|
||||
|
||||
*server*: ++
|
||||
typeof: string ++
|
||||
The network address or Unix socket path of the MPD server. If empty, connect to the default host.
|
||||
typeof: string ++
|
||||
The network address or Unix socket path of the MPD server. If empty, connect to the default host.
|
||||
|
||||
*port*: ++
|
||||
typeof: integer ++
|
||||
The port MPD listens to. If empty, use the default port.
|
||||
typeof: integer ++
|
||||
The port MPD listens to. If empty, use the default port.
|
||||
|
||||
*interval*: ++
|
||||
typeof: integer++
|
||||
default: 5 ++
|
||||
The interval in which the connection to the MPD server is retried
|
||||
typeof: integer++
|
||||
default: 5 ++
|
||||
The interval in which the connection to the MPD server is retried
|
||||
|
||||
*timeout*: ++
|
||||
typeof: integer++
|
||||
default: 30 ++
|
||||
The timeout for the connection. Change this if your MPD server has a low `connection_timeout` setting
|
||||
typeof: integer++
|
||||
default: 30 ++
|
||||
The timeout for the connection. Change this if your MPD server has a low `connection_timeout` setting
|
||||
|
||||
*unknown-tag*: ++
|
||||
typeof: string ++
|
||||
default: "N/A" ++
|
||||
The text to display when a tag is not present in the current song, but used in `format`
|
||||
typeof: string ++
|
||||
default: "N/A" ++
|
||||
The text to display when a tag is not present in the current song, but used in `format`
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: "{album} - {artist} - {title}" ++
|
||||
Information displayed when a song is playing or paused
|
||||
typeof: string ++
|
||||
default: "{album} - {artist} - {title}" ++
|
||||
Information displayed when a song is playing.
|
||||
|
||||
*format-stopped*: ++
|
||||
typeof: string ++
|
||||
default: "stopped" ++
|
||||
Information displayed when the player is stopped.
|
||||
typeof: string ++
|
||||
default: "stopped" ++
|
||||
Information displayed when the player is stopped.
|
||||
|
||||
*format-paused*: ++
|
||||
typeof: string ++
|
||||
This format is used when a song is paused.
|
||||
|
||||
*format-disconnected*: ++
|
||||
typeof: string ++
|
||||
default: "disconnected" ++
|
||||
Information displayed when the MPD server can't be reached.
|
||||
typeof: string ++
|
||||
default: "disconnected" ++
|
||||
Information displayed when the MPD server can't be reached.
|
||||
|
||||
*tooltip*: ++
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*tooltip-format*: ++
|
||||
typeof: string ++
|
||||
default: "MPD (connected)" ++
|
||||
Tooltip information displayed when connected to MPD.
|
||||
typeof: string ++
|
||||
default: "MPD (connected)" ++
|
||||
Tooltip information displayed when connected to MPD.
|
||||
|
||||
*tooltip-format-disconnected*: ++
|
||||
typeof: string ++
|
||||
default: "MPD (disconnected)" ++
|
||||
Tooltip information displayed when the MPD server can't be reached.
|
||||
typeof: string ++
|
||||
default: "MPD (disconnected)" ++
|
||||
Tooltip information displayed when the MPD server can't be reached.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
The maximum length in character the module should display.
|
||||
typeof: integer ++
|
||||
The maximum length in character the module should display.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
Command to execute when clicked on the module.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
typeof: string ++
|
||||
Command to execute when scrolling down on the module.
|
||||
|
||||
*smooth-scrolling-threshold*: ++
|
||||
typeof: double ++
|
||||
Threshold to be used when scrolling.
|
||||
typeof: double ++
|
||||
Threshold to be used when scrolling.
|
||||
|
||||
*state-icons*: ++
|
||||
typeof: object ++
|
||||
default: {} ++
|
||||
Icon to show depending on the play/pause state of the player (*{ "playing": "...", "paused": "..." }*)
|
||||
typeof: object ++
|
||||
default: {} ++
|
||||
Icon to show depending on the play/pause state of the player (*{ "playing": "...", "paused": "..." }*)
|
||||
|
||||
*consume-icons*: ++
|
||||
typeof: object ++
|
||||
default: {} ++
|
||||
Icon to show depending on the "consume" option (*{ "on": "...", "off": "..." }*)
|
||||
typeof: object ++
|
||||
default: {} ++
|
||||
Icon to show depending on the "consume" option (*{ "on": "...", "off": "..." }*)
|
||||
|
||||
*random-icons*: ++
|
||||
typeof: object ++
|
||||
default: {} ++
|
||||
Icon to show depending on the "random" option (*{ "on": "...", "off": "..." }*)
|
||||
typeof: object ++
|
||||
default: {} ++
|
||||
Icon to show depending on the "random" option (*{ "on": "...", "off": "..." }*)
|
||||
|
||||
*repeat-icons*: ++
|
||||
typeof: object ++
|
||||
default: {} ++
|
||||
Icon to show depending on the "repeat" option (*{ "on": "...", "off": "..." }*)
|
||||
typeof: object ++
|
||||
default: {} ++
|
||||
Icon to show depending on the "repeat" option (*{ "on": "...", "off": "..." }*)
|
||||
|
||||
*single-icons*: ++
|
||||
typeof: object ++
|
||||
default: {} ++
|
||||
Icon to show depending on the "single" option (*{ "on": "...", "off": "..." }*)
|
||||
typeof: object ++
|
||||
default: {} ++
|
||||
Icon to show depending on the "single" option (*{ "on": "...", "off": "..." }*)
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
|
@ -21,6 +21,11 @@ Addressed by *network*
|
||||
default: 60 ++
|
||||
The interval in which the network information gets polled (e.g. signal strength).
|
||||
|
||||
*family*: ++
|
||||
typeof: string ++
|
||||
default: *ipv4* ++
|
||||
The address family that is used for the format replacement {ipaddr} and to determine if a network connection is present.
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: *{ifname}* ++
|
||||
@ -42,6 +47,11 @@ Addressed by *network*
|
||||
typeof: string ++
|
||||
This format is used when the displayed interface is disconnected.
|
||||
|
||||
*format-icons*: ++
|
||||
typeof: array/object ++
|
||||
Based on the current signal strength, the corresponding icon gets selected. ++
|
||||
The order is *low* to *high*. Or by the state if it is an object.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
@ -54,6 +64,10 @@ Addressed by *network*
|
||||
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.
|
||||
@ -117,6 +131,8 @@ Addressed by *network*
|
||||
|
||||
*{bandwidthDownOctets}*: Instant down speed in octets/seconds.
|
||||
|
||||
*{icon}*: Icon, as defined in *format-icons*.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
@ -59,6 +59,10 @@ Additionally you can control the volume by scrolling *up* or *down* while the cu
|
||||
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.
|
||||
@ -96,16 +100,17 @@ The following strings for *format-icons* are supported.
|
||||
If they are found in the current PulseAudio port name, the corresponding icons will be selected.
|
||||
|
||||
- *default* (Shown, when no other port is found)
|
||||
- *headphones*
|
||||
- *headphone*
|
||||
- *speaker*
|
||||
- *hdmi*
|
||||
- *headset*
|
||||
- *handsfree*
|
||||
- *hands-free*
|
||||
- *portable*
|
||||
- *car*
|
||||
- *hifi*
|
||||
- *phone*
|
||||
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
@ -29,6 +29,10 @@ Addressed by *sway/mode*
|
||||
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.
|
||||
|
@ -29,6 +29,10 @@ Addressed by *sway/window*
|
||||
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.
|
||||
|
@ -13,71 +13,75 @@ The *temperature* module displays the current temperature from a thermal zone.
|
||||
Addressed by *temperature*
|
||||
|
||||
*thermal-zone*: ++
|
||||
typeof: integer ++
|
||||
The thermal zone, as in */sys/class/thermal/*.
|
||||
typeof: integer ++
|
||||
The thermal zone, as in */sys/class/thermal/*.
|
||||
|
||||
*hwmon-path*: ++
|
||||
typeof: string ++
|
||||
The temperature path to use, e.g. */sys/class/hwmon/hwmon2/temp1_input* instead of one in */sys/class/thermal/*.
|
||||
typeof: string ++
|
||||
The temperature path to use, e.g. */sys/class/hwmon/hwmon2/temp1_input* instead of one in */sys/class/thermal/*.
|
||||
|
||||
*critical-threshold*: ++
|
||||
typeof: integer ++
|
||||
The threshold before it is considered critical (Celcius).
|
||||
typeof: integer ++
|
||||
The threshold before it is considered critical (Celsius).
|
||||
|
||||
*interval*: ++
|
||||
typeof: integer ++
|
||||
default: 10 ++
|
||||
The interval in which the information gets polled.
|
||||
typeof: integer ++
|
||||
default: 10 ++
|
||||
The interval in which the information gets polled.
|
||||
|
||||
*format-critical*: ++
|
||||
typeof: string ++
|
||||
The format to use when temperature is considered critical
|
||||
typeof: string ++
|
||||
The format to use when temperature is considered critical
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: {temperatureC}°C ++
|
||||
The format (Celcius/Farenheit) in which the temperature should be displayed.
|
||||
typeof: string ++
|
||||
default: {temperatureC}°C ++
|
||||
The format (Celsius/Fahrenheit) in which the temperature should be displayed.
|
||||
|
||||
*format-icons*: ++
|
||||
typeof: array ++
|
||||
Based on the current temperature (Celcius) and *critical-threshold* if available, the corresponding icon gets selected. The order is *low* to *high*.
|
||||
typeof: array ++
|
||||
Based on the current temperature (Celsius) and *critical-threshold* if available, the corresponding icon gets selected. The order is *low* to *high*.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
The maximum length in characters the module should display.
|
||||
typeof: integer ++
|
||||
The maximum length in characters the module should display.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
Command to execute when you clicked on the module.
|
||||
typeof: string ++
|
||||
Command to execute when you clicked on the module.
|
||||
|
||||
*on-click-middle*: ++
|
||||
typeof: string ++
|
||||
Command to execute when middle-clicked on the module using mousewheel.
|
||||
|
||||
*on-click-right*: ++
|
||||
typeof: string ++
|
||||
Command to execute when you right clicked on the module.
|
||||
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.
|
||||
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.
|
||||
typeof: string ++
|
||||
Command to execute when scrolling down on the module.
|
||||
|
||||
*smooth-scrolling-threshold*: ++
|
||||
typeof: double ++
|
||||
Threshold to be used when scrolling.
|
||||
typeof: double ++
|
||||
Threshold to be used when scrolling.
|
||||
|
||||
*tooltip*: ++
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{temperatureC}*: Temperature in Celcius.
|
||||
*{temperatureC}*: Temperature in Celsius.
|
||||
|
||||
*{temperatureF}*: Temperature in Fahrenheit.
|
||||
|
||||
|
@ -23,7 +23,8 @@ Also a minimal example configuration can be found on the at the bottom of this m
|
||||
*layer* ++
|
||||
typeof: string ++
|
||||
default: bottom ++
|
||||
Decide if the bar is displayed in front of the windows or behind them.
|
||||
Decide if the bar is displayed in front (*top*) of the windows or behind (*bottom*)
|
||||
them.
|
||||
|
||||
*output* ++
|
||||
typeof: string|array ++
|
||||
@ -66,6 +67,12 @@ Also a minimal example configuration can be found on the at the bottom of this m
|
||||
typeof: string ++
|
||||
Optional name added as a CSS class, for styling multiple waybars.
|
||||
|
||||
*gtk-layer-shell* ++
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
Option to disable the use of gtk-layer-shell for popups.
|
||||
Only functional if compiled with gtk-layer-shell support.
|
||||
|
||||
# MODULE FORMAT
|
||||
|
||||
You can use PangoMarkupFormat (See https://developer.gnome.org/pango/stable/PangoMarkupFormat.html#PangoMarkupFormat).
|
||||
|
22
meson.build
22
meson.build
@ -1,6 +1,6 @@
|
||||
project(
|
||||
'waybar', 'cpp', 'c',
|
||||
version: '0.9.0',
|
||||
version: '0.9.1',
|
||||
license: 'MIT',
|
||||
default_options : [
|
||||
'cpp_std=c++17',
|
||||
@ -42,6 +42,22 @@ if not compiler.has_header('filesystem')
|
||||
endif
|
||||
endif
|
||||
|
||||
code = '''
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
int main(int argc, char** argv) {
|
||||
locale_t locale = newlocale(LC_ALL, "en_US.UTF-8", nullptr);
|
||||
char* str;
|
||||
str = nl_langinfo_l(_NL_TIME_WEEK_1STDAY, locale);
|
||||
str = nl_langinfo_l(_NL_TIME_FIRST_WEEKDAY, locale);
|
||||
freelocale(locale);
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
if compiler.links(code, name : 'nl_langinfo with _NL_TIME_WEEK_1STDAY, _NL_TIME_FIRST_WEEKDAY')
|
||||
add_project_arguments('-DHAVE_LANGINFO_1STDAY', language: 'cpp')
|
||||
endif
|
||||
|
||||
add_global_arguments(cpp_args, language : 'cpp')
|
||||
add_global_link_arguments(cpp_link_args, language : 'cpp')
|
||||
|
||||
@ -66,6 +82,7 @@ gtk_layer_shell = dependency('gtk-layer-shell-0',
|
||||
required: get_option('gtk-layer-shell'),
|
||||
fallback : ['gtk-layer-shell', 'gtk_layer_shell_dep'])
|
||||
systemd = dependency('systemd', required: get_option('systemd'))
|
||||
tz_dep = dependency('date', default_options : [ 'use_system_tzdb=true' ], fallback: [ 'date', 'tz_dep' ])
|
||||
|
||||
prefix = get_option('prefix')
|
||||
conf_data = configuration_data()
|
||||
@ -166,7 +183,8 @@ executable(
|
||||
libpulse,
|
||||
libudev,
|
||||
libmpdclient,
|
||||
gtk_layer_shell
|
||||
gtk_layer_shell,
|
||||
tz_dep
|
||||
],
|
||||
include_directories: [include_directories('include')],
|
||||
install: true,
|
||||
|
@ -31,7 +31,9 @@
|
||||
<property name='Id' type='s' access='read'/>
|
||||
<property name='Title' type='s' access='read'/>
|
||||
<property name='Status' type='s' access='read'/>
|
||||
<!-- See discussion on pull #536
|
||||
<property name='WindowId' type='u' access='read'/>
|
||||
-->
|
||||
<property name='IconThemePath' type='s' access='read'/>
|
||||
<property name='IconName' type='s' access='read'/>
|
||||
<property name='IconPixmap' type='a(iiay)' access='read'/>
|
||||
|
@ -64,7 +64,8 @@
|
||||
"spacing": 10
|
||||
},
|
||||
"clock": {
|
||||
"tooltip-format": "{:%Y-%m-%d | %H:%M}",
|
||||
// "timezone": "America/New_York",
|
||||
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
|
||||
"format-alt": "{:%Y-%m-%d}"
|
||||
},
|
||||
"cpu": {
|
||||
@ -121,8 +122,8 @@
|
||||
"format-source": "{volume}% ",
|
||||
"format-source-muted": "",
|
||||
"format-icons": {
|
||||
"headphones": "",
|
||||
"handsfree": "",
|
||||
"headphone": "",
|
||||
"hands-free": "",
|
||||
"headset": "",
|
||||
"phone": "",
|
||||
"portable": "",
|
||||
|
@ -38,6 +38,8 @@ def on_metadata(player, metadata, manager):
|
||||
elif player.get_artist() != '' and player.get_title() != '':
|
||||
track_info = '{artist} - {title}'.format(artist=player.get_artist(),
|
||||
title=player.get_title())
|
||||
else:
|
||||
track_info = player.get_title()
|
||||
|
||||
if player.props.status != 'Playing' and track_info:
|
||||
track_info = ' ' + track_info
|
||||
@ -77,7 +79,7 @@ def signal_handler(sig, frame):
|
||||
def parse_arguments():
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
# Increase verbosity with every occurance of -v
|
||||
# Increase verbosity with every occurence of -v
|
||||
parser.add_argument('-v', '--verbose', action='count', default=0)
|
||||
|
||||
# Define for which player we're listening
|
||||
@ -123,4 +125,3 @@ def main():
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
@ -49,7 +49,7 @@ void waybar::Client::handleGlobalRemove(void * data, struct wl_registry * /*re
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
void waybar::Client::handleOutput(std::unique_ptr<struct waybar_output> &output) {
|
||||
void waybar::Client::handleOutput(struct waybar_output &output) {
|
||||
static const struct zxdg_output_v1_listener xdgOutputListener = {
|
||||
.logical_position = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {},
|
||||
.logical_size = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {},
|
||||
@ -58,42 +58,39 @@ void waybar::Client::handleOutput(std::unique_ptr<struct waybar_output> &output)
|
||||
.description = [](void *, struct zxdg_output_v1 *, const char *) {},
|
||||
};
|
||||
// owned by output->monitor; no need to destroy
|
||||
auto wl_output = gdk_wayland_monitor_get_wl_output(output->monitor->gobj());
|
||||
output->xdg_output.reset(zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, wl_output));
|
||||
zxdg_output_v1_add_listener(output->xdg_output.get(), &xdgOutputListener, output.get());
|
||||
auto wl_output = gdk_wayland_monitor_get_wl_output(output.monitor->gobj());
|
||||
output.xdg_output.reset(zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, wl_output));
|
||||
zxdg_output_v1_add_listener(output.xdg_output.get(), &xdgOutputListener, &output);
|
||||
}
|
||||
|
||||
bool waybar::Client::isValidOutput(const Json::Value & config,
|
||||
std::unique_ptr<struct waybar_output> &output) {
|
||||
bool waybar::Client::isValidOutput(const Json::Value &config, struct waybar_output &output) {
|
||||
bool found = true;
|
||||
if (config["output"].isArray()) {
|
||||
bool in_array = false;
|
||||
for (auto const &output_conf : config["output"]) {
|
||||
if (output_conf.isString() && output_conf.asString() == output->name) {
|
||||
if (output_conf.isString() && output_conf.asString() == output.name) {
|
||||
in_array = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
found = in_array;
|
||||
}
|
||||
if (config["output"].isString() && config["output"].asString() != output->name) {
|
||||
if (config["output"].isString() && config["output"].asString() != output.name) {
|
||||
found = false;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
std::unique_ptr<struct waybar::waybar_output> &waybar::Client::getOutput(void *addr) {
|
||||
auto it = std::find_if(outputs_.begin(), outputs_.end(), [&addr](const auto &output) {
|
||||
return output.get() == addr;
|
||||
});
|
||||
struct waybar::waybar_output &waybar::Client::getOutput(void *addr) {
|
||||
auto it = std::find_if(
|
||||
outputs_.begin(), outputs_.end(), [&addr](const auto &output) { return &output == addr; });
|
||||
if (it == outputs_.end()) {
|
||||
throw std::runtime_error("Unable to find valid output");
|
||||
}
|
||||
return *it;
|
||||
}
|
||||
|
||||
std::vector<Json::Value> waybar::Client::getOutputConfigs(
|
||||
std::unique_ptr<struct waybar_output> &output) {
|
||||
std::vector<Json::Value> waybar::Client::getOutputConfigs(struct waybar_output &output) {
|
||||
std::vector<Json::Value> configs;
|
||||
if (config_.isArray()) {
|
||||
for (auto const &config : config_) {
|
||||
@ -112,18 +109,18 @@ void waybar::Client::handleOutputName(void * data, struct zxdg_output_v1 *
|
||||
auto client = waybar::Client::inst();
|
||||
try {
|
||||
auto &output = client->getOutput(data);
|
||||
output->name = name;
|
||||
output.name = name;
|
||||
spdlog::debug("Output detected: {} ({} {})",
|
||||
name,
|
||||
output->monitor->get_manufacturer(),
|
||||
output->monitor->get_model());
|
||||
output.monitor->get_manufacturer(),
|
||||
output.monitor->get_model());
|
||||
auto configs = client->getOutputConfigs(output);
|
||||
if (configs.empty()) {
|
||||
output->xdg_output.reset();
|
||||
output.xdg_output.reset();
|
||||
} else {
|
||||
wl_display_roundtrip(client->wl_display);
|
||||
for (const auto &config : configs) {
|
||||
client->bars.emplace_back(std::make_unique<Bar>(output.get(), config));
|
||||
client->bars.emplace_back(std::make_unique<Bar>(&output, config));
|
||||
Glib::RefPtr<Gdk::Screen> screen = client->bars.back()->window.get_screen();
|
||||
client->style_context_->add_provider_for_screen(
|
||||
screen, client->css_provider_, GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
@ -135,7 +132,8 @@ void waybar::Client::handleOutputName(void * data, struct zxdg_output_v1 *
|
||||
}
|
||||
|
||||
void waybar::Client::handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor) {
|
||||
auto &output = outputs_.emplace_back(new struct waybar_output({monitor}));
|
||||
auto &output = outputs_.emplace_back();
|
||||
output.monitor = monitor;
|
||||
handleOutput(output);
|
||||
}
|
||||
|
||||
@ -151,9 +149,7 @@ void waybar::Client::handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor) {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
std::remove_if(outputs_.begin(), outputs_.end(), [&monitor](const auto &output) {
|
||||
return output->monitor == monitor;
|
||||
});
|
||||
outputs_.remove_if([&monitor](const auto &output) { return output.monitor == monitor; });
|
||||
}
|
||||
|
||||
std::tuple<const std::string, const std::string> waybar::Client::getConfigs(
|
||||
|
@ -163,7 +163,12 @@ auto waybar::modules::Battery::update() -> void {
|
||||
}
|
||||
label_.set_tooltip_text(tooltip_text);
|
||||
}
|
||||
// Transform to lowercase
|
||||
std::transform(status.begin(), status.end(), status.begin(), ::tolower);
|
||||
// Replace space with dash
|
||||
std::transform(status.begin(), status.end(), status.begin(), [](char ch) {
|
||||
return ch == ' ' ? '-' : ch;
|
||||
});
|
||||
auto format = format_;
|
||||
auto state = getState(capacity, true);
|
||||
if (!old_status_.empty()) {
|
||||
|
@ -1,8 +1,28 @@
|
||||
#include "modules/clock.hpp"
|
||||
#include <time.h>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
#ifdef HAVE_LANGINFO_1STDAY
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
using waybar::modules::waybar_time;
|
||||
|
||||
waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
||||
: ALabel(config, "clock", id, "{:%H:%M}", 60) {
|
||||
: ALabel(config, "clock", id, "{:%H:%M}", 60)
|
||||
, fixed_time_zone_(false)
|
||||
{
|
||||
if (config_["timezone"].isString()) {
|
||||
time_zone_ = date::locate_zone(config_["timezone"].asString());
|
||||
fixed_time_zone_ = true;
|
||||
}
|
||||
|
||||
if (config_["locale"].isString()) {
|
||||
locale_ = std::locale(config_["locale"].asString());
|
||||
} else {
|
||||
locale_ = std::locale("");
|
||||
}
|
||||
|
||||
thread_ = [this] {
|
||||
dp.emit();
|
||||
auto now = std::chrono::system_clock::now();
|
||||
@ -13,19 +33,113 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
||||
}
|
||||
|
||||
auto waybar::modules::Clock::update() -> void {
|
||||
tzset(); // Update timezone information
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto localtime = fmt::localtime(std::chrono::system_clock::to_time_t(now));
|
||||
auto text = fmt::format(format_, localtime);
|
||||
if (!fixed_time_zone_) {
|
||||
// Time zone can change. Be sure to pick that.
|
||||
time_zone_ = date::current_zone();
|
||||
}
|
||||
auto now = std::chrono::system_clock::now();
|
||||
waybar_time wtime = {locale_,
|
||||
date::make_zoned(time_zone_, date::floor<std::chrono::seconds>(now))};
|
||||
|
||||
auto text = fmt::format(format_, wtime);
|
||||
label_.set_markup(text);
|
||||
|
||||
if (tooltipEnabled()) {
|
||||
if (config_["tooltip-format"].isString()) {
|
||||
const auto calendar = calendar_text(wtime);
|
||||
auto tooltip_format = config_["tooltip-format"].asString();
|
||||
auto tooltip_text = fmt::format(tooltip_format, localtime);
|
||||
label_.set_tooltip_text(tooltip_text);
|
||||
auto tooltip_text = fmt::format(tooltip_format, wtime, fmt::arg("calendar", calendar));
|
||||
label_.set_tooltip_markup(tooltip_text);
|
||||
} else {
|
||||
label_.set_tooltip_text(text);
|
||||
label_.set_tooltip_markup(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::string {
|
||||
const auto daypoint = date::floor<date::days>(wtime.ztime.get_local_time());
|
||||
const auto ymd = date::year_month_day(daypoint);
|
||||
if (cached_calendar_ymd_ == ymd) {
|
||||
return cached_calendar_text_;
|
||||
}
|
||||
|
||||
const date::year_month ym(ymd.year(), ymd.month());
|
||||
const auto curr_day = ymd.day();
|
||||
|
||||
std::stringstream os;
|
||||
const auto first_dow = first_day_of_week();
|
||||
weekdays_header(first_dow, os);
|
||||
|
||||
// First week prefixed with spaces if needed.
|
||||
auto wd = date::weekday(ym/1);
|
||||
auto empty_days = (wd - first_dow).count();
|
||||
if (empty_days > 0) {
|
||||
os << std::string(empty_days * 3 - 1, ' ');
|
||||
}
|
||||
auto last_day = (ym/date::literals::last).day();
|
||||
for (auto d = date::day(1); d <= last_day; ++d, ++wd) {
|
||||
if (wd != first_dow) {
|
||||
os << ' ';
|
||||
} else if (unsigned(d) != 1) {
|
||||
os << '\n';
|
||||
}
|
||||
if (d == curr_day) {
|
||||
os << "<b><u>" << date::format("%e", d) << "</u></b>";
|
||||
} else {
|
||||
os << date::format("%e", d);
|
||||
}
|
||||
}
|
||||
|
||||
auto result = os.str();
|
||||
cached_calendar_ymd_ = ymd;
|
||||
cached_calendar_text_ = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
auto waybar::modules::Clock::weekdays_header(const date::weekday& first_dow, std::ostream& os) -> void {
|
||||
auto wd = first_dow;
|
||||
do {
|
||||
if (wd != first_dow) os << ' ';
|
||||
Glib::ustring wd_ustring(date::format(locale_, "%a", wd));
|
||||
auto wd_len = wd_ustring.length();
|
||||
if (wd_len > 2) {
|
||||
wd_ustring = wd_ustring.substr(0, 2);
|
||||
wd_len = 2;
|
||||
}
|
||||
const std::string pad(2 - wd_len, ' ');
|
||||
os << pad << wd_ustring;
|
||||
} while (++wd != first_dow);
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
#ifdef HAVE_LANGINFO_1STDAY
|
||||
template <auto fn>
|
||||
using deleter_from_fn = std::integral_constant<decltype(fn), fn>;
|
||||
|
||||
template <typename T, auto fn>
|
||||
using deleting_unique_ptr = std::unique_ptr<T, deleter_from_fn<fn>>;
|
||||
#endif
|
||||
|
||||
// Computations done similarly to Linux cal utility.
|
||||
auto waybar::modules::Clock::first_day_of_week() -> date::weekday {
|
||||
#ifdef HAVE_LANGINFO_1STDAY
|
||||
deleting_unique_ptr<std::remove_pointer<locale_t>::type, freelocale>
|
||||
posix_locale{newlocale(LC_ALL, locale_.name().c_str(), nullptr)};
|
||||
if (posix_locale) {
|
||||
const int i = (std::intptr_t) nl_langinfo_l(_NL_TIME_WEEK_1STDAY, posix_locale.get());
|
||||
auto ymd = date::year(i / 10000)/(i / 100 % 100)/(i % 100);
|
||||
auto wd = date::weekday(ymd);
|
||||
uint8_t j = *nl_langinfo_l(_NL_TIME_FIRST_WEEKDAY, posix_locale.get());
|
||||
return wd + date::days(j - 1);
|
||||
}
|
||||
#endif
|
||||
return date::Sunday;
|
||||
}
|
||||
|
||||
template <>
|
||||
struct fmt::formatter<waybar_time> : fmt::formatter<std::tm> {
|
||||
template <typename FormatContext>
|
||||
auto format(const waybar_time& t, FormatContext& ctx) {
|
||||
return format_to(ctx.out(), "{}", date::format(t.locale, fmt::to_string(tm_format), t.ztime));
|
||||
}
|
||||
};
|
||||
|
@ -140,7 +140,9 @@ void waybar::modules::MPD::setLabel() {
|
||||
if (playing()) {
|
||||
label_.get_style_context()->add_class("playing");
|
||||
label_.get_style_context()->remove_class("paused");
|
||||
} else {
|
||||
} else if (paused()) {
|
||||
format =
|
||||
config_["format-paused"].isString() ? config_["format-paused"].asString() : config_["format"].asString();
|
||||
label_.get_style_context()->add_class("paused");
|
||||
label_.get_style_context()->remove_class("playing");
|
||||
}
|
||||
@ -346,3 +348,5 @@ bool waybar::modules::MPD::stopped() {
|
||||
}
|
||||
|
||||
bool waybar::modules::MPD::playing() { return connection_ != nullptr && state_ == MPD_STATE_PLAY; }
|
||||
|
||||
bool waybar::modules::MPD::paused() { return connection_ != nullptr && state_ == MPD_STATE_PAUSE; }
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
#include "util/format.hpp"
|
||||
|
||||
|
||||
@ -280,6 +281,11 @@ auto waybar::modules::Network::update() -> void {
|
||||
fmt::arg("bandwidthUpOctets", pow_format(bandwidth_up / interval_.count(), "o/s")));
|
||||
if (text != label_.get_label()) {
|
||||
label_.set_markup(text);
|
||||
if (text.empty()) {
|
||||
event_box_.hide();
|
||||
} else {
|
||||
event_box_.show();
|
||||
}
|
||||
}
|
||||
if (tooltipEnabled()) {
|
||||
if (tooltip_format.empty() && config_["tooltip-format"].isString()) {
|
||||
@ -434,7 +440,6 @@ out:
|
||||
}
|
||||
|
||||
void waybar::modules::Network::getInterfaceAddress() {
|
||||
unsigned int cidrRaw;
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
cidr_ = 0;
|
||||
int success = getifaddrs(&ifaddr);
|
||||
@ -446,18 +451,34 @@ void waybar::modules::Network::getInterfaceAddress() {
|
||||
if (ifa->ifa_addr != nullptr && ifa->ifa_addr->sa_family == family_ &&
|
||||
ifa->ifa_name == ifname_) {
|
||||
char ipaddr[INET6_ADDRSTRLEN];
|
||||
ipaddr_ = inet_ntop(family_,
|
||||
&reinterpret_cast<struct sockaddr_in *>(ifa->ifa_addr)->sin_addr,
|
||||
ipaddr,
|
||||
INET6_ADDRSTRLEN);
|
||||
char netmask[INET6_ADDRSTRLEN];
|
||||
auto net_addr = reinterpret_cast<struct sockaddr_in *>(ifa->ifa_netmask);
|
||||
netmask_ = inet_ntop(family_, &net_addr->sin_addr, netmask, INET6_ADDRSTRLEN);
|
||||
cidrRaw = net_addr->sin_addr.s_addr;
|
||||
unsigned int cidr = 0;
|
||||
while (cidrRaw) {
|
||||
cidr += cidrRaw & 1;
|
||||
cidrRaw >>= 1;
|
||||
if (family_ == AF_INET) {
|
||||
ipaddr_ = inet_ntop(AF_INET,
|
||||
&reinterpret_cast<struct sockaddr_in *>(ifa->ifa_addr)->sin_addr,
|
||||
ipaddr,
|
||||
INET_ADDRSTRLEN);
|
||||
auto net_addr = reinterpret_cast<struct sockaddr_in *>(ifa->ifa_netmask);
|
||||
netmask_ = inet_ntop(AF_INET, &net_addr->sin_addr, netmask, INET_ADDRSTRLEN);
|
||||
unsigned int cidrRaw = net_addr->sin_addr.s_addr;
|
||||
while (cidrRaw) {
|
||||
cidr += cidrRaw & 1;
|
||||
cidrRaw >>= 1;
|
||||
}
|
||||
} else {
|
||||
ipaddr_ = inet_ntop(AF_INET6,
|
||||
&reinterpret_cast<struct sockaddr_in6 *>(ifa->ifa_addr)->sin6_addr,
|
||||
ipaddr,
|
||||
INET6_ADDRSTRLEN);
|
||||
auto net_addr = reinterpret_cast<struct sockaddr_in6 *>(ifa->ifa_netmask);
|
||||
netmask_ = inet_ntop(AF_INET6, &net_addr->sin6_addr, netmask, INET6_ADDRSTRLEN);
|
||||
for (size_t i = 0; i < sizeof(net_addr->sin6_addr.s6_addr); ++i) {
|
||||
unsigned char cidrRaw = net_addr->sin6_addr.s6_addr[i];
|
||||
while (cidrRaw) {
|
||||
cidr += cidrRaw & 1;
|
||||
cidrRaw >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
cidr_ = cidr;
|
||||
break;
|
||||
|
@ -158,6 +158,9 @@ void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, const pa_
|
||||
pa->desc_ = i->description;
|
||||
pa->monitor_ = i->monitor_source_name;
|
||||
pa->port_name_ = i->active_port != nullptr ? i->active_port->name : "Unknown";
|
||||
if (auto ff = pa_proplist_gets(i->proplist, PA_PROP_DEVICE_FORM_FACTOR)) {
|
||||
pa->form_factor_ = ff;
|
||||
}
|
||||
pa->dp.emit();
|
||||
}
|
||||
}
|
||||
@ -173,11 +176,11 @@ void waybar::modules::Pulseaudio::serverInfoCb(pa_context *context, const pa_ser
|
||||
}
|
||||
|
||||
static const std::array<std::string, 9> ports = {
|
||||
"headphones",
|
||||
"headphone",
|
||||
"speaker",
|
||||
"hdmi",
|
||||
"headset",
|
||||
"handsfree",
|
||||
"hands-free",
|
||||
"portable",
|
||||
"car",
|
||||
"hifi",
|
||||
@ -185,7 +188,7 @@ static const std::array<std::string, 9> ports = {
|
||||
};
|
||||
|
||||
const std::string waybar::modules::Pulseaudio::getPortIcon() const {
|
||||
std::string nameLC = port_name_;
|
||||
std::string nameLC = port_name_ + form_factor_;
|
||||
std::transform(nameLC.begin(), nameLC.end(), nameLC.begin(), ::tolower);
|
||||
for (auto const &port : ports) {
|
||||
if (nameLC.find(port) != std::string::npos) {
|
||||
|
@ -265,7 +265,11 @@ void Item::updateImage() {
|
||||
if (pixbuf->gobj() != nullptr) {
|
||||
// An icon specified by path and filename may be the wrong size for
|
||||
// the tray
|
||||
pixbuf = pixbuf->scale_simple(icon_size, icon_size, Gdk::InterpType::INTERP_BILINEAR);
|
||||
// Keep the aspect ratio and scale to make the height equal to icon_size
|
||||
// If people have non square icons, assume they want it to grow in width not height
|
||||
int width = icon_size * pixbuf->get_width() / pixbuf->get_height();
|
||||
|
||||
pixbuf = pixbuf->scale_simple(width, icon_size, Gdk::InterpType::INTERP_BILINEAR);
|
||||
image.set(pixbuf);
|
||||
}
|
||||
} else {
|
||||
|
@ -10,19 +10,23 @@ Ipc::Ipc() {
|
||||
}
|
||||
|
||||
Ipc::~Ipc() {
|
||||
// To fail the IPC header
|
||||
write(fd_, "close-sway-ipc", 14);
|
||||
write(fd_event_, "close-sway-ipc", 14);
|
||||
thread_.stop();
|
||||
|
||||
if (fd_ > 0) {
|
||||
// To fail the IPC header
|
||||
write(fd_, "close-sway-ipc", 14);
|
||||
close(fd_);
|
||||
fd_ = -1;
|
||||
}
|
||||
if (fd_event_ > 0) {
|
||||
write(fd_event_, "close-sway-ipc", 14);
|
||||
close(fd_event_);
|
||||
fd_event_ = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Ipc::setWorker(std::function<void()>&& func) { thread_ = func; }
|
||||
|
||||
const std::string Ipc::getSocketPath() const {
|
||||
const char* env = getenv("SWAYSOCK");
|
||||
if (env != nullptr) {
|
||||
|
@ -8,7 +8,13 @@ Mode::Mode(const std::string& id, const Json::Value& config)
|
||||
ipc_.subscribe(R"(["mode"])");
|
||||
ipc_.signal_event.connect(sigc::mem_fun(*this, &Mode::onEvent));
|
||||
// Launch worker
|
||||
worker();
|
||||
ipc_.setWorker([this] {
|
||||
try {
|
||||
ipc_.handleEvent();
|
||||
} catch (const std::exception& e) {
|
||||
spdlog::error("Mode: {}", e.what());
|
||||
}
|
||||
});
|
||||
dp.emit();
|
||||
}
|
||||
|
||||
@ -31,16 +37,6 @@ void Mode::onEvent(const struct Ipc::ipc_response& res) {
|
||||
}
|
||||
}
|
||||
|
||||
void Mode::worker() {
|
||||
thread_ = [this] {
|
||||
try {
|
||||
ipc_.handleEvent();
|
||||
} catch (const std::exception& e) {
|
||||
spdlog::error("Mode: {}", e.what());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
auto Mode::update() -> void {
|
||||
if (mode_.empty()) {
|
||||
event_box_.hide();
|
||||
|
@ -11,7 +11,13 @@ Window::Window(const std::string& id, const Bar& bar, const Json::Value& config)
|
||||
// Get Initial focused window
|
||||
getTree();
|
||||
// Launch worker
|
||||
worker();
|
||||
ipc_.setWorker([this] {
|
||||
try {
|
||||
ipc_.handleEvent();
|
||||
} catch (const std::exception& e) {
|
||||
spdlog::error("Window: {}", e.what());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Window::onEvent(const struct Ipc::ipc_response& res) { getTree(); }
|
||||
@ -28,16 +34,6 @@ void Window::onCmd(const struct Ipc::ipc_response& res) {
|
||||
}
|
||||
}
|
||||
|
||||
void Window::worker() {
|
||||
thread_ = [this] {
|
||||
try {
|
||||
ipc_.handleEvent();
|
||||
} catch (const std::exception& e) {
|
||||
spdlog::error("Window: {}", e.what());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
auto Window::update() -> void {
|
||||
if (!old_app_id_.empty()) {
|
||||
bar_.window.get_style_context()->remove_class(old_app_id_);
|
||||
|
@ -22,7 +22,13 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value
|
||||
window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
||||
}
|
||||
// Launch worker
|
||||
worker();
|
||||
ipc_.setWorker([this] {
|
||||
try {
|
||||
ipc_.handleEvent();
|
||||
} catch (const std::exception &e) {
|
||||
spdlog::error("Workspaces: {}", e.what());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Workspaces::onEvent(const struct Ipc::ipc_response &res) {
|
||||
@ -102,16 +108,6 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) {
|
||||
}
|
||||
}
|
||||
|
||||
void Workspaces::worker() {
|
||||
thread_ = [this] {
|
||||
try {
|
||||
ipc_.handleEvent();
|
||||
} catch (const std::exception &e) {
|
||||
spdlog::error("Workspaces: {}", e.what());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
bool Workspaces::filterButtons() {
|
||||
bool needReorder = false;
|
||||
for (auto it = buttons_.begin(); it != buttons_.end();) {
|
||||
|
9
subprojects/date.wrap
Normal file
9
subprojects/date.wrap
Normal file
@ -0,0 +1,9 @@
|
||||
[wrap-file]
|
||||
source_url=https://github.com/HowardHinnant/date/archive/v2.4.1.tar.gz
|
||||
source_filename=date-2.4.1.tar.gz
|
||||
source_hash=98907d243397483bd7ad889bf6c66746db0d7d2a39cc9aacc041834c40b65b98
|
||||
directory=date-2.4.1
|
||||
|
||||
patch_url = https://github.com/mesonbuild/hinnant-date/releases/download/2.4.1-1/hinnant-date.zip
|
||||
patch_filename = hinnant-date-2.4.1-1-wrap.zip
|
||||
patch_hash = 2061673a6f8e6d63c3a40df4da58fa2b3de2835fd9b3e74649e8279599f3a8f6
|
@ -5,6 +5,6 @@ source_url = https://github.com/fmtlib/fmt/archive/5.3.0.tar.gz
|
||||
source_filename = fmt-5.3.0.tar.gz
|
||||
source_hash = defa24a9af4c622a7134076602070b45721a43c51598c8456ec6f2c4dbb51c89
|
||||
|
||||
patch_url = https://wrapdb.mesonbuild.com/v1/projects/fmt/5.3.0/1/get_zip
|
||||
patch_url = https://github.com/mesonbuild/fmt/releases/download/5.3.0-1/fmt.zip
|
||||
patch_filename = fmt-5.3.0-1-wrap.zip
|
||||
patch_hash = 18f21a3b8833949c35d4ac88a7059577d5fa24b98786e4b1b2d3d81bb811440f
|
@ -5,6 +5,6 @@ source_url = https://github.com/gabime/spdlog/archive/v1.3.1.tar.gz
|
||||
source_filename = v1.3.1.tar.gz
|
||||
source_hash = 160845266e94db1d4922ef755637f6901266731c4cb3b30b45bf41efa0e6ab70
|
||||
|
||||
patch_url = https://wrapdb.mesonbuild.com/v1/projects/spdlog/1.3.1/1/get_zip
|
||||
patch_url = https://github.com/mesonbuild/spdlog/releases/download/1.3.1-1/spdlog.zip
|
||||
patch_filename = spdlog-1.3.1-1-wrap.zip
|
||||
patch_hash = 715a0229781019b853d409cc0bf891ee4b9d3a17bec0cf87f4ad30b28bbecc87
|
||||
|
Reference in New Issue
Block a user