#include "modules/river/mode.hpp" #include #include #include "client.hpp" namespace waybar::modules::river { static void listen_focused_output(void *data, struct zriver_seat_status_v1 *seat_status, struct wl_output *output) { // Intentionally empty } static void listen_unfocused_output(void *data, struct zriver_seat_status_v1 *seat_status, struct wl_output *output) { // Intentionally empty } static void listen_focused_view(void *data, struct zriver_seat_status_v1 *seat_status, const char *title) { // Intentionally empty } static void listen_mode(void *data, struct zriver_seat_status_v1 *seat_status, const char *mode) { static_cast(data)->handle_mode(mode); } static const zriver_seat_status_v1_listener seat_status_listener_impl = { .focused_output = listen_focused_output, .unfocused_output = listen_unfocused_output, .focused_view = listen_focused_view, .mode = listen_mode, }; static void handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { if (std::strcmp(interface, zriver_status_manager_v1_interface.name) == 0) { version = std::min(version, 3); if (version < ZRIVER_SEAT_STATUS_V1_MODE_SINCE_VERSION) { spdlog::error( "river server does not support the \"mode\" event; the module will be disabled"); return; } static_cast(data)->status_manager_ = static_cast( wl_registry_bind(registry, name, &zriver_status_manager_v1_interface, version)); } else if (std::strcmp(interface, wl_seat_interface.name) == 0) { version = std::min(version, 1); static_cast(data)->seat_ = static_cast( wl_registry_bind(registry, name, &wl_seat_interface, version)); } } static void handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) { // Nobody cares } static const wl_registry_listener registry_listener_impl = {.global = handle_global, .global_remove = handle_global_remove}; Mode::Mode(const std::string &id, const waybar::Bar &bar, const Json::Value &config) : waybar::ALabel(config, "mode", id, "{}"), status_manager_{nullptr}, seat_{nullptr}, bar_(bar), mode_{""}, seat_status_{nullptr} { struct wl_display *display = Client::inst()->wl_display; struct wl_registry *registry = wl_display_get_registry(display); wl_registry_add_listener(registry, ®istry_listener_impl, this); wl_display_roundtrip(display); if (!status_manager_) { spdlog::error("river_status_manager_v1 not advertised"); return; } if (!seat_) { spdlog::error("wl_seat not advertised"); } label_.hide(); ALabel::update(); seat_status_ = zriver_status_manager_v1_get_river_seat_status(status_manager_, seat_); zriver_seat_status_v1_add_listener(seat_status_, &seat_status_listener_impl, this); zriver_status_manager_v1_destroy(status_manager_); } Mode::~Mode() { if (seat_status_) { zriver_seat_status_v1_destroy(seat_status_); } } void Mode::handle_mode(const char *mode) { if (format_.empty()) { label_.hide(); } else { if (!mode_.empty()) { label_.get_style_context()->remove_class(mode_); } label_.get_style_context()->add_class(mode); label_.set_markup(fmt::format(format_, mode)); label_.show(); } mode_ = mode; ALabel::update(); } } /* namespace waybar::modules::river */