diff -rcN setup.ORIG/Makefile.am setup.apply/Makefile.am
*** Makefile.am	Tue Jul 22 21:47:55 2008
--- Makefile.am	Wed May 13 21:49:13 2009
***************
*** 245,250 ****
--- 245,252 ----
  	proppage.h \
  	propsheet.cc \
  	propsheet.h \
+ 	PropSheetGeometry.cc \
+ 	PropSheetGeometry.h \
  	RECTWrapper.h \
  	res.rc \
  	resource.h \
***************
*** 280,285 ****
--- 282,289 ----
  	win32.h \
  	window.cc \
  	window.h \
+ 	WinGeometrySetting.cc \
+ 	WinGeometrySetting.h \
  	csu_util/MD5Sum.cc \
  	csu_util/MD5Sum.h \
  	csu_util/rfc1738.cc \
diff -rcN setup.ORIG/PropSheetGeometry.cc setup.apply/PropSheetGeometry.cc
*** PropSheetGeometry.cc	Wed Dec 31 19:00:00 1969
--- PropSheetGeometry.cc	Wed May 13 21:49:13 2009
***************
*** 0 ****
--- 1,40 ----
+ /*
+  * Copyright (c) 2009, Jonathon Merz <jonathon.merz@gmail.com>
+  *
+  *     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 of the License, or
+  *     (at your option) any later version.
+  *
+  *     A copy of the GNU General Public License can be found at
+  *     http://www.gnu.org/
+  *
+  * Written by Jonathon Merz.
+  *
+  */
+ 
+ // This is the implementation for the PropSheetGeometry class which contains
+ // window geometry information for the WinGeometrySetting class.
+ 
+ #include "PropSheetGeometry.h"
+ 
+ #include "getopt++/BoolOption.h"
+ 
+ static BoolOption ResetGeomOption (false, 'g', "reset-geometry", "Reset saved window geometry to default");
+ 
+ PropSheetGeometry::PropSheetGeometry ()
+ {
+     resetGeometry = ResetGeomOption;
+ 
+     maximized = false;
+     loadedGeometry = false;
+     initializedGeometry = false;
+     changedGeometry = false;
+ }
+ 
+ PropSheetGeometry&
+ PropSheetGeometry::Instance()
+ {
+     static PropSheetGeometry TheInstance;
+     return TheInstance;
+ }
diff -rcN setup.ORIG/PropSheetGeometry.h setup.apply/PropSheetGeometry.h
*** PropSheetGeometry.h	Wed Dec 31 19:00:00 1969
--- PropSheetGeometry.h	Wed May 13 21:49:13 2009
***************
*** 0 ****
--- 1,55 ----
+ /*
+  * Copyright (c) 2009, Jonathon Merz <jonathon.merz@gmail.com>
+  *
+  *     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 of the License, or
+  *     (at your option) any later version.
+  *
+  *     A copy of the GNU General Public License can be found at
+  *     http://www.gnu.org/
+  *
+  * Written by Jonathon Merz.
+  *
+  */
+ 
+ #ifndef SETUP_PROPSHEETGEOMETRY_H
+ #define SETUP_PROPSHEETGEOMETRY_H
+ 
+ // This is the header for the PropSheetGeometry class which contains window
+ // geometry information for the WinGeometrySetting class.
+ 
+ #include <Windows.h>
+ 
+ #include "RECTWrapper.h"
+ 
+ 
+ class PropSheetGeometry
+ {
+     public:
+         RECTWrapper windowRect;
+ 
+         // Whether the window is maximized.
+         bool maximized;
+ 
+         // Whether saved Geometry was loaded from the file.
+         bool loadedGeometry;
+ 
+         // Whether the window was set to the loaded Geometry.
+         bool initializedGeometry;
+ 
+         // Whether the Geometry is changed (and should be saved on shutdown).
+         bool changedGeometry;
+ 
+         // Option to ignore saved Geometry and restore defaults
+         bool resetGeometry;
+ 
+         static PropSheetGeometry& Instance();
+ 
+     protected:
+         PropSheetGeometry ();
+         PropSheetGeometry (const PropSheetGeometry&);
+         PropSheetGeometry& operator= (const PropSheetGeometry&);
+ };
+ 
+ #endif /* SETUP_PROPSHEETGEOMETRY_H */
diff -rcN setup.ORIG/WinGeometrySetting.cc setup.apply/WinGeometrySetting.cc
*** WinGeometrySetting.cc	Wed Dec 31 19:00:00 1969
--- WinGeometrySetting.cc	Wed May 13 21:49:13 2009
***************
*** 0 ****
--- 1,80 ----
+ /*
+  * Copyright (c) 2009, Jonathon Merz <jonathon.merz@gmail.com>
+  *
+  *     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 of the License, or
+  *     (at your option) any later version.
+  *
+  *     A copy of the GNU General Public License can be found at
+  *     http://www.gnu.org/
+  *
+  * Written by Jonathon Merz.
+  *
+  */
+ 
+ // This is the implementation for the WinGeometrySetting class, which persists
+ // and reads in user settings to restore setup's window geometry on startup.
+ 
+ #include "WinGeometrySetting.h"
+ #include "UserSettings.h"
+ #include "io_stream.h"
+ #include "resource.h"
+ #include "String++.h"
+ #include "propsheet.h"
+ #include "PropSheetGeometry.h"
+ 
+ #define WIN_GEOMETRY_FILE "last-wingeometry"
+ 
+ void
+ WinGeometrySetting::load()
+ {
+     PropSheetGeometry& psg = PropSheetGeometry::Instance();
+     if (psg.loadedGeometry || psg.resetGeometry)
+         return;
+ 
+     io_stream *f = UserSettings::Instance().settingFileForLoad(WIN_GEOMETRY_FILE);
+     if (f)
+     {
+         char geom_str[40]; // Should be long enough... even for a window with 5-digit dimensions
+         char *fg_ret = f->gets (geom_str, 40);
+         if (fg_ret) {
+             int width  = 0;
+             int height = 0;
+             int left   = 0;
+             int top    = 0;
+ 
+             sscanf(geom_str, "%dx%d+%d+%d!%d", &width, &height, &left, &top, &(int&)psg.maximized);
+             psg.windowRect.top    = top;
+             psg.windowRect.bottom = top + height;
+             psg.windowRect.left   = left;
+             psg.windowRect.right  = left + width;
+             psg.loadedGeometry = true;
+         }
+     }
+ }
+ 
+ void
+ WinGeometrySetting::save()
+ {
+     char geom_str[40];
+     PropSheetGeometry& psg = PropSheetGeometry::Instance();
+ 
+     io_stream *f = UserSettings::Instance().settingFileForSave(WIN_GEOMETRY_FILE);
+     if (f)
+     {
+         if( psg.changedGeometry )
+         {
+             sprintf(geom_str, "%dx%d+%ld+%ld!%d", psg.windowRect.width(), psg.windowRect.height(), psg.windowRect.left, psg.windowRect.top, (int)psg.maximized);
+             f->write(geom_str, strlen(geom_str));
+             delete f;
+         }
+         else if(psg.resetGeometry)
+         {
+             // If geometry was reset via the command line option and not
+             // changed from the default, write a blank WIN_GEOMETRY_FILE to
+             // keep defaults for next time.
+             f->write("", 0);
+         }
+     }
+ }
diff -rcN setup.ORIG/WinGeometrySetting.h setup.apply/WinGeometrySetting.h
*** WinGeometrySetting.h	Wed Dec 31 19:00:00 1969
--- WinGeometrySetting.h	Wed May 13 21:49:13 2009
***************
*** 0 ****
--- 1,32 ----
+ /*
+  * Copyright (c) 2009, Jonathon Merz <jonathon.merz@gmail.com>
+  *
+  *     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 of the License, or
+  *     (at your option) any later version.
+  *
+  *     A copy of the GNU General Public License can be found at
+  *     http://www.gnu.org/
+  *
+  * Written by Jonathon Merz.
+  *
+  */
+ 
+ #ifndef SETUP_WINGEOMETRYSETTING_H
+ #define SETUP_WINGEOMETRYSETTING_H
+ 
+ // This is the header for the WinGeometrySetting class, which persists and reads
+ // in user settings to restore setup's window geometry on startup.
+ 
+ #include <string>
+ #include "UserSetting.h"
+ 
+ class WinGeometrySetting : public UserSetting
+ {
+   public:
+     virtual void load();
+     virtual void save();
+ };
+ 
+ #endif /* SETUP_WINGEOMETRYSETTING_H */
diff -rcN setup.ORIG/propsheet.cc setup.apply/propsheet.cc
*** propsheet.cc	Fri Apr 24 16:57:48 2009
--- propsheet.cc	Wed May 13 21:49:13 2009
***************
*** 25,30 ****
--- 25,34 ----
  #include "ControlAdjuster.h"
  #include "threebar.h"
  
