[balsa/autocrypt: 5/11] Simplify window geometry management



commit 98d51aeb6613ff513d04bb5cda38ea030fadf731
Author: Albrecht Dreß <albrecht dress arcor de>
Date:   Sat Jan 5 14:13:44 2019 -0500

    Simplify window geometry management
    
    * libbalsa/Makefile.am: add geometry manager module
    * libbalsa/geometry-manager.[hc]: geometry manager module
      implementation
    * libbalsa/libbalsa-gpgme-cb.c: use geometry manager for the
      key list dialogue
    * libbalsa/libbalsa-gpgme-widgets.c: use geometry manager for
      the key dialogue
    * libbalsa/libbalsa.h: simplify libbalsa_show_message_source()
      api, remove unimplemented function prototype
    * libbalsa/source-viewer.c: use geometry manager, simplify
      libbalsa_show_message_source() api
    * src/balsa-app.c: remove initialisation of obsolete balsa_app
      items
    * src/balsa-app.h: remove obsolete balsa_app items
    * src/balsa-index.c: use new libbalsa_show_message_source() api
    * src/folder-conf.c, src/main-window.c, src/main.c,
    src/message-window.c, src/sendmsg-window.c: use geometry manager
      and new libbalsa_show_message_source() api
    * src/save-restore.c: use geometry manager to load and save values
    
    Signed-off-by: Peter Bloomfield <PeterBloomfield bellsouth net>

 ChangeLog                         |  26 +++++-
 libbalsa/Makefile.am              |   2 +
 libbalsa/geometry-manager.c       | 174 ++++++++++++++++++++++++++++++++++++++
 libbalsa/geometry-manager.h       |  90 ++++++++++++++++++++
 libbalsa/libbalsa-gpgme-cb.c      |   9 +-
 libbalsa/libbalsa-gpgme-widgets.c |   4 +-
 libbalsa/libbalsa.h               |   4 +-
 libbalsa/source-viewer.c          |  33 +-------
 src/balsa-app.c                   |   7 --
 src/balsa-app.h                   |  13 +--
 src/balsa-index.c                 |   4 +-
 src/folder-conf.c                 |  13 ++-
 src/main-window.c                 |  38 +--------
 src/main.c                        |   6 +-
 src/message-window.c              |  32 +------
 src/save-restore.c                |  47 +++-------
 src/sendmsg-window.c              |  34 +-------
 17 files changed, 337 insertions(+), 199 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 968787ed0..ce756454a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,28 @@
-2019-01-05  Peter Bloomfield  <pbloomfield bellsouth net>
+2018-01-05  Albrecht Dreß  <albrecht dress arcor de>
+
+       Simplify window geometry management
+
+       * libbalsa/Makefile.am: add geometry manager module
+       * libbalsa/geometry-manager.[hc]: geometry manager module
+         implementation
+       * libbalsa/libbalsa-gpgme-cb.c: use geometry manager for the
+         key list dialogue
+       * libbalsa/libbalsa-gpgme-widgets.c: use geometry manager for
+         the key dialogue
+       * libbalsa/libbalsa.h: simplify libbalsa_show_message_source()
+         api, remove unimplemented function prototype
+       * libbalsa/source-viewer.c: use geometry manager, simplify
+         libbalsa_show_message_source() api
+       * src/balsa-app.c: remove initialisation of obsolete balsa_app
+         items
+       * src/balsa-app.h: remove obsolete balsa_app items
+       * src/balsa-index.c: use new libbalsa_show_message_source() api
+       * src/folder-conf.c, src/main-window.c, src/main.c,
+       src/message-window.c, src/sendmsg-window.c: use geometry manager
+         and new libbalsa_show_message_source() api
+       * src/save-restore.c: use geometry manager to load and save values
+
+2018-01-05  Albrecht Dreß  <albrecht dress arcor de>
 
        minor Autocrypt fixes
 
diff --git a/libbalsa/Makefile.am b/libbalsa/Makefile.am
index edf589a22..c4f29403b 100644
--- a/libbalsa/Makefile.am
+++ b/libbalsa/Makefile.am
@@ -159,6 +159,8 @@ libbalsa_a_SOURCES =                \
        source-viewer.c         \
        url.c                   \
        url.h                   \
+       geometry-manager.c      \
+       geometry-manager.h      \
        ${libbalsa_gpgme_extra}
 
 
