Clean (#31)
parent
b7e3d10fb7
commit
49232eed8d
|
@ -7,13 +7,13 @@ namespace waybar {
|
||||||
|
|
||||||
class ALabel : public IModule {
|
class ALabel : public IModule {
|
||||||
public:
|
public:
|
||||||
ALabel(Json::Value);
|
ALabel(const Json::Value&);
|
||||||
virtual ~ALabel() = default;
|
virtual ~ALabel() = default;
|
||||||
virtual auto update() -> void;
|
virtual auto update() -> void;
|
||||||
virtual operator Gtk::Widget &();
|
virtual operator Gtk::Widget &();
|
||||||
protected:
|
protected:
|
||||||
Gtk::Label label_;
|
Gtk::Label label_;
|
||||||
Json::Value config_;
|
const Json::Value& config_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,10 @@ namespace waybar {
|
||||||
|
|
||||||
class IModule {
|
class IModule {
|
||||||
public:
|
public:
|
||||||
virtual ~IModule() {}
|
virtual ~IModule() = default;
|
||||||
virtual auto update() -> void = 0;
|
virtual auto update() -> void = 0;
|
||||||
virtual operator Gtk::Widget &() = 0;
|
virtual operator Gtk::Widget &() = 0;
|
||||||
|
Glib::Dispatcher dp; // Hmmm Maybe I should create an abstract class ?
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,12 @@ class Factory;
|
||||||
|
|
||||||
class Bar {
|
class Bar {
|
||||||
public:
|
public:
|
||||||
Bar(Client&, std::unique_ptr<struct wl_output *>&&, uint32_t wl_name);
|
Bar(const Client&, std::unique_ptr<struct wl_output *>&&, uint32_t);
|
||||||
Bar(const Bar&) = delete;
|
Bar(const Bar&) = delete;
|
||||||
|
|
||||||
auto toggle() -> void;
|
auto toggle() -> void;
|
||||||
|
|
||||||
Client& client;
|
const Client& client;
|
||||||
Gtk::Window window;
|
Gtk::Window window;
|
||||||
struct wl_surface *surface;
|
struct wl_surface *surface;
|
||||||
struct zwlr_layer_surface_v1 *layer_surface;
|
struct zwlr_layer_surface_v1 *layer_surface;
|
||||||
|
@ -43,7 +43,7 @@ class Bar {
|
||||||
auto setupConfig() -> void;
|
auto setupConfig() -> void;
|
||||||
auto setupWidgets() -> void;
|
auto setupWidgets() -> void;
|
||||||
auto setupCss() -> void;
|
auto setupCss() -> void;
|
||||||
void getModules(Factory factory, const std::string& pos);
|
void getModules(const Factory&, const std::string&);
|
||||||
|
|
||||||
uint32_t width_ = 0;
|
uint32_t width_ = 0;
|
||||||
uint32_t height_ = 30;
|
uint32_t height_ = 30;
|
||||||
|
|
|
@ -15,11 +15,11 @@ namespace waybar {
|
||||||
|
|
||||||
class Factory {
|
class Factory {
|
||||||
public:
|
public:
|
||||||
Factory(Bar &bar, Json::Value config);
|
Factory(Bar& bar, const Json::Value& config);
|
||||||
IModule* makeModule(const std::string &name);
|
IModule* makeModule(const std::string &name) const;
|
||||||
private:
|
private:
|
||||||
Bar &_bar;
|
Bar& bar_;
|
||||||
Json::Value _config;
|
const Json::Value& config_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,14 @@ namespace fs = std::filesystem;
|
||||||
|
|
||||||
class Battery : public ALabel {
|
class Battery : public ALabel {
|
||||||
public:
|
public:
|
||||||
Battery(Json::Value);
|
Battery(const Json::Value&);
|
||||||
~Battery();
|
~Battery();
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
std::string getIcon(uint16_t percentage);
|
|
||||||
|
|
||||||
static inline const fs::path data_dir_ = "/sys/class/power_supply/";
|
static inline const fs::path data_dir_ = "/sys/class/power_supply/";
|
||||||
|
|
||||||
|
void worker();
|
||||||
|
std::string getIcon(uint16_t percentage);
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
std::vector<fs::path> batteries_;
|
std::vector<fs::path> batteries_;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace waybar::modules {
|
||||||
|
|
||||||
class Clock : public ALabel {
|
class Clock : public ALabel {
|
||||||
public:
|
public:
|
||||||
Clock(Json::Value);
|
Clock(const Json::Value&);
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
waybar::util::SleeperThread thread_;
|
waybar::util::SleeperThread thread_;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace waybar::modules {
|
||||||
|
|
||||||
class Cpu : public ALabel {
|
class Cpu : public ALabel {
|
||||||
public:
|
public:
|
||||||
Cpu(Json::Value);
|
Cpu(const Json::Value&);
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
waybar::util::SleeperThread thread_;
|
waybar::util::SleeperThread thread_;
|
||||||
|
|
|
@ -10,10 +10,12 @@ namespace waybar::modules {
|
||||||
|
|
||||||
class Custom : public ALabel {
|
class Custom : public ALabel {
|
||||||
public:
|
public:
|
||||||
Custom(std::string, Json::Value);
|
Custom(const std::string&, const Json::Value&);
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
void worker();
|
||||||
|
|
||||||
|
const std::string& name_;
|
||||||
waybar::util::SleeperThread thread_;
|
waybar::util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace waybar::modules {
|
||||||
|
|
||||||
class Memory : public ALabel {
|
class Memory : public ALabel {
|
||||||
public:
|
public:
|
||||||
Memory(Json::Value);
|
Memory(const Json::Value&);
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
waybar::util::SleeperThread thread_;
|
waybar::util::SleeperThread thread_;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace waybar::modules {
|
||||||
|
|
||||||
class Network : public ALabel {
|
class Network : public ALabel {
|
||||||
public:
|
public:
|
||||||
Network(Json::Value);
|
Network(const Json::Value&);
|
||||||
~Network();
|
~Network();
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace waybar::modules {
|
||||||
|
|
||||||
class Pulseaudio : public ALabel {
|
class Pulseaudio : public ALabel {
|
||||||
public:
|
public:
|
||||||
Pulseaudio(Json::Value);
|
Pulseaudio(const Json::Value&);
|
||||||
~Pulseaudio();
|
~Pulseaudio();
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,33 +1,41 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include "ipc.hpp"
|
#include "ipc.hpp"
|
||||||
|
|
||||||
/**
|
namespace waybar::modules::sway {
|
||||||
* IPC response including type of IPC response, size of payload and the json
|
|
||||||
* encoded payload string.
|
class Ipc {
|
||||||
*/
|
public:
|
||||||
struct ipc_response {
|
Ipc();
|
||||||
uint32_t size;
|
~Ipc();
|
||||||
uint32_t type;
|
|
||||||
std::string payload;
|
struct ipc_response {
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t type;
|
||||||
|
std::string payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
void connect();
|
||||||
|
struct ipc_response sendCmd(uint32_t type,
|
||||||
|
const std::string& payload = "") const;
|
||||||
|
void subscribe(const std::string& payload) const;
|
||||||
|
struct ipc_response handleEvent() const;
|
||||||
|
protected:
|
||||||
|
static inline const std::string ipc_magic_ = "i3-ipc";
|
||||||
|
static inline const size_t ipc_header_size_ = ipc_magic_.size() + 8;
|
||||||
|
|
||||||
|
const std::string getSocketPath() const;
|
||||||
|
int open(const std::string&) const;
|
||||||
|
struct ipc_response send(int fd, uint32_t type,
|
||||||
|
const std::string& payload = "") const;
|
||||||
|
struct ipc_response recv(int fd) const;
|
||||||
|
|
||||||
|
int fd_;
|
||||||
|
int fd_event_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
}
|
||||||
* Gets the path to the IPC socket from sway.
|
|
||||||
*/
|
|
||||||
std::string getSocketPath(void);
|
|
||||||
/**
|
|
||||||
* Opens the sway socket.
|
|
||||||
*/
|
|
||||||
int ipcOpenSocket(const std::string &socketPath);
|
|
||||||
/**
|
|
||||||
* Issues a single IPC command and returns the buffer. len will be updated with
|
|
||||||
* the length of the buffer returned from sway.
|
|
||||||
*/
|
|
||||||
struct ipc_response ipcSingleCommand(int socketfd, uint32_t type,
|
|
||||||
const std::string& payload);
|
|
||||||
/**
|
|
||||||
* Receives a single IPC response and returns an ipc_response.
|
|
||||||
*/
|
|
||||||
struct ipc_response ipcRecvResponse(int socketfd);
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define event_mask(ev) (1 << (ev & 0x7F))
|
#define event_mask(ev) (1u << (ev & 0x7F))
|
||||||
|
|
||||||
enum ipc_command_type {
|
enum ipc_command_type {
|
||||||
// i3 command types - see i3's I3_REPLY_TYPE constants
|
// i3 command types - see i3's I3_REPLY_TYPE constants
|
||||||
|
|
|
@ -6,23 +6,23 @@
|
||||||
#include "util/chrono.hpp"
|
#include "util/chrono.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
|
#include "modules/sway/ipc/client.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
class Window : public ALabel {
|
class Window : public ALabel {
|
||||||
public:
|
public:
|
||||||
Window(waybar::Bar&, Json::Value);
|
Window(waybar::Bar&, const Json::Value&);
|
||||||
~Window();
|
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
|
void worker();
|
||||||
std::string getFocusedNode(Json::Value nodes);
|
std::string getFocusedNode(Json::Value nodes);
|
||||||
void getFocusedWindow();
|
void getFocusedWindow();
|
||||||
|
|
||||||
Bar& bar_;
|
Bar& bar_;
|
||||||
waybar::util::SleeperThread thread_;
|
waybar::util::SleeperThread thread_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
int ipcfd_;
|
Ipc ipc_;
|
||||||
int ipc_eventfd_;
|
|
||||||
std::string window_;
|
std::string window_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,16 +6,17 @@
|
||||||
#include "util/chrono.hpp"
|
#include "util/chrono.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
#include "IModule.hpp"
|
#include "IModule.hpp"
|
||||||
|
#include "modules/sway/ipc/client.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
class Workspaces : public IModule {
|
class Workspaces : public IModule {
|
||||||
public:
|
public:
|
||||||
Workspaces(waybar::Bar&, Json::Value);
|
Workspaces(waybar::Bar&, const Json::Value&);
|
||||||
~Workspaces();
|
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
operator Gtk::Widget &();
|
operator Gtk::Widget &();
|
||||||
private:
|
private:
|
||||||
|
void worker();
|
||||||
void addWorkspace(Json::Value);
|
void addWorkspace(Json::Value);
|
||||||
std::string getIcon(std::string);
|
std::string getIcon(std::string);
|
||||||
bool handleScroll(GdkEventScroll*);
|
bool handleScroll(GdkEventScroll*);
|
||||||
|
@ -23,7 +24,7 @@ class Workspaces : public IModule {
|
||||||
int getNextWorkspace();
|
int getNextWorkspace();
|
||||||
|
|
||||||
Bar& bar_;
|
Bar& bar_;
|
||||||
Json::Value config_;
|
const Json::Value& config_;
|
||||||
waybar::util::SleeperThread thread_;
|
waybar::util::SleeperThread thread_;
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
|
@ -31,8 +32,7 @@ class Workspaces : public IModule {
|
||||||
bool scrolling_;
|
bool scrolling_;
|
||||||
std::unordered_map<int, Gtk::Button> buttons_;
|
std::unordered_map<int, Gtk::Button> buttons_;
|
||||||
Json::Value workspaces_;
|
Json::Value workspaces_;
|
||||||
int ipcfd_;
|
Ipc ipc_;
|
||||||
int ipc_eventfd_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,26 +70,13 @@ struct SleeperThread {
|
||||||
condvar_.notify_all();
|
condvar_.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit()
|
|
||||||
{
|
|
||||||
Glib::signal_idle().connect_once([this] {
|
|
||||||
sig_update.emit();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
~SleeperThread()
|
~SleeperThread()
|
||||||
{
|
{
|
||||||
do_run_ = false;
|
do_run_ = false;
|
||||||
condvar_.notify_all();
|
condvar_.notify_all();
|
||||||
auto native_handle = thread_.native_handle();
|
thread_.detach();
|
||||||
pthread_cancel(native_handle);
|
|
||||||
if (thread_.joinable()) {
|
|
||||||
thread_.join();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sigc::signal<void> sig_update;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::thread thread_;
|
std::thread thread_;
|
||||||
std::condition_variable condvar_;
|
std::condition_variable condvar_;
|
||||||
|
|
|
@ -7,32 +7,25 @@ namespace waybar::util {
|
||||||
struct JsonParser {
|
struct JsonParser {
|
||||||
|
|
||||||
JsonParser()
|
JsonParser()
|
||||||
: _reader(_builder.newCharReader())
|
: reader_(builder_.newCharReader())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Json::Value parse(const std::string data)
|
const Json::Value parse(const std::string data) const
|
||||||
{
|
{
|
||||||
Json::Value root;
|
Json::Value root;
|
||||||
std::string err;
|
std::string err;
|
||||||
if (_reader == nullptr) {
|
|
||||||
throw std::runtime_error("Unable to parse");
|
|
||||||
}
|
|
||||||
bool res =
|
bool res =
|
||||||
_reader->parse(data.c_str(), data.c_str() + data.size(), &root, &err);
|
reader_->parse(data.c_str(), data.c_str() + data.size(), &root, &err);
|
||||||
if (!res)
|
if (!res)
|
||||||
throw std::runtime_error(err);
|
throw std::runtime_error(err);
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
~JsonParser()
|
~JsonParser() = default;
|
||||||
{
|
|
||||||
delete _reader;
|
|
||||||
_reader = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Json::CharReaderBuilder _builder;
|
Json::CharReaderBuilder builder_;
|
||||||
Json::CharReader *_reader;
|
std::unique_ptr<Json::CharReader> const reader_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
|
|
||||||
waybar::ALabel::ALabel(Json::Value config)
|
waybar::ALabel::ALabel(const Json::Value& config)
|
||||||
: config_(std::move(config))
|
: config_(config)
|
||||||
{
|
{
|
||||||
if (config_["max-length"]) {
|
if (config_["max-length"]) {
|
||||||
label_.set_max_width_chars(config_["max-length"].asUInt());
|
label_.set_max_width_chars(config_["max-length"].asUInt());
|
||||||
|
|
19
src/bar.cpp
19
src/bar.cpp
|
@ -3,10 +3,11 @@
|
||||||
#include "factory.hpp"
|
#include "factory.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
|
|
||||||
waybar::Bar::Bar(Client &client,
|
waybar::Bar::Bar(const Client& client,
|
||||||
std::unique_ptr<struct wl_output *> &&p_output, uint32_t p_wl_name)
|
std::unique_ptr<struct wl_output *> &&p_output, uint32_t p_wl_name)
|
||||||
: client(client), window{Gtk::WindowType::WINDOW_TOPLEVEL},
|
: client(client), window{Gtk::WindowType::WINDOW_TOPLEVEL},
|
||||||
output(std::move(p_output)), wl_name(std::move(p_wl_name))
|
surface(nullptr), layer_surface(nullptr),
|
||||||
|
output(std::move(p_output)), wl_name(p_wl_name)
|
||||||
{
|
{
|
||||||
static const struct zxdg_output_v1_listener xdgOutputListener = {
|
static const struct zxdg_output_v1_listener xdgOutputListener = {
|
||||||
.logical_position = handleLogicalPosition,
|
.logical_position = handleLogicalPosition,
|
||||||
|
@ -135,13 +136,13 @@ auto waybar::Bar::toggle() -> void
|
||||||
|
|
||||||
auto waybar::Bar::setupConfig() -> void
|
auto waybar::Bar::setupConfig() -> void
|
||||||
{
|
{
|
||||||
util::JsonParser parser;
|
|
||||||
std::ifstream file(client.config_file);
|
std::ifstream file(client.config_file);
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
throw std::runtime_error("Can't open config file");
|
throw std::runtime_error("Can't open config file");
|
||||||
}
|
}
|
||||||
std::string str((std::istreambuf_iterator<char>(file)),
|
std::string str((std::istreambuf_iterator<char>(file)),
|
||||||
std::istreambuf_iterator<char>());
|
std::istreambuf_iterator<char>());
|
||||||
|
util::JsonParser parser;
|
||||||
config_ = parser.parse(str);
|
config_ = parser.parse(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +151,7 @@ auto waybar::Bar::setupCss() -> void
|
||||||
css_provider_ = Gtk::CssProvider::create();
|
css_provider_ = Gtk::CssProvider::create();
|
||||||
style_context_ = Gtk::StyleContext::create();
|
style_context_ = Gtk::StyleContext::create();
|
||||||
|
|
||||||
// load our css file, wherever that may be hiding
|
// Load our css file, wherever that may be hiding
|
||||||
if (css_provider_->load_from_path(client.css_file)) {
|
if (css_provider_->load_from_path(client.css_file)) {
|
||||||
Glib::RefPtr<Gdk::Screen> screen = window.get_screen();
|
Glib::RefPtr<Gdk::Screen> screen = window.get_screen();
|
||||||
style_context_->add_provider_for_screen(screen, css_provider_,
|
style_context_->add_provider_for_screen(screen, css_provider_,
|
||||||
|
@ -158,20 +159,22 @@ auto waybar::Bar::setupCss() -> void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Bar::getModules(Factory factory, const std::string& pos)
|
void waybar::Bar::getModules(const Factory& factory, const std::string& pos)
|
||||||
{
|
{
|
||||||
if (config_[pos]) {
|
if (config_[pos]) {
|
||||||
for (const auto &name : config_[pos]) {
|
for (const auto &name : config_[pos]) {
|
||||||
try {
|
try {
|
||||||
|
auto module = factory.makeModule(name.asString());
|
||||||
if (pos == "modules-left") {
|
if (pos == "modules-left") {
|
||||||
modules_left_.emplace_back(factory.makeModule(name.asString()));
|
modules_left_.emplace_back(module);
|
||||||
}
|
}
|
||||||
if (pos == "modules-center") {
|
if (pos == "modules-center") {
|
||||||
modules_center_.emplace_back(factory.makeModule(name.asString()));
|
modules_center_.emplace_back(module);
|
||||||
}
|
}
|
||||||
if (pos == "modules-right") {
|
if (pos == "modules-right") {
|
||||||
modules_right_.emplace_back(factory.makeModule(name.asString()));
|
modules_right_.emplace_back(module);
|
||||||
}
|
}
|
||||||
|
module->dp.connect([module] { module->update(); });
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
#include "factory.hpp"
|
#include "factory.hpp"
|
||||||
|
|
||||||
waybar::Factory::Factory(Bar &bar, Json::Value config)
|
waybar::Factory::Factory(Bar& bar, const Json::Value& config)
|
||||||
: _bar(bar), _config(std::move(config))
|
: bar_(bar), config_(config)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
waybar::IModule* waybar::Factory::makeModule(const std::string &name)
|
waybar::IModule* waybar::Factory::makeModule(const std::string &name) const
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (name == "battery") {
|
if (name == "battery") {
|
||||||
return new waybar::modules::Battery(_config[name]);
|
return new waybar::modules::Battery(config_[name]);
|
||||||
}
|
}
|
||||||
if (name == "sway/workspaces") {
|
if (name == "sway/workspaces") {
|
||||||
return new waybar::modules::sway::Workspaces(_bar, _config[name]);
|
return new waybar::modules::sway::Workspaces(bar_, config_[name]);
|
||||||
}
|
}
|
||||||
if (name == "sway/window") {
|
if (name == "sway/window") {
|
||||||
return new waybar::modules::sway::Window(_bar, _config[name]);
|
return new waybar::modules::sway::Window(bar_, config_[name]);
|
||||||
}
|
}
|
||||||
if (name == "memory") {
|
if (name == "memory") {
|
||||||
return new waybar::modules::Memory(_config[name]);
|
return new waybar::modules::Memory(config_[name]);
|
||||||
}
|
}
|
||||||
if (name == "cpu") {
|
if (name == "cpu") {
|
||||||
return new waybar::modules::Cpu(_config[name]);
|
return new waybar::modules::Cpu(config_[name]);
|
||||||
}
|
}
|
||||||
if (name == "clock") {
|
if (name == "clock") {
|
||||||
return new waybar::modules::Clock(_config[name]);
|
return new waybar::modules::Clock(config_[name]);
|
||||||
}
|
}
|
||||||
if (name == "network") {
|
if (name == "network") {
|
||||||
return new waybar::modules::Network(_config[name]);
|
return new waybar::modules::Network(config_[name]);
|
||||||
}
|
}
|
||||||
if (name == "pulseaudio") {
|
if (name == "pulseaudio") {
|
||||||
return new waybar::modules::Pulseaudio(_config[name]);
|
return new waybar::modules::Pulseaudio(config_[name]);
|
||||||
}
|
}
|
||||||
if (name.compare(0, 7, "custom/") == 0 && name.size() > 7) {
|
if (name.compare(0, 7, "custom/") == 0 && name.size() > 7) {
|
||||||
return new waybar::modules::Custom(name.substr(7), _config[name]);
|
return new waybar::modules::Custom(name.substr(7), config_[name]);
|
||||||
}
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
auto err = fmt::format("Disabling module \"{}\", {}", name, e.what());
|
auto err = fmt::format("Disabling module \"{}\", {}", name, e.what());
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "modules/battery.hpp"
|
#include "modules/battery.hpp"
|
||||||
|
|
||||||
waybar::modules::Battery::Battery(Json::Value config)
|
waybar::modules::Battery::Battery(const Json::Value& config)
|
||||||
: ALabel(std::move(config))
|
: ALabel(config)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
for (auto &node : fs::directory_iterator(data_dir_)) {
|
for (auto &node : fs::directory_iterator(data_dir_)) {
|
||||||
|
@ -23,25 +23,29 @@ waybar::modules::Battery::Battery(Json::Value config)
|
||||||
for (auto &bat : batteries_) {
|
for (auto &bat : batteries_) {
|
||||||
inotify_add_watch(fd_, (bat / "uevent").c_str(), IN_ACCESS);
|
inotify_add_watch(fd_, (bat / "uevent").c_str(), IN_ACCESS);
|
||||||
}
|
}
|
||||||
// Trigger first values
|
|
||||||
update();
|
|
||||||
label_.set_name("battery");
|
label_.set_name("battery");
|
||||||
thread_.sig_update.connect(sigc::mem_fun(*this, &Battery::update));
|
worker();
|
||||||
|
}
|
||||||
|
|
||||||
|
waybar::modules::Battery::~Battery()
|
||||||
|
{
|
||||||
|
close(fd_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::Battery::worker()
|
||||||
|
{
|
||||||
|
// Trigger first values
|
||||||
|
dp.emit();
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
struct inotify_event event = {0};
|
struct inotify_event event = {0};
|
||||||
int nbytes = read(fd_, &event, sizeof(event));
|
int nbytes = read(fd_, &event, sizeof(event));
|
||||||
if (nbytes != sizeof(event)) {
|
if (nbytes != sizeof(event)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
thread_.emit();
|
dp.emit();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
waybar::modules::Battery::~Battery()
|
|
||||||
{
|
|
||||||
close(fd_);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto waybar::modules::Battery::update() -> void
|
auto waybar::modules::Battery::update() -> void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
#include "modules/clock.hpp"
|
#include "modules/clock.hpp"
|
||||||
|
|
||||||
waybar::modules::Clock::Clock(Json::Value config)
|
waybar::modules::Clock::Clock(const Json::Value& config)
|
||||||
: ALabel(std::move(config))
|
: ALabel(config)
|
||||||
{
|
{
|
||||||
label_.set_name("clock");
|
label_.set_name("clock");
|
||||||
uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 60;
|
uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 60;
|
||||||
thread_.sig_update.connect(sigc::mem_fun(*this, &Clock::update));
|
|
||||||
thread_ = [this, interval] {
|
thread_ = [this, interval] {
|
||||||
auto now = waybar::chrono::clock::now();
|
auto now = waybar::chrono::clock::now();
|
||||||
thread_.emit();
|
dp.emit();
|
||||||
auto timeout = std::chrono::floor<std::chrono::seconds>(now
|
auto timeout = std::chrono::floor<std::chrono::seconds>(now
|
||||||
+ std::chrono::seconds(interval));
|
+ std::chrono::seconds(interval));
|
||||||
thread_.sleep_until(timeout);
|
thread_.sleep_until(timeout);
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
#include "modules/cpu.hpp"
|
#include "modules/cpu.hpp"
|
||||||
|
|
||||||
waybar::modules::Cpu::Cpu(Json::Value config)
|
waybar::modules::Cpu::Cpu(const Json::Value& config)
|
||||||
: ALabel(std::move(config))
|
: ALabel(config)
|
||||||
{
|
{
|
||||||
label_.set_name("cpu");
|
label_.set_name("cpu");
|
||||||
uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 10;
|
uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 10;
|
||||||
thread_.sig_update.connect(sigc::mem_fun(*this, &Cpu::update));
|
|
||||||
thread_ = [this, interval] {
|
thread_ = [this, interval] {
|
||||||
thread_.emit();
|
dp.emit();
|
||||||
thread_.sleep_for(chrono::seconds(interval));
|
thread_.sleep_for(chrono::seconds(interval));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
#include "modules/custom.hpp"
|
#include "modules/custom.hpp"
|
||||||
|
|
||||||
waybar::modules::Custom::Custom(std::string name, Json::Value config)
|
waybar::modules::Custom::Custom(const std::string& name,
|
||||||
: ALabel(std::move(config)), name_(std::move(name))
|
const Json::Value& config)
|
||||||
|
: ALabel(config), name_(name)
|
||||||
{
|
{
|
||||||
if (!config_["exec"]) {
|
if (!config_["exec"]) {
|
||||||
throw std::runtime_error(name_ + " has no exec path.");
|
throw std::runtime_error(name_ + " has no exec path.");
|
||||||
}
|
}
|
||||||
|
worker();
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::Custom::worker()
|
||||||
|
{
|
||||||
uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 30;
|
uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 30;
|
||||||
thread_ = [this, interval] {
|
thread_ = [this, interval] {
|
||||||
bool can_update = true;
|
bool can_update = true;
|
||||||
|
@ -16,11 +22,10 @@ waybar::modules::Custom::Custom(std::string name, Json::Value config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (can_update) {
|
if (can_update) {
|
||||||
thread_.emit();
|
dp.emit();
|
||||||
}
|
}
|
||||||
thread_.sleep_for(chrono::seconds(interval));
|
thread_.sleep_for(chrono::seconds(interval));
|
||||||
};
|
};
|
||||||
thread_.sig_update.connect(sigc::mem_fun(*this, &Custom::update));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::modules::Custom::update() -> void
|
auto waybar::modules::Custom::update() -> void
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
#include "modules/memory.hpp"
|
#include "modules/memory.hpp"
|
||||||
|
|
||||||
waybar::modules::Memory::Memory(Json::Value config)
|
waybar::modules::Memory::Memory(const Json::Value& config)
|
||||||
: ALabel(std::move(config))
|
: ALabel(config)
|
||||||
{
|
{
|
||||||
label_.set_name("memory");
|
label_.set_name("memory");
|
||||||
uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 30;
|
uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 30;
|
||||||
thread_.sig_update.connect(sigc::mem_fun(*this, &Memory::update));
|
|
||||||
thread_ = [this, interval] {
|
thread_ = [this, interval] {
|
||||||
thread_.emit();
|
dp.emit();
|
||||||
thread_.sleep_for(chrono::seconds(interval));
|
thread_.sleep_for(chrono::seconds(interval));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "modules/network.hpp"
|
#include "modules/network.hpp"
|
||||||
|
|
||||||
waybar::modules::Network::Network(Json::Value config)
|
waybar::modules::Network::Network(const Json::Value& config)
|
||||||
: ALabel(std::move(config)), family_(AF_INET),
|
: ALabel(config), family_(AF_INET),
|
||||||
signal_strength_dbm_(0), signal_strength_(0)
|
signal_strength_dbm_(0), signal_strength_(0)
|
||||||
{
|
{
|
||||||
sock_fd_ = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
sock_fd_ = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||||
|
@ -31,8 +31,7 @@ waybar::modules::Network::Network(Json::Value config)
|
||||||
label_.set_name("network");
|
label_.set_name("network");
|
||||||
// Trigger first values
|
// Trigger first values
|
||||||
getInfo();
|
getInfo();
|
||||||
update();
|
dp.emit();
|
||||||
thread_.sig_update.connect(sigc::mem_fun(*this, &Network::update));
|
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
uint64_t len = netlinkResponse(sock_fd_, buf, sizeof(buf),
|
uint64_t len = netlinkResponse(sock_fd_, buf, sizeof(buf),
|
||||||
|
@ -69,7 +68,7 @@ waybar::modules::Network::Network(Json::Value config)
|
||||||
}
|
}
|
||||||
if (need_update) {
|
if (need_update) {
|
||||||
getInfo();
|
getInfo();
|
||||||
thread_.emit();
|
dp.emit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -116,20 +115,18 @@ void waybar::modules::Network::disconnected()
|
||||||
// Based on https://gist.github.com/Yawning/c70d804d4b8ae78cc698
|
// Based on https://gist.github.com/Yawning/c70d804d4b8ae78cc698
|
||||||
int waybar::modules::Network::getExternalInterface()
|
int waybar::modules::Network::getExternalInterface()
|
||||||
{
|
{
|
||||||
|
static const uint32_t route_buffer_size = 8192;
|
||||||
struct nlmsghdr *hdr = nullptr;
|
struct nlmsghdr *hdr = nullptr;
|
||||||
struct rtmsg *rt = nullptr;
|
struct rtmsg *rt = nullptr;
|
||||||
void *resp = nullptr;
|
char resp[route_buffer_size] = {0};
|
||||||
int ifidx = -1;
|
int ifidx = -1;
|
||||||
|
|
||||||
/* Allocate space for the request. */
|
/* Prepare request. */
|
||||||
uint32_t reqlen = NLMSG_SPACE(sizeof(*rt));
|
uint32_t reqlen = NLMSG_SPACE(sizeof(*rt));
|
||||||
void *req = nullptr;
|
char req[reqlen] = {0};
|
||||||
if ((req = calloc(1, reqlen)) == nullptr) {
|
|
||||||
goto out; /* ENOBUFS */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build the RTM_GETROUTE request. */
|
/* Build the RTM_GETROUTE request. */
|
||||||
hdr = static_cast<struct nlmsghdr *>(req);
|
hdr = reinterpret_cast<struct nlmsghdr *>(req);
|
||||||
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*rt));
|
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*rt));
|
||||||
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
|
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
|
||||||
hdr->nlmsg_type = RTM_GETROUTE;
|
hdr->nlmsg_type = RTM_GETROUTE;
|
||||||
|
@ -142,12 +139,6 @@ int waybar::modules::Network::getExternalInterface()
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate space for the response. */
|
|
||||||
static const uint32_t route_buffer_size = 8192;
|
|
||||||
if ((resp = calloc(1, route_buffer_size)) == nullptr) {
|
|
||||||
goto out; /* ENOBUFS */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the response(s).
|
/* Read the response(s).
|
||||||
*
|
*
|
||||||
* WARNING: All the packets generated by the request must be consumed (as in,
|
* WARNING: All the packets generated by the request must be consumed (as in,
|
||||||
|
@ -160,7 +151,7 @@ int waybar::modules::Network::getExternalInterface()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse the response payload into netlink messages. */
|
/* Parse the response payload into netlink messages. */
|
||||||
for (hdr = static_cast<struct nlmsghdr *>(resp); NLMSG_OK(hdr, len);
|
for (hdr = reinterpret_cast<struct nlmsghdr *>(resp); NLMSG_OK(hdr, len);
|
||||||
hdr = NLMSG_NEXT(hdr, len)) {
|
hdr = NLMSG_NEXT(hdr, len)) {
|
||||||
if (hdr->nlmsg_type == NLMSG_DONE) {
|
if (hdr->nlmsg_type == NLMSG_DONE) {
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -241,10 +232,6 @@ int waybar::modules::Network::getExternalInterface()
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (req != nullptr)
|
|
||||||
free(req);
|
|
||||||
if (resp != nullptr)
|
|
||||||
free(resp);
|
|
||||||
return ifidx;
|
return ifidx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,8 +256,9 @@ uint64_t waybar::modules::Network::netlinkResponse(int fd, void *resp,
|
||||||
struct iovec iov = { resp, resplen };
|
struct iovec iov = { resp, resplen };
|
||||||
struct msghdr msg = { &sa, sizeof(sa), &iov, 1, nullptr, 0, 0 };
|
struct msghdr msg = { &sa, sizeof(sa), &iov, 1, nullptr, 0, 0 };
|
||||||
ret = recvmsg(fd, &msg, 0);
|
ret = recvmsg(fd, &msg, 0);
|
||||||
if (msg.msg_flags & MSG_TRUNC)
|
if (msg.msg_flags & MSG_TRUNC) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "modules/pulseaudio.hpp"
|
#include "modules/pulseaudio.hpp"
|
||||||
|
|
||||||
waybar::modules::Pulseaudio::Pulseaudio(Json::Value config)
|
waybar::modules::Pulseaudio::Pulseaudio(const Json::Value& config)
|
||||||
: ALabel(std::move(config)), mainloop_(nullptr), mainloop_api_(nullptr),
|
: ALabel(config), mainloop_(nullptr), mainloop_api_(nullptr),
|
||||||
context_(nullptr), sink_idx_(0), volume_(0), muted_(false)
|
context_(nullptr), sink_idx_(0), volume_(0), muted_(false)
|
||||||
{
|
{
|
||||||
label_.set_name("pulseaudio");
|
label_.set_name("pulseaudio");
|
||||||
|
@ -89,7 +89,7 @@ void waybar::modules::Pulseaudio::sinkInfoCb(pa_context* /*context*/,
|
||||||
pa->volume_ = volume * 100.0f;
|
pa->volume_ = volume * 100.0f;
|
||||||
pa->muted_ = i->mute != 0;
|
pa->muted_ = i->mute != 0;
|
||||||
pa->desc_ = i->description;
|
pa->desc_ = i->description;
|
||||||
Glib::signal_idle().connect_once(sigc::mem_fun(*pa, &Pulseaudio::update));
|
pa->dp.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
|
||||||
#include "modules/sway/ipc/client.hpp"
|
#include "modules/sway/ipc/client.hpp"
|
||||||
#include <cstdio>
|
|
||||||
#include <string>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
|
|
||||||
static const std::string ipc_magic("i3-ipc");
|
waybar::modules::sway::Ipc::Ipc()
|
||||||
static const size_t ipc_header_size = ipc_magic.size() + 8;
|
: fd_(-1), fd_event_(-1)
|
||||||
|
{}
|
||||||
|
|
||||||
std::string getSocketPath() {
|
waybar::modules::sway::Ipc::~Ipc()
|
||||||
|
{
|
||||||
|
close(fd_);
|
||||||
|
close(fd_event_);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string waybar::modules::sway::Ipc::getSocketPath() const
|
||||||
|
{
|
||||||
const char *env = getenv("SWAYSOCK");
|
const char *env = getenv("SWAYSOCK");
|
||||||
if (env != nullptr) {
|
if (env != nullptr) {
|
||||||
return std::string(env);
|
return std::string(env);
|
||||||
|
@ -33,31 +36,41 @@ std::string getSocketPath() {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipcOpenSocket(const std::string &socketPath) {
|
int waybar::modules::sway::Ipc::open(const std::string& socketPath) const
|
||||||
|
{
|
||||||
struct sockaddr_un addr = {0};
|
struct sockaddr_un addr = {0};
|
||||||
int socketfd;
|
int fd = -1;
|
||||||
if ((socketfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||||
throw std::runtime_error("Unable to open Unix socket");
|
throw std::runtime_error("Unable to open Unix socket");
|
||||||
}
|
}
|
||||||
addr.sun_family = AF_UNIX;
|
addr.sun_family = AF_UNIX;
|
||||||
strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
|
strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
|
||||||
addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
|
addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
|
||||||
int l = sizeof(struct sockaddr_un);
|
int l = sizeof(struct sockaddr_un);
|
||||||
if (connect(socketfd, reinterpret_cast<struct sockaddr *>(&addr), l) == -1) {
|
if (::connect(fd, reinterpret_cast<struct sockaddr *>(&addr), l) == -1) {
|
||||||
throw std::runtime_error("Unable to connect to " + socketPath);
|
throw std::runtime_error("Unable to connect to " + socketPath);
|
||||||
}
|
}
|
||||||
return socketfd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ipc_response ipcRecvResponse(int socketfd) {
|
void waybar::modules::sway::Ipc::connect()
|
||||||
|
{
|
||||||
|
const std::string& socketPath = getSocketPath();
|
||||||
|
fd_ = open(socketPath);
|
||||||
|
fd_event_ = open(socketPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct waybar::modules::sway::Ipc::ipc_response
|
||||||
|
waybar::modules::sway::Ipc::recv(int fd) const
|
||||||
|
{
|
||||||
std::string header;
|
std::string header;
|
||||||
header.reserve(ipc_header_size);
|
header.reserve(ipc_header_size_);
|
||||||
auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic.size());
|
auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic_.size());
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
|
|
||||||
while (total < ipc_header_size) {
|
while (total < ipc_header_size_) {
|
||||||
ssize_t res =
|
ssize_t res =
|
||||||
::recv(socketfd, header.data() + total, ipc_header_size - total, 0);
|
::recv(fd, header.data() + total, ipc_header_size_ - total, 0);
|
||||||
if (res <= 0) {
|
if (res <= 0) {
|
||||||
throw std::runtime_error("Unable to receive IPC response");
|
throw std::runtime_error("Unable to receive IPC response");
|
||||||
}
|
}
|
||||||
|
@ -66,32 +79,56 @@ struct ipc_response ipcRecvResponse(int socketfd) {
|
||||||
|
|
||||||
total = 0;
|
total = 0;
|
||||||
std::string payload;
|
std::string payload;
|
||||||
payload.reserve(data32[0]);
|
payload.reserve(data32[0] + 1);
|
||||||
while (total < data32[0]) {
|
while (total < data32[0]) {
|
||||||
ssize_t res =
|
ssize_t res =
|
||||||
::recv(socketfd, payload.data() + total, data32[0] - total, 0);
|
::recv(fd, payload.data() + total, data32[0] - total, 0);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
throw std::runtime_error("Unable to receive IPC response");
|
throw std::runtime_error("Unable to receive IPC response");
|
||||||
}
|
}
|
||||||
total += res;
|
total += res;
|
||||||
}
|
}
|
||||||
|
payload[data32[0]] = 0;
|
||||||
return { data32[0], data32[1], &payload.front() };
|
return { data32[0], data32[1], &payload.front() };
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ipc_response ipcSingleCommand(int socketfd, uint32_t type,
|
struct waybar::modules::sway::Ipc::ipc_response
|
||||||
const std::string& payload) {
|
waybar::modules::sway::Ipc::send(int fd, uint32_t type,
|
||||||
|
const std::string& payload) const
|
||||||
|
{
|
||||||
std::string header;
|
std::string header;
|
||||||
header.reserve(ipc_header_size);
|
header.reserve(ipc_header_size_);
|
||||||
auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic.size());
|
auto data32 = reinterpret_cast<uint32_t *>(header.data() + ipc_magic_.size());
|
||||||
memcpy(header.data(), ipc_magic.c_str(), ipc_magic.size());
|
memcpy(header.data(), ipc_magic_.c_str(), ipc_magic_.size());
|
||||||
data32[0] = payload.size();
|
data32[0] = payload.size();
|
||||||
data32[1] = type;
|
data32[1] = type;
|
||||||
|
|
||||||
if (send(socketfd, header.data(), ipc_header_size, 0) == -1) {
|
if (::send(fd, header.data(), ipc_header_size_, 0) == -1) {
|
||||||
throw std::runtime_error("Unable to send IPC header");
|
throw std::runtime_error("Unable to send IPC header");
|
||||||
}
|
}
|
||||||
if (send(socketfd, payload.c_str(), payload.size(), 0) == -1) {
|
if (::send(fd, payload.c_str(), payload.size(), 0) == -1) {
|
||||||
throw std::runtime_error("Unable to send IPC payload");
|
throw std::runtime_error("Unable to send IPC payload");
|
||||||
}
|
}
|
||||||
return ipcRecvResponse(socketfd);
|
return recv(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct waybar::modules::sway::Ipc::ipc_response
|
||||||
|
waybar::modules::sway::Ipc::sendCmd(uint32_t type,
|
||||||
|
const std::string& payload) const
|
||||||
|
{
|
||||||
|
return send(fd_, type, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::sway::Ipc::subscribe(const std::string& payload) const
|
||||||
|
{
|
||||||
|
auto res = send(fd_event_, IPC_SUBSCRIBE, payload);
|
||||||
|
if (res.payload != "{\"success\": true}") {
|
||||||
|
throw std::runtime_error("Unable to subscribe ipc event");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct waybar::modules::sway::Ipc::ipc_response
|
||||||
|
waybar::modules::sway::Ipc::handleEvent() const
|
||||||
|
{
|
||||||
|
return recv(fd_event_);
|
||||||
|
}
|
|
@ -1,24 +1,26 @@
|
||||||
#include "modules/sway/window.hpp"
|
#include "modules/sway/window.hpp"
|
||||||
#include "modules/sway/ipc/client.hpp"
|
|
||||||
|
|
||||||
waybar::modules::sway::Window::Window(Bar &bar, Json::Value config)
|
waybar::modules::sway::Window::Window(Bar &bar, const Json::Value& config)
|
||||||
: ALabel(std::move(config)), bar_(bar)
|
: ALabel(config), bar_(bar)
|
||||||
{
|
{
|
||||||
label_.set_name("window");
|
label_.set_name("window");
|
||||||
std::string socketPath = getSocketPath();
|
ipc_.connect();
|
||||||
ipcfd_ = ipcOpenSocket(socketPath);
|
ipc_.subscribe("[ \"window\" ]");
|
||||||
ipc_eventfd_ = ipcOpenSocket(socketPath);
|
|
||||||
ipcSingleCommand(ipc_eventfd_, IPC_SUBSCRIBE, "[ \"window\" ]");
|
|
||||||
getFocusedWindow();
|
getFocusedWindow();
|
||||||
thread_.sig_update.connect(sigc::mem_fun(*this, &Window::update));
|
// Launch worker
|
||||||
|
worker();
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::sway::Window::worker()
|
||||||
|
{
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
try {
|
try {
|
||||||
auto res = ipcRecvResponse(ipc_eventfd_);
|
auto res = ipc_.handleEvent();
|
||||||
auto parsed = parser_.parse(res.payload);
|
auto parsed = parser_.parse(res.payload);
|
||||||
if ((parsed["change"] == "focus" || parsed["change"] == "title")
|
if ((parsed["change"] == "focus" || parsed["change"] == "title")
|
||||||
&& parsed["container"]["focused"].asBool()) {
|
&& parsed["container"]["focused"].asBool()) {
|
||||||
window_ = parsed["container"]["name"].asString();
|
window_ = parsed["container"]["name"].asString();
|
||||||
thread_.emit();
|
dp.emit();
|
||||||
}
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
|
@ -26,12 +28,6 @@ waybar::modules::sway::Window::Window(Bar &bar, Json::Value config)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
waybar::modules::sway::Window::~Window()
|
|
||||||
{
|
|
||||||
close(ipcfd_);
|
|
||||||
close(ipc_eventfd_);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto waybar::modules::sway::Window::update() -> void
|
auto waybar::modules::sway::Window::update() -> void
|
||||||
{
|
{
|
||||||
label_.set_text(window_);
|
label_.set_text(window_);
|
||||||
|
@ -55,7 +51,7 @@ std::string waybar::modules::sway::Window::getFocusedNode(Json::Value nodes)
|
||||||
void waybar::modules::sway::Window::getFocusedWindow()
|
void waybar::modules::sway::Window::getFocusedWindow()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
auto res = ipcSingleCommand(ipcfd_, IPC_GET_TREE, "");
|
auto res = ipc_.sendCmd(IPC_GET_TREE);
|
||||||
auto parsed = parser_.parse(res.payload);
|
auto parsed = parser_.parse(res.payload);
|
||||||
window_ = getFocusedNode(parsed["nodes"]);
|
window_ = getFocusedNode(parsed["nodes"]);
|
||||||
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Window::update));
|
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Window::update));
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
#include "modules/sway/workspaces.hpp"
|
#include "modules/sway/workspaces.hpp"
|
||||||
#include "modules/sway/ipc/client.hpp"
|
|
||||||
|
|
||||||
waybar::modules::sway::Workspaces::Workspaces(Bar &bar, Json::Value config)
|
waybar::modules::sway::Workspaces::Workspaces(Bar& bar,
|
||||||
: bar_(bar), config_(std::move(config)), scrolling_(false)
|
const Json::Value& config)
|
||||||
|
: bar_(bar), config_(config), scrolling_(false)
|
||||||
{
|
{
|
||||||
box_.set_name("workspaces");
|
box_.set_name("workspaces");
|
||||||
std::string socketPath = getSocketPath();
|
ipc_.connect();
|
||||||
ipcfd_ = ipcOpenSocket(socketPath);
|
ipc_.subscribe("[ \"workspace\" ]");
|
||||||
ipc_eventfd_ = ipcOpenSocket(socketPath);
|
// Launch worker
|
||||||
ipcSingleCommand(ipc_eventfd_, IPC_SUBSCRIBE, "[ \"workspace\" ]");
|
worker();
|
||||||
thread_.sig_update.connect(sigc::mem_fun(*this, &Workspaces::update));
|
}
|
||||||
|
|
||||||
|
void waybar::modules::sway::Workspaces::worker()
|
||||||
|
{
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
try {
|
try {
|
||||||
// Wait for the name of the output
|
// Wait for the name of the output
|
||||||
|
@ -18,28 +21,24 @@ waybar::modules::sway::Workspaces::Workspaces(Bar &bar, Json::Value config)
|
||||||
thread_.sleep_for(chrono::milliseconds(150));
|
thread_.sleep_for(chrono::milliseconds(150));
|
||||||
}
|
}
|
||||||
} else if (!workspaces_.empty()) {
|
} else if (!workspaces_.empty()) {
|
||||||
ipcRecvResponse(ipc_eventfd_);
|
ipc_.handleEvent();
|
||||||
}
|
}
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
{
|
||||||
auto res = ipcSingleCommand(ipcfd_, IPC_GET_WORKSPACES, "");
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
workspaces_ = parser_.parse(res.payload);
|
auto res = ipc_.sendCmd(IPC_GET_WORKSPACES);
|
||||||
thread_.emit();
|
workspaces_ = parser_.parse(res.payload);
|
||||||
|
}
|
||||||
|
dp.emit();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
waybar::modules::sway::Workspaces::~Workspaces()
|
|
||||||
{
|
|
||||||
close(ipcfd_);
|
|
||||||
close(ipc_eventfd_);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto waybar::modules::sway::Workspaces::update() -> void
|
auto waybar::modules::sway::Workspaces::update() -> void
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
|
||||||
bool needReorder = false;
|
bool needReorder = false;
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
for (auto it = buttons_.begin(); it != buttons_.end();) {
|
for (auto it = buttons_.begin(); it != buttons_.end();) {
|
||||||
auto ws = std::find_if(workspaces_.begin(), workspaces_.end(),
|
auto ws = std::find_if(workspaces_.begin(), workspaces_.end(),
|
||||||
[it](auto node) -> bool { return node["num"].asInt() == it->first; });
|
[it](auto node) -> bool { return node["num"].asInt() == it->first; });
|
||||||
|
@ -101,7 +100,7 @@ void waybar::modules::sway::Workspaces::addWorkspace(Json::Value node)
|
||||||
try {
|
try {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
auto cmd = fmt::format("workspace \"{}\"", pair.first->first);
|
auto cmd = fmt::format("workspace \"{}\"", pair.first->first);
|
||||||
ipcSingleCommand(ipcfd_, IPC_COMMAND, cmd);
|
ipc_.sendCmd(IPC_COMMAND, cmd);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -144,11 +143,13 @@ bool waybar::modules::sway::Workspaces::handleScroll(GdkEventScroll *e)
|
||||||
scrolling_ = true;
|
scrolling_ = true;
|
||||||
int id = -1;
|
int id = -1;
|
||||||
uint16_t idx = 0;
|
uint16_t idx = 0;
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
{
|
||||||
for (; idx < workspaces_.size(); idx += 1) {
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
if (workspaces_[idx]["focused"].asBool()) {
|
for (; idx < workspaces_.size(); idx += 1) {
|
||||||
id = workspaces_[idx]["num"].asInt();
|
if (workspaces_[idx]["focused"].asBool()) {
|
||||||
break;
|
id = workspaces_[idx]["num"].asInt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (id == -1) {
|
if (id == -1) {
|
||||||
|
@ -171,12 +172,15 @@ bool waybar::modules::sway::Workspaces::handleScroll(GdkEventScroll *e)
|
||||||
id = getPrevWorkspace();
|
id = getPrevWorkspace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (id == workspaces_[idx]["num"].asInt()) {
|
{
|
||||||
scrolling_ = false;
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
return false;
|
if (id == workspaces_[idx]["num"].asInt()) {
|
||||||
|
scrolling_ = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"", id));
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(150));
|
||||||
}
|
}
|
||||||
ipcSingleCommand(ipcfd_, IPC_COMMAND, fmt::format("workspace \"{}\"", id));
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(150));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue