From: Ben Pfaff <blp@cs.stanford.edu>
Date: Fri, 26 Feb 2010 05:40:52 +0000 (-0800)
Subject: gui: Save positions of windows only when they are closed.
X-Git-Tag: sav-api~370
X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fbuilds%2F20100227040506%2Fpspp;p=pspp

gui: Save positions of windows only when they are closed.

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>.
---

diff --git a/src/ui/gui/psppire-conf.c b/src/ui/gui/psppire-conf.c
index 4090b74c3e..07db3b58c2 100644
--- a/src/ui/gui/psppire-conf.c
+++ b/src/ui/gui/psppire-conf.c
@@ -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);
+    }
 }
diff --git a/src/ui/gui/psppire-conf.h b/src/ui/gui/psppire-conf.h
index a7415b2451..4e7ece0a5a 100644
--- a/src/ui/gui/psppire-conf.h
+++ b/src/ui/gui/psppire-conf.h
@@ -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
diff --git a/src/ui/gui/psppire-dialog.c b/src/ui/gui/psppire-dialog.c
index 4bcb5cc925..e4d04a1fa3 100644
--- a/src/ui/gui/psppire-dialog.c
+++ b/src/ui/gui/psppire-dialog.c
@@ -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;
 }
diff --git a/src/ui/gui/psppire-window.c b/src/ui/gui/psppire-window.c
index 70500e6a0b..d3137ff223 100644
--- a/src/ui/gui/psppire-window.c
+++ b/src/ui/gui/psppire-window.c
@@ -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);