[geany/geany] 99552d: Fix emission of the ::document-activate signal

Colomban Wendling git-noreply at xxxxx
Sat Feb 21 17:49:09 UTC 2015


Branch:      refs/heads/master
Author:      Colomban Wendling <ban at herbesfolles.org>
Committer:   Colomban Wendling <ban at herbesfolles.org>
Date:        Sat, 21 Feb 2015 17:49:09 UTC
Commit:      99552dbe1256e5051a96623db4f0c68bbf591fbc
             https://github.com/geany/geany/commit/99552dbe1256e5051a96623db4f0c68bbf591fbc

Log Message:
-----------
Fix emission of the ::document-activate signal

The ::document-activate signal was not emitted when opening the first
tab of the notebook, e.g. when the tab count changed from 0 to 1.

This is because the ::document-activate signal is emitted in response
to the GtkNotebook::switch-page signal, which is emitted whenever the
currently displayed page changes.  When there already is a current page
(when there is one or more pages), adding a new page does not trigger
the signal, as this new page doesn't become the current one (we will
switch to it later).  However, when there are none, the newly added one
becomes current, and so the signal is emitted right away.

This is problematic because when we add the page to the notebook, the
document associated with it is not yet ready (only partly initialized),
and so we can't emit the signal on a valid document, and we discard it.

Not emitting this signal leads to inconsistent behavior introducing
subtle bugs in plugins relying on it.

To work this around, only show the page widget (the child added to the
notebook) after we finished initializing everything.  This is the
simplest fix, because a lot of the code around document creation and
opening depend on the fact the page is already added, so while delaying
the page addition sounds like the more sensible fix, it has non-trivial
consequences that would require a large amount of work to overcome.

Note that interestingly, in addition to our problem, GtkNotebook seems
to have a bug as it emits the ::switch-page right when adding the first
page even if that page is not visible.  However, it properly emits it
again when the child becomes visible, so we just still discard the
first emission like we used to.


Modified Paths:
--------------
    src/document.c
    src/notebook.c

Modified: src/document.c
25 lines changed, 20 insertions(+), 5 deletions(-)
===================================================================
@@ -272,11 +272,8 @@ GeanyDocument *document_find_by_id(guint id)
 }
 
 
-/** Gets the notebook page index for a document.
- * @param doc The document.
- * @return The index.
- * @since 0.19 */
-gint document_get_notebook_page(GeanyDocument *doc)
+/* gets the widget the main_widgets.notebook consider is its child for this document */
+static GtkWidget *document_get_notebook_child(GeanyDocument *doc)
 {
 	GtkWidget *parent;
 	GtkWidget *child;
@@ -292,6 +289,18 @@ gint document_get_notebook_page(GeanyDocument *doc)
 		parent = gtk_widget_get_parent(child);
 	}
 
+	return child;
+}
+
+
+/** Gets the notebook page index for a document.
+ * @param doc The document.
+ * @return The index.
+ * @since 0.19 */
+gint document_get_notebook_page(GeanyDocument *doc)
+{
+	GtkWidget *child = document_get_notebook_child(doc);
+
 	return gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook), child);
 }
 
@@ -840,6 +849,9 @@ GeanyDocument *document_new_file(const gchar *utf8_filename, GeanyFiletype *ft,
 
 	document_set_filetype(doc, ft); /* also re-parses tags */
 
+	/* now the document is fully ready, display it (see notebook_new_tab()) */
+	gtk_widget_show(document_get_notebook_child(doc));
+
 	ui_set_window_title(doc);
 	build_menu_update(doc);
 	document_set_text_changed(doc, FALSE);
@@ -1418,6 +1430,9 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename
 				display_filename, gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)),
 				(readonly) ? _(", read-only") : "");
 		}
+
+		/* now the document is fully ready, display it (see notebook_new_tab()) */
+		gtk_widget_show(document_get_notebook_child(doc));
 	}
 
 	g_free(display_filename);


Modified: src/notebook.c
10 lines changed, 8 insertions(+), 2 deletions(-)
===================================================================
@@ -645,7 +645,14 @@ static void notebook_tab_close_button_style_set(GtkWidget *btn, GtkRcStyle *prev
 }
 
 
-/* Returns page number of notebook page, or -1 on error */
+/* Returns page number of notebook page, or -1 on error
+ *
+ * Note: the widget added to the notebook is *not* shown by this function, so you have to call
+ * something like `gtk_widget_show(document_get_notebook_child(doc))` when finished setting up the
+ * document.  This is necessary because when the notebook tab is added, the document isn't ready
+ * yet, and we  need the notebook to emit ::switch-page after it actually is.  Actually this
+ * doesn't prevent the signal to me emitted straight when we insert the page (this looks like a
+ * GTK bug), but it emits it again when showing the child, and it's all we need. */
 gint notebook_new_tab(GeanyDocument *this)
 {
 	GtkWidget *hbox, *ebox, *vbox;
@@ -659,7 +666,6 @@ gint notebook_new_tab(GeanyDocument *this)
 	vbox = gtk_vbox_new(FALSE, 0);
 	page = GTK_WIDGET(this->editor->sci);
 	gtk_box_pack_start(GTK_BOX(vbox), page, TRUE, TRUE, 0);
-	gtk_widget_show(vbox);
 
 	this->priv->tab_label = gtk_label_new(NULL);
 



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list