gui: Save positions of windows only when they are closed.
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 26 Feb 2010 05:40:52 +0000 (21:40 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 26 Feb 2010 05:40:52 +0000 (21:40 -0800)
When windows in the GUI are moved around the desktop or resized, the
machine's disk can thrash madly in some setups.  This is because each
change in a window's position or size triggers a write to the PSPPIRE
preferences file noting the new position as a default for the next
PSPPIRE run.  It wasn't always a problem, but newer Glib versions call
fsync() from g_file_set_contents(), the function used to write the
preferences file, which bypasses the OS cache and forces a synchronous
disk write.

This commit makes PSPPIRE update the preferences file only when a window
is closed, which fixes the problem.  Avoiding g_file_set_contents() would
be another reasonable solution.

Reported by Grzegorz Artur Daszuta <crefff@gmail.com>.

src/ui/gui/psppire-conf.c
src/ui/gui/psppire-conf.h
src/ui/gui/psppire-dialog.c
src/ui/gui/psppire-window.c

index 4090b74c3ea9dce414e42cb59bb643c6c312a15e..07db3b58c21e5d07e16d8789a285f2ad20978450 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2009  Free Software Foundation
+   Copyright (C) 2009, 2010  Free Software Foundation
 
    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
@@ -262,36 +262,29 @@ psppire_conf_set_window_geometry (PsppireConf *conf,
 void
 psppire_conf_save_window_geometry (PsppireConf *conf,
                                   const gchar *base,
-                                  GdkEvent *e)
+                                  GtkWindow *gtk_window)
 {
-  switch (e->type)
-    {
-    case GDK_CONFIGURE:
-      {
-       GdkEventConfigure *event = &e->configure;
+  gboolean maximized;
+  GdkWindow *w;
 
-       if ( gdk_window_get_state (event->window) &
-            GDK_WINDOW_STATE_MAXIMIZED )
-         return;
+  w = gtk_widget_get_window (GTK_WIDGET (gtk_window));
+  if (w == NULL)
+    return;
 
-       psppire_conf_set_int (conf, base, "height", event->height);
-       psppire_conf_set_int (conf, base, "width", event->width);
+  maximized = (gdk_window_get_state (w) & GDK_WINDOW_STATE_MAXIMIZED) != 0;
+  psppire_conf_set_boolean (conf, base, "maximize", maximized);
 
-       psppire_conf_set_int (conf, base, "x", event->x);
-       psppire_conf_set_int (conf, base, "y", event->y);
-      }
-      break;
-    case GDK_WINDOW_STATE:
-      {
-       GdkEventWindowState *event = &e->window_state;
+  if (!maximized)
+    {
+      gint width, height;
+      gint x, y;
 
-       psppire_conf_set_boolean (conf, base, "maximize",
-                                 event->new_window_state &
-                                 GDK_WINDOW_STATE_MAXIMIZED );
-      }
-      break;
-    default:
-      break;
-    };
+      gdk_drawable_get_size (w, &width, &height);
+      gdk_window_get_position (w, &x, &y);
 
+      psppire_conf_set_int (conf, base, "height", height);
+      psppire_conf_set_int (conf, base, "width", width);
+      psppire_conf_set_int (conf, base, "x", x);
+      psppire_conf_set_int (conf, base, "y", y);
+    }
 }
index a7415b2451010b081b0774c9b014c8b205c34613..4e7ece0a5a6ce2c1f1c922c5d097ad474ced7367 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2009  Free Software Foundation
+   Copyright (C) 2009, 2010  Free Software Foundation
 
    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
@@ -96,7 +96,7 @@ void psppire_conf_set_window_geometry (PsppireConf *conf,
 
 void psppire_conf_save_window_geometry (PsppireConf *,
                                        const gchar *,
-                                       GdkEvent *);
+                                       GtkWindow *);
 
 
 G_END_DECLS
index 4bcb5cc92550e2901742ea51840a6c04e2899c9d..e4d04a1fa3cfecccdb3468c916dbb636e2543f75 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007  Free Software Foundation
+   Copyright (C) 2007, 2010  Free Software Foundation
 
    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
@@ -305,7 +305,7 @@ configure_event_callback (GtkDialog *dialog,
 
   g_object_get (dialog, "name", &base, NULL);
 
-  psppire_conf_save_window_geometry (conf, base, event);
+  psppire_conf_save_window_geometry (conf, base, GTK_WINDOW (dialog));
 
   return FALSE;
 }
index 70500e6a0b4f1fa8a78228aa95fdb05ba58c1b2b..d3137ff2234d0d036329596a0c8ad0746d72dcd7 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2009  Free Software Foundation
+   Copyright (C) 2009, 2010  Free Software Foundation
 
    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
@@ -203,19 +203,6 @@ on_realize (GtkWindow *window, gpointer data)
 }
 
 
-static gboolean
-save_geometry (GtkWidget *window, GdkEvent *event, gpointer data)
-{
-  const gchar *base = G_OBJECT_TYPE_NAME (window);
-
-  PsppireConf *conf = psppire_conf_new ();
-
-  psppire_conf_save_window_geometry (conf, base, event);
-
-  return FALSE;
-}
-
-
 static void
 psppire_window_finalize (GObject *object)
 {
@@ -382,6 +369,13 @@ on_delete (PsppireWindow *w, GdkEvent *event, gpointer user_data)
 {
   PsppireWindowRegister *reg = psppire_window_register_new ();
 
+  const gchar *base = G_OBJECT_TYPE_NAME (w);
+
+  PsppireConf *conf = psppire_conf_new ();
+
+  psppire_conf_save_window_geometry (conf, base, GTK_WINDOW (w));
+
+
   if ( w->dirty )
     {
       gint response = psppire_window_query_save (w);
@@ -435,12 +429,6 @@ psppire_window_init (PsppireWindow *window)
 
   g_object_set (window, "icon-name", "psppicon", NULL);
 
-  g_signal_connect (window, "configure-event",
-                   G_CALLBACK (save_geometry), window);
-
-  g_signal_connect (window, "window-state-event",
-                   G_CALLBACK (save_geometry), window);
-
   g_signal_connect (window, "realize",
                    G_CALLBACK (on_realize), window);