From: Colin Clark Date: Wed, 4 Aug 2021 15:11:38 +0000 (+0100) Subject: Fix #872: Geometry of Icon pane not being saved X-Git-Tag: v1.7~81 X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?p=geeqie.git;a=commitdiff_plain;h=094ce1cf0e62e2faf72e6091d714dbfa304b5f73 Fix #872: Geometry of Icon pane not being saved https://github.com/BestImageViewer/geeqie/issues/872 Permit the user to save the current window layout as the default for all new windows. --- diff --git a/doc/docbook/GuideOptionsWindow.xml b/doc/docbook/GuideOptionsWindow.xml index 04c4708f..62ca439d 100644 --- a/doc/docbook/GuideOptionsWindow.xml +++ b/doc/docbook/GuideOptionsWindow.xml @@ -7,7 +7,7 @@ - Remember window positions + Remember session This will maintain windows size and position between Geeqie sessions. @@ -96,6 +96,18 @@ + + + + Use current layout for default + + + + Press the Set button to store the current window layout for use as the default for all new windows. + + + +
Size diff --git a/src/layout.c b/src/layout.c index 37fe728a..fae646b2 100644 --- a/src/layout.c +++ b/src/layout.c @@ -2598,6 +2598,7 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, GdkGeometry hint; GdkWindowHints hint_mask; Histogram *histogram; + gchar *default_path; DEBUG_1("%s layout_new: start", get_exec_time()); lw = g_new0(LayoutWindow, 1); @@ -2625,11 +2626,16 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, /* divider positions */ + default_path = g_build_filename(get_rc_dir(), DEFAULT_WINDOW_LAYOUT, NULL); + if (!options->save_window_positions) { - lw->options.main_window.hdivider_pos = MAIN_WINDOW_DIV_HPOS; - lw->options.main_window.vdivider_pos = MAIN_WINDOW_DIV_VPOS; - lw->options.float_window.vdivider_pos = MAIN_WINDOW_DIV_VPOS; + if (!isfile(default_path)) + { + lw->options.main_window.hdivider_pos = MAIN_WINDOW_DIV_HPOS; + lw->options.main_window.vdivider_pos = MAIN_WINDOW_DIV_VPOS; + lw->options.float_window.vdivider_pos = MAIN_WINDOW_DIV_VPOS; + } } /* window */ @@ -2657,7 +2663,7 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, gtk_window_set_geometry_hints(GTK_WINDOW(lw->window), NULL, &hint, GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | hint_mask); - if (options->save_window_positions) + if (options->save_window_positions || isfile(default_path)) { gtk_window_set_default_size(GTK_WINDOW(lw->window), lw->options.main_window.w, lw->options.main_window.h); // if (!layout_window_list) @@ -2673,6 +2679,7 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, gtk_window_set_default_size(GTK_WINDOW(lw->window), MAINWINDOW_DEF_WIDTH, MAINWINDOW_DEF_HEIGHT); } + g_free(default_path); g_signal_connect(G_OBJECT(lw->window), "delete_event", G_CALLBACK(layout_delete_cb), lw); @@ -3041,5 +3048,31 @@ void layout_update_from_config(LayoutWindow *lw, const gchar **attribute_names, free_layout_options_content(&lop); } +LayoutWindow *layout_new_from_default() +{ + LayoutWindow *lw; + gchar *path = NULL; + GList *work; + gboolean success; + gchar *default_path; + + default_path = g_build_filename(get_rc_dir(), DEFAULT_WINDOW_LAYOUT, NULL); + success = load_config_from_file(default_path, TRUE); + g_free(default_path); + + if (success) + { + work = g_list_last(layout_window_list); + lw = work->data; + g_free(lw->options.id); + lw->options.id = g_strdup(layout_get_unique_id()); + } + else + { + layout_new_from_config(NULL, NULL, TRUE); + } + return lw; +} + /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/layout.h b/src/layout.h index ddb0d896..cf1441c3 100644 --- a/src/layout.h +++ b/src/layout.h @@ -32,6 +32,7 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, const gchar *geometry); LayoutWindow *layout_new_from_config(const gchar **attribute_names, const gchar **attribute_values, gboolean use_commandline); void layout_update_from_config(LayoutWindow *lw, const gchar **attribute_names, const gchar **attribute_values); +LayoutWindow *layout_new_from_default(); void layout_close(LayoutWindow *lw); void layout_free(LayoutWindow *lw); diff --git a/src/layout_util.c b/src/layout_util.c index a9c7da75..9a2cb590 100644 --- a/src/layout_util.c +++ b/src/layout_util.c @@ -221,31 +221,6 @@ static void layout_exit_fullscreen(LayoutWindow *lw) layout_image_full_screen_stop(lw); } -LayoutWindow *layout_menu_new_window(GtkAction *action, gpointer data) -{ - LayoutWindow *lw = data; - LayoutWindow *nw; - LayoutOptions lop; - gboolean tmp = options->save_window_positions; - - if (!options->use_saved_window_positions_for_new_windows) - options->save_window_positions = FALSE; /* let the windowmanager decide for the first time */ - - layout_exit_fullscreen(lw); - - layout_sync_options_with_current_state(lw); - lop = lw->options; /* we can copy it directly, no strings are modified */ - - lop.id = NULL; /* get a new id */ - nw = layout_new(NULL, &lop); - layout_sort_set(nw, options->file_sort.method, options->file_sort.ascending); - layout_set_fd(nw, lw->dir_fd); - options->save_window_positions = tmp; - - return nw; -} - - static void clear_marks_cancel_cb(GenericDialog *gd, gpointer data) { generic_dialog_close(gd); @@ -2233,7 +2208,7 @@ static void window_delete_ok_cb(GenericDialog *gd, gpointer data) static void layout_menu_window_default_cb(GtkWidget *widget, gpointer data) { - layout_new_from_config(NULL, NULL, TRUE); + layout_new_from_default(); } static void layout_menu_windows_menu_cb(GtkWidget *widget, gpointer data) diff --git a/src/layout_util.h b/src/layout_util.h index c2a4d3a4..5b15aa37 100644 --- a/src/layout_util.h +++ b/src/layout_util.h @@ -73,7 +73,6 @@ void layout_bars_close(LayoutWindow *lw); void layout_exif_window_new(LayoutWindow *lw); gboolean is_help_key(GdkEventKey *event); -LayoutWindow *layout_menu_new_window(GtkAction *action, gpointer data); void layout_menu_close_cb(GtkAction *action, gpointer data); GtkWidget *layout_actions_menu_tool_bar(LayoutWindow *lw); #endif diff --git a/src/main.c b/src/main.c index fd3343ee..ee4de769 100644 --- a/src/main.c +++ b/src/main.c @@ -44,6 +44,7 @@ #include "layout_util.h" #include "misc.h" #include "options.h" +#include "rcfile.h" #include "remote.h" #include "secure_save.h" #include "similar.h" @@ -67,6 +68,198 @@ #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; @@ -1112,8 +1305,8 @@ gint main(gint argc, gchar *argv[]) /* handle missing config file and commandline additions*/ if (!layout_window_list) { - /* broken or no config file */ - layout_new_from_config(NULL, NULL, TRUE); + /* broken or no config file or no section */ + layout_new_from_default(); } layout_editors_reload_start(); diff --git a/src/main.h b/src/main.h index 61cc21d3..87aa96ef 100644 --- a/src/main.h +++ b/src/main.h @@ -88,6 +88,7 @@ #define GQ_SYSTEM_WIDE_DIR "/etc/" GQ_APPNAME_LC #define RC_FILE_NAME GQ_APPNAME_LC "rc.xml" +#define DEFAULT_WINDOW_LAYOUT "default_window_layout.xml" #define GQ_COLLECTION_EXT ".gqv" diff --git a/src/preferences.c b/src/preferences.c index d0d34a2c..476b4812 100644 --- a/src/preferences.c +++ b/src/preferences.c @@ -41,6 +41,7 @@ #include "metadata.h" #include "osd.h" #include "pixbuf_util.h" +#include "rcfile.h" #include "slideshow.h" #include "toolbar.h" #include "trash.h" @@ -2311,11 +2312,32 @@ static void config_tab_image(GtkWidget *notebook) } /* windows tab */ + +static void save_default_window_layout_cb(GtkWidget *widget, gpointer data) +{ + LayoutWindow *lw = NULL; + gchar *default_path; + gchar *tmp_id; + + /* Get current lw */ + layout_valid(&lw); + + tmp_id = lw->options.id; + lw->options.id = g_strdup("lw_default"); + + default_path = g_build_filename(get_rc_dir(), DEFAULT_WINDOW_LAYOUT, NULL); + save_default_layout_options_to_file(default_path, options, lw); + g_free(lw->options.id); + lw->options.id = tmp_id; + g_free(default_path); +} + static void config_tab_windows(GtkWidget *notebook) { GtkWidget *hbox; GtkWidget *vbox; GtkWidget *group; + GtkWidget *subgroup; GtkWidget *button; GtkWidget *ct_button; GtkWidget *spin; @@ -2324,7 +2346,7 @@ static void config_tab_windows(GtkWidget *notebook) group = pref_group_new(vbox, FALSE, _("State"), GTK_ORIENTATION_VERTICAL); - ct_button = pref_checkbox_new_int(group, _("Remember window positions"), + ct_button = pref_checkbox_new_int(group, _("Remember session"), options->save_window_positions, &c_options->save_window_positions); button = pref_checkbox_new_int(group, _("Use saved window positions also for new windows"), @@ -2344,6 +2366,10 @@ static void config_tab_windows(GtkWidget *notebook) pref_checkbox_new_int(group, _("Show window IDs"), options->show_window_ids, &c_options->show_window_ids); + subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); + pref_label_new(subgroup, _("Use current layout for default: ")); + button = pref_button_new(subgroup, NULL, _("Set"), FALSE, G_CALLBACK(save_default_window_layout_cb), NULL); + group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL); pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"), diff --git a/src/rcfile.c b/src/rcfile.c index 7f3d3842..8c90aec1 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -699,12 +699,16 @@ gboolean save_config_to_file(const gchar *utf8_path, ConfOptions *options, Layou /* Layout Options */ if (!lw) { - work = layout_window_list; - while (work) + /* If not save_window_positions, do not include a section */ + if (options->save_window_positions) { - LayoutWindow *lw = work->data; - layout_write_config(lw, outstr, indent); - work = work->next; + work = layout_window_list; + while (work) + { + LayoutWindow *lw = work->data; + layout_write_config(lw, outstr, indent); + work = work->next; + } } } else @@ -729,6 +733,57 @@ gboolean save_config_to_file(const gchar *utf8_path, ConfOptions *options, Layou return TRUE; } +gboolean save_default_layout_options_to_file(const gchar *utf8_path, ConfOptions *options, LayoutWindow *lw) +{ + SecureSaveInfo *ssi; + gchar *rc_pathl; + GString *outstr; + gint indent = 0; + + rc_pathl = path_from_utf8(utf8_path); + ssi = secure_open(rc_pathl); + g_free(rc_pathl); + if (!ssi) + { + log_printf(_("error saving default layout file: %s\n"), utf8_path); + return FALSE; + } + + outstr = g_string_new(""); + g_string_append_printf(outstr, "\n"); + WRITE_SEPARATOR(); + + WRITE_STRING("\n"); + indent++; + + layout_write_config(lw, outstr, indent); + + indent--; + WRITE_NL(); WRITE_STRING("\n"); + WRITE_SEPARATOR(); + + secure_fputs(ssi, outstr->str); + g_string_free(outstr, TRUE); + + if (secure_close(ssi)) + { + log_printf(_("error saving config file: %s\nerror: %s\n"), utf8_path, + secsave_strerror(secsave_errno)); + return FALSE; + } + + return TRUE; +} + /* *----------------------------------------------------------------------------- * loading attributes for elements (private) diff --git a/src/rcfile.h b/src/rcfile.h index 919139b0..4d873ba8 100644 --- a/src/rcfile.h +++ b/src/rcfile.h @@ -84,6 +84,7 @@ void options_parse_func_set_data(GQParserData *parser_data, gpointer data); gboolean save_config_to_file(const gchar *utf8_path, ConfOptions *options, LayoutWindow *lw); +gboolean save_default_layout_options_to_file(const gchar *utf8_path, ConfOptions *options, LayoutWindow *lw); gboolean load_config_from_buf(const gchar *buf, gsize size, gboolean startup); gboolean load_config_from_file(const gchar *utf8_path, gboolean startup); diff --git a/src/remote.c b/src/remote.c index 7149c3c8..90030ac5 100644 --- a/src/remote.c +++ b/src/remote.c @@ -460,7 +460,8 @@ static void gr_new_window(const gchar *text, GIOChannel *channel, gpointer data) if (!layout_valid(&lw)) return; - lw_id = layout_menu_new_window(NULL, lw); + lw_id = layout_new_from_default(); + layout_set_path(lw_id, pwd); }