feat(swaybar-ipc): add swaybar IPC client
This commit is contained in:
parent
452dcaa5d3
commit
23e5181cac
|
@ -8,6 +8,9 @@
|
||||||
#include <gtkmm/window.h>
|
#include <gtkmm/window.h>
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
|
@ -43,6 +46,12 @@ struct bar_mode {
|
||||||
bool visible;
|
bool visible;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef HAVE_SWAY
|
||||||
|
namespace modules::sway {
|
||||||
|
class BarIpcClient;
|
||||||
|
}
|
||||||
|
#endif // HAVE_SWAY
|
||||||
|
|
||||||
class BarSurface {
|
class BarSurface {
|
||||||
protected:
|
protected:
|
||||||
BarSurface() = default;
|
BarSurface() = default;
|
||||||
|
@ -68,7 +77,7 @@ class Bar {
|
||||||
|
|
||||||
Bar(struct waybar_output *w_output, const Json::Value &);
|
Bar(struct waybar_output *w_output, const Json::Value &);
|
||||||
Bar(const Bar &) = delete;
|
Bar(const Bar &) = delete;
|
||||||
~Bar() = default;
|
~Bar();
|
||||||
|
|
||||||
void setMode(const std::string_view &);
|
void setMode(const std::string_view &);
|
||||||
void setVisible(bool visible);
|
void setVisible(bool visible);
|
||||||
|
@ -82,6 +91,10 @@ class Bar {
|
||||||
bool vertical = false;
|
bool vertical = false;
|
||||||
Gtk::Window window;
|
Gtk::Window window;
|
||||||
|
|
||||||
|
#ifdef HAVE_SWAY
|
||||||
|
std::string bar_id;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onMap(GdkEventAny *);
|
void onMap(GdkEventAny *);
|
||||||
auto setupWidgets() -> void;
|
auto setupWidgets() -> void;
|
||||||
|
@ -102,6 +115,10 @@ class Bar {
|
||||||
std::vector<std::unique_ptr<waybar::AModule>> modules_left_;
|
std::vector<std::unique_ptr<waybar::AModule>> modules_left_;
|
||||||
std::vector<std::unique_ptr<waybar::AModule>> modules_center_;
|
std::vector<std::unique_ptr<waybar::AModule>> modules_center_;
|
||||||
std::vector<std::unique_ptr<waybar::AModule>> modules_right_;
|
std::vector<std::unique_ptr<waybar::AModule>> modules_right_;
|
||||||
|
#ifdef HAVE_SWAY
|
||||||
|
using BarIpcClient = modules::sway::BarIpcClient;
|
||||||
|
std::unique_ptr<BarIpcClient> _ipc_client;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "modules/sway/ipc/client.hpp"
|
||||||
|
#include "util/SafeSignal.hpp"
|
||||||
|
#include "util/json.hpp"
|
||||||
|
|
||||||
|
namespace waybar {
|
||||||
|
|
||||||
|
class Bar;
|
||||||
|
|
||||||
|
namespace modules::sway {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Supported subset of i3/sway IPC barconfig object
|
||||||
|
*/
|
||||||
|
struct swaybar_config {
|
||||||
|
std::string id;
|
||||||
|
std::string mode;
|
||||||
|
std::string hidden_state;
|
||||||
|
std::string position;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* swaybar IPC client
|
||||||
|
*/
|
||||||
|
class BarIpcClient {
|
||||||
|
public:
|
||||||
|
BarIpcClient(waybar::Bar& bar);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onInitialConfig(const struct Ipc::ipc_response& res);
|
||||||
|
void onIpcEvent(const struct Ipc::ipc_response&);
|
||||||
|
void onConfigUpdate(const swaybar_config& config);
|
||||||
|
void onVisibilityUpdate(bool visible_by_modifier);
|
||||||
|
|
||||||
|
Bar& bar_;
|
||||||
|
util::JsonParser parser_;
|
||||||
|
Ipc ipc_;
|
||||||
|
|
||||||
|
swaybar_config bar_config_;
|
||||||
|
|
||||||
|
SafeSignal<bool> signal_visible_;
|
||||||
|
SafeSignal<swaybar_config> signal_config_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace modules::sway
|
||||||
|
} // namespace waybar
|
|
@ -177,6 +177,7 @@ endif
|
||||||
add_project_arguments('-DHAVE_SWAY', language: 'cpp')
|
add_project_arguments('-DHAVE_SWAY', language: 'cpp')
|
||||||
src_files += [
|
src_files += [
|
||||||
'src/modules/sway/ipc/client.cpp',
|
'src/modules/sway/ipc/client.cpp',
|
||||||
|
'src/modules/sway/bar.cpp',
|
||||||
'src/modules/sway/mode.cpp',
|
'src/modules/sway/mode.cpp',
|
||||||
'src/modules/sway/language.cpp',
|
'src/modules/sway/language.cpp',
|
||||||
'src/modules/sway/window.cpp',
|
'src/modules/sway/window.cpp',
|
||||||
|
|
17
src/bar.cpp
17
src/bar.cpp
|
@ -11,6 +11,10 @@
|
||||||
#include "factory.hpp"
|
#include "factory.hpp"
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_SWAY
|
||||||
|
#include "modules/sway/bar.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
static constexpr const char* MIN_HEIGHT_MSG =
|
static constexpr const char* MIN_HEIGHT_MSG =
|
||||||
"Requested height: {} is less than the minimum height: {} required by the modules";
|
"Requested height: {} is less than the minimum height: {} required by the modules";
|
||||||
|
@ -546,6 +550,16 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
||||||
|
|
||||||
window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap));
|
window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap));
|
||||||
|
|
||||||
|
#if HAVE_SWAY
|
||||||
|
if (auto ipc = config["ipc"]; ipc.isBool() && ipc.asBool()) {
|
||||||
|
bar_id = Client::inst()->bar_id;
|
||||||
|
if (auto id = config["id"]; id.isString()) {
|
||||||
|
bar_id = id.asString();
|
||||||
|
}
|
||||||
|
_ipc_client = std::make_unique<BarIpcClient>(*this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
setupWidgets();
|
setupWidgets();
|
||||||
window.show_all();
|
window.show_all();
|
||||||
|
|
||||||
|
@ -560,6 +574,9 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Need to define it here because of forward declared members */
|
||||||
|
waybar::Bar::~Bar() = default;
|
||||||
|
|
||||||
void waybar::Bar::setMode(const std::string_view& mode) {
|
void waybar::Bar::setMode(const std::string_view& mode) {
|
||||||
using namespace std::literals::string_literals;
|
using namespace std::literals::string_literals;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include "modules/sway/bar.hpp"
|
||||||
|
|
||||||
|
#include <fmt/ostream.h>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/sway/ipc/ipc.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::sway {
|
||||||
|
|
||||||
|
BarIpcClient::BarIpcClient(waybar::Bar& bar) : bar_{bar} {
|
||||||
|
{
|
||||||
|
sigc::connection handle =
|
||||||
|
ipc_.signal_cmd.connect(sigc::mem_fun(*this, &BarIpcClient::onInitialConfig));
|
||||||
|
ipc_.sendCmd(IPC_GET_BAR_CONFIG, bar_.bar_id);
|
||||||
|
|
||||||
|
handle.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_config_.connect(sigc::mem_fun(*this, &BarIpcClient::onConfigUpdate));
|
||||||
|
signal_visible_.connect(sigc::mem_fun(*this, &BarIpcClient::onVisibilityUpdate));
|
||||||
|
|
||||||
|
ipc_.subscribe(R"(["bar_state_update", "barconfig_update"])");
|
||||||
|
ipc_.signal_event.connect(sigc::mem_fun(*this, &BarIpcClient::onIpcEvent));
|
||||||
|
// Launch worker
|
||||||
|
ipc_.setWorker([this] {
|
||||||
|
try {
|
||||||
|
ipc_.handleEvent();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::error("BarIpcClient::handleEvent {}", e.what());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
struct swaybar_config parseConfig(const Json::Value& payload) {
|
||||||
|
swaybar_config conf;
|
||||||
|
if (auto id = payload["id"]; id.isString()) {
|
||||||
|
conf.id = id.asString();
|
||||||
|
}
|
||||||
|
if (auto mode = payload["mode"]; mode.isString()) {
|
||||||
|
conf.mode = mode.asString();
|
||||||
|
}
|
||||||
|
if (auto hs = payload["hidden_state"]; hs.isString()) {
|
||||||
|
conf.hidden_state = hs.asString();
|
||||||
|
}
|
||||||
|
if (auto position = payload["position"]; position.isString()) {
|
||||||
|
conf.position = position.asString();
|
||||||
|
}
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BarIpcClient::onInitialConfig(const struct Ipc::ipc_response& res) {
|
||||||
|
try {
|
||||||
|
auto payload = parser_.parse(res.payload);
|
||||||
|
auto config = parseConfig(payload);
|
||||||
|
onConfigUpdate(config);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::error("BarIpcClient::onInitialConfig {}", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BarIpcClient::onIpcEvent(const struct Ipc::ipc_response& res) {
|
||||||
|
try {
|
||||||
|
auto payload = parser_.parse(res.payload);
|
||||||
|
if (auto id = payload["id"]; id.isString() && id.asString() != bar_.bar_id) {
|
||||||
|
spdlog::trace("swaybar ipc: ignore event for {}", id.asString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (payload.isMember("visible_by_modifier")) {
|
||||||
|
// visibility change for hidden bar
|
||||||
|
signal_visible_(payload["visible_by_modifier"].asBool());
|
||||||
|
} else {
|
||||||
|
// configuration update
|
||||||
|
auto config = parseConfig(payload);
|
||||||
|
signal_config_(config);
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::error("BarIpcClient::onEvent {}", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BarIpcClient::onConfigUpdate(const swaybar_config& config) {
|
||||||
|
spdlog::info("config update: {} {} {}", config.id, config.mode, config.position);
|
||||||
|
// TODO: pass config to bars
|
||||||
|
}
|
||||||
|
|
||||||
|
void BarIpcClient::onVisibilityUpdate(bool visible_by_modifier) {
|
||||||
|
spdlog::trace("visiblity update: {}", visible_by_modifier);
|
||||||
|
// TODO: pass visibility to bars
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace waybar::modules::sway
|
Loading…
Reference in New Issue