Fix #543: Size of dialog windows in the GTK3 version is too small
authorColin Clark <colin.clark@cclark.uk>
Thu, 23 Nov 2017 20:44:03 +0000 (20:44 +0000)
committerColin Clark <colin.clark@cclark.uk>
Thu, 23 Nov 2017 20:44:03 +0000 (20:44 +0000)
https://github.com/BestImageViewer/geeqie/issues/543

Additional option in Preferences/Windows to preserve size and location
of dialog windows

doc/docbook/GuideOptionsWindow.xml
src/layout.c
src/options.c
src/options.h
src/preferences.c
src/rcfile.c
src/ui_utildlg.c
src/ui_utildlg.h

index cfcf70f..7ada147 100644 (file)
         </listitem>\r
       </varlistentry>\r
     </variablelist>\r
+    <variablelist>\r
+      <varlistentry>\r
+        <term>\r
+          <guilabel>Remember dialog window positions</guilabel>\r
+        </term>\r
+        <listitem>\r
+          <para>This will maintain dialog windows size and position between Geeqie sessions.</para>\r
+        </listitem>\r
+      </varlistentry>\r
+    </variablelist>\r
   </section>\r
   <section id="Size">\r
     <title>Size</title>\r
index 21a9c1b..f50d683 100644 (file)
@@ -2489,6 +2489,10 @@ void layout_write_config(LayoutWindow *lw, GString *outstr, gint indent)
        bar_sort_write_config(lw->bar_sort, outstr, indent + 1);
        bar_write_config(lw->bar, outstr, indent + 1);
 
+       WRITE_SEPARATOR();
+       generic_dialog_windows_write_config(outstr, indent + 1);
+
+       WRITE_SEPARATOR();
        layout_toolbar_write_config(lw, TOOLBAR_MAIN, outstr, indent + 1);
 
        WRITE_NL(); WRITE_STRING("</layout>");
index b0695bc..1f982dd 100644 (file)
@@ -59,6 +59,7 @@ ConfOptions *init_options(ConfOptions *options)
        options->save_window_positions = TRUE;
        options->use_saved_window_positions_for_new_windows = FALSE;
        options->tools_restore_state = TRUE;
+       options->save_dialog_window_positions = FALSE;
 
        options->file_ops.confirm_delete = TRUE;
        options->file_ops.enable_delete_key = TRUE;
index ca08d39..6d89a49 100644 (file)
@@ -56,6 +56,7 @@ struct _ConfOptions
        gboolean save_window_positions;
        gboolean use_saved_window_positions_for_new_windows;
        gboolean tools_restore_state;
+       gboolean save_dialog_window_positions;
 
        gint log_window_lines;
 
index 46d8736..6e63eaf 100644 (file)
@@ -255,6 +255,7 @@ static void config_window_apply(void)
        options->tools_restore_state = c_options->tools_restore_state;
        options->save_window_positions = c_options->save_window_positions;
        options->use_saved_window_positions_for_new_windows = c_options->use_saved_window_positions_for_new_windows;
+       options->save_dialog_window_positions = c_options->save_dialog_window_positions;
        options->image.scroll_reset_method = c_options->image.scroll_reset_method;
        options->image.zoom_2pass = c_options->image.zoom_2pass;
        options->image.fit_window_to_image = c_options->image.fit_window_to_image;
@@ -1792,6 +1793,9 @@ static void config_tab_windows(GtkWidget *notebook)
        pref_checkbox_new_int(group, _("Remember tool state (float/hidden)"),
                              options->tools_restore_state, &c_options->tools_restore_state);
 
+       pref_checkbox_new_int(group, _("Remember dialog window positions"),
+                             options->save_dialog_window_positions, &c_options->save_dialog_window_positions);
+
        group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL);
 
        pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"),
index 4d3356d..224a874 100644 (file)
@@ -44,7 +44,7 @@
 #include "metadata.h"
 #include "bar_gps.h"
 #include "dupe.h"
