Blame use-std-list-to-store-outputs.patch

81aac4d
From f80270519b55d7b12d06538df5d989c615eea1df Mon Sep 17 00:00:00 2001
81aac4d
From: Aleksei Bavshin <alebastr89@gmail.com>
81aac4d
Date: Mon, 13 Jan 2020 23:27:57 -0800
81aac4d
Subject: [PATCH] refactor(client): use std::list<waybar_output> to store
81aac4d
 outputs
81aac4d
81aac4d
std::unique_ptr is not required here as the only benefit it gives is
81aac4d
stability of address on vector resize and it's easy to invalidate it
81aac4d
accidentaly. std::list provides the same guarantee of stable addresses
81aac4d
of the elements and correct destruction while avoiding smart pointer
81aac4d
overhead.
81aac4d
81aac4d
Also fixes #554, caused by incorrect usage of std::remove_if.
81aac4d
---
81aac4d
 include/client.hpp | 16 ++++++++--------
81aac4d
 src/client.cpp     | 42 +++++++++++++++++++-----------------------
81aac4d
 2 files changed, 27 insertions(+), 31 deletions(-)
81aac4d
81aac4d
diff --git a/include/client.hpp b/include/client.hpp
81aac4d
index 65a814fc..39b6ae3b 100644
81aac4d
--- a/include/client.hpp
81aac4d
+++ b/include/client.hpp
81aac4d
@@ -30,12 +30,12 @@ class Client {
81aac4d
                                                               const std::string &style) const;
81aac4d
   void                                             bindInterfaces();
81aac4d
   const std::string getValidPath(const std::vector<std::string> &paths) const;
81aac4d
-  void              handleOutput(std::unique_ptr<struct waybar_output> &output);
81aac4d
-  bool isValidOutput(const Json::Value &config, std::unique_ptr<struct waybar_output> &output);
81aac4d
+  void              handleOutput(struct waybar_output &output);
81aac4d
+  bool isValidOutput(const Json::Value &config, struct waybar_output &output);
81aac4d
   auto setupConfig(const std::string &config_file) -> void;
81aac4d
   auto setupCss(const std::string &css_file) -> void;
81aac4d
-  std::unique_ptr<struct waybar_output> &getOutput(void *);
81aac4d
-  std::vector<Json::Value> getOutputConfigs(std::unique_ptr<struct waybar_output> &output);
81aac4d
+  struct waybar_output &getOutput(void *);
81aac4d
+  std::vector<Json::Value> getOutputConfigs(struct waybar_output &output);
81aac4d
 
81aac4d
   static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
81aac4d
                            const char *interface, uint32_t version);
81aac4d
@@ -44,10 +44,10 @@ class Client {
81aac4d
   void        handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor);
81aac4d
   void        handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor);
81aac4d
 
81aac4d
-  Json::Value                                        config_;
81aac4d
-  Glib::RefPtr<Gtk::StyleContext>                    style_context_;
81aac4d
-  Glib::RefPtr<Gtk::CssProvider>                     css_provider_;
81aac4d
-  std::vector<std::unique_ptr<struct waybar_output>> outputs_;
81aac4d
+  Json::Value                     config_;
81aac4d
+  Glib::RefPtr<Gtk::StyleContext> style_context_;
81aac4d
+  Glib::RefPtr<Gtk::CssProvider>  css_provider_;
81aac4d
+  std::list<struct waybar_output> outputs_;
81aac4d
 };
81aac4d
 
81aac4d
 }  // namespace waybar