diff --git a/libbalsa/geometry-manager.c b/libbalsa/geometry-manager.c
new file mode 100644
index 000000000..a1c8ade68
--- /dev/null
+++ b/libbalsa/geometry-manager.c
@@ -0,0 +1,174 @@
+/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
+/* Balsa E-Mail Client
+ *
+ * Copyright (C) 1997-2019 Stuart Parmenter and others,
+ *                         See the file AUTHORS for a list.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H
+#      include "config.h"
+#endif                          /* HAVE_CONFIG_H */
+
+
+#include <stdlib.h>
+#include "libbalsa-conf.h"
+#include "geometry-manager.h"
+
+
+static GHashTable *geometry_hash = NULL;
+G_LOCK_DEFINE_STATIC(geometry_hash);
+
+
+static void geometry_manager_destroy(void);
+static void geometry_manager_save_item(const gchar            *key,
+                                                                          const geometry_t       *size_item,
+                                                                          gpointer G_GNUC_UNUSED  user_data);
+static void size_allocate_cb(GtkWindow                  *window,
+                                        GdkRectangle G_GNUC_UNUSED *allocation,
+                                                        geometry_t                 *size_item);
+static void notify_is_maximized_cb(GtkWindow                *window,
+                                                  GParamSpec G_GNUC_UNUSED *pspec,
+                                                                  geometry_t               *size_item);
+
+
+void
+geometry_manager_init(const gchar *key, gint width, gint height, gboolean maximized)
+{
+       geometry_t *size_item;
+       gchar *config_key;
+
+       g_return_if_fail((key != NULL) && (key[0] != '\0') && (width > 0) && (height > 0));
+
+       G_LOCK(geometry_hash);
+
+       if (geometry_hash == NULL) {
+               geometry_hash = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify) g_free, 
(GDestroyNotify) g_free);
+               atexit(geometry_manager_destroy);
+       }
+
+       if (g_hash_table_contains(geometry_hash, key)) {
+               g_assert_not_reached();                 /* programming error: key must be unique */
+       } else {
+               size_item = g_new0(geometry_t, 1);
+               g_hash_table_insert(geometry_hash, g_strdup(key), size_item);
+       }
+
+       config_key = g_strdup_printf("%sWidth=%d", key, width);
+       size_item->width = libbalsa_conf_get_int(config_key);
+       g_free(config_key);
+
+       config_key = g_strdup_printf("%sHeight=%d", key, height);
+       size_item->height = libbalsa_conf_get_int(config_key);
+       g_free(config_key);
+
+       config_key = g_strdup_printf("%sMaximized=%s", key, maximized ? "true" : "false");
+       size_item->maximized = libbalsa_conf_get_bool(config_key);
+       g_free(config_key);
+
+       G_UNLOCK(geometry_hash);
+}
+
+
+const geometry_t *
+geometry_manager_get(const gchar *key)
+{
+       return (const geometry_t *) g_hash_table_lookup(geometry_hash, key);
+}
+
+
+void
+geometry_manager_attach(GtkWindow *window, const gchar *key)
+{
+       geometry_t *size_item;
+
+       G_LOCK(geometry_hash);
+       size_item = g_hash_table_lookup(geometry_hash, key);
+       if (size_item != NULL) {
+               gtk_window_set_resizable(window, TRUE);
+               gtk_window_set_default_size(window, size_item->width, size_item->height);
+               if (size_item->maximized) {
+                       gtk_window_maximize(window);
+               }
+               g_signal_connect(window, "size_allocate", G_CALLBACK(size_allocate_cb), size_item);
+           g_signal_connect(window, "notify::is-maximized", G_CALLBACK(notify_is_maximized_cb), size_item);
+       }
+       G_UNLOCK(geometry_hash);
+}
+
+
+void
+geometry_manager_save(void)
+{
+       G_LOCK(geometry_hash);
+       g_assert(geometry_hash != NULL);
+       g_hash_table_foreach(geometry_hash, (GHFunc) geometry_manager_save_item, NULL);
+       G_UNLOCK(geometry_hash);
+}
+
+
+static void
+geometry_manager_destroy(void)
+{
+       G_LOCK(geometry_hash);
+       g_hash_table_unref(geometry_hash);
+       geometry_hash = NULL;
+       G_UNLOCK(geometry_hash);
+}
+
+
+static void
+geometry_manager_save_item(const gchar            *key,
+                                                  const geometry_t       *size_item,
+                                                  gpointer G_GNUC_UNUSED  user_data)
+{
+       gchar *config_key;
+
+       config_key = g_strdup_printf("%sWidth", key);
+       libbalsa_conf_set_int(config_key, size_item->width);
+       g_free(config_key);
+
+       config_key = g_strdup_printf("%sHeight", key);
+       libbalsa_conf_set_int(config_key, size_item->height);
+       g_free(config_key);
+
+       config_key = g_strdup_printf("%sMaximized", key);
+       libbalsa_conf_set_bool(config_key, size_item->maximized);
+       g_free(config_key);
+}
+
+
+static void
+size_allocate_cb(GtkWindow                  *window,
+                 GdkRectangle G_GNUC_UNUSED *allocation,
+                geometry_t                 *size_item)
+{
+       G_LOCK(geometry_hash);
+        if (!size_item->maximized) {
+                gtk_window_get_size(window, &size_item->width, &size_item->height);
+        }
+       G_UNLOCK(geometry_hash);
+}
+
+
+static void
+notify_is_maximized_cb(GtkWindow                *window,
+                       GParamSpec G_GNUC_UNUSED *pspec,
+                                          geometry_t               *size_item)
+{
+       G_LOCK(geometry_hash);
+       size_item->maximized = gtk_window_is_maximized(window);
+       G_UNLOCK(geometry_hash);
+}
diff --git a/libbalsa/geometry-manager.h b/libbalsa/geometry-manager.h
new file mode 100644
index 000000000..b08ff1e94
--- /dev/null
+++ b/libbalsa/geometry-manager.h
@@ -0,0 +1,90 @@
+/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
+/* Balsa E-Mail Client
+ *
+ * Copyright (C) 1997-2019 Stuart Parmenter and others,
+ *                         See the file AUTHORS for a list.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GEOMETRY_MANAGER_H_
+#define _GEOMETRY_MANAGER_H_
+
+#ifndef BALSA_VERSION
+# error "Include config.h before this file."
+#endif
+
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+
+G_BEGIN_DECLS
+
+
+typedef struct {
+       gint width;
+       gint height;
+       gboolean maximized;
+} geometry_t;
+
+
+/** \brief Add a dialog to the geometry manager
+ *
+ * \param key dialog identifier, must not be NULL or empty
+ * \param width default width
+ * \param height default height
+ * \param maximized default maximized state
+ *
+ * This function initialises the geometry management for a dialog with the passed key.  It shall be called 
in the "Geometry" group
+ * when the configuration is read.  The config values are <key>Width, <key>Height and <key>Maximized, using 
the passed default
+ * values.
+ *
+ * It is an error to call the function more than once for the same key.
+ */
+void geometry_manager_init(const gchar *key,
+                                                  gint         width,
+                                                  gint         height,
+                                                  gboolean     maximized);
+
+/** \brief Get the geometry of a dialog
+ *
+ * \param key dialog identifier
+ * \return the currently active dialog extents, or NULL on error
+ */
+const geometry_t *geometry_manager_get(const gchar *key);
+
+/** \brief Activate geometry management for a window instance
+ *
+ * \param window window for which geometry management shall be used
+ * \param key dialog identifier
+ *
+ * If the passed key is known, make the passed window resizable, set the default extents to the stored 
values, and connect signals
+ * to internally track size changes.
+ */
+void geometry_manager_attach(GtkWindow   *window,
+                                                        const gchar *key);
+
+/** \brief Save the geometry manager state
+ *
+ * This function shall be called when the configuration file is saved, and the "Geometry" group is selected. 
 It simply writes all
+ * collected values with appropriate keys.
+ */
+void geometry_manager_save(void);
+
+
+G_END_DECLS
+
+
+#endif /* GEOMETRY_MANAGER_H_ */
diff --git a/libbalsa/libbalsa-gpgme-cb.c b/libbalsa/libbalsa-gpgme-cb.c
index ce45566c3..e05a6c803 100644
--- a/libbalsa/libbalsa-gpgme-cb.c
+++ b/libbalsa/libbalsa-gpgme-cb.c
@@ -38,6 +38,7 @@
 #include "rfc3156.h"
 #include "libbalsa-gpgme-widgets.h"
 #include "libbalsa-gpgme-cb.h"
