From 29ba1aac6142035cc0858f70942965397a170143 Mon Sep 17 00:00:00 2001 From: Bryan Tan Date: Sun, 16 Feb 2020 00:40:20 -0800 Subject: [PATCH] Fix deadlock when another PDF with an outline is opened --- src/gui/sidebar/indextree/SidebarIndexPage.cpp | 9 ++++++++- src/gui/sidebar/indextree/SidebarIndexPage.h | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gui/sidebar/indextree/SidebarIndexPage.cpp b/src/gui/sidebar/indextree/SidebarIndexPage.cpp index 6a58c968..7838b553 100644 --- a/src/gui/sidebar/indextree/SidebarIndexPage.cpp +++ b/src/gui/sidebar/indextree/SidebarIndexPage.cpp @@ -47,7 +47,8 @@ SidebarIndexPage::SidebarIndexPage(Control* control, SidebarToolbar* toolbar): A DOCUMENT_LINKS_COLUMN_PAGE_NUMBER, nullptr); g_object_set(G_OBJECT(renderer), "style", PANGO_STYLE_ITALIC, nullptr); - g_signal_connect(treeViewBookmarks, "cursor-changed", G_CALLBACK(treeBookmarkSelected), this); + this->selectHandler = g_signal_connect(treeViewBookmarks, "cursor-changed", G_CALLBACK(treeBookmarkSelected), this); + g_assert(this->selectHandler != 0); gtk_widget_show(this->treeViewBookmarks); @@ -342,11 +343,17 @@ void SidebarIndexPage::documentChanged(DocumentChangeType type) { Document* doc = this->control->getDocument(); + // Block the cursor-change signal when the document changes, otherwise + // there will be a deadlock: both the selectHandler and this code will + // lock the document. + g_signal_handler_block(this->treeViewBookmarks, this->selectHandler); doc->lock(); GtkTreeModel* model = doc->getContentsModel(); gtk_tree_view_set_model(GTK_TREE_VIEW(this->treeViewBookmarks), model); int count = expandOpenLinks(model, nullptr); doc->unlock(); + g_signal_handler_unblock(this->treeViewBookmarks, this->selectHandler); + this->treeBookmarkSelected(this->treeViewBookmarks, this); hasContents = (count != 0); } diff --git a/src/gui/sidebar/indextree/SidebarIndexPage.h b/src/gui/sidebar/indextree/SidebarIndexPage.h index ffb74ac9..56801509 100644 --- a/src/gui/sidebar/indextree/SidebarIndexPage.h +++ b/src/gui/sidebar/indextree/SidebarIndexPage.h @@ -105,6 +105,12 @@ private: */ GtkWidget* scrollBookmarks = nullptr; + /** + * Keep track of the tree bookmark selection handler; see documentChanged + * method for why this is necessary. + */ + unsigned long selectHandler = 0; // g_signal_connect uses 0 as error value + /** * If currently searching, scroll to the page is disable, else search is not really working *