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 + * + * 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 + * + * 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 + + #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 + * + * 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 + * + * 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 + #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 // ...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,