+#include "geometry-manager.h"
 
 
 #ifdef G_LOG_DOMAIN
@@ -184,7 +185,6 @@ lb_gpgme_select_key(const gchar * user_name, lb_key_sel_md_t mode, GList * keys,
     GtkTreeIter iter;
     gchar *prompt;
     gpgme_key_t use_key = NULL;
-    gint width, height;
        GtkCellRenderer *renderer;
        GtkTreeViewColumn *column;
 
@@ -198,6 +198,7 @@ lb_gpgme_select_key(const gchar * user_name, lb_key_sel_md_t mode, GList * keys,
                                          NULL);
     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
     gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_OK, FALSE);
+       geometry_manager_attach(GTK_WINDOW(dialog), "KeyList");
 #if HAVE_MACOSX_DESKTOP
     libbalsa_macosx_menu_for_parent(dialog, parent);
 #endif
@@ -206,7 +207,7 @@ lb_gpgme_select_key(const gchar * user_name, lb_key_sel_md_t mode, GList * keys,
     gtk_container_add(GTK_CONTAINER
                      (gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
                      vbox);
-   gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
+    gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
     switch (mode) {
        case LB_SELECT_PRIVATE_KEY:
                prompt =
@@ -229,6 +230,7 @@ lb_gpgme_select_key(const gchar * user_name, lb_key_sel_md_t mode, GList * keys,
                g_assert_not_reached();
        }
     label = gtk_label_new(prompt);
+    gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
     gtk_widget_set_halign(label, GTK_ALIGN_START);
     g_free(prompt);
     gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
@@ -290,9 +292,6 @@ lb_gpgme_select_key(const gchar * user_name, lb_key_sel_md_t mode, GList * keys,
     gtk_container_add(GTK_CONTAINER(scrolled_window), tree_view);
     g_signal_connect(tree_view, "button_press_event", G_CALLBACK(key_button_event_press_cb), dialog);
 
-    /* set window size to 2/3 of the parent */
-    gtk_window_get_size(parent, &width, &height);
-    gtk_window_set_default_size(GTK_WINDOW(dialog), (2 * width) / 3, (2 * height) / 3);
     gtk_widget_show_all(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
 
     if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
diff --git a/libbalsa/libbalsa-gpgme-widgets.c b/libbalsa/libbalsa-gpgme-widgets.c
index 76773e709..814ee6deb 100644
--- a/libbalsa/libbalsa-gpgme-widgets.c
+++ b/libbalsa/libbalsa-gpgme-widgets.c
@@ -23,6 +23,8 @@
 #include "libbalsa-gpgme-widgets.h"
 #include <string.h>
 #include <glib/gi18n.h>
+
+#include "geometry-manager.h"
 #include "rfc3156.h"
 
 
@@ -379,7 +381,7 @@ libbalsa_key_dialog(GtkWindow            *parent,
        default:
                g_error("%s: buttons type %d not yet implemented", __func__, buttons);
        }
-       gtk_window_set_resizable(GTK_WINDOW(dialog), TRUE);
+       geometry_manager_attach(GTK_WINDOW(dialog), "KeyDialog");
 
        hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
        gtk_container_set_border_width(GTK_CONTAINER(hbox), 6);
diff --git a/libbalsa/libbalsa.h b/libbalsa/libbalsa.h
index c8f3b53bf..276759156 100644
--- a/libbalsa/libbalsa.h
+++ b/libbalsa/libbalsa.h
@@ -110,13 +110,11 @@ enum {
  * Initialize the library
  */
 void libbalsa_init(void);
-void libbalsa_set_spool(const gchar * spool);
 
 void libbalsa_show_message_source(GtkApplication * application,
                                   LibBalsaMessage * msg,
                                   const gchar * font,
-                                  gboolean *escape_specials,
-                                  gint * width, gint * height);
+                                  gboolean *escape_specials);
 
 gchar *libbalsa_guess_email_address(void);
 gchar *libbalsa_guess_mail_spool(void);
diff --git a/libbalsa/source-viewer.c b/libbalsa/source-viewer.c
index 77dd8480f..bec50f9c8 100644
--- a/libbalsa/source-viewer.c
+++ b/libbalsa/source-viewer.c
@@ -32,6 +32,7 @@
 #include "libbalsa_private.h"
 #include "misc.h"
 #include "macosx-helpers.h"
+#include "geometry-manager.h"
 #include <glib/gi18n.h>
 
 typedef struct {
@@ -39,8 +40,6 @@ typedef struct {
     GtkWidget *text;
     GtkWidget *window;
     gboolean *escape_specials;
-    gint *width;
-    gint *height;
 } LibBalsaSourceViewerInfo;
 
 static void
@@ -168,34 +167,13 @@ lsv_window_destroy_notify(LibBalsaSourceViewerInfo * lsvi)
    pops up a window containing the source of the message msg.
 */
 
-static void
-lsv_size_allocate_cb(GtkWidget * window, GtkAllocation * alloc,
-                     LibBalsaSourceViewerInfo * lsvi)
-{
-    GdkWindow *gdk_window;
-    gboolean maximized;
-
-    gdk_window = gtk_widget_get_window(window);
-    if (gdk_window == NULL)
-        return;
-
-    maximized =
-        (gdk_window_get_state(gdk_window) &
-         (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) != 0;
-
-    if (!maximized)
-        gtk_window_get_size(GTK_WINDOW(window), lsvi->width, lsvi->height);
-}
-
 #define BALSA_SOURCE_VIEWER "balsa-source-viewer"
 
 void
 libbalsa_show_message_source(GtkApplication  * application,
                              LibBalsaMessage * msg,
                              const gchar     * font,
-                            gboolean        * escape_specials,
-                             gint            * width,
-                             gint            * height)
+                            gboolean        * escape_specials)
 {
     GtkWidget *text;
     gchar *css;
@@ -237,7 +215,7 @@ libbalsa_show_message_source(GtkApplication  * application,
     window = gtk_application_window_new(application);
     gtk_window_set_title(GTK_WINDOW(window), _("Message Source"));
     gtk_window_set_role(GTK_WINDOW(window), "message-source");
-    gtk_window_set_default_size(GTK_WINDOW(window), *width, *height);
+    geometry_manager_attach(GTK_WINDOW(window), "SourceView");
 
     menu_bar = libbalsa_window_get_menu_bar(GTK_APPLICATION_WINDOW(window),
                                             win_entries,
@@ -266,14 +244,9 @@ libbalsa_show_message_source(GtkApplication  * application,
     lsvi->text = text;
     lsvi->window = window;
     lsvi->escape_specials = escape_specials;
-    lsvi->width = width;
-    lsvi->height = height;
     g_object_set_data_full(G_OBJECT(window), "lsvi", lsvi,
                            (GDestroyNotify) lsv_window_destroy_notify);
 
-    g_signal_connect(window, "size-allocate",
-                     G_CALLBACK(lsv_size_allocate_cb), lsvi);
-
     gtk_widget_show_all(window);
 
     escape_action =
diff --git a/src/balsa-app.c b/src/balsa-app.c
index 39e23a2a9..583e6093f 100644
--- a/src/balsa-app.c
+++ b/src/balsa-app.c
@@ -306,13 +306,6 @@ balsa_app_init(void)
     /* GUI settings */
     balsa_app.mblist = NULL;
     balsa_app.mblist_width = 100;
-    balsa_app.mw_width = MW_DEFAULT_WIDTH;
-    balsa_app.mw_height = MW_DEFAULT_HEIGHT;
-    balsa_app.mw_maximized = FALSE;
-
-    balsa_app.sw_width = 0;
-    balsa_app.sw_height = 0;
-    balsa_app.sw_maximized = FALSE;
 
     balsa_app.toolbar_wrap_button_text = TRUE;
     balsa_app.send_progress_dialog = TRUE;
diff --git a/src/balsa-app.h b/src/balsa-app.h
index 79ca4be1a..9ec45c0f9 100644
--- a/src/balsa-app.h
+++ b/src/balsa-app.h
@@ -189,17 +189,8 @@ extern struct BalsaApplication {
     gint quiet_background_check;
     gint msg_size_limit; /* for POP mailboxes; in kB */
 
-    /* GUI settings */
-    gint mw_width;
-    gint mw_height;
-    gboolean mw_maximized;
+    /* GUI settings (note: window sizes are tracked by the geometry-manager) */
     gint mblist_width;
-    gint sw_width; /* sendmsg window */
-    gint sw_height;
-    gboolean sw_maximized;
-    gint message_window_width;
-    gint message_window_height;
-    gboolean message_window_maximized;
 
     /* toolbars */
     int toolbar_wrap_button_text;
@@ -268,8 +259,6 @@ extern struct BalsaApplication {
 
     /* Source viewer */
     gboolean source_escape_specials;
-    gint source_width;
-    gint source_height;
 
     /* MRU mailbox tree */
     gint mru_tree_width;
diff --git a/src/balsa-index.c b/src/balsa-index.c
index 38455f792..0850dc4c0 100644
--- a/src/balsa-index.c
+++ b/src/balsa-index.c
@@ -1466,9 +1466,7 @@ bndx_view_source(gpointer data)
             continue;
        libbalsa_show_message_source(balsa_app.application,
                                      message, balsa_app.message_font,
-                                    &balsa_app.source_escape_specials,
-                                     &balsa_app.source_width,
-                                     &balsa_app.source_height);
+                                    &balsa_app.source_escape_specials);
         g_object_unref(message);
     }
     balsa_index_selected_msgnos_free(index, selected);
diff --git a/src/folder-conf.c b/src/folder-conf.c
index 77341d5e8..def90f81e 100644
--- a/src/folder-conf.c
+++ b/src/folder-conf.c
@@ -31,6 +31,7 @@
 #include "pref-manager.h"
 #include "imap-server.h"
 #include "server-config.h"
+#include "geometry-manager.h"
 #include <glib/gi18n.h>
 
 #if HAVE_MACOSX_DESKTOP
@@ -422,6 +423,8 @@ browse_button_cb(GtkWidget * widget, SubfolderDialogData * sdd)
     GtkTreeSelection *selection =
         gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
     BrowseButtonData *bbd;
+    const geometry_t *main_size;
+
     /*
      * Make only IMAP nodes selectable:
      */
@@ -467,10 +470,12 @@ browse_button_cb(GtkWidget * widget, SubfolderDialogData * sdd)
     /* Force the mailbox list to be a reasonable size. */
     gtk_widget_get_preferred_size(tree_view, NULL, &req);
     /* don't mess with the width, it gets saved! */
-    if (req.height > balsa_app.mw_height)
-        req.height = balsa_app.mw_height;
-    else if (req.height < balsa_app.mw_height / 2)
-        req.height = balsa_app.mw_height / 2;
+    main_size = geometry_manager_get("MainWindow");
+    g_assert(main_size != NULL);
+    if (req.height > main_size->height)
+        req.height = main_size->height;
+    else if (req.height < main_size->height / 2)
+        req.height = main_size->height / 2;
     gtk_window_set_default_size(GTK_WINDOW(dialog), req.width, req.height);
 
     /* To prevent multiple dialogs, desensitize the browse button. */
diff --git a/src/main-window.c b/src/main-window.c
index 9529e1154..6c6922324 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -67,6 +67,7 @@
 #include "toolbar-prefs.h"
 #include "toolbar-factory.h"
 #include "libbalsa-progress.h"
+#include "geometry-manager.h"
 
 #include "filter.h"
 #include "filter-funcs.h"
@@ -152,7 +153,6 @@ static void bw_find_real(BalsaWindow * window, BalsaIndex * bindex,
 static void bw_slave_position_cb(GtkPaned   * paned_slave,
                                  GParamSpec * pspec,
                                  gpointer     user_data);
-static void bw_size_allocate_cb(GtkWidget * window, GtkAllocation * alloc);
 
 static void bw_notebook_switch_page_cb(GtkWidget * notebook,
                                        void * page,
@@ -642,19 +642,6 @@ balsa_window_get_toolbar_model(void)
     return model;
 }
 
-/*
- * "notify::is-maximized" signal handler
- */
-static void
-bw_notify_is_maximized_cb(GtkWindow  * window,
-                          GParamSpec * pspec,
-                          gpointer     user_data)
-{
-    /* Note when we are either maximized or fullscreen, to avoid saving
-     * nonsensical geometry. */
-    balsa_app.mw_maximized = gtk_window_is_maximized(window);
-}
-
 #define NEW_MAIL_NOTIFICATION "new-mail-notification"
 
 static void
@@ -1536,9 +1523,7 @@ view_source_activated(GSimpleAction * action,
 
        libbalsa_show_message_source(application,
                                      message, balsa_app.message_font,
-                                    &balsa_app.source_escape_specials,
-                                     &balsa_app.source_width,
-                                     &balsa_app.source_height);
+                                    &balsa_app.source_escape_specials);
     }
     g_list_free_full(messages, g_object_unref);
 }
@@ -2212,9 +2197,6 @@ balsa_window_new(GtkApplication *application)
                        0);
 
     window->statusbar = gtk_statusbar_new();
-    g_signal_connect(window, "notify::is-maximized",
-                     G_CALLBACK(bw_notify_is_maximized_cb),
-                     window->statusbar);
     gtk_box_pack_start(GTK_BOX(hbox), window->statusbar, TRUE, TRUE, 0);
     gtk_widget_show_all(hbox);
 
@@ -2223,11 +2205,7 @@ balsa_window_new(GtkApplication *application)
                                         main_menu);
 #endif
 
-    gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
-    gtk_window_set_default_size(GTK_WINDOW(window), balsa_app.mw_width,
-                                balsa_app.mw_height);
-    if (balsa_app.mw_maximized)
-        gtk_window_maximize(GTK_WINDOW(window));
+    geometry_manager_attach(GTK_WINDOW(window), "MainWindow");
 
     window->notebook = gtk_notebook_new();
     gtk_notebook_set_show_tabs(GTK_NOTEBOOK(window->notebook),
@@ -2333,8 +2311,6 @@ balsa_window_new(GtkApplication *application)
     /* set initial state of next-unread controls */
     bw_enable_next_unread(window, FALSE);
 
-    g_signal_connect(window, "size_allocate",
-                     G_CALLBACK(bw_size_allocate_cb), NULL);
     g_signal_connect(window, "delete-event",
                      G_CALLBACK(bw_delete_cb), NULL);
 
@@ -4123,14 +4099,6 @@ bw_slave_position_cb(GtkPaned   * paned_slave,
             gtk_paned_get_position(paned_slave);
 }
 
-    static void
-bw_size_allocate_cb(GtkWidget * window, GtkAllocation * alloc)
-{
-    gtk_window_get_size(GTK_WINDOW(window),
-                        & balsa_app.mw_width,
-                        & balsa_app.mw_height);
-}
-
 /* When page is switched we change the preview window and the selected
    mailbox in the mailbox tree.
  */
diff --git a/src/main.c b/src/main.c
index 343b280a4..c23f93aec 100644
--- a/src/main.c
+++ b/src/main.c
@@ -48,6 +48,7 @@
 #include "imap-server.h"
 #include "libbalsa-conf.h"
 #include "autocrypt.h"
+#include "geometry-manager.h"
 
 #include "libinit_balsa/assistant_init.h"
 
@@ -591,6 +592,7 @@ balsa_activate_cb(GApplication *application,
             gpointer      user_data)
 {
     GtkWidget *window;
+    const geometry_t *main_size;
 
     if (balsa_app.main_window != NULL) {
         gtk_window_present(GTK_WINDOW(balsa_app.main_window));
@@ -605,7 +607,9 @@ balsa_activate_cb(GApplication *application,
     balsa_check_open_compose_window();
 
     g_idle_add((GSourceFunc) scan_mailboxes_idle_cb, NULL);
-    if (balsa_app.mw_maximized) {
+    main_size = geometry_manager_get("MainWindow");
+    g_assert(main_size != NULL);
+    if (main_size->maximized) {
         /*
          * When maximized at startup, the window changes from maximized
          * to not maximized a couple of times, so we wait until it has
diff --git a/src/message-window.c b/src/message-window.c
index cb3d5d29d..1c9d2ed7e 100644
--- a/src/message-window.c
+++ b/src/message-window.c
@@ -31,6 +31,7 @@
 #include "sendmsg-window.h"
 #include "print.h"
 #include "mailbox-node.h"
+#include "geometry-manager.h"
 
 #include <glib/gi18n.h>
 #include <gdk/gdkkeysyms.h>
@@ -497,9 +498,7 @@ mw_view_source_activated(GSimpleAction * action, GVariant * parameter,
     MessageWindow *mw = (MessageWindow *) data;
     libbalsa_show_message_source(balsa_app.application,
                                  mw->message, balsa_app.message_font,
-                                 &balsa_app.source_escape_specials,
-                                 &balsa_app.source_width,
-                                 &balsa_app.source_height);
+                                 &balsa_app.source_escape_specials);
 }
 
 static void
@@ -510,25 +509,6 @@ mw_close_activated(GSimpleAction * action, GVariant * parameter,
     gtk_widget_destroy(mw->window);
 }
 
-static void
-size_alloc_cb(GtkWidget * window, GtkAllocation * alloc)
-{
-    GdkWindow *gdk_window;
-
-    gdk_window = gtk_widget_get_window(window);
-    if (gdk_window == NULL)
-        return;
-
-    balsa_app.message_window_maximized =
-        (gdk_window_get_state(gdk_window) &
-         (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) != 0;
-
-    if (!balsa_app.message_window_maximized)
-        gtk_window_get_size(GTK_WINDOW(window),
-                            & balsa_app.message_window_width,
-                            & balsa_app.message_window_height);
-}
-
 static void
 mw_copy_activated(GSimpleAction * action, GVariant * parameter,
                   gpointer data)
@@ -863,8 +843,6 @@ message_window_new(LibBalsaMailbox * mailbox, guint msgno)
 
     g_signal_connect(G_OBJECT(window), "destroy",
                     G_CALLBACK(destroy_message_window), mw);
-    g_signal_connect(G_OBJECT(window), "size_allocate",
-                     G_CALLBACK(size_alloc_cb), NULL);
     
     mw->bindex = balsa_find_index_by_mailbox(mailbox);
     g_object_weak_ref(G_OBJECT(mw->bindex), mw_bindex_closed_cb, mw);
@@ -910,11 +888,7 @@ message_window_new(LibBalsaMailbox * mailbox, guint msgno)
     mw_set_enabled(mw, "reply-group",
                    libbalsa_message_get_user_header(message, "list-post") != NULL);
 
-    gtk_window_set_default_size(GTK_WINDOW(window),
-                                balsa_app.message_window_width, 
-                                balsa_app.message_window_height);
-    if (balsa_app.message_window_maximized)
-        gtk_window_maximize(GTK_WINDOW(window));
+    geometry_manager_attach(GTK_WINDOW(window),"MessageWindow" );
 
     gtk_widget_show(window);
     mw_set_message(mw, message);
diff --git a/src/save-restore.c b/src/save-restore.c
index 3d306be24..4c96754c3 100644
--- a/src/save-restore.c
+++ b/src/save-restore.c
@@ -38,6 +38,7 @@
 #include "mailbox-filter.h"
 #include "libbalsa-conf.h"
 #include "net-client-utils.h"
+#include "geometry-manager.h"
 
 #include "smtp-server.h"
 #include "send.h"
@@ -686,23 +687,16 @@ config_global_load(void)
        d_get_gint("IndexSizeWidth", SIZE_DEFAULT_WIDTH);
 
     /* ... window sizes */
-    balsa_app.mw_width = libbalsa_conf_get_int("MainWindowWidth=640");
-    balsa_app.mw_height = libbalsa_conf_get_int("MainWindowHeight=480");
-    balsa_app.mw_maximized =
-        libbalsa_conf_get_bool("MainWindowMaximized=false");
+    geometry_manager_init("MainWindow", 640, 480, FALSE);
     balsa_app.mblist_width = libbalsa_conf_get_int("MailboxListWidth=130");
-    /* sendmsg window sizes */
-    balsa_app.sw_width = libbalsa_conf_get_int("SendMsgWindowWidth=640");
-    balsa_app.sw_height = libbalsa_conf_get_int("SendMsgWindowHeight=480");
-    balsa_app.sw_maximized =
-        libbalsa_conf_get_bool("SendmsgWindowMaximized=false");
-    /* message window sizes */
-    balsa_app.message_window_width =
-        libbalsa_conf_get_int("MessageWindowWidth=400");
-    balsa_app.message_window_height =
-        libbalsa_conf_get_int("MessageWindowHeight=500");
-    balsa_app.message_window_maximized =
-        libbalsa_conf_get_bool("MessageWindowMaximized=false");
+    geometry_manager_init("SendMsgWindow", 640, 480, FALSE);
+    geometry_manager_init("MessageWindow", 400, 500, FALSE);
+    geometry_manager_init("SourceView", 500, 400, FALSE);
+#ifdef HAVE_GPGME
+    geometry_manager_init("KeyDialog", 400, 200, FALSE);
+    geometry_manager_init("KeyList", 300, 200, FALSE);
+#endif
+
     /* FIXME: PKGW: why comment this out? Breaks my Transfer context menu. */
     if (balsa_app.mblist_width < 100)
        balsa_app.mblist_width = 170;
@@ -871,8 +865,6 @@ config_global_load(void)
     libbalsa_conf_push_group("SourcePreview");
     balsa_app.source_escape_specials = 
         libbalsa_conf_get_bool("EscapeSpecials=true");
-    balsa_app.source_width  = libbalsa_conf_get_int("Width=500");
-    balsa_app.source_height = libbalsa_conf_get_int("Height=400");
     libbalsa_conf_pop_group();
 
     /* MRU mailbox tree ... */
@@ -1255,24 +1247,9 @@ config_save(void)
     libbalsa_conf_set_int("IndexDateWidth", balsa_app.index_date_width);
     libbalsa_conf_set_int("IndexSizeWidth", balsa_app.index_size_width);
 
-    libbalsa_conf_set_int("MainWindowWidth", balsa_app.mw_width);
-    libbalsa_conf_set_int("MainWindowHeight", balsa_app.mw_height);
-    libbalsa_conf_set_bool("MainWindowMaximized",
-                           !!balsa_app.mw_maximized);
+    geometry_manager_save();
     libbalsa_conf_set_int("MailboxListWidth", balsa_app.mblist_width);
 
-    libbalsa_conf_set_int("SendMsgWindowWidth", balsa_app.sw_width);
-    libbalsa_conf_set_int("SendMsgWindowHeight", balsa_app.sw_height);
-    libbalsa_conf_set_bool("SendmsgWindowMaximized",
-                           !!balsa_app.sw_maximized);
-
-    libbalsa_conf_set_int("MessageWindowWidth",
-                         balsa_app.message_window_width);
-    libbalsa_conf_set_int("MessageWindowHeight",
-                         balsa_app.message_window_height);
-    libbalsa_conf_set_bool("MessageWindowMaximized",
-                           !!balsa_app.message_window_maximized);
-
     libbalsa_conf_set_int("NotebookHeight", balsa_app.notebook_height);
 
     libbalsa_conf_pop_group();
@@ -1355,8 +1332,6 @@ config_save(void)
     libbalsa_conf_push_group("SourcePreview");
     libbalsa_conf_set_bool("EscapeSpecials",
                           balsa_app.source_escape_specials);
-    libbalsa_conf_set_int("Width",  balsa_app.source_width);
-    libbalsa_conf_set_int("Height", balsa_app.source_height);
     libbalsa_conf_pop_group();
 
     /* MRU mailbox tree ... */
diff --git a/src/sendmsg-window.c b/src/sendmsg-window.c
index d47b709c4..d66b29e9f 100644
--- a/src/sendmsg-window.c
+++ b/src/sendmsg-window.c
@@ -65,6 +65,7 @@
 #include "address-view.h"
 #include "print.h"
 #include "macosx-helpers.h"
+#include "geometry-manager.h"
 
 #if !HAVE_GSPELL && !HAVE_GTKSPELL_3_0_3
 #include <enchant/enchant.h>
@@ -124,7 +125,6 @@ static void replace_identity_signature(BalsaSendmsg* bsmsg,
                                        const gchar* new_sig);
 static void update_bsmsg_identity(BalsaSendmsg*, LibBalsaIdentity*);
 
-static void sw_size_alloc_cb(GtkWidget * window, GtkAllocation * alloc);
 static GString *quote_message_body(BalsaSendmsg * bsmsg,
                                    LibBalsaMessage * message,
                                    QuoteType type);
@@ -1306,26 +1306,6 @@ update_bsmsg_identity(BalsaSendmsg* bsmsg, LibBalsaIdentity* ident)
 }
 
 
-static void
-sw_size_alloc_cb(GtkWidget * window, GtkAllocation * alloc)
-{
-    GdkWindow *gdk_window;
-
-    gdk_window = gtk_widget_get_window(window);
-    if (gdk_window == NULL)
-        return;
-
-    balsa_app.sw_maximized =
-        (gdk_window_get_state(gdk_window) &
-         (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) != 0;
-
-    if (!balsa_app.sw_maximized)
-        gtk_window_get_size(GTK_WINDOW(window),
-                            & balsa_app.sw_width,
-                            & balsa_app.sw_height);
-}
-
-
 /* remove_attachment - right mouse button callback */
 static void
 remove_attachment(GtkWidget * menu_item, BalsaAttachInfo *info)
@@ -6754,15 +6734,7 @@ sendmsg_window_new()
 
     bsmsg->window = window =
         gtk_application_window_new(balsa_app.application);
-
-    /*
-     * restore the SendMsg window size
-     */
-    gtk_window_set_default_size(GTK_WINDOW(window),
-                                balsa_app.sw_width,
-                                balsa_app.sw_height);
-    if (balsa_app.sw_maximized)
-        gtk_window_maximize(GTK_WINDOW(window));
+    geometry_manager_attach(GTK_WINDOW(window), "SendMsgWindow");
 
     gtk_window_set_role(GTK_WINDOW(window), "compose");
 
@@ -6787,8 +6759,6 @@ sendmsg_window_new()
                     G_CALLBACK(delete_event_cb), bsmsg);
     g_signal_connect(G_OBJECT(window), "destroy",
                     G_CALLBACK(destroy_event_cb), bsmsg);
-    g_signal_connect(G_OBJECT(window), "size_allocate",
-                    G_CALLBACK(sw_size_alloc_cb), bsmsg);
     /* If any compose windows are open when Balsa is closed, we want
      * them also to be closed. */
     g_object_weak_ref(G_OBJECT(balsa_app.main_window),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]