-
+#include "ui_utildlg.h"
 
 /*
  *-----------------------------------------------------------------------------
@@ -337,6 +337,7 @@ static void write_global_attributes(GString *outstr, gint indent)
        WRITE_NL(); WRITE_BOOL(*options, save_window_positions);
        WRITE_NL(); WRITE_BOOL(*options, use_saved_window_positions_for_new_windows);
        WRITE_NL(); WRITE_BOOL(*options, tools_restore_state);
+       WRITE_NL(); WRITE_BOOL(*options, save_dialog_window_positions);
 
        WRITE_NL(); WRITE_UINT(*options, log_window_lines);
        WRITE_NL(); WRITE_BOOL(*options, log_window.timer_data);
@@ -637,6 +638,7 @@ static gboolean load_global_params(const gchar **attribute_names, const gchar **
                if (READ_BOOL(*options, save_window_positions)) continue;
                if (READ_BOOL(*options, use_saved_window_positions_for_new_windows)) continue;
                if (READ_BOOL(*options, tools_restore_state)) continue;
+               if (READ_BOOL(*options, save_dialog_window_positions)) continue;
 
                if (READ_INT(*options, log_window_lines)) continue;
                if (READ_BOOL(*options, log_window.timer_data)) continue;
@@ -1098,6 +1100,19 @@ static void options_parse_toolbar(GQParserData *parser_data, GMarkupParseContext
                options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
                }
 }
+static void options_parse_dialogs(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
+{
+       if (g_ascii_strcasecmp(element_name, "window") == 0)
+               {
+               generic_dialog_windows_load_config(attribute_names, attribute_values);
+               options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+               }
+       else
+               {
+               log_printf("unexpected in <dialogs>: <%s>\n", element_name);
+               options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+               }
+}
 
 static void options_parse_layout(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
 {
@@ -1129,6 +1144,10 @@ static void options_parse_layout(GQParserData *parser_data, GMarkupParseContext
                {
                options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
                }
+       else if (g_ascii_strcasecmp(element_name, "dialogs") == 0)
+               {
+               options_parse_func_push(parser_data, options_parse_dialogs, NULL, NULL);
+               }
        else
                {
                log_printf("unexpected in <layout>: <%s>\n", element_name);
index 2641e79..897488f 100644 (file)
@@ -36,6 +36,7 @@
 #include "ui_utildlg.h"
 
 #include "filedata.h"
+#include "rcfile.h"
 #include "ui_fileops.h"
 #include "ui_misc.h"
 #include "ui_pathsel.h"
  *-----------------------------------------------------------------------------
  */
 
+typedef struct _DialogWindow DialogWindow;
+struct _DialogWindow
+{
+       gint x;
+       gint y;
+       gint w;
+       gint h;
+       gchar *title;
+       gchar *role;
+};
+
+static GList *dialog_windows = NULL;
+
+static void generic_dialog_save_window(const gchar *title, const gchar *role, gint x, gint y, gint h, gint w)
+{
+       GList *work;
+
+       work = g_list_first(dialog_windows);
+       while (work)
+               {
+               DialogWindow *dw = work->data;
+               if (g_strcmp0(dw->title ,title) == 0 && g_strcmp0(dw->role, role) == 0)
+                       {
+                       dw->x = x;
+                       dw->y = y;
+                       dw->w = w;
+                       dw->h = h;
+                       return;
+                       }
+               work = work->next;
+               }
+
+       DialogWindow *dw = g_new0(DialogWindow, 1);
+       dw->title = g_strdup(title);
+       dw->role = g_strdup(role);
+       dw->x = x;
+       dw->y = y;
+       dw->w = w;
+       dw->h = h;
+
+       dialog_windows = g_list_append(dialog_windows, dw);
+}
+
+static gboolean generic_dialog_find_window(const gchar *title, const gchar *role, gint *x, gint *y, gint *h, gint *w)
+{
+       GList *work;
+
+       work = g_list_first(dialog_windows);
+       while (work)
+               {
+               DialogWindow *dw = work->data;
+
+               if (g_strcmp0(dw->title,title) == 0 && g_strcmp0(dw->role, role) == 0)
+                       {
+                       *x = dw->x;
+                       *y = dw->y;
+                       *w = dw->w;
+                       *h = dw->h;
+                       return TRUE;
+                       }
+               work = work->next;
+               }
+       return FALSE;
+}
+
 void generic_dialog_close(GenericDialog *gd)
 {
+       gchar *ident_string;
+       gchar *full_title;
+       gchar *actual_title;
+       gint x, y, h, w;
+
+       gdk_window_get_root_origin(gtk_widget_get_window (gd->dialog), &x, &y);
+       w = gdk_window_get_width(gtk_widget_get_window (gd->dialog));
+       h = gdk_window_get_height(gtk_widget_get_window (gd->dialog));
+
+       /* The window title is modified in window.c: window_new()
+        * by appending the string " - Geeqie"
+        */
+       ident_string = g_strconcat(" - ", GQ_APPNAME, NULL);
+       full_title = g_strdup(gtk_window_get_title(GTK_WINDOW(gd->dialog)));
+       actual_title = strndup(full_title, g_strrstr(full_title, ident_string) - full_title);
+
+       generic_dialog_save_window(actual_title, gtk_window_get_role(GTK_WINDOW(gd->dialog)), x, y, w, h);
+
        gtk_widget_destroy(gd->dialog);
        g_free(gd);
+       g_free(ident_string);
+       g_free(full_title);
+       g_free(actual_title);
 }
 
 static void generic_dialog_click_cb(GtkWidget *widget, gpointer data)
