2023-09-02 20:22:26 +00:00
|
|
|
#pragma once
|
|
|
|
|
2023-06-27 23:52:01 +00:00
|
|
|
#include <gtkmm/button.h>
|
|
|
|
#include <gtkmm/label.h>
|
2023-09-22 21:18:02 +00:00
|
|
|
#include <json/value.h>
|
2023-07-03 22:24:34 +00:00
|
|
|
|
2023-09-22 19:37:26 +00:00
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdint>
|
2023-09-02 20:22:26 +00:00
|
|
|
#include <map>
|
2023-07-03 22:17:26 +00:00
|
|
|
#include <memory>
|
2023-09-22 19:37:26 +00:00
|
|
|
#include <optional>
|
2023-10-11 13:59:33 +00:00
|
|
|
#include <regex>
|
2023-09-02 20:22:26 +00:00
|
|
|
#include <string>
|
2023-10-16 22:07:00 +00:00
|
|
|
#include <variant>
|
2023-09-02 20:22:26 +00:00
|
|
|
#include <vector>
|
2023-06-27 23:52:01 +00:00
|
|
|
|
|
|
|
#include "AModule.hpp"
|
|
|
|
#include "bar.hpp"
|
|
|
|
#include "modules/hyprland/backend.hpp"
|
2023-09-09 14:32:55 +00:00
|
|
|
#include "util/enum.hpp"
|
2023-10-09 16:53:00 +00:00
|
|
|
#include "util/regex_collection.hpp"
|
2023-06-27 23:52:01 +00:00
|
|
|
|
2023-09-22 19:37:26 +00:00
|
|
|
using WindowAddress = std::string;
|
2023-10-09 16:53:00 +00:00
|
|
|
|
2023-06-27 23:52:01 +00:00
|
|
|
namespace waybar::modules::hyprland {
|
|
|
|
|
2023-08-10 17:40:14 +00:00
|
|
|
class Workspaces;
|
|
|
|
|
2023-10-21 16:15:22 +00:00
|
|
|
class WindowCreationPayload {
|
2023-10-16 22:07:00 +00:00
|
|
|
public:
|
2023-10-21 16:15:22 +00:00
|
|
|
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
|
|
|
|
std::string window_repr);
|
|
|
|
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
|
|
|
|
std::string window_class, std::string window_title);
|
|
|
|
WindowCreationPayload(Json::Value const& client_data);
|
2023-10-16 22:07:00 +00:00
|
|
|
|
|
|
|
int increment_time_spent_uncreated();
|
|
|
|
bool is_empty(Workspaces& workspace_manager);
|
|
|
|
bool repr_is_ready() const { return std::holds_alternative<Repr>(window_); }
|
|
|
|
std::string repr(Workspaces& workspace_manager);
|
|
|
|
|
|
|
|
std::string workspace_name() const { return workspace_name_; }
|
|
|
|
WindowAddress addr() const { return window_address_; }
|
|
|
|
|
2023-10-18 22:04:09 +00:00
|
|
|
void move_to_worksace(std::string& new_workspace_name);
|
|
|
|
|
2023-10-16 22:07:00 +00:00
|
|
|
private:
|
|
|
|
void clear_addr();
|
2023-10-16 23:48:52 +00:00
|
|
|
void clear_workspace_name();
|
2023-10-16 22:07:00 +00:00
|
|
|
|
|
|
|
using Repr = std::string;
|
|
|
|
using ClassAndTitle = std::pair<std::string, std::string>;
|
|
|
|
std::variant<Repr, ClassAndTitle> window_;
|
|
|
|
|
|
|
|
WindowAddress window_address_;
|
|
|
|
std::string workspace_name_;
|
2023-10-21 14:52:23 +00:00
|
|
|
|
2023-10-16 22:07:00 +00:00
|
|
|
int time_spent_uncreated_ = 0;
|
|
|
|
};
|
|
|
|
|
2023-06-27 23:52:01 +00:00
|
|
|
class Workspace {
|
|
|
|
public:
|
2023-09-22 19:37:26 +00:00
|
|
|
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager,
|
2023-10-21 14:52:23 +00:00
|
|
|
const Json::Value& clients_data = Json::Value::nullRef);
|
2023-06-30 21:18:57 +00:00
|
|
|
std::string& select_icon(std::map<std::string, std::string>& icons_map);
|
2023-06-27 23:52:01 +00:00
|
|
|
Gtk::Button& button() { return button_; };
|
|
|
|
|
2023-07-15 17:44:57 +00:00
|
|
|
int id() const { return id_; };
|
|
|
|
std::string name() const { return name_; };
|
2023-07-16 01:20:30 +00:00
|
|
|
std::string output() const { return output_; };
|
2023-07-23 16:53:32 +00:00
|
|
|
bool active() const { return active_; };
|
2023-07-15 17:44:57 +00:00
|
|
|
bool is_special() const { return is_special_; };
|
2023-07-23 16:53:32 +00:00
|
|
|
bool is_persistent() const { return is_persistent_; };
|
2023-08-10 17:40:14 +00:00
|
|
|
bool is_visible() const { return is_visible_; };
|
2023-07-23 16:53:32 +00:00
|
|
|
bool is_empty() const { return windows_ == 0; };
|
2023-08-23 17:18:35 +00:00
|
|
|
bool is_urgent() const { return is_urgent_; };
|
2023-07-15 17:44:57 +00:00
|
|
|
|
2023-10-21 14:52:23 +00:00
|
|
|
bool handle_clicked(GdkEventButton* bt) const;
|
2023-07-16 01:20:30 +00:00
|
|
|
void set_active(bool value = true) { active_ = value; };
|
2023-07-23 16:53:32 +00:00
|
|
|
void set_persistent(bool value = true) { is_persistent_ = value; };
|
2023-08-23 17:18:35 +00:00
|
|
|
void set_urgent(bool value = true) { is_urgent_ = value; };
|
2023-08-10 17:40:14 +00:00
|
|
|
void set_visible(bool value = true) { is_visible_ = value; };
|
2023-07-23 16:53:32 +00:00
|
|
|
void set_windows(uint value) { windows_ = value; };
|
2023-10-21 14:52:23 +00:00
|
|
|
void set_name(std::string const& value) { name_ = value; };
|
|
|
|
bool contains_window(WindowAddress const& addr) const { return window_map_.contains(addr); }
|
2023-10-21 16:15:22 +00:00
|
|
|
void insert_window(WindowCreationPayload create_window_paylod);
|
2023-10-21 14:52:23 +00:00
|
|
|
std::string remove_window(WindowAddress const& addr);
|
2023-09-22 19:37:26 +00:00
|
|
|
void initialize_window_map(const Json::Value& clients_data);
|
|
|
|
|
2023-10-21 16:15:22 +00:00
|
|
|
bool on_window_opened(WindowCreationPayload const& create_window_paylod);
|
2023-10-21 17:33:55 +00:00
|
|
|
std::optional<std::string> close_window(WindowAddress const& addr);
|
2023-07-15 17:44:57 +00:00
|
|
|
|
2023-06-30 21:18:57 +00:00
|
|
|
void update(const std::string& format, const std::string& icon);
|
2023-06-27 23:52:01 +00:00
|
|
|
|
|
|
|
private:
|
2023-08-10 17:40:14 +00:00
|
|
|
Workspaces& workspace_manager_;
|
|
|
|
|
2023-06-27 23:52:01 +00:00
|
|
|
int id_;
|
2023-07-15 17:44:57 +00:00
|
|
|
std::string name_;
|
2023-07-16 01:20:30 +00:00
|
|
|
std::string output_;
|
2023-07-23 16:53:32 +00:00
|
|
|
uint windows_;
|
|
|
|
bool active_ = false;
|
|
|
|
bool is_special_ = false;
|
|
|
|
bool is_persistent_ = false;
|
2023-08-23 17:18:35 +00:00
|
|
|
bool is_urgent_ = false;
|
2023-08-10 17:40:14 +00:00
|
|
|
bool is_visible_ = false;
|
2023-06-27 23:52:01 +00:00
|
|
|
|
2023-09-22 21:18:02 +00:00
|
|
|
std::map<WindowAddress, std::string> window_map_;
|
2023-09-22 19:37:26 +00:00
|
|
|
|
2023-06-27 23:52:01 +00:00
|
|
|
Gtk::Button button_;
|
|
|
|
Gtk::Box content_;
|
|
|
|
Gtk::Label label_;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Workspaces : public AModule, public EventHandler {
|
|
|
|
public:
|
|
|
|
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
|
2023-07-16 12:47:14 +00:00
|
|
|
~Workspaces() override;
|
2023-06-27 23:52:01 +00:00
|
|
|
void update() override;
|
|
|
|
void init();
|
|
|
|
|
2023-07-15 17:44:57 +00:00
|
|
|
auto all_outputs() const -> bool { return all_outputs_; }
|
|
|
|
auto show_special() const -> bool { return show_special_; }
|
2023-08-10 17:40:14 +00:00
|
|
|
auto active_only() const -> bool { return active_only_; }
|
2023-07-15 17:44:57 +00:00
|
|
|
|
|
|
|
auto get_bar_output() const -> std::string { return bar_.output->name; }
|
|
|
|
|
2023-10-09 16:53:00 +00:00
|
|
|
std::string get_rewrite(std::string window_class, std::string window_title);
|
2023-09-22 21:18:02 +00:00
|
|
|
std::string& get_window_separator() { return format_window_separator_; }
|
2023-10-21 17:33:55 +00:00
|
|
|
bool is_workspace_ignored(std::string const& workspace_name);
|
2023-09-22 21:18:02 +00:00
|
|
|
|
2023-10-11 14:40:49 +00:00
|
|
|
bool window_rewrite_config_uses_title() const { return any_window_rewrite_rule_uses_title_; }
|
|
|
|
|
2023-06-27 23:52:01 +00:00
|
|
|
private:
|
2023-10-21 14:52:23 +00:00
|
|
|
void onEvent(const std::string& e) override;
|
2023-07-23 16:53:32 +00:00
|
|
|
void update_window_count();
|
2023-06-30 21:18:57 +00:00
|
|
|
void sort_workspaces();
|
2023-10-21 14:52:23 +00:00
|
|
|
void create_workspace(Json::Value const& workspace_data,
|
|
|
|
Json::Value const& clients_data = Json::Value::nullRef);
|
|
|
|
void remove_workspace(std::string const& name);
|
|
|
|
void set_urgent_workspace(std::string const& windowaddress);
|
2023-09-09 03:24:05 +00:00
|
|
|
void parse_config(const Json::Value& config);
|
|
|
|
void register_ipc();
|
2023-07-15 17:44:57 +00:00
|
|
|
|
2023-10-21 17:33:55 +00:00
|
|
|
// workspace events
|
|
|
|
void on_workspace_activated(std::string const& payload);
|
|
|
|
void on_workspace_destroyed(std::string const& payload);
|
|
|
|
void on_workspace_created(std::string const& payload);
|
|
|
|
void on_workspace_moved(std::string const& payload);
|
|
|
|
void on_workspace_renamed(std::string const& payload);
|
|
|
|
|
|
|
|
// monitor events
|
|
|
|
void on_monitor_focused(std::string const& payload);
|
|
|
|
|
|
|
|
// window events
|
2023-10-21 14:52:23 +00:00
|
|
|
void on_window_opened(std::string const& payload);
|
|
|
|
void on_window_closed(std::string const& payload);
|
|
|
|
void on_window_moved(std::string const& payload);
|
2023-09-22 19:37:26 +00:00
|
|
|
|
2023-10-21 17:33:55 +00:00
|
|
|
void on_window_title_event(std::string const& payload);
|
|
|
|
|
2023-10-21 14:52:23 +00:00
|
|
|
int window_rewrite_priority_function(std::string const& window_rule);
|
2023-10-09 17:42:53 +00:00
|
|
|
|
2023-07-15 17:44:57 +00:00
|
|
|
bool all_outputs_ = false;
|
|
|
|
bool show_special_ = false;
|
2023-08-10 17:40:14 +00:00
|
|
|
bool active_only_ = false;
|
2023-09-09 16:18:12 +00:00
|
|
|
|
2023-09-09 17:02:56 +00:00
|
|
|
enum class SORT_METHOD { ID, NAME, NUMBER, DEFAULT };
|
2023-09-09 16:18:12 +00:00
|
|
|
util::EnumParser<SORT_METHOD> enum_parser_;
|
|
|
|
SORT_METHOD sort_by_ = SORT_METHOD::DEFAULT;
|
|
|
|
std::map<std::string, SORT_METHOD> sort_map_ = {{"ID", SORT_METHOD::ID},
|
|
|
|
{"NAME", SORT_METHOD::NAME},
|
|
|
|
{"NUMBER", SORT_METHOD::NUMBER},
|
|
|
|
{"DEFAULT", SORT_METHOD::DEFAULT}};
|
2023-06-27 23:52:01 +00:00
|
|
|
|
2023-07-23 16:53:32 +00:00
|
|
|
void fill_persistent_workspaces();
|
2023-10-20 00:23:00 +00:00
|
|
|
void create_persistent_workspaces();
|
2023-07-23 16:53:32 +00:00
|
|
|
std::vector<std::string> persistent_workspaces_to_create_;
|
|
|
|
bool persistent_created_ = false;
|
|
|
|
|
2023-06-30 21:18:57 +00:00
|
|
|
std::string format_;
|
2023-10-09 16:53:00 +00:00
|
|
|
|
2023-06-30 21:18:57 +00:00
|
|
|
std::map<std::string, std::string> icons_map_;
|
2023-10-09 16:53:00 +00:00
|
|
|
util::RegexCollection window_rewrite_rules_;
|
|
|
|
bool any_window_rewrite_rule_uses_title_ = false;
|
2023-09-22 19:37:26 +00:00
|
|
|
std::string format_window_separator_;
|
2023-10-09 16:53:00 +00:00
|
|
|
|
2023-06-30 21:18:57 +00:00
|
|
|
bool with_icon_;
|
2023-07-23 16:53:32 +00:00
|
|
|
uint64_t monitor_id_;
|
|
|
|
std::string active_workspace_name_;
|
2023-07-03 22:17:26 +00:00
|
|
|
std::vector<std::unique_ptr<Workspace>> workspaces_;
|
2023-07-16 01:43:54 +00:00
|
|
|
std::vector<Json::Value> workspaces_to_create_;
|
2023-07-15 17:44:57 +00:00
|
|
|
std::vector<std::string> workspaces_to_remove_;
|
2023-10-21 16:15:22 +00:00
|
|
|
std::vector<WindowCreationPayload> windows_to_create_;
|
2023-10-11 13:59:33 +00:00
|
|
|
|
|
|
|
std::vector<std::regex> ignore_workspaces_;
|
|
|
|
|
2023-06-27 23:52:01 +00:00
|
|
|
std::mutex mutex_;
|
|
|
|
const Bar& bar_;
|
|
|
|
Gtk::Box box_;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace waybar::modules::hyprland
|