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:
parent
ea14f91ac8
commit
02af4c2982
1 changed files with 14 additions and 1 deletions
15
gtk/Utils.cc
15
gtk/Utils.cc
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue