On Mon, 27 Jul 2009 14:34:36 +0200, Jonas wrote:
Am 27.07.2009 13:59, schrieb Enrico Tröger:
Sorry, I don't see how this could be an improvement.
Well just open some new tab and set its label to Loading foo.ext...
and you're done ;-)
Hmm ok. Not sure I would like this but it could be at least a start of
a solution for the mentioned problems.
[...]e.g. when
compiling/building/running the current file. At this point we need
synchronous saving otherwise the whole point in saving a file prior
to an operation which relies on it becomes useless.
Yes, but that's the only case in that you need synchronous saving.
There was another case as well but I can't remember it right now,
unfortunately.
Anyway, attached is the patch I mentioned. It's a few months old so it
probably won't apply cleanly anymore against trunk but it should be
easily possible to manually replay the changes.
Note that the patch is in an early alpha state, I only tested it
shortly and there might be still tons of problems.
But if anyone wants to work on this, feel free to do it. I can't spend
any time on this in the next few weeks, sorry.
Regards,
Enrico
--
Get my GPG key from http://www.uvena.de/pub.asc
diff --git a/configure.in b/configure.in
index f94a741..00e03a7 100644
--- a/configure.in
+++ b/configure.in
@@ -128,7 +128,7 @@ fi
# GTK checks
-gtk_modules=gtk+-2.0 = 2.6.0
+gtk_modules=gtk+-2.0 = 2.6.0 gthread-2.0
PKG_CHECK_MODULES(GTK, [$gtk_modules])
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
diff --git a/src/callbacks.c b/src/callbacks.c
index 688c910..377b86c 100644
--- a/src/callbacks.c
+++ b/src/callbacks.c
@@ -182,7 +182,7 @@ on_save1_activate (GtkMenuItem *menuitem,
if (doc-file_name == NULL)
dialogs_show_save_as();
else
- document_save_file(doc, FALSE);
+ document_save_file_async(doc, FALSE);
}
}
@@ -214,7 +214,7 @@ on_save_all1_activate (GtkMenuItem *menuitem,
dialogs_show_save_as();
}
else
- document_save_file(doc, FALSE);
+ document_save_file_async(doc, FALSE);
}
treeviews_update_tag_list(cur_doc, TRUE);
ui_set_window_title(cur_doc);
diff --git a/src/document.c b/src/document.c
index 6711282..b314233 100644
--- a/src/document.c
+++ b/src/document.c
@@ -1430,52 +1430,125 @@ _(An error occurred while converting the file from UTF-8 in \%s\. The file re
}
-static gint write_data_to_disk(GeanyDocument *doc, const gchar *data, gint len)
+typedef struct
+{
+ GeanyDocument *doc;
+ gchar *text;
+ gsize len;
+ gint err;
+ gboolean async;
+} SaveData;
+
+
+/* Callback which is called from the saving thread when it is finished, to do GTK stuff */
+static gboolean save_file_finished(gpointer data)
{
+ SaveData *sd = data;
+ gboolean async = sd-async; /* cache the async flag as we need it after we freed 'sd' */
+
+ if (sd-err != 0)
+ {
+ ui_set_statusbar(TRUE, _(Error saving file (%s).), g_strerror(sd-err));
+ dialogs_show_msgbox_with_secondary(GTK_MESSAGE_ERROR,
+ _(Error saving file.), g_strerror(sd-err));
+ utils_beep();
+ sd-doc-priv-save_in_progress = FALSE;
+ return FALSE;
+ }
+
+ /* store the opened encoding for undo/redo */
+ store_saved_encoding(sd-doc);
+
+ /* ignore the following things if we are quitting */
+ if (! main_status.quitting)
+ {
+ sci_set_savepoint(sd-doc-editor-sci);
+
+ /* stat the file to get the timestamp, otherwise on Windows the actual
+ * timestamp can be ahead of time(NULL) */
+ if (file_prefs.disk_check_timeout 0)
+ document_update_timestamp(sd-doc);
+
+ /* update filetype-related things */
+ /** TODO possibly refactor document_set_filetype() to move separate updating the
+ * tm_file in the threaded code and keep the GUI updating outside */
+ document_set_filetype(sd-doc, sd-doc-file_type);
+
+ tm_workspace_update(TM_WORK_OBJECT(app-tm_workspace), TRUE, TRUE, FALSE);
+
+ document_update_tab_label(sd-doc);
+
+ msgwin_status_add(_(File %s saved.), sd-doc-file_name);
+ ui_update_statusbar(sd-doc, -1);
+#ifdef HAVE_VTE
+ vte_cwd(sd-doc-file_name, FALSE);
+#endif
+ }
+ sd-doc-priv-save_in_progress = FALSE;
+ g_signal_emit_by_name(geany_object, document-save, sd-doc);
+
+ g_free(sd-text);
+ g_free(sd);
+
+ return (async) ? FALSE : TRUE;
+}
+
+
+/* Saving thread to write the data to the file on disk.
+ * Don't do any GTK stuff in here. save_file_finished() is called at the end as an idle function
+ * to update GUI things in the GTK main thread.
+ * If called asynchronously, it returns always NULL.
+ * If called synchronously, it returns NULL on any error or non-NULL on success. */
+static gpointer save_file_start(gpointer data)
+{
+ SaveData *sd = data;
FILE *fp;
- gint bytes_written;
+ gsize bytes_written;
gchar *locale_filename = NULL;
- gint err = 0;
- g_return_val_if_fail(data != NULL, EINVAL);
+ g_return_val_if_fail(data != NULL sd-text != NULL, NULL);
- locale_filename = utils_get_locale_from_utf8(doc-file_name);
+ locale_filename = utils_get_locale_from_utf8(sd-doc-file_name);