fix: schedule output destruction on idle callback

Defer destruction of bars for the output to the next iteration of the
event loop to avoid deleting objects referenced by currently executed
code.
This commit is contained in:
Aleksei Bavshin 2021-02-09 19:24:46 -08:00
parent 4d150e9340
commit 943ba3a2da
No known key found for this signature in database
GPG Key ID: 4F071603387A382A
2 changed files with 11 additions and 0 deletions

View File

@ -51,6 +51,7 @@ class Client {
static void handleOutputDescription(void *, struct zxdg_output_v1 *, const char *);
void handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor);
void handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor);
void handleDeferredMonitorRemoval(Glib::RefPtr<Gdk::Monitor> monitor);
Json::Value config_;
Glib::RefPtr<Gtk::StyleContext> style_context_;

View File

@ -179,6 +179,16 @@ void waybar::Client::handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor) {
void waybar::Client::handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor) {
spdlog::debug("Output removed: {} {}", monitor->get_manufacturer(), monitor->get_model());
/* This event can be triggered from wl_display_roundtrip called by GTK or our code.
* Defer destruction of bars for the output to the next iteration of the event loop to avoid
* deleting objects referenced by currently executed code.
*/
Glib::signal_idle().connect_once(
sigc::bind(sigc::mem_fun(*this, &Client::handleDeferredMonitorRemoval), monitor),
Glib::PRIORITY_HIGH_IDLE);
}
void waybar::Client::handleDeferredMonitorRemoval(Glib::RefPtr<Gdk::Monitor> monitor) {
for (auto it = bars.begin(); it != bars.end();) {
if ((*it)->output->monitor == monitor) {
auto output_name = (*it)->output->name;