+ #include "PropSheetGeometry.h"
+ #include "WinGeometrySetting.h"
+ static WinGeometrySetting theSetting;
+ 
  //#include <shlwapi.h>
  // ...but since there is no shlwapi.h in mingw yet:
  typedef struct _DllVersionInfo
***************
*** 164,169 ****
--- 168,174 ----
    WPARAM wParam, LPARAM lParam)
  {
    PropSheetData& psd = PropSheetData::Instance();
+   PropSheetGeometry& psg = PropSheetGeometry::Instance();
    switch (uMsg)
      {
      case WM_SYSCOMMAND:
***************
*** 221,227 ****
  		psd.clientRectValid = true;
  	      }
  	    /*
! 	      Store away the current size and use it as the minmal window size.
  	     */
  	    if (!psd.hasMinRect)
  	      {
--- 226,232 ----
  		psd.clientRectValid = true;
  	      }
  	    /*
! 	      Store away the current size and use it as the minimal window size.
  	     */
  	    if (!psd.hasMinRect)
  	      {
***************
*** 229,238 ****
--- 234,280 ----
  		psd.hasMinRect = true;
  	      }
  	    
+              /*
+               * Update window size and position, but only if done initializing.
+               */
+             if (psg.initializedGeometry)
+             {
+                 // If the window is being maximized, just take note of that and
+                 // save the old geometry to restore to.
+                 if(wParam == SIZE_MAXIMIZED) {
+                     psg.maximized = true;
+                     psg.changedGeometry = true;
+                 }
+                 else
+                 {
+                     psg.maximized = false;
+                     GetWindowRect(hwnd, &psg.windowRect);
+                     psg.changedGeometry = true;
+                 }
+             }
+ 
  	    psd.lastClientRect = clientRect;
  	  }
        }
        break;