81aac4d
diff --git a/src/client.cpp b/src/client.cpp
81aac4d
index dd4cd50e..f7c70e06 100644
81aac4d
--- a/src/client.cpp
81aac4d
+++ b/src/client.cpp
81aac4d
@@ -49,7 +49,7 @@ void waybar::Client::handleGlobalRemove(void *   data, struct wl_registry * /*re
81aac4d
   // Nothing here
81aac4d
 }
81aac4d
 
81aac4d
-void waybar::Client::handleOutput(std::unique_ptr<struct waybar_output> &output) {
81aac4d
+void waybar::Client::handleOutput(struct waybar_output &output) {
81aac4d
   static const struct zxdg_output_v1_listener xdgOutputListener = {
81aac4d
       .logical_position = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {},
81aac4d
       .logical_size = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {},
81aac4d
@@ -58,42 +58,39 @@ void waybar::Client::handleOutput(std::unique_ptr<struct waybar_output> &output)
81aac4d
       .description = [](void *, struct zxdg_output_v1 *, const char *) {},
81aac4d
   };
81aac4d
   // owned by output->monitor; no need to destroy
81aac4d
-  auto wl_output = gdk_wayland_monitor_get_wl_output(output->monitor->gobj());
81aac4d
-  output->xdg_output.reset(zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, wl_output));
81aac4d
-  zxdg_output_v1_add_listener(output->xdg_output.get(), &xdgOutputListener, output.get());
81aac4d
+  auto wl_output = gdk_wayland_monitor_get_wl_output(output.monitor->gobj());
81aac4d
+  output.xdg_output.reset(zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, wl_output));
81aac4d
+  zxdg_output_v1_add_listener(output.xdg_output.get(), &xdgOutputListener, &output);
81aac4d
 }
81aac4d
 
81aac4d
-bool waybar::Client::isValidOutput(const Json::Value &                    config,
81aac4d
-                                   std::unique_ptr<struct waybar_output> &output) {
81aac4d
+bool waybar::Client::isValidOutput(const Json::Value &config, struct waybar_output &output) {
81aac4d
   bool found = true;
81aac4d
   if (config["output"].isArray()) {
81aac4d
     bool in_array = false;
81aac4d
     for (auto const &output_conf : config["output"]) {
81aac4d
-      if (output_conf.isString() && output_conf.asString() == output->name) {
81aac4d
+      if (output_conf.isString() && output_conf.asString() == output.name) {
81aac4d
         in_array = true;
81aac4d
         break;
81aac4d
       }
81aac4d
     }
81aac4d
     found = in_array;
81aac4d
   }
81aac4d
-  if (config["output"].isString() && config["output"].asString() != output->name) {
81aac4d
+  if (config["output"].isString() && config["output"].asString() != output.name) {
81aac4d
     found = false;
81aac4d
   }
81aac4d
   return found;
81aac4d
 }
81aac4d
 
81aac4d
-std::unique_ptr<struct waybar::waybar_output> &waybar::Client::getOutput(void *addr) {
81aac4d
-  auto it = std::find_if(outputs_.begin(), outputs_.end(), [&addr](const auto &output) {
81aac4d
-    return output.get() == addr;
81aac4d
-  });
81aac4d
+struct waybar::waybar_output &waybar::Client::getOutput(void *addr) {
81aac4d
+  auto it = std::find_if(
81aac4d
+      outputs_.begin(), outputs_.end(), [&addr](const auto &output) { return &output == addr; });
81aac4d
   if (it == outputs_.end()) {
81aac4d
     throw std::runtime_error("Unable to find valid output");
81aac4d
   }
81aac4d
   return *it;
81aac4d
 }
81aac4d
 
81aac4d
-std::vector<Json::Value> waybar::Client::getOutputConfigs(
81aac4d
-    std::unique_ptr<struct waybar_output> &output) {
81aac4d
+std::vector<Json::Value> waybar::Client::getOutputConfigs(struct waybar_output &output) {
81aac4d
   std::vector<Json::Value> configs;
81aac4d
   if (config_.isArray()) {
81aac4d
     for (auto const &config : config_) {
81aac4d
@@ -112,18 +109,18 @@ void waybar::Client::handleOutputName(void *      data, struct zxdg_output_v1 *
81aac4d
   auto client = waybar::Client::inst();
81aac4d
   try {
81aac4d
     auto &output = client->getOutput(data);
81aac4d
-    output->name = name;
81aac4d
+    output.name = name;
81aac4d
     spdlog::debug("Output detected: {} ({} {})",
81aac4d
                   name,
81aac4d
-                  output->monitor->get_manufacturer(),
81aac4d
-                  output->monitor->get_model());
81aac4d
+                  output.monitor->get_manufacturer(),
81aac4d
+                  output.monitor->get_model());
81aac4d
     auto configs = client->getOutputConfigs(output);
81aac4d
     if (configs.empty()) {
81aac4d
-      output->xdg_output.reset();
81aac4d
+      output.xdg_output.reset();
81aac4d
     } else {
81aac4d
       wl_display_roundtrip(client->wl_display);
81aac4d
       for (const auto &config : configs) {
81aac4d
-        client->bars.emplace_back(std::make_unique<Bar>(output.get(), config));
81aac4d
+        client->bars.emplace_back(std::make_unique<Bar>(&output, config));
81aac4d
         Glib::RefPtr<Gdk::Screen> screen = client->bars.back()->window.get_screen();
81aac4d
         client->style_context_->add_provider_for_screen(
81aac4d
             screen, client->css_provider_, GTK_STYLE_PROVIDER_PRIORITY_USER);
81aac4d
@@ -135,7 +132,8 @@ void waybar::Client::handleOutputName(void *      data, struct zxdg_output_v1 *
81aac4d
 }
81aac4d
 
81aac4d
 void waybar::Client::handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor) {
81aac4d
-  auto &output = outputs_.emplace_back(new struct waybar_output({monitor}));
81aac4d
+  auto &output = outputs_.emplace_back();
81aac4d
+  output.monitor = monitor;
81aac4d
   handleOutput(output);
81aac4d
 }
81aac4d
 
81aac4d
@@ -151,9 +149,7 @@ void waybar::Client::handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor) {
81aac4d
       ++it;
81aac4d
     }
81aac4d
   }
81aac4d
-  std::remove_if(outputs_.begin(), outputs_.end(), [&monitor](const auto &output) {
81aac4d
-    return output->monitor == monitor;
81aac4d
-  });
81aac4d
+  outputs_.remove_if([&monitor](const auto &output) { return output.monitor == monitor; });
81aac4d
 }
81aac4d
 
81aac4d
 std::tuple<const std::string, const std::string> waybar::Client::getConfigs(