123 lines
4.3 KiB
C++
123 lines
4.3 KiB
C++
#pragma once
|
|
|
|
#include <json/json.h>
|
|
#include <unistd.h>
|
|
|
|
#include <functional>
|
|
#include <list>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <utility>
|
|
|
|
namespace waybar::modules::wayfire {
|
|
|
|
using EventHandler = std::function<void(const std::string& event)>;
|
|
|
|
struct State {
|
|
/*
|
|
┌───────────┐ ┌───────────┐
|
|
│ output #1 │ │ output #2 │
|
|
└─────┬─────┘ └─────┬─────┘
|
|
└─┐ └─────┐─ ─ ─ ─ ─ ─ ─ ─ ┐
|
|
┌───────┴───────┐ ┌───────┴──────┐ ┌───────┴───────┐
|
|
│ wset #1 │ │ wset #2 │ │ wset #3 │
|
|
│┌────────────┐ │ │┌────────────┐│ │┌────────────┐ │
|
|
││ workspaces │ │ ││ workspaces ││ ││ workspaces │ │
|
|
│└─┬──────────┘ │ │└────────────┘│ │└─┬──────────┘ │
|
|
│ │ ┌─────────┐│ └──────────────┘ │ │ ┌─────────┐│
|
|
│ ├─┤ view #1 ││ │ └─┤ view #3 ││
|
|
│ │ └─────────┘│ │ └─────────┘│
|
|
│ │ ┌─────────┐│ └───────────────┘
|
|
│ └─┤ view #2 ││
|
|
│ └─────────┘│
|
|
└───────────────┘
|
|
*/
|
|
|
|
struct Output {
|
|
size_t id;
|
|
size_t w, h;
|
|
size_t wset_idx;
|
|
};
|
|
|
|
struct Workspace {
|
|
size_t num_views;
|
|
size_t num_sticky_views;
|
|
};
|
|
|
|
struct Wset {
|
|
std::optional<std::reference_wrapper<Output>> output;
|
|
std::vector<Workspace> wss;
|
|
size_t ws_w, ws_h, ws_x, ws_y;
|
|
size_t focused_view_id;
|
|
|
|
auto ws_idx() const { return ws_w * ws_y + ws_x; }
|
|
auto count_ws(const Json::Value& pos) -> Workspace&;
|
|
auto locate_ws(const Json::Value& geo) -> Workspace&;
|
|
auto locate_ws(const Json::Value& geo) const -> const Workspace&;
|
|
};
|
|
|
|
std::unordered_map<std::string, Output> outputs;
|
|
std::unordered_map<size_t, Wset> wsets;
|
|
std::unordered_map<size_t, Json::Value> views;
|
|
std::string focused_output_name;
|
|
size_t maybe_empty_focus_wset_idx = {};
|
|
size_t vswitch_sticky_view_id = {};
|
|
bool new_output_detected = {};
|
|
bool vswitching = {};
|
|
|
|
auto update_view(const Json::Value& view) -> void;
|
|
};
|
|
|
|
struct Sock {
|
|
int fd;
|
|
|
|
Sock(int fd) : fd{fd} {}
|
|
~Sock() { close(fd); }
|
|
Sock(const Sock&) = delete;
|
|
auto operator=(const Sock&) = delete;
|
|
Sock(Sock&& rhs) noexcept {
|
|
fd = rhs.fd;
|
|
rhs.fd = -1;
|
|
}
|
|
auto& operator=(Sock&& rhs) noexcept {
|
|
fd = rhs.fd;
|
|
rhs.fd = -1;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
class IPC {
|
|
static std::weak_ptr<IPC> instance;
|
|
Json::CharReaderBuilder reader_builder;
|
|
Json::StreamWriterBuilder writer_builder;
|
|
std::list<std::pair<std::string, std::reference_wrapper<const EventHandler>>> handlers;
|
|
std::mutex handlers_mutex;
|
|
State state;
|
|
std::mutex state_mutex;
|
|
|
|
IPC() { start(); }
|
|
|
|
static auto connect() -> Sock;
|
|
auto receive(Sock& sock) -> Json::Value;
|
|
auto start() -> void;
|
|
auto root_event_handler(const std::string& event, const Json::Value& data) -> void;
|
|
auto update_state_handler(const std::string& event, const Json::Value& data) -> void;
|
|
|
|
public:
|
|
static auto get_instance() -> std::shared_ptr<IPC>;
|
|
auto send(const std::string& method, Json::Value&& data) -> Json::Value;
|
|
auto register_handler(const std::string& event, const EventHandler& handler) -> void;
|
|
auto unregister_handler(EventHandler& handler) -> void;
|
|
|
|
auto lock_state() -> std::lock_guard<std::mutex> { return std::lock_guard{state_mutex}; }
|
|
auto& get_outputs() const { return state.outputs; }
|
|
auto& get_wsets() const { return state.wsets; }
|
|
auto& get_views() const { return state.views; }
|
|
auto& get_focused_output_name() const { return state.focused_output_name; }
|
|
};
|
|
|
|
} // namespace waybar::modules::wayfire
|