# HG changeset patch # User nadvornik # Date 1252245663 0 # Node ID 8e64965c1d92b0c8ecb9a1fa6e683aa330d2ae35 # Parent 6cae2af8fdd1af0614ced932fbc73fd84d4d21ef load desktop files in idle time - scanning all desktop files takes a lot of time because of hdd seek - this change moves the scanning to idle time - the editors appears in the menus some time after startup https://sourceforge.net/tracker/index.php?func=detail&aid=2852522&group_id=222125&atid=1054680 diff -r 6cae2af8fdd1 -r 8e64965c1d92 src/desktop_file.c --- a/src/desktop_file.c Sun Sep 06 09:08:37 2009 +0000 +++ b/src/desktop_file.c Sun Sep 06 14:01:03 2009 +0000 @@ -95,7 +95,9 @@ g_free(path); g_free(dir); g_free(text); - layout_editors_reload_all(); + layout_editors_reload_start(); + /* idle function is not needed, everything should be cached */ + layout_editors_reload_finish(); return ret; } @@ -290,7 +292,9 @@ else { /* refresh list */ - layout_editors_reload_all(); + layout_editors_reload_start(); + /* idle function is not needed, everything should be cached */ + layout_editors_reload_finish(); } editor_list_window_delete_dlg_cancel(gd, data); diff -r 6cae2af8fdd1 -r 8e64965c1d92 src/editors.c --- a/src/editors.c Sun Sep 06 09:08:37 2009 +0000 +++ b/src/editors.c Sun Sep 06 14:01:03 2009 +0000 @@ -17,6 +17,7 @@ #include "filedata.h" #include "filefilter.h" #include "misc.h" +#include "pixbuf_util.h" #include "ui_fileops.h" #include "ui_spinner.h" #include "ui_utildlg.h" @@ -69,7 +70,7 @@ GHashTable *editors = NULL; GtkListStore *desktop_file_list; - +gboolean editors_finished = FALSE; #ifdef G_KEY_FILE_DESKTOP_GROUP #define DESKTOP_GROUP G_KEY_FILE_DESKTOP_GROUP @@ -147,7 +148,7 @@ return list; } -static gboolean editor_read_desktop_file(const gchar *path) +gboolean editor_read_desktop_file(const gchar *path) { GKeyFile *key_file; EditorDescription *editor; @@ -283,6 +284,11 @@ *ext = '\0'; } } + if (editor->icon && !register_theme_icon_as_stock(editor->key, editor->icon)) + { + g_free(editor->icon); + editor->icon = NULL; + } editor->exec = g_key_file_get_string(key_file, DESKTOP_GROUP, "Exec", NULL); @@ -338,44 +344,14 @@ return editor->hidden || editor->ignored; } -static void editor_read_desktop_dir(const gchar *path) +void editor_table_finish(void) { - DIR *dp; - struct dirent *dir; - gchar *pathl; - - pathl = path_from_utf8(path); - dp = opendir(pathl); - g_free(pathl); - if (!dp) - { - /* dir not found */ - return; - } - while ((dir = readdir(dp)) != NULL) - { - gchar *namel = dir->d_name; - - if (g_str_has_suffix(namel, ".desktop")) - { - gchar *name = path_to_utf8(namel); - gchar *dpath = g_build_filename(path, name, NULL); - editor_read_desktop_file(dpath); - g_free(dpath); - g_free(name); - } - } - closedir(dp); + g_hash_table_foreach_remove(editors, editor_remove_desktop_file_cb, NULL); + editors_finished = TRUE; } -void editor_load_descriptions(void) +void editor_table_clear(void) { - gchar *path; - gchar *xdg_data_dirs; - gchar *all_dirs; - gchar **split_dirs; - gint i; - if (desktop_file_list) { gtk_list_store_clear(desktop_file_list); @@ -389,7 +365,48 @@ g_hash_table_destroy(editors); } editors = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)editor_description_free); + editors_finished = FALSE; +} +static GList *editor_add_desktop_dir(GList *list, const gchar *path) +{ + DIR *dp; + struct dirent *dir; + gchar *pathl; + + pathl = path_from_utf8(path); + dp = opendir(pathl); + g_free(pathl); + if (!dp) + { + /* dir not found */ + return list; + } + while ((dir = readdir(dp)) != NULL) + { + gchar *namel = dir->d_name; + + if (g_str_has_suffix(namel, ".desktop")) + { + gchar *name = path_to_utf8(namel); + gchar *dpath = g_build_filename(path, name, NULL); + list = g_list_prepend(list, dpath); + g_free(name); + } + } + closedir(dp); + return list; +} + +GList *editor_get_desktop_files(void) +{ + gchar *path; + gchar *xdg_data_dirs; + gchar *all_dirs; + gchar **split_dirs; + gint i; + GList *list = NULL; + xdg_data_dirs = getenv("XDG_DATA_DIRS"); if (xdg_data_dirs && xdg_data_dirs[0]) xdg_data_dirs = path_to_utf8(xdg_data_dirs); @@ -404,16 +421,16 @@ g_free(all_dirs); - for (i = 0; split_dirs[i]; i++) + for (i = 0; split_dirs[i]; i++); + for (--i; i >= 0; i--) { path = g_build_filename(split_dirs[i], "applications", NULL); - editor_read_desktop_dir(path); + list = editor_add_desktop_dir(list, path); g_free(path); } g_strfreev(split_dirs); - - g_hash_table_foreach_remove(editors, editor_remove_desktop_file_cb, NULL); + return g_list_reverse(list); } static void editor_list_add_cb(gpointer key, gpointer value, gpointer data) @@ -446,6 +463,9 @@ GList *editor_list_get(void) { GList *editors_list = NULL; + + if (!editors_finished) return NULL; + g_hash_table_foreach(editors, editor_list_add_cb, &editors_list); editors_list = g_list_sort(editors_list, editor_sort); diff -r 6cae2af8fdd1 -r 8e64965c1d92 src/editors.h --- a/src/editors.h Sun Sep 06 09:08:37 2009 +0000 +++ b/src/editors.h Sun Sep 06 14:01:03 2009 +0000 @@ -78,7 +78,11 @@ extern GHashTable *editors; -void editor_load_descriptions(void); +void editor_table_finish(void); +void editor_table_clear(void); +GList *editor_get_desktop_files(void); +gboolean editor_read_desktop_file(const gchar *path); + GList *editor_list_get(void); diff -r 6cae2af8fdd1 -r 8e64965c1d92 src/layout_util.c --- a/src/layout_util.c Sun Sep 06 09:08:37 2009 +0000 +++ b/src/layout_util.c Sun Sep 06 14:01:03 2009 +0000 @@ -1801,6 +1801,11 @@ GList *old_path; GString *desc; + if (lw->action_group_editors) + { + gtk_ui_manager_remove_action_group(lw->ui_manager, lw->action_group_editors); + g_object_unref(lw->action_group_editors); + } lw->action_group_editors = gtk_action_group_new("MenuActionsExternal"); gtk_ui_manager_insert_action_group(lw->ui_manager, lw->action_group_editors, 1); @@ -1824,7 +1829,7 @@ editor->comment ? editor->comment : editor->name, G_CALLBACK(layout_menu_edit_cb) }; - if (editor->icon && register_theme_icon_as_stock(editor->key, editor->icon)) + if (editor->icon) { entry.stock_id = editor->key; } @@ -1927,11 +1932,56 @@ DEBUG_1("%s layout_actions_setup: end", get_exec_time()); } -void layout_editors_reload_all(void) +static gint layout_editors_reload_idle_id = -1; +static GList *layout_editors_desktop_files = NULL; + +static gboolean layout_editors_reload_idle_cb(gpointer data) +{ + if (!layout_editors_desktop_files) + { + DEBUG_1("%s layout_editors_reload_idle_cb: get_desktop_files", get_exec_time()); + layout_editors_desktop_files = editor_get_desktop_files(); + return TRUE; + } + + editor_read_desktop_file(layout_editors_desktop_files->data); + g_free(layout_editors_desktop_files->data); + layout_editors_desktop_files = g_list_delete_link(layout_editors_desktop_files, layout_editors_desktop_files); + + + if (!layout_editors_desktop_files) + { + GList *work; + DEBUG_1("%s layout_editors_reload_idle_cb: setup_editors", get_exec_time()); + editor_table_finish(); + + work = layout_window_list; + while (work) + { + LayoutWindow *lw = work->data; + work = work->next; + layout_actions_setup_editors(lw); + } + + DEBUG_1("%s layout_editors_reload_idle_cb: setup_editors done", get_exec_time()); + + layout_editors_reload_idle_id = -1; + return FALSE; + } + return TRUE; +} + +void layout_editors_reload_start(void) { GList *work; - DEBUG_1("%s layout_editors_reload_all: start", get_exec_time()); + DEBUG_1("%s layout_editors_reload_start", get_exec_time()); + + if (layout_editors_reload_idle_id != -1) + { + g_source_remove(layout_editors_reload_idle_id); + string_list_free(layout_editors_desktop_files); + } work = layout_window_list; while (work) @@ -1942,20 +1992,23 @@ gtk_ui_manager_remove_ui(lw->ui_manager, lw->ui_editors_id); gtk_ui_manager_remove_action_group(lw->ui_manager, lw->action_group_editors); g_object_unref(lw->action_group_editors); + lw->action_group_editors = NULL; } - - DEBUG_1("%s layout_editors_reload_all: editor_load_descriptions", get_exec_time()); - editor_load_descriptions(); + editor_table_clear(); + layout_editors_reload_idle_id = g_idle_add(layout_editors_reload_idle_cb, NULL); +} - DEBUG_1("%s layout_editors_reload_all: setup_editors", get_exec_time()); - work = layout_window_list; - while (work) +void layout_editors_reload_finish(void) +{ + if (layout_editors_reload_idle_id != -1) { - LayoutWindow *lw = work->data; - work = work->next; - layout_actions_setup_editors(lw); + DEBUG_1("%s layout_editors_reload_finish", get_exec_time()); + g_source_remove(layout_editors_reload_idle_id); + while (layout_editors_reload_idle_id != -1) + { + layout_editors_reload_idle_cb(NULL); + } } - DEBUG_1("%s layout_editors_reload_all: end", get_exec_time()); } void layout_actions_add_window(LayoutWindow *lw, GtkWidget *window) @@ -2032,6 +2085,29 @@ break; } + + if (g_str_has_suffix(action, ".desktop")) + { + /* this may be called before the external editors are read + create a dummy action for now */ + + if (!lw->action_group_editors) + { + lw->action_group_editors = gtk_action_group_new("MenuActionsExternal"); + gtk_ui_manager_insert_action_group(lw->ui_manager, lw->action_group_editors, 1); + } + if (!gtk_action_group_get_action(lw->action_group_editors, action)) + { + GtkActionEntry entry = { action, + GTK_STOCK_MISSING_IMAGE, + action, + NULL, + NULL, + NULL }; + DEBUG_1("Creating temporary action %s", action); + gtk_action_group_add_actions(lw->action_group_editors, &entry, 1, lw); + } + } gtk_ui_manager_add_ui(lw->ui_manager, lw->toolbar_merge_id[type], path, action, action, GTK_UI_MANAGER_TOOLITEM, FALSE); lw->toolbar_actions[type] = g_list_append(lw->toolbar_actions[type], g_strdup(action)); } diff -r 6cae2af8fdd1 -r 8e64965c1d92 src/layout_util.h --- a/src/layout_util.h Sun Sep 06 09:08:37 2009 +0000 +++ b/src/layout_util.h Sun Sep 06 14:01:03 2009 +0000 @@ -33,7 +33,8 @@ void layout_copy_path_update_all(void); -void layout_editors_reload_all(void); +void layout_editors_reload_start(void); +void layout_editors_reload_finish(void); void layout_actions_setup(LayoutWindow *lw); void layout_actions_add_window(LayoutWindow *lw, GtkWidget *window); GtkWidget *layout_actions_menu_bar(LayoutWindow *lw); diff -r 6cae2af8fdd1 -r 8e64965c1d92 src/main.c --- a/src/main.c Sun Sep 06 09:08:37 2009 +0000 +++ b/src/main.c Sun Sep 06 14:01:03 2009 +0000 @@ -31,6 +31,7 @@ #include "image-overlay.h" #include "layout.h" #include "layout_image.h" +#include "layout_util.h" #include "options.h" #include "remote.h" #include "secure_save.h" @@ -605,6 +606,9 @@ { LayoutWindow *lw = NULL; + /* make sure that external editors are loaded, we would save incomplete configuration otherwise */ + layout_editors_reload_finish(); + remote_close(remote_connection); collect_manager_flush(); @@ -816,8 +820,6 @@ /* load_options calls these functions after it parses global options, we have to call it here if it fails */ filter_add_defaults(); filter_rebuild(); - - editor_load_descriptions(); } /* handle missing config file and commandline additions*/ @@ -827,6 +829,8 @@ layout_new_from_config(NULL, NULL, TRUE); } + layout_editors_reload_start(); + if (command_line->collection_list && !command_line->startup_command_line_collection) { GList *work; diff -r 6cae2af8fdd1 -r 8e64965c1d92 src/rcfile.c --- a/src/rcfile.c Sun Sep 06 09:08:37 2009 +0000 +++ b/src/rcfile.c Sun Sep 06 14:01:03 2009 +0000 @@ -884,9 +884,6 @@ options->metadata.write_orientation = FALSE; DEBUG_1("compiled without Exiv2 - disabling XMP write support"); #endif - - /* on startup there are no layout windows and this just loads the editors */ - layout_editors_reload_all(); } static void options_parse_pane_exif(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)