@@ -227,6 +314,68 @@ GtkWidget *generic_dialog_add_message(GenericDialog *gd, const gchar *icon_stock
        return vbox;
 }
 
+void generic_dialog_windows_load_config(const gchar **attribute_names, const gchar **attribute_values)
+{
+       DialogWindow *dw =  g_new0(DialogWindow, 1);
+       gchar *title = NULL;
+       gchar *role = NULL;
+       gint x = 0;
+       gint y = 0;
+       gint w = 0;
+       gint h = 0;
+
+       while (*attribute_names)
+               {
+               const gchar *option = *attribute_names++;
+               const gchar *value = *attribute_values++;
+               if (READ_CHAR_FULL("title", title)) continue;
+               if (READ_CHAR_FULL("role", role)) continue;
+               if (READ_INT_FULL("x", x)) continue;
+               if (READ_INT_FULL("y", y)) continue;
+               if (READ_INT_FULL("w", w)) continue;
+               if (READ_INT_FULL("h", h)) continue;
+
+               log_printf("unknown attribute %s = %s\n", option, value);
+               }
+
+       if (title && title[0] != 0)
+               {
+               dw->title = g_strdup(title);
+               dw->role = g_strdup(role);
+               dw->x = x;
+               dw->y = y;
+               dw->w = w;
+               dw->h = h;
+
+               dialog_windows = g_list_append(dialog_windows, dw);
+               }
+}
+
+void generic_dialog_windows_write_config(GString *outstr, gint indent)
+{
+       GList *work;
+
+       WRITE_NL(); WRITE_STRING("<%s>", "dialogs");
+       indent++;
+
+       work = g_list_first(dialog_windows);
+       while (work)
+               {
+               DialogWindow *dw = work->data;
+               WRITE_NL(); WRITE_STRING("<window ");
+               write_char_option(outstr, indent + 1, "title", dw->title);
+               write_char_option(outstr, indent + 1, "role", dw->role);
+               WRITE_INT(*dw, x);
+               WRITE_INT(*dw, y);
+               WRITE_INT(*dw, w);
+               WRITE_INT(*dw, h);
+               WRITE_STRING("/>");
+               work = work->next;
+               }
+       indent--;
+       WRITE_NL(); WRITE_STRING("</%s>", "dialogs");
+}
+
 static void generic_dialog_setup(GenericDialog *gd,
                                 const gchar *title,
                                 const gchar *role,
@@ -234,6 +383,7 @@ static void generic_dialog_setup(GenericDialog *gd,
                                 void (*cancel_cb)(GenericDialog *, gpointer), gpointer data)
 {
        GtkWidget *vbox;
+       gint x, y, w, h;
 
        gd->auto_close = auto_close;
        gd->data = data;
@@ -242,6 +392,15 @@ static void generic_dialog_setup(GenericDialog *gd,
        gd->dialog = window_new(GTK_WINDOW_TOPLEVEL, role, NULL, NULL, title);
        gtk_window_set_type_hint(GTK_WINDOW(gd->dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
 
+       if (options->save_dialog_window_positions)
+               {
+               if (generic_dialog_find_window(title, role, &x, &y, &w, &h))
+                       {
+                       gtk_window_set_default_size(GTK_WINDOW(gd->dialog), w, h);
+                       gtk_window_move(GTK_WINDOW(gd->dialog), x, y);
+                       }
+               }
+
        if (parent)
                {
                GtkWindow *window = NULL;
index 7a5e7e1..963d327 100644 (file)
@@ -99,6 +99,7 @@ void file_dialog_add_filter(FileDialog *fd, const gchar *filter, const gchar *fi
 void file_dialog_clear_filter(FileDialog *fd);
 void file_dialog_sync_history(FileDialog *fd, gboolean dir_only);
 
-
+void generic_dialog_windows_load_config(const gchar **window_attributes, const gchar **attribute_values);
+void generic_dialog_windows_write_config(GString *outstr, gint indent);
 #endif
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */