Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: Colomban Wendling ban@herbesfolles.org Date: Sat, 21 Feb 2015 17:49:09 UTC Commit: 99552dbe1256e5051a96623db4f0c68bbf591fbc https://github.com/geany/geany/commit/99552dbe1256e5051a96623db4f0c68bbf591f...
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).