Here is a program that remembers its position and state. If the program is resized and positioned on the screen and then closed, it will appear in the same position when it is run again. If the program is minimized (iconified) and closed, it will appear iconified when run again, and take its proper position when restored.
Also, if the program is maximized and closed, it will appear maximized when run again, but return to its proper position when unmaximized. This apparently only works under windows. On unix or MacOS, the window will reappear maximized, but will not go back to its original position when "unmaximized".
MDL #!/usr/bin/env tclsh
#
# remember.tcl --
#
# This file implements a simple Tk program that remembers its window position,
# size, and state. It saves this information to remember.ini when it closes
# and loads it again when started.
#
# Copyright (c) 2005 Michael Leonhard
#
# This file is placed in the public domain.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
# SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
# SOFTWARE, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHOR HAS BEEN ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
#
# THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS"
# BASIS, AND THE AUTHOR HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
# UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
package require Tk
namespace eval rememberini {
namespace export sourceIni
namespace export writeIni
set INIFILE "remember.ini"
# rememberini::sourceIni --
#
# Sets default variable values and sources the remember.ini file.
# Informs user if sourcing fails. Ignores missing ini file.
#
# Expected variables:
# WindowGeom = WxH+X+Y where W=width, H=height, position=(X,Y)
# WindowState = normal | maximized | minimized
proc sourceIni {} {
variable INIFILE
# defaults
variable WindowGeom 500x400+100+100
variable WindowState normal
# check that the file is readable
if { ![file readable $INIFILE]} { # no inifile, use defaults
puts "ini file not found, using defaults"
return
}
# try to source, giving a popup if there was an error
# (so the user knows why his settings vanished)
if { [catch {source $INIFILE}] } {
tk_messageBox -title "Error" -type ok -icon error -message \
[join [list \
"Settings cannot be loaded.\n" \
"The file \"$INIFILE\" is corrupt.\n" \
"Using default settings."] ""]
return
}
}
# rememberini::sourceIni --
#
# Write the variables to the remember.ini as a Tcl script.
proc writeIni {} {
variable INIFILE
variable WindowGeom
variable WindowState
# open the file for writing (truncates if file exists)
if { [catch {set fc [open $INIFILE w]}] } {
tk_messageBox -title "Error" -type ok -icon error -message \
"Unable to save settings to \"$INIFILE\"."
return
}
# write file
puts $fc "# remember.ini - settings for Remember"
puts $fc "# This file is generated automatically when Remember closes."
puts $fc "# Do not edit this file! Incorrect entries will crash the program."
puts $fc [list set WindowGeom $WindowGeom]
puts $fc [list set WindowState $WindowState]
close $fc
}
}
namespace eval remember {
namespace export start_program
# remember::unmapEvent --
#
# Handles <Unmap> event which occurs when the main window is minimized.
# Saves window state.
proc unmapEvent w {
# do nothing if event is not for main window
if { $w ne "." } {
return
}
# window is minimized (hidden)
variable WindowState minimized
puts "MainState := minimized (hidden)"
bell
}
# remember::configureEvent --
#
# Handles <Configure> event which occurs when window is reposition,
# resized, iconified, or maximized. Saves new position if window is not
# minimized or maximized. Saves window state.
proc configureEvent { w x y height width } {
# do nothing if event is not for main window
if { $w ne "." } {
return
}
# window is iconified
if { [wm state $w] eq "iconic" } {
variable WindowState minimized
puts "WindowState := minimized (iconic)"
bell
return
}
# window is maximized (Windows only)
if { [wm state $w] eq "zoomed" } {
variable WindowState maximized
puts "WindowState := maximized"
bell
return
}
# window has been moved/resized
if { [wm state $w] eq "normal" } {
variable WindowState normal
variable WindowGeom [join [list $width x $height + $x + $y] ""]
puts "WindowState := normal, geom:=$WindowGeom"
return
}
# execution should never reach here
puts "unknown window state [wm state .]"
}
proc makeWindow {} {
set w .
# Set window geometry and maximize/minimized state
variable WindowState
variable WindowGeom
if { $WindowState eq "minimized" } { wm iconify $w}
wm geometry $w $WindowGeom
if { $WindowState eq "maximized" } { wm state $w zoomed}
wm title $w "Remember"
wm iconname $w "Remember"
# event bindings
bind . <Configure> "remember::configureEvent %W %x %y %h %w"
bind . <Unmap> "remember::unmapEvent %W"
wm protocol $w WM_DELETE_WINDOW "remember::close_program $w"
# window contents (label)
label .message -text [join [list \
"Remember - a Tcl/Tk program that remembers\n" \
"its window position, size, and state."] ""]
pack .message -expand yes -fill both
}
proc start_program {} {
# read ini file and set variables in the remember namespace
rememberini::sourceIni
variable WindowState $rememberini::WindowState
variable WindowGeom $rememberini::WindowGeom
makeWindow
}
proc close_program { w } {
# set variables in rememberini namespace and write ini file
variable WindowGeom
variable WindowState
set rememberini::WindowGeom $WindowGeom
set rememberini::WindowState $WindowState
rememberini::writeIni
destroy $w
}
}
remember::start_program