1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-26 17:47:37 +00:00

Don't crash when hiding top-level windows (#3757)

Current window management approach results in secondary windows being
destroyed once they are hidden. Since those windows are managed by
`std::unique_ptr<>`, we can't just [temporarily] increase their refcount
to avoid use-after-free situation, so retrieve updated top-level windows
list every time we hide one instead.
This commit is contained in:
Mike Gelfand 2022-09-04 16:52:35 +03:00 committed by GitHub
parent ea14f91ac8
commit 02af4c2982
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -489,15 +489,24 @@ Gtk::ComboBox* gtr_priority_combo_new()
**** ****
***/ ***/
namespace
{
auto const ChildHiddenKey = Glib::Quark("gtr-child-hidden"); auto const ChildHiddenKey = Glib::Quark("gtr-child-hidden");
} // namespace
void gtr_widget_set_visible(Gtk::Widget& w, bool b) void gtr_widget_set_visible(Gtk::Widget& w, bool b)
{ {
/* toggle the transient children, too */ /* toggle the transient children, too */
if (auto const* const window = dynamic_cast<Gtk::Window*>(&w); window != nullptr) if (auto const* const window = dynamic_cast<Gtk::Window*>(&w); window != nullptr)
{ {
for (auto* const l : Gtk::Window::list_toplevels()) auto top_levels = Gtk::Window::list_toplevels();
for (auto top_level_it = top_levels.begin(); top_level_it != top_levels.end();)
{ {
auto* const l = *top_level_it++;
if (l->get_transient_for() != window) if (l->get_transient_for() != window)
{ {
continue; continue;
@ -517,6 +526,10 @@ void gtr_widget_set_visible(Gtk::Widget& w, bool b)
{ {
l->set_data(ChildHiddenKey, GINT_TO_POINTER(1)); l->set_data(ChildHiddenKey, GINT_TO_POINTER(1));
gtr_widget_set_visible(*l, false); gtr_widget_set_visible(*l, false);
// Retrieve updated top-levels list in case hiding the window resulted in its destruction
top_levels = Gtk::Window::list_toplevels();
top_level_it = top_levels.begin();
} }
} }
} }