+     case WM_MOVE:
+       {
+           // Only update geometry if we're done initializing
+           if(psg.initializedGeometry)
+           {
+               // Don't update position if the window is maximized.  That way,
+               // we keep the same restore position in the saved geometry.
+               // Maximizing generates both a WM_MOVE (first) and then a WM_SIZE
+               // (second), but since only the WM_SIZE message gets the
+               // SIZE_MAXIMIZED parameter, set psg.maximized there rather than
+               // here.
+               if(!IsZoomed(hwnd)) {
+                   GetWindowRect(hwnd, &psg.windowRect);
+                   psg.changedGeometry = true;
+               }
+           }
+       }
+       break;
      case WM_GETMINMAXINFO:
        {
  	if (psd.hasMinRect)
***************
*** 392,397 ****
--- 434,440 ----
  PropSheet::AdjustPageSize (HWND page)
  {
    PropSheetData& psd = PropSheetData::Instance();
+   PropSheetGeometry& psg = PropSheetGeometry::Instance();
    if (!psd.clientRectValid) return;
  
    /*
***************
*** 422,427 ****
--- 465,484 ----
        int marginY = MulDiv (5, HIWORD(dialogBaseUnits), 8);
  
        pageRect.move (marginX, marginY);
+ 
+       if( !psg.initializedGeometry && psg.loadedGeometry ) {
+           // Set the window position and size before possibly setting it
+           // maximized so restoring un-maximized geometry will result in the
+           // last saved geometry.
+           HWND parent = ::GetParent(page);
+           if( parent )
+           {
+               SetWindowPos(parent, 0, psg.windowRect.left, psg.windowRect.top, psg.windowRect.width(), psg.windowRect.height(), SWP_NOACTIVATE | SWP_NOZORDER);
+               if(psg.maximized)
+                   ShowWindow(parent, SW_SHOWMAXIMIZED);
+           }
+       }
+       psg.initializedGeometry = true;
      }
  
    SetWindowPos (page, 0, psd.pageRect.left, psd.pageRect.top, 
