Merge pull request #2592 from zjeffer/hyprland/workspaces
General cleanup in hyprland/workspaces
This commit is contained in:
		
						commit
						f2085fcd92
					
				|  | @ -14,7 +14,7 @@ namespace waybar::modules::hyprland { | |||
| class Window : public waybar::AAppIconLabel, public EventHandler { | ||||
|  public: | ||||
|   Window(const std::string&, const waybar::Bar&, const Json::Value&); | ||||
|   virtual ~Window(); | ||||
|   ~Window() override; | ||||
| 
 | ||||
|   auto update() -> void override; | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,12 +26,13 @@ namespace waybar::modules::hyprland { | |||
| 
 | ||||
| class Workspaces; | ||||
| 
 | ||||
| class CreateWindow { | ||||
| class WindowCreationPayload { | ||||
|  public: | ||||
|   CreateWindow(std::string workspace_name, WindowAddress window_address, std::string window_repr); | ||||
|   CreateWindow(std::string workspace_name, WindowAddress window_address, std::string window_class, | ||||
|                std::string window_title); | ||||
|   CreateWindow(Json::Value& client_data); | ||||
|   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); | ||||
| 
 | ||||
|   int increment_time_spent_uncreated(); | ||||
|   bool is_empty(Workspaces& workspace_manager); | ||||
|  | @ -49,18 +50,18 @@ class CreateWindow { | |||
| 
 | ||||
|   using Repr = std::string; | ||||
|   using ClassAndTitle = std::pair<std::string, std::string>; | ||||
| 
 | ||||
|   std::variant<Repr, ClassAndTitle> window_; | ||||
| 
 | ||||
|   WindowAddress window_address_; | ||||
|   std::string workspace_name_; | ||||
| 
 | ||||
|   int time_spent_uncreated_ = 0; | ||||
| }; | ||||
| 
 | ||||
| class Workspace { | ||||
|  public: | ||||
|   explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager, | ||||
|                      const Json::Value& clients_json = Json::Value::nullRef); | ||||
|                      const Json::Value& clients_data = Json::Value::nullRef); | ||||
|   std::string& select_icon(std::map<std::string, std::string>& icons_map); | ||||
|   Gtk::Button& button() { return button_; }; | ||||
| 
 | ||||
|  | @ -74,21 +75,20 @@ class Workspace { | |||
|   bool is_empty() const { return windows_ == 0; }; | ||||
|   bool is_urgent() const { return is_urgent_; }; | ||||
| 
 | ||||
|   auto handle_clicked(GdkEventButton* bt) -> bool; | ||||
|   bool handle_clicked(GdkEventButton* bt) const; | ||||
|   void set_active(bool value = true) { active_ = value; }; | ||||
|   void set_persistent(bool value = true) { is_persistent_ = value; }; | ||||
|   void set_urgent(bool value = true) { is_urgent_ = value; }; | ||||
|   void set_visible(bool value = true) { is_visible_ = value; }; | ||||
|   void set_windows(uint value) { windows_ = value; }; | ||||
|   void set_name(std::string value) { name_ = value; }; | ||||
|   bool contains_window(WindowAddress addr) const { return window_map_.contains(addr); } | ||||
|   void insert_window(CreateWindow create_window_paylod); | ||||
|   std::string remove_window(WindowAddress addr); | ||||
|   void set_name(std::string const& value) { name_ = value; }; | ||||
|   bool contains_window(WindowAddress const& addr) const { return window_map_.contains(addr); } | ||||
|   void insert_window(WindowCreationPayload create_window_paylod); | ||||
|   std::string remove_window(WindowAddress const& addr); | ||||
|   void initialize_window_map(const Json::Value& clients_data); | ||||
| 
 | ||||
|   bool on_window_opened(CreateWindow create_window_paylod); | ||||
| 
 | ||||
|   std::optional<std::string> on_window_closed(WindowAddress& addr); | ||||
|   bool on_window_opened(WindowCreationPayload const& create_window_paylod); | ||||
|   std::optional<std::string> close_window(WindowAddress const& addr); | ||||
| 
 | ||||
|   void update(const std::string& format, const std::string& icon); | ||||
| 
 | ||||
|  | @ -127,26 +127,39 @@ class Workspaces : public AModule, public EventHandler { | |||
| 
 | ||||
|   std::string get_rewrite(std::string window_class, std::string window_title); | ||||
|   std::string& get_window_separator() { return format_window_separator_; } | ||||
|   bool is_workspace_ignored(std::string& workspace_name); | ||||
|   bool is_workspace_ignored(std::string const& workspace_name); | ||||
| 
 | ||||
|   bool window_rewrite_config_uses_title() const { return any_window_rewrite_rule_uses_title_; } | ||||
| 
 | ||||
|  private: | ||||
|   void onEvent(const std::string&) override; | ||||
|   void onEvent(const std::string& e) override; | ||||
|   void update_window_count(); | ||||
|   void sort_workspaces(); | ||||
|   void create_workspace(Json::Value& workspace_data, | ||||
|                         const Json::Value& clients_data = Json::Value::nullRef); | ||||
|   void remove_workspace(std::string name); | ||||
|   void set_urgent_workspace(std::string windowaddress); | ||||
|   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); | ||||
|   void parse_config(const Json::Value& config); | ||||
|   void register_ipc(); | ||||
| 
 | ||||
|   void on_window_opened(std::string payload); | ||||
|   void on_window_closed(std::string payload); | ||||
|   void on_window_moved(std::string payload); | ||||
|   // 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); | ||||
| 
 | ||||
|   int window_rewrite_priority_function(std::string& window_rule); | ||||
|   // monitor events
 | ||||
|   void on_monitor_focused(std::string const& payload); | ||||
| 
 | ||||
|   // window events
 | ||||
|   void on_window_opened(std::string const& payload); | ||||
|   void on_window_closed(std::string const& payload); | ||||
|   void on_window_moved(std::string const& payload); | ||||
| 
 | ||||
|   void on_window_title_event(std::string const& payload); | ||||
| 
 | ||||
|   int window_rewrite_priority_function(std::string const& window_rule); | ||||
| 
 | ||||
|   bool all_outputs_ = false; | ||||
|   bool show_special_ = false; | ||||
|  | @ -178,7 +191,7 @@ class Workspaces : public AModule, public EventHandler { | |||
|   std::vector<std::unique_ptr<Workspace>> workspaces_; | ||||
|   std::vector<Json::Value> workspaces_to_create_; | ||||
|   std::vector<std::string> workspaces_to_remove_; | ||||
|   std::vector<CreateWindow> windows_to_create_; | ||||
|   std::vector<WindowCreationPayload> windows_to_create_; | ||||
| 
 | ||||
|   std::vector<std::regex> ignore_workspaces_; | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,23 +14,24 @@ | |||
| 
 | ||||
| namespace waybar::modules::hyprland { | ||||
| 
 | ||||
| int Workspaces::window_rewrite_priority_function(std::string &window_rule) { | ||||
| int Workspaces::window_rewrite_priority_function(std::string const &window_rule) { | ||||
|   // Rules that match against title are prioritized
 | ||||
|   // Rules that don't specify if they're matching against either title or class are deprioritized
 | ||||
|   bool has_title = window_rule.find("title") != std::string::npos; | ||||
|   bool has_class = window_rule.find("class") != std::string::npos; | ||||
|   bool const has_title = window_rule.find("title") != std::string::npos; | ||||
|   bool const has_class = window_rule.find("class") != std::string::npos; | ||||
| 
 | ||||
|   if (has_title && has_class) { | ||||
|     any_window_rewrite_rule_uses_title_ = true; | ||||
|     return 3; | ||||
|   } else if (has_title) { | ||||
|   } | ||||
|   if (has_title) { | ||||
|     any_window_rewrite_rule_uses_title_ = true; | ||||
|     return 2; | ||||
|   } else if (has_class) { | ||||
|     return 1; | ||||
|   } else { | ||||
|     return 0; | ||||
|   } | ||||
|   if (has_class) { | ||||
|     return 1; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value &config) | ||||
|  | @ -51,7 +52,7 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value | |||
| } | ||||
| 
 | ||||
| auto Workspaces::parse_config(const Json::Value &config) -> void { | ||||
|   Json::Value config_format = config["format"]; | ||||
|   const Json::Value &config_format = config["format"]; | ||||
| 
 | ||||
|   format_ = config_format.isString() ? config_format.asString() : "{name}"; | ||||
|   with_icon_ = format_.find("{icon}") != std::string::npos; | ||||
|  | @ -109,13 +110,13 @@ auto Workspaces::parse_config(const Json::Value &config) -> void { | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Json::Value format_window_separator = config["format-window-separator"]; | ||||
|   const Json::Value &format_window_separator = config["format-window-separator"]; | ||||
|   format_window_separator_ = | ||||
|       format_window_separator.isString() ? format_window_separator.asString() : " "; | ||||
| 
 | ||||
|   Json::Value window_rewrite = config["window-rewrite"]; | ||||
|   const Json::Value &window_rewrite = config["window-rewrite"]; | ||||
| 
 | ||||
|   Json::Value window_rewrite_default_config = config["window-rewrite-default"]; | ||||
|   const Json::Value &window_rewrite_default_config = config["window-rewrite-default"]; | ||||
|   std::string window_rewrite_default = | ||||
|       window_rewrite_default_config.isString() ? window_rewrite_default_config.asString() : "?"; | ||||
| 
 | ||||
|  | @ -152,13 +153,13 @@ auto Workspaces::register_ipc() -> void { | |||
| } | ||||
| 
 | ||||
| auto Workspaces::update() -> void { | ||||
|   for (std::string workspace_to_remove : workspaces_to_remove_) { | ||||
|   for (const std::string &workspace_to_remove : workspaces_to_remove_) { | ||||
|     remove_workspace(workspace_to_remove); | ||||
|   } | ||||
| 
 | ||||
|   workspaces_to_remove_.clear(); | ||||
| 
 | ||||
|   for (Json::Value &workspace_to_create : workspaces_to_create_) { | ||||
|   for (Json::Value const &workspace_to_create : workspaces_to_create_) { | ||||
|     create_workspace(workspace_to_create); | ||||
|   } | ||||
| 
 | ||||
|  | @ -195,7 +196,7 @@ auto Workspaces::update() -> void { | |||
|   } | ||||
| 
 | ||||
|   bool any_window_created = false; | ||||
|   std::vector<CreateWindow> not_created; | ||||
|   std::vector<WindowCreationPayload> not_created; | ||||
| 
 | ||||
|   for (auto &window_payload : windows_to_create_) { | ||||
|     bool created = false; | ||||
|  | @ -207,7 +208,7 @@ auto Workspaces::update() -> void { | |||
|       } | ||||
|     } | ||||
|     if (!created) { | ||||
|       static const int WINDOW_CREATION_TIMEOUT = 2; | ||||
|       static auto const WINDOW_CREATION_TIMEOUT = 2; | ||||
|       if (window_payload.increment_time_spent_uncreated() < WINDOW_CREATION_TIMEOUT) { | ||||
|         not_created.push_back(window_payload); | ||||
|       } | ||||
|  | @ -224,7 +225,7 @@ auto Workspaces::update() -> void { | |||
|   AModule::update(); | ||||
| } | ||||
| 
 | ||||
| bool isDoubleSpecial(std::string &workspace_name) { | ||||
| bool isDoubleSpecial(std::string const &workspace_name) { | ||||
|   // Hyprland's IPC sometimes reports the creation of workspaces strangely named
 | ||||
|   // `special:special:<some_name>`. This function checks for that and is used
 | ||||
|   // to avoid creating (and then removing) such workspaces.
 | ||||
|  | @ -232,7 +233,7 @@ bool isDoubleSpecial(std::string &workspace_name) { | |||
|   return workspace_name.find("special:special:") != std::string::npos; | ||||
| } | ||||
| 
 | ||||
| bool Workspaces::is_workspace_ignored(std::string &name) { | ||||
| bool Workspaces::is_workspace_ignored(std::string const &name) { | ||||
|   for (auto &rule : ignore_workspaces_) { | ||||
|     if (std::regex_match(name, rule)) { | ||||
|       return true; | ||||
|  | @ -249,13 +250,43 @@ void Workspaces::onEvent(const std::string &ev) { | |||
|   std::string payload = ev.substr(eventName.size() + 2); | ||||
| 
 | ||||
|   if (eventName == "workspace") { | ||||
|     active_workspace_name_ = payload; | ||||
| 
 | ||||
|     on_workspace_activated(payload); | ||||
|   } else if (eventName == "destroyworkspace") { | ||||
|     on_workspace_destroyed(payload); | ||||
|   } else if (eventName == "createworkspace") { | ||||
|     on_workspace_created(payload); | ||||
|   } else if (eventName == "focusedmon") { | ||||
|     on_monitor_focused(payload); | ||||
|   } else if (eventName == "moveworkspace" && !all_outputs()) { | ||||
|     on_workspace_moved(payload); | ||||
|   } else if (eventName == "openwindow") { | ||||
|     on_window_opened(payload); | ||||
|   } else if (eventName == "closewindow") { | ||||
|     on_window_closed(payload); | ||||
|   } else if (eventName == "movewindow") { | ||||
|     on_window_moved(payload); | ||||
|   } else if (eventName == "urgent") { | ||||
|     set_urgent_workspace(payload); | ||||
|   } else if (eventName == "renameworkspace") { | ||||
|     on_workspace_renamed(payload); | ||||
|   } else if (eventName == "windowtitle") { | ||||
|     on_window_title_event(payload); | ||||
|   } | ||||
| 
 | ||||
|   dp.emit(); | ||||
| } | ||||
| 
 | ||||
| void Workspaces::on_workspace_activated(std::string const &payload) { | ||||
|   active_workspace_name_ = payload; | ||||
| } | ||||
| 
 | ||||
| void Workspaces::on_workspace_destroyed(std::string const &payload) { | ||||
|   if (!isDoubleSpecial(payload)) { | ||||
|     workspaces_to_remove_.push_back(payload); | ||||
|   } | ||||
|   } else if (eventName == "createworkspace") { | ||||
| } | ||||
| 
 | ||||
| void Workspaces::on_workspace_created(std::string const &payload) { | ||||
|   const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces"); | ||||
| 
 | ||||
|   if (!is_workspace_ignored(payload)) { | ||||
|  | @ -269,10 +300,9 @@ void Workspaces::onEvent(const std::string &ev) { | |||
|       } | ||||
|     } | ||||
|   } | ||||
|   } else if (eventName == "focusedmon") { | ||||
|     active_workspace_name_ = payload.substr(payload.find(',') + 1); | ||||
| } | ||||
| 
 | ||||
|   } else if (eventName == "moveworkspace" && !all_outputs()) { | ||||
| void Workspaces::on_workspace_moved(std::string const &payload) { | ||||
|   std::string workspace = payload.substr(0, payload.find(',')); | ||||
|   std::string new_output = payload.substr(payload.find(',') + 1); | ||||
|   if (bar_.output->name == new_output) {  // TODO: implement this better
 | ||||
|  | @ -287,18 +317,9 @@ void Workspaces::onEvent(const std::string &ev) { | |||
|   } else { | ||||
|     workspaces_to_remove_.push_back(workspace); | ||||
|   } | ||||
|   } else if (eventName == "openwindow") { | ||||
|     update_window_count(); | ||||
|     on_window_opened(payload); | ||||
|   } else if (eventName == "closewindow") { | ||||
|     update_window_count(); | ||||
|     on_window_closed(payload); | ||||
|   } else if (eventName == "movewindow") { | ||||
|     update_window_count(); | ||||
|     on_window_moved(payload); | ||||
|   } else if (eventName == "urgent") { | ||||
|     set_urgent_workspace(payload); | ||||
|   } else if (eventName == "renameworkspace") { | ||||
| } | ||||
| 
 | ||||
| void Workspaces::on_workspace_renamed(std::string const &payload) { | ||||
|   std::string workspace_id_str = payload.substr(0, payload.find(',')); | ||||
|   int workspace_id = workspace_id_str == "special" ? -99 : std::stoi(workspace_id_str); | ||||
|   std::string new_name = payload.substr(payload.find(',') + 1); | ||||
|  | @ -311,30 +332,14 @@ void Workspaces::onEvent(const std::string &ev) { | |||
|       break; | ||||
|     } | ||||
|   } | ||||
|   } else if (eventName == "windowtitle") { | ||||
|     auto window_workspace = | ||||
|         std::find_if(workspaces_.begin(), workspaces_.end(), | ||||
|                      [payload](auto &workspace) { return workspace->contains_window(payload); }); | ||||
| 
 | ||||
|     if (window_workspace != workspaces_.end()) { | ||||
|       Json::Value clients_data = gIPC->getSocket1JsonReply("clients"); | ||||
|       std::string json_window_address = fmt::format("0x{}", payload); | ||||
| 
 | ||||
|       auto client = std::find_if(clients_data.begin(), clients_data.end(), | ||||
|                                  [json_window_address](auto &client) { | ||||
|                                    return client["address"].asString() == json_window_address; | ||||
|                                  }); | ||||
| 
 | ||||
|       if (!client->empty()) { | ||||
|         (*window_workspace)->insert_window({*client}); | ||||
|       } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|   dp.emit(); | ||||
| void Workspaces::on_monitor_focused(std::string const &payload) { | ||||
|   active_workspace_name_ = payload.substr(payload.find(',') + 1); | ||||
| } | ||||
| 
 | ||||
| void Workspaces::on_window_opened(std::string payload) { | ||||
| void Workspaces::on_window_opened(std::string const &payload) { | ||||
|   update_window_count(); | ||||
|   size_t last_comma_idx = 0; | ||||
|   size_t next_comma_idx = payload.find(','); | ||||
|   std::string window_address = payload.substr(last_comma_idx, next_comma_idx - last_comma_idx); | ||||
|  | @ -351,19 +356,20 @@ void Workspaces::on_window_opened(std::string payload) { | |||
| 
 | ||||
|   std::string window_title = payload.substr(next_comma_idx + 1, payload.length() - next_comma_idx); | ||||
| 
 | ||||
|   windows_to_create_.emplace_back( | ||||
|       CreateWindow(workspace_name, window_address, window_class, window_title)); | ||||
|   windows_to_create_.emplace_back(workspace_name, window_address, window_class, window_title); | ||||
| } | ||||
| 
 | ||||
| void Workspaces::on_window_closed(std::string addr) { | ||||
| void Workspaces::on_window_closed(std::string const &addr) { | ||||
|   update_window_count(); | ||||
|   for (auto &workspace : workspaces_) { | ||||
|     if (workspace->on_window_closed(addr)) { | ||||
|     if (workspace->close_window(addr)) { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void Workspaces::on_window_moved(std::string payload) { | ||||
| void Workspaces::on_window_moved(std::string const &payload) { | ||||
|   update_window_count(); | ||||
|   size_t last_comma_idx = 0; | ||||
|   size_t next_comma_idx = payload.find(','); | ||||
|   std::string window_address = payload.substr(last_comma_idx, next_comma_idx - last_comma_idx); | ||||
|  | @ -384,18 +390,35 @@ void Workspaces::on_window_moved(std::string payload) { | |||
| 
 | ||||
|   // Take the window's representation from the old workspace...
 | ||||
|   for (auto &workspace : workspaces_) { | ||||
|     try { | ||||
|       window_repr = workspace->on_window_closed(window_address).value(); | ||||
|     if (auto window_addr = workspace->close_window(window_address); window_addr != std::nullopt) { | ||||
|       window_repr = window_addr.value(); | ||||
|       break; | ||||
|     } catch (const std::bad_optional_access &e) { | ||||
|       // window was not found in this workspace
 | ||||
|       continue; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // ...and add it to the new workspace
 | ||||
|   if (!window_repr.empty()) { | ||||
|     windows_to_create_.emplace_back(CreateWindow(workspace_name, window_address, window_repr)); | ||||
|     windows_to_create_.emplace_back(workspace_name, window_address, window_repr); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void Workspaces::on_window_title_event(std::string const &payload) { | ||||
|   auto window_workspace = | ||||
|       std::find_if(workspaces_.begin(), workspaces_.end(), | ||||
|                    [payload](auto &workspace) { return workspace->contains_window(payload); }); | ||||
| 
 | ||||
|   if (window_workspace != workspaces_.end()) { | ||||
|     Json::Value clients_data = gIPC->getSocket1JsonReply("clients"); | ||||
|     std::string json_window_address = fmt::format("0x{}", payload); | ||||
| 
 | ||||
|     auto client = | ||||
|         std::find_if(clients_data.begin(), clients_data.end(), [json_window_address](auto &client) { | ||||
|           return client["address"].asString() == json_window_address; | ||||
|         }); | ||||
| 
 | ||||
|     if (!client->empty()) { | ||||
|       (*window_workspace)->insert_window({*client}); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -426,37 +449,35 @@ void Workspace::initialize_window_map(const Json::Value &clients_data) { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| void Workspace::insert_window(CreateWindow create_window_paylod) { | ||||
| void Workspace::insert_window(WindowCreationPayload create_window_paylod) { | ||||
|   if (!create_window_paylod.is_empty(workspace_manager_)) { | ||||
|     window_map_[create_window_paylod.addr()] = create_window_paylod.repr(workspace_manager_); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| std::string Workspace::remove_window(WindowAddress addr) { | ||||
| std::string Workspace::remove_window(WindowAddress const &addr) { | ||||
|   std::string window_repr = window_map_[addr]; | ||||
|   window_map_.erase(addr); | ||||
| 
 | ||||
|   return window_repr; | ||||
| } | ||||
| 
 | ||||
| bool Workspace::on_window_opened(CreateWindow create_window_paylod) { | ||||
| bool Workspace::on_window_opened(WindowCreationPayload const &create_window_paylod) { | ||||
|   if (create_window_paylod.workspace_name() == name()) { | ||||
|     insert_window(create_window_paylod); | ||||
|     return true; | ||||
|   } else { | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
| } | ||||
| 
 | ||||
| std::optional<std::string> Workspace::on_window_closed(WindowAddress &addr) { | ||||
| std::optional<std::string> Workspace::close_window(WindowAddress const &addr) { | ||||
|   if (window_map_.contains(addr)) { | ||||
|     return remove_window(addr); | ||||
|   } else { | ||||
|     return {}; | ||||
|   } | ||||
|   return std::nullopt; | ||||
| } | ||||
| 
 | ||||
| void Workspaces::create_workspace(Json::Value &workspace_data, const Json::Value &clients_data) { | ||||
| void Workspaces::create_workspace(Json::Value const &workspace_data, | ||||
|                                   Json::Value const &clients_data) { | ||||
|   // avoid recreating existing workspaces
 | ||||
|   auto workspace_name = workspace_data["name"].asString(); | ||||
|   auto workspace = std::find_if( | ||||
|  | @ -477,7 +498,7 @@ void Workspaces::create_workspace(Json::Value &workspace_data, const Json::Value | |||
|   new_workspace_button.show_all(); | ||||
| } | ||||
| 
 | ||||
| void Workspaces::remove_workspace(std::string name) { | ||||
| void Workspaces::remove_workspace(std::string const &name) { | ||||
|   auto workspace = | ||||
|       std::find_if(workspaces_.begin(), workspaces_.end(), [&](std::unique_ptr<Workspace> &x) { | ||||
|         return (name.starts_with("special:") && name.substr(8) == x->name()) || name == x->name(); | ||||
|  | @ -816,7 +837,7 @@ std::string &Workspace::select_icon(std::map<std::string, std::string> &icons_ma | |||
|   return name_; | ||||
| } | ||||
| 
 | ||||
| auto Workspace::handle_clicked(GdkEventButton *bt) -> bool { | ||||
| bool Workspace::handle_clicked(GdkEventButton *bt) const { | ||||
|   try { | ||||
|     if (id() > 0) {  // normal or numbered persistent
 | ||||
|       gIPC->getSocket1Reply("dispatch workspace " + std::to_string(id())); | ||||
|  | @ -834,7 +855,7 @@ auto Workspace::handle_clicked(GdkEventButton *bt) -> bool { | |||
|   return false; | ||||
| } | ||||
| 
 | ||||
| void Workspaces::set_urgent_workspace(std::string windowaddress) { | ||||
| void Workspaces::set_urgent_workspace(std::string const &windowaddress) { | ||||
|   const Json::Value clients_json = gIPC->getSocket1JsonReply("clients"); | ||||
|   int workspace_id = -1; | ||||
| 
 | ||||
|  | @ -863,58 +884,63 @@ std::string Workspaces::get_rewrite(std::string window_class, std::string window | |||
|   return window_rewrite_rules_.get(window_repr_key); | ||||
| } | ||||
| 
 | ||||
| CreateWindow::CreateWindow(std::string workspace_name, WindowAddress window_address, | ||||
|                            std::string window_repr) | ||||
|     : window_(window_repr), window_address_(window_address), workspace_name_(workspace_name) { | ||||
| WindowCreationPayload::WindowCreationPayload(std::string workspace_name, | ||||
|                                              WindowAddress window_address, std::string window_repr) | ||||
|     : window_(std::move(window_repr)), | ||||
|       window_address_(std::move(window_address)), | ||||
|       workspace_name_(std::move(workspace_name)) { | ||||
|   clear_addr(); | ||||
|   clear_workspace_name(); | ||||
| } | ||||
| 
 | ||||
| CreateWindow::CreateWindow(std::string workspace_name, WindowAddress window_address, | ||||
|                            std::string window_class, std::string window_title) | ||||
|     : window_(std::make_pair(window_class, window_title)), | ||||
|       window_address_(window_address), | ||||
|       workspace_name_(workspace_name) { | ||||
| WindowCreationPayload::WindowCreationPayload(std::string workspace_name, | ||||
|                                              WindowAddress window_address, std::string window_class, | ||||
|                                              std::string window_title) | ||||
|     : window_(std::make_pair(std::move(window_class), std::move(window_title))), | ||||
|       window_address_(std::move(window_address)), | ||||
|       workspace_name_(std::move(workspace_name)) { | ||||
|   clear_addr(); | ||||
|   clear_workspace_name(); | ||||
| } | ||||
| 
 | ||||
| CreateWindow::CreateWindow(Json::Value &client_data) { | ||||
|   window_address_ = client_data["address"].asString(); | ||||
|   workspace_name_ = client_data["workspace"]["name"].asString(); | ||||
|   window_ = std::make_pair(client_data["class"].asString(), client_data["title"].asString()); | ||||
| WindowCreationPayload::WindowCreationPayload(Json::Value const &client_data) | ||||
|     : window_(std::make_pair(client_data["class"].asString(), client_data["title"].asString())), | ||||
|       window_address_(client_data["address"].asString()), | ||||
|       workspace_name_(client_data["workspace"]["name"].asString()) { | ||||
|   clear_addr(); | ||||
|   clear_workspace_name(); | ||||
| } | ||||
| 
 | ||||
| std::string CreateWindow::repr(Workspaces &workspace_manager) { | ||||
| std::string WindowCreationPayload::repr(Workspaces &workspace_manager) { | ||||
|   if (std::holds_alternative<Repr>(window_)) { | ||||
|     return std::get<Repr>(window_); | ||||
|   } else if (std::holds_alternative<ClassAndTitle>(window_)) { | ||||
|   } | ||||
|   if (std::holds_alternative<ClassAndTitle>(window_)) { | ||||
|     auto [window_class, window_title] = std::get<ClassAndTitle>(window_); | ||||
|     return workspace_manager.get_rewrite(window_class, window_title); | ||||
|   } else { | ||||
|     // Unreachable
 | ||||
|     return ""; | ||||
|   } | ||||
|   // Unreachable
 | ||||
|   spdlog::error("WorkspaceWindow::repr: Unreachable"); | ||||
|   throw std::runtime_error("WorkspaceWindow::repr: Unreachable"); | ||||
| } | ||||
| 
 | ||||
| bool CreateWindow::is_empty(Workspaces &workspace_manager) { | ||||
| bool WindowCreationPayload::is_empty(Workspaces &workspace_manager) { | ||||
|   if (std::holds_alternative<Repr>(window_)) { | ||||
|     return std::get<Repr>(window_).empty(); | ||||
|   } else if (std::holds_alternative<ClassAndTitle>(window_)) { | ||||
|   } | ||||
|   if (std::holds_alternative<ClassAndTitle>(window_)) { | ||||
|     auto [window_class, window_title] = std::get<ClassAndTitle>(window_); | ||||
|     return (window_class.empty() && | ||||
|             (!workspace_manager.window_rewrite_config_uses_title() || window_title.empty())); | ||||
|   } else { | ||||
|   } | ||||
|   // Unreachable
 | ||||
|     return true; | ||||
|   } | ||||
|   spdlog::error("WorkspaceWindow::is_empty: Unreachable"); | ||||
|   throw std::runtime_error("WorkspaceWindow::is_empty: Unreachable"); | ||||
| } | ||||
| 
 | ||||
| int CreateWindow::increment_time_spent_uncreated() { return time_spent_uncreated_++; } | ||||
| int WindowCreationPayload::increment_time_spent_uncreated() { return time_spent_uncreated_++; } | ||||
| 
 | ||||
| void CreateWindow::clear_addr() { | ||||
| void WindowCreationPayload::clear_addr() { | ||||
|   // substr(2, ...) is necessary because Hyprland's JSON follows this format:
 | ||||
|   // 0x{ADDR}
 | ||||
|   // While Hyprland's IPC follows this format:
 | ||||
|  | @ -928,7 +954,7 @@ void CreateWindow::clear_addr() { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| void CreateWindow::clear_workspace_name() { | ||||
| void WindowCreationPayload::clear_workspace_name() { | ||||
|   // The workspace name may optionally feature "special:" at the beginning.
 | ||||
|   // If so, we need to remove it because the workspace is saved WITHOUT the
 | ||||
|   // special qualifier. The reasoning is that not all of Hyprland's IPC events
 | ||||
|  | @ -943,7 +969,7 @@ void CreateWindow::clear_workspace_name() { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| void CreateWindow::move_to_worksace(std::string &new_workspace_name) { | ||||
| void WindowCreationPayload::move_to_worksace(std::string &new_workspace_name) { | ||||
|   workspace_name_ = new_workspace_name; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -655,8 +655,7 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) { | |||
|         higher priority. Disable router -> RTA_GATEWAY -> up new router -> set higher priority added | ||||
|         checking route id | ||||
|         **/ | ||||
|         if (!is_del_event && | ||||
|             ((net->ifid_ == -1) || (priority < net->route_priority))) { | ||||
|         if (!is_del_event && ((net->ifid_ == -1) || (priority < net->route_priority))) { | ||||
|           // Clear if's state for the case were there is a higher priority
 | ||||
|           // route on a different interface.
 | ||||
|           net->clearIface(); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue