|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include <fmt/format.h> |
| 4 | +#include <gtkmm/button.h> |
| 5 | +#include <gtkmm/image.h> |
| 6 | +#include <gtkmm/label.h> |
| 7 | + |
| 8 | +#include <map> |
| 9 | +#include <memory> |
| 10 | +#include <vector> |
| 11 | + |
| 12 | +#include "AModule.hpp" |
| 13 | +#include "bar.hpp" |
| 14 | +#include "ext-workspace-v1-client-protocol.h" |
| 15 | + |
| 16 | +namespace waybar::modules::ext { |
| 17 | + |
| 18 | +class WorkspaceGroup; |
| 19 | +class Workspace; |
| 20 | + |
| 21 | +class WorkspaceManager final : public AModule { |
| 22 | + public: |
| 23 | + WorkspaceManager(const std::string &id, const waybar::Bar &bar, const Json::Value &config); |
| 24 | + ~WorkspaceManager() override; |
| 25 | + void register_manager(wl_registry *registry, uint32_t name, uint32_t version); |
| 26 | + void remove_workspace_group(uint32_t id); |
| 27 | + void remove_workspace(uint32_t id); |
| 28 | + void set_needs_sorting() { needs_sorting_ = true; } |
| 29 | + |
| 30 | + // wl events |
| 31 | + void handle_workspace_group(ext_workspace_group_handle_v1 *handle); |
| 32 | + void handle_workspace(ext_workspace_handle_v1 *handle); |
| 33 | + void handle_done(); |
| 34 | + void handle_finished(); |
| 35 | + |
| 36 | + // wl requests |
| 37 | + void commit() const; |
| 38 | + |
| 39 | + private: |
| 40 | + void update() override; |
| 41 | + bool has_button(const Gtk::Button *button); |
| 42 | + void sort_workspaces(); |
| 43 | + void clear_buttons(); |
| 44 | + void update_buttons(); |
| 45 | + |
| 46 | + static uint32_t group_global_id; |
| 47 | + static uint32_t workspace_global_id; |
| 48 | + uint32_t workspace_name = 0; |
| 49 | + |
| 50 | + bool sort_by_id_ = false; |
| 51 | + bool sort_by_name_ = true; |
| 52 | + bool sort_by_coordinates_ = false; |
| 53 | + bool all_outputs_ = false; |
| 54 | + |
| 55 | + const waybar::Bar &bar_; |
| 56 | + Gtk::Box box_; |
| 57 | + |
| 58 | + ext_workspace_manager_v1 *ext_manager_ = nullptr; |
| 59 | + std::vector<std::unique_ptr<WorkspaceGroup>> groups_; |
| 60 | + std::vector<std::unique_ptr<Workspace>> workspaces_; |
| 61 | + |
| 62 | + bool needs_sorting_ = false; |
| 63 | +}; |
| 64 | + |
| 65 | +class WorkspaceGroup { |
| 66 | + public: |
| 67 | + WorkspaceGroup(WorkspaceManager &manager, ext_workspace_group_handle_v1 *handle, uint32_t id); |
| 68 | + ~WorkspaceGroup(); |
| 69 | + |
| 70 | + u_int32_t id() const { return id_; } |
| 71 | + bool has_output(const wl_output *output); |
| 72 | + bool has_workspace(const ext_workspace_handle_v1 *workspace); |
| 73 | + |
| 74 | + // wl events |
| 75 | + void handle_capabilities(uint32_t capabilities); |
| 76 | + void handle_output_enter(wl_output *output); |
| 77 | + void handle_output_leave(wl_output *output); |
| 78 | + void handle_workspace_enter(ext_workspace_handle_v1 *handle); |
| 79 | + void handle_workspace_leave(ext_workspace_handle_v1 *handle); |
| 80 | + void handle_removed(); |
| 81 | + |
| 82 | + private: |
| 83 | + WorkspaceManager &workspaces_manager_; |
| 84 | + ext_workspace_group_handle_v1 *ext_handle_; |
| 85 | + uint32_t id_; |
| 86 | + std::vector<wl_output *> outputs_; |
| 87 | + std::vector<ext_workspace_handle_v1 *> workspaces_; |
| 88 | +}; |
| 89 | + |
| 90 | +class Workspace { |
| 91 | + public: |
| 92 | + Workspace(const Json::Value &config, WorkspaceManager &manager, ext_workspace_handle_v1 *handle, |
| 93 | + uint32_t id, const std::string &name); |
| 94 | + ~Workspace(); |
| 95 | + |
| 96 | + ext_workspace_handle_v1 *handle() const { return ext_handle_; } |
| 97 | + u_int32_t id() const { return id_; } |
| 98 | + std::string &workspace_id() { return workspace_id_; } |
| 99 | + std::string &name() { return name_; } |
| 100 | + std::vector<u_int32_t> &coordinates() { return coordinates_; } |
| 101 | + Gtk::Button &button() { return button_; } |
| 102 | + void update(); |
| 103 | + |
| 104 | + // wl events |
| 105 | + void handle_id(const std::string &id); |
| 106 | + void handle_name(const std::string &name); |
| 107 | + void handle_coordinates(const std::vector<uint32_t> &coordinates); |
| 108 | + void handle_state(uint32_t state); |
| 109 | + void handle_capabilities(uint32_t capabilities); |
| 110 | + void handle_removed(); |
| 111 | + |
| 112 | + // gdk events |
| 113 | + bool handle_clicked(const GdkEventButton *button) const; |
| 114 | + |
| 115 | + private: |
| 116 | + bool has_state(uint32_t state) const { return (state_ & state) == state; } |
| 117 | + std::string icon(); |
| 118 | + |
| 119 | + WorkspaceManager &workspace_manager_; |
| 120 | + ext_workspace_handle_v1 *ext_handle_ = nullptr; |
| 121 | + uint32_t id_; |
| 122 | + uint32_t state_ = 0; |
| 123 | + std::string workspace_id_; |
| 124 | + std::string name_; |
| 125 | + std::vector<uint32_t> coordinates_; |
| 126 | + |
| 127 | + bool active_only_ = false; |
| 128 | + bool ignore_hidden_ = true; |
| 129 | + std::string format_; |
| 130 | + bool with_icon_ = false; |
| 131 | + static std::map<std::string, std::string> icon_map_; |
| 132 | + std::string on_click_action_; |
| 133 | + std::string on_click_middle_action_; |
| 134 | + std::string on_click_right_action_; |
| 135 | + |
| 136 | + Gtk::Button button_; |
| 137 | + Gtk::Box content_; |
| 138 | + Gtk::Label label_; |
| 139 | + |
| 140 | + bool needs_updating_ = false; |
| 141 | +}; |
| 142 | + |
| 143 | +} // namespace waybar::modules::ext |
0 commit comments