X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmain.c;h=2cef1c940c89d2e745b22cdf6475f4680f9419a9;hb=88fe8ed29e7396372cab9b3fe3182b0f57e3d3e8;hp=7f0c4f28ed84d8e4be6b56ac00f6038898351815;hpb=f8dcb10b89825eced654065c42ca61eaf6632220;p=geeqie.git diff --git a/src/main.c b/src/main.c index 7f0c4f28..2cef1c94 100644 --- a/src/main.c +++ b/src/main.c @@ -42,7 +42,9 @@ #include "layout.h" #include "layout_image.h" #include "layout_util.h" +#include "misc.h" #include "options.h" +#include "rcfile.h" #include "remote.h" #include "secure_save.h" #include "similar.h" @@ -56,19 +58,222 @@ #include "histogram.h" #include "pixbuf_util.h" #include "glua.h" +#include "whereami.h" #ifdef HAVE_CLUTTER #include #endif #ifdef HAVE_GTHREAD -/* FIXME: see below */ +/** @FIXME see below */ #include #endif +/** + * @page diagrams Diagrams + * @section options_overview Options Overview + * + * #_ConfOptions #_LayoutOptions + * + * @startuml + * + * object options.h + * object typedefs.h + * + * options.h : ConfOptions + * options.h : \n + * options.h : Options applicable to **all** Layout Windows + * options.h : These are in the section of geeqierc.xml + * options.h : Available to all modules via the global variable **options** + * typedefs.h : LayoutOptions + * typedefs.h : \n + * typedefs.h : Options applicable to **each** Layout Window + * typedefs.h : These are in the section of geeqierc.xml + * typedefs.h : There is one section for each Layout Window displayed + * typedefs.h : Available via **->options** + * + * @enduml + */ + +/** + * @page diagrams Diagrams + * @section options_diagrams_main Options - New Window From Main + * #main + * #init_options + * #layout_new_from_default + * #load_config_from_file + * #load_options + * #setup_default_options + * + * @startuml + * group main.c + * start + * group options.c + * : **init_options()** + * + * Set **options** = ConfOptions from hard-coded init values; + * end group + * + * group options.c + * : **setup_default_options()** + * + * set hard-coded ConfOptions: + * + * bookmarks: + * * dot dir + * * Home + * * Desktop + * * Collections + * safe delete path + * OSD template string + * sidecar extensions + * shell path and options + * marks tooltips + * help search engine; + * end group + * + * if (first entry + * or + * --new-instance) then (yes) + * group options.c + * : **load_options()** + * ; + * + * split + * : GQ_SYSTEM_WIDE_DIR + * /geeqierc.xml; + * split again + * : XDG_CONFIG_HOME + * /geeqierc.xml; + * split again + * : HOME + * /.geeqie/geeqierc.xml; + * end split + * + * group rcfile.c + * : **load_config_from_file()** + * + * set **options** from file + * and all ->options in file; + * end group + * + * end group + * + * if (broken config. file + * or no config file + * or no layout section loaded + * (i.e. session not saved)) then (yes) + * group layout.c + * : **layout_new_from_default()**; + * if (default.xml exists) then (yes) + * : Load user-saved + * layout_window default options + * from default.xml file; + * else (no) + * : Load hard-coded + * layout_window default options; + * endif + * end group + * endif + * + * else (no) + * : Send --new-window request to remote + * No return to this point + * This instance terminates; + * stop + * endif + * + * : Enter gtk main loop; + * + * end group + * @enduml + */ + +/** + * @page diagrams Diagrams + * @section options_diagrams_remote Options - New Window From Remote + * #layout_new_from_default + * @startuml + * + * group remote.c + * start + * group layout.c + * : **layout_new_from_default()**; + * if (default.xml exists) then (yes) + * : Load user-saved + * layout_window default options + * from default.xml file; + * else (no) + * : Load hard-coded + * layout_window default options; + * endif + * end group + * : set path from PWD; + * @enduml + */ + +/** + * @page diagrams Diagrams + * @section options_diagrams_menu Options - New Window From Menu + * #layout_menu_new_window_cb + * #layout_menu_window_from_current_cb + * #layout_new_from_default + * @startuml + * + * group layout_util.c + * start + * + * split + * : default; + * group layout.c + * : **layout_new_from_default()**; + * if (default.xml exists) then (yes) + * : Load user-saved + * layout_window default options + * from default.xml file; + * else (no) + * : Load hard-coded + * layout_window default options; + * endif + * end group + * + * split again + * : from current + * + * **layout_menu_window_from_current_cb()** + * copy layout_window options + * from current window; + * + * split again + * : named + * + * **layout_menu_new_window_cb()** + * load layout_window options + * from saved xml file list; + * end split + * + * end group + * @enduml + */ + /** + * @file + * @ref options_overview Options Overview + */ + + gboolean thumb_format_changed = FALSE; static RemoteConnection *remote_connection = NULL; +gchar *gq_prefix; +gchar *gq_localedir; +gchar *gq_helpdir; +gchar *gq_htmldir; +gchar *gq_app_dir; +gchar *gq_bin_dir; +gchar *gq_executable_path; +gchar *desktop_file_template; +gchar *instance_identifier; + /* *----------------------------------------------------------------------------- * keyboard functions @@ -138,7 +343,7 @@ static void parse_command_line_add_file(const gchar *file_path, gchar **path, gc { if (!*path) *path = remove_level_from_path(path_parsed); if (!*file) *file = g_strdup(path_parsed); - *list = g_list_prepend(*list, file_data_new_no_grouping(path_parsed)); + *list = g_list_prepend(*list, path_parsed); } } @@ -229,6 +434,8 @@ static void parse_command_line(gint argc, gchar *argv[]) gchar *pwd; gchar *current_dir; gchar *geometry = NULL; + GtkWidget *dialog_warning; + GString *command_line_errors = g_string_new(NULL); command_line = g_new0(CommandLine, 1); @@ -368,7 +575,7 @@ static void parse_command_line(gint argc, gchar *argv[]) else if (strcmp(cmd_line, "-v") == 0 || strcmp(cmd_line, "--version") == 0) { - printf_term(FALSE, "%s %s\n", GQ_APPNAME, VERSION); + printf_term(FALSE, "%s %s GTK%d\n", GQ_APPNAME, VERSION, gtk_major_version); exit(0); } else if (strcmp(cmd_line, "--alternate") == 0) @@ -401,7 +608,8 @@ static void parse_command_line(gint argc, gchar *argv[]) print_term(FALSE, _(" -o:, --log-file: save log data to file\n")); print_term(FALSE, _(" -v, --version print version info\n")); print_term(FALSE, _(" -h, --help show this message\n")); - print_term(FALSE, _(" --disable-clutter disable use of Clutter library (i.e. GPU accel.)\n\n")); + print_term(FALSE, _(" --disable-clutter disable use of Clutter library (i.e. GPU accel.)\n")); + print_term(FALSE, _(" --cache-maintenance run cache maintenance in non-GUI mode\n\n")); #if 0 /* these options are not officially supported! @@ -414,13 +622,28 @@ static void parse_command_line(gint argc, gchar *argv[]) } else if (!remote_do) { - printf_term(TRUE, _("invalid or ignored: %s\nUse --help for options\n"), cmd_line); + command_line_errors = g_string_append(command_line_errors, cmd_line); + command_line_errors = g_string_append(command_line_errors, "\n"); } g_free(cmd_all); g_free(cmd_line); i++; } + + if (command_line_errors->len > 0) + { + dialog_warning = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", "Invalid parameter(s):"); + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog_warning), "%s", command_line_errors->str); + gtk_window_set_title(GTK_WINDOW(dialog_warning), GQ_APPNAME); + gtk_window_set_keep_above(GTK_WINDOW(dialog_warning), TRUE); + gtk_dialog_run(GTK_DIALOG(dialog_warning)); + gtk_widget_destroy(dialog_warning); + g_string_free(command_line_errors, TRUE); + + exit(EXIT_FAILURE); + } + g_free(base_dir); parse_out_relatives(command_line->path); parse_out_relatives(command_line->file); @@ -452,7 +675,7 @@ static void parse_command_line(gint argc, gchar *argv[]) remote_list = g_list_prepend(remote_list, geometry); } remote_list = g_list_prepend(remote_list, "--new-window"); - } + } g_free(app_lock); } @@ -462,16 +685,24 @@ static void parse_command_line(gint argc, gchar *argv[]) { GList *work = remote_errors; - printf_term(TRUE,_("Invalid or ignored remote options: ")); while (work) { gchar *opt = work->data; - printf_term(TRUE, "%s%s", (work == remote_errors) ? "" : ", ", opt); + command_line_errors = g_string_append(command_line_errors, opt); + command_line_errors = g_string_append(command_line_errors, "\n"); work = work->next; } - printf_term(TRUE, _("\nUse --remote-help for valid remote options.\n")); + dialog_warning = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", "Invalid parameter(s):"); + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog_warning), "%s", command_line_errors->str); + gtk_window_set_title(GTK_WINDOW(dialog_warning), GQ_APPNAME); + gtk_window_set_keep_above(GTK_WINDOW(dialog_warning), TRUE); + gtk_dialog_run(GTK_DIALOG(dialog_warning)); + gtk_widget_destroy(dialog_warning); + g_string_free(command_line_errors, TRUE); + + exit(EXIT_FAILURE); } /* prepend the current dir the remote command was made from, @@ -482,6 +713,8 @@ static void parse_command_line(gint argc, gchar *argv[]) remote_list = g_list_prepend(remote_list, pwd); remote_control(argv[0], remote_list, command_line->path, list, command_line->collection_list); + /* There is no return to this point + */ g_free(pwd); g_free(current_dir); } @@ -494,7 +727,7 @@ static void parse_command_line(gint argc, gchar *argv[]) } else { - filelist_free(list); + string_list_free(list); command_line->cmd_list = NULL; } @@ -545,6 +778,7 @@ static void parse_command_line_for_debug_option(gint argc, gchar *argv[]) #endif } +#ifdef HAVE_CLUTTER static gboolean parse_command_line_for_clutter_option(gint argc, gchar *argv[]) { const gchar *clutter_option = "--disable-clutter"; @@ -567,6 +801,96 @@ static gboolean parse_command_line_for_clutter_option(gint argc, gchar *argv[]) return ret; } +#endif + +static gboolean parse_command_line_for_cache_maintenance_option(gint argc, gchar *argv[]) +{ + const gchar *cache_maintenance_option = "--cache-maintenance"; + gint len = strlen(cache_maintenance_option); + gboolean ret = FALSE; + + if (argc >= 2) + { + const gchar *cmd_line = argv[1]; + if (strncmp(cmd_line, cache_maintenance_option, len) == 0) + { + ret = TRUE; + } + } + + return ret; +} + +static void process_command_line_for_cache_maintenance_option(gint argc, gchar *argv[]) +{ + gchar *rc_path; + gchar *folder_path = NULL; + gsize size; + gsize i = 0; + gchar *buf_config_file; + gint diff_count; + + if (argc >= 3) + { + folder_path = expand_tilde(argv[2]); + + if (isdir(folder_path)) + { + rc_path = g_build_filename(get_rc_dir(), RC_FILE_NAME, NULL); + + if (isfile(rc_path)) + { + if (g_file_get_contents(rc_path, &buf_config_file, &size, NULL)) + { + while (i < size) + { + diff_count = strncmp("", &buf_config_file[i], 9); + if (diff_count == 0) + { + break; + } + i++; + } + /* Load only the section */ + load_config_from_buf(buf_config_file, i + 9, FALSE); + + if (options->thumbnails.enable_caching) + { + cache_maintenance(folder_path); + } + else + { + print_term(TRUE, "Caching not enabled\n"); + exit(EXIT_FAILURE); + } + g_free(buf_config_file); + } + else + { + print_term(TRUE, g_strconcat(_("Cannot load "), rc_path, "\n", NULL)); + exit(EXIT_FAILURE); + } + } + else + { + print_term(TRUE, g_strconcat(_("Configuration file path "), rc_path, _(" is not a file\n"), NULL)); + exit(EXIT_FAILURE); + } + g_free(rc_path); + } + else + { + print_term(TRUE, g_strconcat(argv[2], _(" is not a folder\n"), NULL)); + exit(EXIT_FAILURE); + } + g_free(folder_path); + } + else + { + print_term(TRUE, _("No path parameter given\n")); + exit(EXIT_FAILURE); + } +} /* *----------------------------------------------------------------------------- @@ -580,7 +904,7 @@ static gboolean parse_command_line_for_clutter_option(gint argc, gchar *argv[]) static void setup_env_path(void) { const gchar *old_path = g_getenv("PATH"); - gchar *path = g_strconcat(GQ_BIN_DIR, ":", old_path, NULL); + gchar *path = g_strconcat(gq_bin_dir, ":", old_path, NULL); g_setenv("PATH", path, TRUE); g_free(path); } @@ -752,6 +1076,10 @@ static void gtkrc_load(void) static void exit_program_final(void) { LayoutWindow *lw = NULL; + GList *list; + LayoutWindow *tmp_lw; + gchar *archive_dir; + GFile *archive_file; /* make sure that external editors are loaded, we would save incomplete configuration otherwise */ layout_editors_reload_finish(); @@ -760,6 +1088,21 @@ static void exit_program_final(void) collect_manager_flush(); + /* Save the named windows */ + if (layout_window_list && layout_window_list->next) + { + list = layout_window_list; + while (list) + { + tmp_lw = list->data; + if (!g_str_has_prefix(tmp_lw->options.id, "lw")) + { + save_layout(list->data); + } + list = list->next; + } + } + save_options(options); keys_save(); accel_map_save(); @@ -769,6 +1112,27 @@ static void exit_program_final(void) layout_free(lw); } + /* Delete any files/folders in /tmp that have been created by the open archive function */ + archive_dir = g_build_filename(g_get_tmp_dir(), GQ_ARCHIVE_DIR, instance_identifier, NULL); + if (isdir(archive_dir)) + { + archive_file = g_file_new_for_path(archive_dir); + rmdir_recursive(archive_file, NULL, NULL); + g_free(archive_dir); + g_object_unref(archive_file); + } + + /* If there are still sub-dirs created by another instance, this will fail + * but that does not matter */ + archive_dir = g_build_filename(g_get_tmp_dir(), GQ_ARCHIVE_DIR, NULL); + if (isdir(archive_dir)) + { + archive_file = g_file_new_for_path(archive_dir); + g_file_delete(archive_file, NULL, NULL); + g_free(archive_dir); + g_object_unref(archive_file); + } + secure_close(command_line->ssi); gtk_main_quit(); @@ -852,7 +1216,7 @@ void exit_program(void) * crash otherwise. * Ideas for improvement are welcome ;) */ -/* FIXME: this probably needs some better ifdefs. Please report any compilation problems */ +/** @FIXME this probably needs some better ifdefs. Please report any compilation problems */ #if defined(SIGBUS) && defined(SA_SIGINFO) static void sigbus_handler_cb(int signum, siginfo_t *info, void *context) @@ -875,21 +1239,56 @@ static void setup_sigbus_handler(void) #endif } +/** + * @brief Set up the application paths + * + * This function is required for use of AppImages. AppImages are + * relocatable, and therefore cannot use fixed paths to various components. + * These paths were originally #defines created during compilation. + * They are now variables, all defined relative to one level above the + * directory that the executable is run from. + */ +static void create_application_paths(gchar *argv[]) +{ + gchar *dirname; + gchar *tmp; + gint length; + gchar *path; + + length = wai_getExecutablePath(NULL, 0, NULL); + path = (gchar *)malloc(length + 1); + wai_getExecutablePath(path, length, NULL); + path[length] = '\0'; + + gq_executable_path = g_strdup(path); + dirname = g_path_get_dirname(gq_executable_path); // default is /usr/bin/ + gq_prefix = g_path_get_dirname(dirname); + + gq_localedir = g_build_filename(gq_prefix, "share", "locale", NULL); + tmp = g_build_filename(gq_prefix, "share", "doc", NULL); + gq_helpdir = g_strconcat(tmp, G_DIR_SEPARATOR_S, "geeqie-", VERSION, NULL); + gq_htmldir = g_build_filename(gq_helpdir, "html", NULL); + gq_app_dir = g_build_filename(gq_prefix, "share", "geeqie", NULL); + gq_bin_dir = g_build_filename(gq_prefix, "lib", "geeqie", NULL); + desktop_file_template = g_build_filename(gq_app_dir, "template.desktop", NULL); + + g_free(tmp); + g_free(dirname); + g_free(path); +} + gint main(gint argc, gchar *argv[]) { CollectionData *first_collection = NULL; gchar *buf; CollectionData *cd = NULL; gboolean disable_clutter = FALSE; + gboolean single_dir = TRUE; + LayoutWindow *lw; #ifdef HAVE_GTHREAD #if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); -#endif -#ifdef HAVE_CLUTTER -/* FIXME: see below */ - putenv("LIBGL_ALWAYS_INDIRECT=1"); - XInitThreads(); #endif gdk_threads_init(); gdk_threads_enter(); @@ -899,11 +1298,13 @@ gint main(gint argc, gchar *argv[]) /* init execution time counter (debug only) */ init_exec_time(); + create_application_paths(argv); + /* setup locale, i18n */ setlocale(LC_ALL, ""); #ifdef ENABLE_NLS - bindtextdomain(PACKAGE, GQ_LOCALEDIR); + bindtextdomain(PACKAGE, gq_localedir); bind_textdomain_codeset(PACKAGE, "UTF-8"); textdomain(PACKAGE); #endif @@ -942,6 +1343,7 @@ gint main(gint argc, gchar *argv[]) if (gtk_clutter_init(&argc, &argv) != CLUTTER_INIT_SUCCESS) { log_printf("Can't initialize clutter-gtk.\nStart Geeqie with the option \"geeqie --disable-clutter\""); + runcmd("zenity --error --title=\"Geeqie\" --text \"Can't initialize clutter-gtk.\n\nStart Geeqie with the option:\n geeqie --disable-clutter\" --width=300"); exit(1); } } @@ -970,8 +1372,8 @@ gint main(gint argc, gchar *argv[]) options->disable_gpu = TRUE; } - DEBUG_1("%s main: parse_command_line", get_exec_time()); - parse_command_line(argc, argv); + /* Generate a unique identifier used by the open archive function */ + instance_identifier = g_strdup_printf("%x", g_random_int()); DEBUG_1("%s main: mkdir_if_not_exists", get_exec_time()); /* these functions don't depend on config file */ @@ -983,133 +1385,195 @@ gint main(gint argc, gchar *argv[]) setup_env_path(); - keys_load(); - accel_map_load(); + if (parse_command_line_for_cache_maintenance_option(argc, argv)) + { + process_command_line_for_cache_maintenance_option(argc, argv); + } + else + { + DEBUG_1("%s main: parse_command_line", get_exec_time()); + parse_command_line(argc, argv); - /* restore session from the config file */ + keys_load(); + accel_map_load(); + /* restore session from the config file */ - DEBUG_1("%s main: load_options", get_exec_time()); - if (!load_options(options)) - { - /* load_options calls these functions after it parses global options, we have to call it here if it fails */ - filter_add_defaults(); - filter_rebuild(); - } -#ifdef HAVE_CLUTTER -/* FIXME: For the background of this see: - * https://github.com/BestImageViewer/geeqie/issues/397 - * The feature CLUTTER_FEATURE_SWAP_EVENTS indictates if the - * system is liable to exhibit this problem. - * The user is provided with an override in Preferences/Behavior - */ - if (!options->override_disable_gpu && !options->disable_gpu) - { - DEBUG_1("CLUTTER_FEATURE_SWAP_EVENTS %d",clutter_feature_available(CLUTTER_FEATURE_SWAP_EVENTS)); - if (clutter_feature_available(CLUTTER_FEATURE_SWAP_EVENTS) != 0) + DEBUG_1("%s main: load_options", get_exec_time()); + if (!load_options(options)) { - options->disable_gpu = TRUE; + /* load_options calls these functions after it parses global options, we have to call it here if it fails */ + filter_add_defaults(); + filter_rebuild(); } - } -#endif - /* handle missing config file and commandline additions*/ - if (!layout_window_list) - { - /* broken or no config file */ - layout_new_from_config(NULL, NULL, TRUE); - } + #ifdef HAVE_CLUTTER + /** @FIXME For the background of this see: + * https://github.com/BestImageViewer/geeqie/issues/397 + * The feature CLUTTER_FEATURE_SWAP_EVENTS indictates if the + * system is liable to exhibit this problem. + * The user is provided with an override in Preferences/Behavior + */ + if (!options->override_disable_gpu && !options->disable_gpu) + { + DEBUG_1("CLUTTER_FEATURE_SWAP_EVENTS %d",clutter_feature_available(CLUTTER_FEATURE_SWAP_EVENTS)); + if (clutter_feature_available(CLUTTER_FEATURE_SWAP_EVENTS) != 0) + { + options->disable_gpu = TRUE; + } + } + #endif - layout_editors_reload_start(); + /* handle missing config file and commandline additions*/ + if (!layout_window_list) + { + /* broken or no config file or no section */ + layout_new_from_default(); + } - if (command_line->collection_list && !command_line->startup_command_line_collection) - { - GList *work; + layout_editors_reload_start(); - work = command_line->collection_list; - while (work) + /* If no --list option, open a separate collection window for each + * .gqv file on the command line + */ + if (command_line->collection_list && !command_line->startup_command_line_collection) { - CollectWindow *cw; - const gchar *path; + GList *work; - path = work->data; - work = work->next; + work = command_line->collection_list; + while (work) + { + CollectWindow *cw; + const gchar *path; - cw = collection_window_new(path); - if (!first_collection && cw) first_collection = cw->cd; + path = work->data; + work = work->next; + + cw = collection_window_new(path); + if (!first_collection && cw) first_collection = cw->cd; + } } - } - if (command_line->log_file) - { - gchar *pathl; - gchar *path = g_strdup(command_line->log_file); + if (command_line->log_file) + { + gchar *pathl; + gchar *path = g_strdup(command_line->log_file); - pathl = path_from_utf8(path); - command_line->ssi = secure_open(pathl); - } + pathl = path_from_utf8(path); + command_line->ssi = secure_open(pathl); + } - if (command_line->cmd_list || - (command_line->startup_command_line_collection && command_line->collection_list)) - { - GList *work; + /* If there is a files list on the command line and no --list option, + * check if they are all in the same folder + */ + if (command_line->cmd_list && !(command_line->startup_command_line_collection)) + { + GList *work; + gchar *path = NULL; + + work = command_line->cmd_list; - if (command_line->startup_command_line_collection) + while (work && single_dir) + { + gchar *dirname; + + dirname = g_path_get_dirname(work->data); + if (!path) + { + path = g_strdup(dirname); + } + else + { + if (g_strcmp0(path, dirname) != 0) + { + single_dir = FALSE; + } + } + g_free(dirname); + work = work->next; + } + g_free(path); + } + + /* Files from multiple folders, or --list option given + * then open an unnamed collection and insert all files + */ + if ((command_line->cmd_list && !single_dir) || (command_line->startup_command_line_collection && command_line->cmd_list)) { + GList *work; CollectWindow *cw; - cw = collection_window_new(""); + cw = collection_window_new(NULL); cd = cw->cd; - } - else - { - cd = collection_new(""); /* if we pass NULL, untitled counter is falsely increm. */ - } - g_free(cd->path); - cd->path = NULL; - g_free(cd->name); - cd->name = g_strdup(_("Command line")); + collection_path_changed(cd); - collection_path_changed(cd); + work = command_line->cmd_list; + while (work) + { + FileData *fd; - work = command_line->cmd_list; - while (work) - { - collection_add(cd, (FileData *)work->data, FALSE); - work = work->next; - } + fd = file_data_new_simple(work->data); + collection_add(cd, fd, FALSE); + file_data_unref(fd); + work = work->next; + } - work = command_line->collection_list; - while (work) + work = command_line->collection_list; + while (work) + { + collection_load(cd, (gchar *)work->data, COLLECTION_LOAD_APPEND); + work = work->next; + } + + if (cd->list) layout_image_set_collection(NULL, cd, cd->list->data); + + /* mem leak, we never unref this collection when !startup_command_line_collection + * (the image view of the main window does not hold a ref to the collection) + * this is sort of unavoidable, for if it did hold a ref, next/back + * may not work as expected when closing collection windows. + * + * collection_unref(cd); + */ + + } + else if (first_collection) { - collection_load(cd, (gchar *)work->data, COLLECTION_LOAD_APPEND); - work = work->next; + layout_image_set_collection(NULL, first_collection, + collection_get_first(first_collection)); } - if (cd->list) layout_image_set_collection(NULL, cd, cd->list->data); - - /* mem leak, we never unref this collection when !startup_command_line_collection - * (the image view of the main window does not hold a ref to the collection) - * this is sort of unavoidable, for if it did hold a ref, next/back - * may not work as expected when closing collection windows. - * - * collection_unref(cd); + /* If the files on the command line are from one folder, select those files + * unless it is a command line collection - then leave focus on collection window */ + lw = NULL; + layout_valid(&lw); - } - else if (first_collection) - { - layout_image_set_collection(NULL, first_collection, - collection_get_first(first_collection)); - } + if (single_dir && command_line->cmd_list && !command_line->startup_command_line_collection) + { + GList *work; + GList *selected; + FileData *fd; + + selected = NULL; + work = command_line->cmd_list; + while (work) + { + fd = file_data_new_simple((gchar *)work->data); + selected = g_list_append(selected, fd); + file_data_unref(fd); + work = work->next; + } + layout_select_list(lw, selected); + } - buf = g_build_filename(get_rc_dir(), ".command", NULL); - remote_connection = remote_server_init(buf, cd); - g_free(buf); + buf = g_build_filename(get_rc_dir(), ".command", NULL); + remote_connection = remote_server_init(buf, cd); + g_free(buf); - marks_load(); + marks_load(); + } DEBUG_1("%s main: gtk_main", get_exec_time()); gtk_main();