Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: Colomban Wendling ban@herbesfolles.org Date: Thu, 13 Jun 2024 10:02:22 UTC Commit: 293157c7a99880523900e29a1e3191800c2018fe https://github.com/geany/geany/commit/293157c7a99880523900e29a1e3191800c2018...
Log Message: ----------- Fix emission of document-activate signal and associated UI glitches
PR https://github.com/geany/geany/pull/3267 broke handling of several special tab switch cases:
* By showing the tab's child too early, it prevented the switch-page handler to properly work in situations where there was only one page, as the tab switch would happen at page creation yet the document would not be valid yet. * It removed explicit emission of the switch-page signal when the source and target pages are the same after session opening, which happens if the active session page is the first one.
Fix this by mostly reverting 23367de0c5237558ea63cb8c711d46390d978267 and implementing the delay directly in the switch-page handler.
Fixes #3684.
Modified Paths: -------------- src/callbacks.c src/document.c src/editor.c src/keyfile.c src/libmain.c src/notebook.c
Modified: src/callbacks.c 59 lines changed, 48 insertions(+), 11 deletions(-) =================================================================== @@ -515,18 +515,8 @@ void on_normal_size1_activate(GtkMenuItem *menuitem, gpointer user_data) }
-/* Changes window-title after switching tabs and lots of other things. - * note: using 'after' makes Scintilla redraw before the UI, appearing more responsive */ -static void on_notebook1_switch_page_after(GtkNotebook *notebook, gpointer page, - guint page_num, gpointer user_data) +static void handle_switch_page(GeanyDocument *doc) { - GeanyDocument *doc; - - if (G_UNLIKELY(main_status.opening_session_files || main_status.closing_all)) - return; - - doc = document_get_from_notebook_child(page); - if (doc != NULL) { GtkEntry *filter_entry = GTK_ENTRY(ui_lookup_widget(main_widgets.window, "entry_tagfilter")); @@ -559,6 +549,53 @@ static void on_notebook1_switch_page_after(GtkNotebook *notebook, gpointer page, }
+static gboolean delay_handle_switch_page(gpointer data) +{ + gulong *handler_id = data; + + if (main_status.opening_session_files) + return G_SOURCE_CONTINUE; + /* guard against the unlikely case where we didn't run yet but are already + * closing all documents */ + else if (! main_status.closing_all) + handle_switch_page(document_get_current()); + + *handler_id = 0; + return G_SOURCE_REMOVE; +} + + +/* Changes window-title after switching tabs and lots of other things. + * note: using 'after' makes Scintilla redraw before the UI, appearing more responsive + * + * When page switch happens while opening session files, we delay handling of the + * event to when session opening is complete. This is mostly to avoid repeatedly update + * the UI unnecessarily, which isn't entirely cheap */ +static void on_notebook1_switch_page_after(GtkNotebook *notebook, gpointer page, + guint page_num, gpointer user_data) +{ + static gulong handler_id = 0; + + if (main_status.opening_session_files) + { + /* if opening session files, delay the handling to after session is fully open */ + if (handler_id == 0) + handler_id = g_idle_add(delay_handle_switch_page, &handler_id); + return; + } + else if (main_status.closing_all) + return; + + if (handler_id != 0) + { + g_source_remove(handler_id); + handler_id = 0; + } + + handle_switch_page(document_get_from_notebook_child(page)); +} + + static void on_tv_notebook_switch_page(GtkNotebook *notebook, gpointer page, guint page_num, gpointer user_data) {
Modified: src/document.c 39 lines changed, 9 insertions(+), 30 deletions(-) =================================================================== @@ -104,7 +104,6 @@ enum };
-static guint show_tab_idle = 0; static guint doc_id_counter = 0;
@@ -859,6 +858,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); @@ -1264,40 +1266,14 @@ void document_apply_indent_settings(GeanyDocument *doc)
void document_show_tab(GeanyDocument *doc) { - if (show_tab_idle) - { - g_source_remove(show_tab_idle); - show_tab_idle = 0; - } - gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), document_get_notebook_page(doc));
/* finally, let the editor widget grab the focus so you can start coding * right away */ - document_try_focus(doc, NULL); -} - - -static gboolean show_tab_cb(gpointer data) -{ - GeanyDocument *doc = (GeanyDocument *) data; - - show_tab_idle = 0; - /* doc might not be valid e.g. if user closed a tab whilst Geany is opening files */ - if (DOC_VALID(doc)) - document_show_tab(doc); - - return G_SOURCE_REMOVE; -} - - -void document_show_tab_idle(GeanyDocument *doc) -{ - if (show_tab_idle) - g_source_remove(show_tab_idle); - - show_tab_idle = g_idle_add(show_tab_cb, doc); + /* FIXME: is that actually useful?? I don't see any difference disabling this code... */ + if (!main_status.opening_session_files) + document_try_focus(doc, NULL); }
@@ -1517,6 +1493,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/editor.c 7 lines changed, 2 insertions(+), 5 deletions(-) =================================================================== @@ -4743,11 +4743,8 @@ gboolean editor_goto_pos(GeanyEditor *editor, gint pos, gboolean mark) sci_goto_pos(editor->sci, pos, TRUE); editor->scroll_percent = 0.25F;
- /* switch to the page, via idle callback in case of batch-opening */ - if (main_status.opening_session_files) - document_show_tab_idle(editor->document); - else - document_show_tab(editor->document); + /* switch to the page */ + document_show_tab(editor->document);
return TRUE; }
Modified: src/keyfile.c 6 lines changed, 3 insertions(+), 3 deletions(-) =================================================================== @@ -1353,8 +1353,8 @@ static gboolean open_session_file(gchar **tmp, guint len)
/* Open session files - * Note: notebook page switch handler and adding to recent files list is always disabled - * for all files opened within this function */ + * Note: notebook page switch handler is delayed, and adding to recent files list is + * always disabled for all files opened within this function */ void configuration_open_files(GPtrArray *session_files) { gboolean failure = FALSE; @@ -1380,7 +1380,7 @@ void configuration_open_files(GPtrArray *session_files) if (failure) ui_set_statusbar(TRUE, _("Failed to load one or more session files.")); else - document_show_tab_idle(session_notebook_page >= 0 ? document_get_from_page(session_notebook_page) : document_get_current()); + document_show_tab(session_notebook_page >= 0 ? document_get_from_page(session_notebook_page) : document_get_current());
session_notebook_page = -1; main_status.opening_session_files--;
Modified: src/libmain.c 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -849,7 +849,7 @@ gboolean main_handle_filename(const gchar *locale_filename)
doc = document_find_by_filename(utf8_filename); if (doc) - document_show_tab_idle(doc); + document_show_tab(doc); else doc = document_new_file(utf8_filename, NULL, NULL); g_free(utf8_filename);
Modified: src/notebook.c 2 lines changed, 0 insertions(+), 2 deletions(-) =================================================================== @@ -716,8 +716,6 @@ gint notebook_new_tab(GeanyDocument *this) page = GTK_WIDGET(this->editor->sci); gtk_box_pack_start(GTK_BOX(vbox), page, TRUE, TRUE, 0);
- gtk_widget_show_all(vbox); - this->priv->tab_label = gtk_label_new(NULL);
/* get button press events for the tab label and the space between it and
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).