1# File: init-other.tcl
2
3# Purpose: post-character-generation initialization script
4
5#
6# Copyright (c) 1997-2001 Tim Baker
7#
8# This software may be copied and distributed for educational, research, and
9# not for profit purposes provided that this copyright and statement are
10# included in all such copies.
11#
12
13# Toplevel headaches (Win32, Tk 8.3.3):
14# If a window is withdrawn, then "wm geometry $w" returns the geometry
15# from the last time the window was visible, *not* any requested geomtry.
16# Also, "wm geometry $w $g" doesn't actually change the geometry until
17# the window is displayed.
18
19proc tryGeometry {win geometry} {
20	if {1 || [string compare $geometry [wm geometry $win]]} {
21		wm geometry $win $geometry
22	}
23	return
24}
25
26# Deiconify a window. If the window does not appear at the location
27# we requested, then move it there.
28proc wmDeiconify {win} {
29	set geometry [wm geometry $win]
30	wm deiconify $win
31	update
32	tryGeometry $win $geometry
33}
34
35# Show a window. If the window does not appear at the location
36# we requested, then move it there.
37proc wmStateNormal {win} {
38	set geometry [wm geometry $win]
39	wm state $win normal
40	update
41	tryGeometry $win $geometry
42}
43
44proc WMSetWindowGeometry {win geometry} {
45
46	wm geometry $win $geometry
47
48	return
49}
50
51# ReadGeometryFile --
52#
53#	Reads the "geometry" file which contains the desired geometry
54#	of each of the game's windows. If the "geometry" file does not
55#	exist, then the game uses the default window positions, as set
56#	in HarcodeGeometry() below. To create the "geometry" file, the
57#	user can choose "Save Window Positions" from the Other Menu.
58#
59# Arguments:
60#	arg1					about arg1
61#
62# Results:
63#	What happened.
64
65proc ReadGeometryFile {} {
66
67	global Angband
68	global Windows
69
70	if {[catch {open [PathTk config geometry]} fileId]} {
71		set msg "The following error occurred while attempting to open "
72		append msg "the \"geometry\" file for reading:\n\n$fileId"
73		tk_messageBox -title Oops -message $msg
74		return
75	}
76
77	set buf [read $fileId]
78	close $fileId
79
80	# Check each line
81	foreach geomInfo [split $buf \n] {
82
83		# Skip blank lines
84		if {![string length $geomInfo]} continue
85
86		# Skip comments
87		if {[string equal [string index $geomInfo 0] #]} continue
88
89		# Split line into window keyword and geometry
90		if {[scan $geomInfo "%s %s" window geometry] != 2} continue
91
92		# Request geometry. The window may not exist yet.
93		NSWindowManager::RequestGeometry $window $geometry
94
95		# Sanity: Windows(win) exists?
96		if {![info exists Windows($window)]} continue
97
98		# Get the toplevel pathname
99		set win [Window $window]
100
101		if {[scan $geometry {%dx%d%[+-]%d%[+-]%d} width height xs x ys y] != 6} {
102			continue
103		}
104
105		# If this window is not resizeable, then ignore the given
106		# height or width and use the dimension requested for the
107		# window.
108		set resize [wm resizable $win]
109		if {![lindex $resize 0]} {set width [winfo reqwidth $win]}
110		if {![lindex $resize 1]} {set height [winfo reqheight $win]}
111
112		# If this is a gridded window, convert from dimensions in
113		# pixels to grid units.
114		set grid [wm grid $win]
115		if {[llength $grid]} {
116			set width [expr {$width / [lindex $grid 2]}]
117			set height [expr {$height / [lindex $grid 3]}]
118		}
119
120		# Set the window geometry
121		set geometry ${width}x$height$xs$x$ys$y
122
123WMSetWindowGeometry $win $geometry
124continue
125
126		# Get the toplevel state
127		set state [wm state $win]
128
129		# If this toplevel is showing, then hide it first
130		# to make the geometry request work
131		if {[string equal $state normal]} {
132			wm withdraw $win
133			update idletasks
134		}
135
136		# Set the toplevel geometry
137		tryGeometry $win $geometry
138
139		# Restore the window if it was hidden by us
140		if {[string equal $state normal]} {
141			update idletasks
142			wmDeiconify $win
143		}
144	}
145
146	return
147}
148
149# WriteGeometryFile --
150#
151#	Writes the "geometry" file with the current geometry of each of the
152#	game's windows. The "geometry" file is created if it does not already
153#	exist. To create the "geometry" file, the user can choose "Save
154#	Window Positions" from the Other Menu.
155#
156# Arguments:
157#	arg1					about arg1
158#
159# Results:
160#	It seems a toplevel's geometry is not correct until is has been
161#	displayed at least once. This routine brings any non-"normal"
162#	windows to the front before getting its geometry. This looks bad.
163#	It might be better to move the window offscreen first.
164#	-> FixWindows() fixed this problem...?
165
166proc WriteGeometryFile {} {
167
168	global Angband
169	global Windows
170
171	set tempName [NSUtils::TempFileName [PathTk config]]
172	if {[catch {openlf $tempName} fileId]} {
173		set msg "The following error occurred while attempting to open "
174		append msg "the \"geometry\" file for writing:\n\n$fileId"
175		tk_messageBox -title Oops -message $msg
176		return
177	}
178
179	set success 1
180
181	if {[catch {
182
183	puts $fileId "# Automatically generated. Do not edit.\n"
184
185	# Be sure to keep any requested geometry for windows which may not
186	# have been created.
187	foreach name [array names NSWindowManager::Priv *,geomRequest] {
188		regexp "(.*),geomRequest" $name ignore window
189		set geometry $NSWindowManager::Priv($name)
190		if {[scan $geometry {%dx%d%[+-]%d%[+-]%d} \
191			width height xs x ys y] != 6} continue
192		set geometryInfo($window) $geometry
193	}
194
195	# Get the current geometry for existing windows.
196	foreach window [array names Windows] {
197		set win [Window $window]
198
199		# HighScore destroys itself after character death
200		if {![winfo exists $win]} continue
201
202		# Get the window geometry
203		if {[scan [wm geometry $win] {%dx%d%[+-]%d%[+-]%d} \
204			width height xs x ys y] != 6} continue
205
206		# If this is a gridded window, the geometry information
207		# is returned as {columns rows columnWidth rowWidth}. In
208		# this case I save the total area of the grid in pixels.
209		# This is needed because (1) the user can switch between
210		# 16x16 and 32x32 icons at startup, and (2) the window
211		# may not be gridded in the next version of the game.
212		set grid [wm grid $win]
213		if {[llength $grid]} {
214			set width [expr {$width * [lindex $grid 2]}]
215			set height [expr {$height * [lindex $grid 3]}]
216		}
217
218		set geometryInfo($window) ${width}x$height$xs$x$ys$y
219	}
220
221	# Write the geometry for each window
222	foreach window [lsort -dictionary [array names geometryInfo]] {
223		puts $fileId "$window $geometryInfo($window)"
224	}
225
226	# catch
227	} result]} {
228		set msg "The following error occurred while attempting to write "
229		append msg "the \"geometry\" file:\n\n$result"
230		tk_messageBox -title Oops -message $msg
231
232		set success 0
233	}
234
235	close $fileId
236
237	if {$success} {
238		set fileName [NSUtils::ReadLink [PathTk config geometry]]
239		if {[file exists $fileName]} {
240			file rename -force -- $fileName $fileName.bak
241		}
242		file rename -- $tempName $fileName
243	} else {
244		file delete $tempName
245	}
246
247	return
248}
249
250# HardcodeGeometry --
251#
252#	Sets the position of all the game's windows to an appropriate
253#	default position. This is done at startup if the "geometry" file does
254#	not exist, and when the user chooses "Arrange Windows" from
255#	the Other Menu.
256#
257# Arguments:
258#	arg1					about arg1
259#
260# Results:
261#	What happened.
262
263proc HardcodeGeometry {} {
264
265	global Windows
266
267	set spacing 0
268	set offset [winfo screenwidth .]
269
270	# Tk 8.3.0 bug
271	set win [Window main]
272	set visible(main) [winfo ismapped $win]
273	wm geometry $win +$offset+0
274	update idletasks
275	wm deiconify $win
276
277	# Move each window offscreen, and show it.
278	foreach window [array names Windows] {
279
280		# Tk 8.3.0 bug
281		if {[string equal $window main]} continue
282
283		set win [Window $window]
284		set visible($window) [winfo ismapped $win]
285		wm geometry $win +$offset+0
286		update idletasks
287		wm deiconify $win
288	}
289
290	# Must be update, not "update idletasks", or the Main Window geometry
291	# is silly (too tall). Don't know why.
292	update
293
294	# Message Window
295	set win1 [Window message]
296	set x 0 ; incr x $offset
297	wm geometry $win1 +$x+0
298	update idletasks
299
300	# Main Window
301	set x 0 ; incr x $offset
302	if {[Value message,float]} {
303		set y [expr {[NSToplevel::FrameBottom $win1] + $spacing}]
304	} else {
305		set y 0
306	}
307	set win1 [Window main]
308	wm geometry $win1 +$x+$y
309	update idletasks
310
311	# Misc Window
312	set y [expr {[NSToplevel::FrameBottom $win3] + $spacing}]
313	set win1 [Window misc]
314	wm geometry $win1 +$x+$y
315	update idletasks
316
317	# Progress Window
318	set y [expr {[NSToplevel::FrameBottom $win1] + $spacing}]
319	set win1 [Window progress]
320	wm geometry $win1 +$x+$y
321	update idletasks
322
323	# Message Window (width)
324	set win2 [Window message]
325	set x 0 ; incr x $offset
326	set width [NSToplevel::ContentWidth $win2 \
327		[expr {0 - $x}]]
328	wm geometry $win2 ${width}x[winfo height $win2]+$x+0
329	update idletasks
330
331	# Tips Window (centered)
332	if {[info exists Windows(tip)]} {
333		set win [Window tip]
334	    set x2 [expr {([winfo screenwidth $win] - [winfo reqwidth $win]) / 2 \
335		    - [winfo vrootx $win] + $offset}]
336	    set y2 [expr {([winfo screenheight $win] - [winfo reqheight $win]) / 3 \
337		    - [winfo vrooty $win]}]
338	    wm geometry $win +$x2+$y2
339	}
340
341	NSWindowManager::ArrangeAll
342
343	# Iterate over each window. Move the mapped window from its offscreen
344	# position onto the screen again. If it wasn't mapped previously, then
345	# hide the window.
346	foreach window [array names Windows] {
347		set win [Window $window]
348
349		scan [wm geometry $win] {%dx%d%[+-]%d%[+-]%d} width height xs x ys y
350		incr x -$offset
351		wm geometry $win ${width}x$height$xs$x$ys$y
352
353		if {$visible($window)} continue
354
355		# Tk 8.3.0 bug
356		if {[string equal $window main]} continue
357
358		wm withdraw $win
359	}
360
361	# Tk 8.3.0 bug
362	if {!$visible(main)} {
363		wm withdraw [Window main]
364	}
365
366	update
367
368	return
369}
370
371if {[Platform unix]} {
372
373proc HardcodeGeometry {} {
374
375	global Windows
376
377	set screenWidth [winfo screenwidth .]
378	set spacing 0
379
380	# Tk 8.3.0 bug
381	set win [Window main]
382	set visible(main) [winfo ismapped $win]
383	if {!$visible(main)} {
384		wm state $win normal
385	}
386
387	# Move each window offscreen, and show it.
388	foreach window [array names Windows] {
389
390		# Tk 8.3.0 bug
391		if {[string equal $window main]} continue
392
393		set win [Window $window]
394		set visible($window) [winfo ismapped $win]
395		if {!$visible($window)} {
396			wm state $win normal
397		}
398	}
399
400	# Must be update, not "update idletasks", or the Main Window geometry
401	# is silly (too tall). Don't know why.
402	update
403
404	# Message Window
405	set win1 [Window message]
406	wm geometry $win1 +0+0
407	update
408
409	# Main Window
410	set x 0
411	if {[Value message,float]} {
412		set y [expr {[NSToplevel::FrameBottom $win1] + $spacing}]
413	} else {
414		set y 0
415	}
416	set win1 [Window main]
417	wm geometry $win1 +$x+$y
418	update
419
420	# Misc Window
421	set y [expr {[NSToplevel::FrameBottom $win3] + $spacing}]
422	set win1 [Window misc]
423	wm geometry $win1 +$x+$y
424	update
425
426	# Progress Window
427	set y [expr {[NSToplevel::FrameBottom $win1] + $spacing}]
428	set win1 [Window progress]
429	wm geometry $win1 +$x+$y
430	update
431
432	# Message Window (width)
433	set win2 [Window message]
434	set x 0
435	set width [NSToplevel::ContentWidth $win2 \
436		[expr {0 - $x}]]
437	wm geometry $win2 ${width}x[winfo height $win2]+$x+0
438	update
439
440	# Tips Window (centered)
441	if {[info exists Windows(tip)]} {
442		set win [Window tip]
443	    set x2 [expr {([winfo screenwidth $win] - [winfo reqwidth $win]) / 2 \
444		    - [winfo vrootx $win]}]
445	    set y2 [expr {([winfo screenheight $win] - [winfo reqheight $win]) / 3 \
446		    - [winfo vrooty $win]}]
447	    wm geometry $win +$x2+$y2
448	}
449
450	NSWindowManager::ArrangeAll
451
452	# Iterate over each window. Move the mapped window from its offscreen
453	# position onto the screen again. If it wasn't mapped previously, then
454	# hide the window.
455	foreach window [array names Windows] {
456		set win [Window $window]
457
458		scan [wm geometry $win] {%dx%d%[+-]%d%[+-]%d} width height xs x ys y
459
460		if {!$visible($window)} {
461
462			# Tk 8.3.0 bug
463			if {![string equal $window main]} {
464				wm withdraw $win
465				update idletasks
466			}
467		}
468	}
469
470	# Tk 8.3.0 bug
471	if {!$visible(main)} {
472		wm withdraw [Window main]
473	}
474
475	update
476
477	return
478}
479
480# unix
481}
482
483# MaximizeWindows --
484#
485#	Calculates the largest possible size for the Main Window, resizes
486#	the Main Window, then positions all the other game windows accordingly.
487#
488# Arguments:
489#	arg1					about arg1
490#
491# Results:
492#	What happened.
493
494proc MaximizeWindows {} {
495
496	set left 0
497	set top 0
498	set right [winfo screenwidth .]
499	set bottom [winfo screenheight .]
500
501	# Start with the Main Window as big as the desktop
502	set width $right
503	set height $bottom
504
505	set winMessage [Window message]
506	set winMain [Window main]
507	set winMisc [Window misc]
508	set winRecall [Window recall]
509
510	# Subtract the width of the  Misc Window.
511	set width [expr {$width - $widthMisc}]
512
513	# Sutbtract the height of the Message Window
514	if {[Value message,float]} {
515		set height [expr {$height - [NSToplevel::TotalHeight $winMessage]}]
516	}
517
518	# Subtract the height of the Recall Window or Choice Window
519	if {[Value recall,show]} {
520		set height [expr {$height - [NSToplevel::TotalHeight $winRecall]}]
521	} elseif {[Value choicewindow,show]} {
522		set height [expr {$height - [NSToplevel::TotalHeight [Window choice]]}]
523	}
524
525	# Subtract the height of other subwindows of the Main Window.
526	# This is done because I know main,widget is gridded, and
527	# cannot therefore simply set the height of the window itself.
528	set grid [wm grid $winMain]
529	if {[llength $grid]} {
530		set height2 [winfo height [Global main,widget]]
531		set height [expr {$height - ([winfo height $winMain] - $height2)}]
532	}
533
534	# Calculate the required dimensions of the content area of
535	# the Main Window
536	set width [NSToplevel::ContentWidth $winMain $width]
537	set height [NSToplevel::ContentHeight $winMain $height]
538
539	# If the Main Window is a gridded window, convert from dimensions in
540	# pixels to dimensions in grid units.
541	set grid [wm grid $winMain]
542	if {[llength $grid]} {
543		set gridWidth [lindex $grid 2]
544		set gridHeight [lindex $grid 3]
545		set width [expr {$width / $gridWidth}]
546		set height [expr {$height / $gridHeight}]
547	}
548
549	# Set the geometry of the Main Window
550	wm geometry $winMain ${width}x$height
551	update idletasks
552
553	if {[Value recall,show]} {
554		# Grow the Recall Window vertically
555		set height [expr {$bottom - [NSToplevel::TotalHeight $winMessage] \
556			- [NSToplevel::TotalHeight $winMain]}]
557		set height [NSToplevel::ContentHeight $winRecall $height]
558		wm geometry $winRecall [winfo width $winRecall]x$height
559	}
560
561	# Arrange the other windows relative to the Main Window
562	HardcodeGeometry
563
564	return
565}
566
567# FixWindows --
568#
569#	Here's a stinker for you. In "inventory.tcl" the command CalcLineLength()
570#	calls "winfo width $canvas". Well, if the Inventory Window was never
571#	shown, then "winfo width $canvas" returns a useless value. Ditto for the
572#	Store Window. So to avoid this problem (and any other similar ones)
573#	I call this command to move all the windows offscreen, show them, then
574#	hide them again, once, during startup. This isn't a problem when
575#	starting up with HardcodeGeometry(), only when setting window positions
576#	with ReadGeometryFile().
577#
578# Arguments:
579#	arg1					about arg1
580#
581# Results:
582#	What happened.
583
584proc FixWindows {} {
585
586	global Windows
587
588	set offset [winfo screenwidth .]
589
590	# Can anyone make this simpler? It is completely beyond me.
591
592	foreach window [array names Windows] {
593		set win [Window $window]
594
595		# "winfo geometry" returns bad x,y values, as do both
596		# "winfo x" and "winfo"y" at this point...
597		set geomList [split [wm geometry $win] +x]
598		set x [lindex $geomList 2]
599		set y [lindex $geomList 3]
600
601		wm geometry $win +$offset+0
602		update idletasks
603
604#		wm deiconify $win
605wm state $win normal
606
607		# "update idletasks" does NOT work here
608		update
609
610		wm withdraw $win
611		update idletasks
612
613		wm geometry $win +$x+$y
614		update idletasks
615	}
616
617	return
618}
619
620# GetDefaultGeometry --
621#
622#	Calculates the default geometry for one of the secondary game windows,
623#	such as the Inventory, Character or Knowledge Window. The top edge is
624#	the same as the Main Window, the left edge zero, and the right edge
625#	is 800 pixels, or the width of the screen, whichever is less.
626#
627# Arguments:
628#	arg1					about arg1
629#
630# Results:
631#	What happened.
632
633proc GetDefaultGeometry {win reqWidth reqHeight} {
634
635	set winMain [Window main]
636	set screenWidth [winfo screenwidth $winMain]
637
638	# If this is being called in HardcodeGeometry(), then the window
639	# should be positioned offscreen.
640	if {[winfo x $winMain] >= $screenWidth} {
641		set x $screenWidth
642	} else {
643		set x 0
644	}
645
646	# If the Message Window is embedded, then windows should be
647	# below it.
648	if {[Value message,float]} {
649		set y [NSToplevel::FrameTop $winMain]
650	} else {
651		set y [winfo rooty [Window main].message]
652		incr y [winfo height [Window main].message]
653		incr y 2
654	}
655
656	# BUG: When a window is minimized (not withdrawn), Win32 tells
657	# us that rootx and rooty are "3000".
658
659	# Calculate the width
660	switch -- $reqWidth {
661		main {
662			set width [NSToplevel::TotalWidth $winMain]
663			if {$width > 600} {
664				set width 600
665			}
666			set width [NSToplevel::ContentWidth $win $width]
667		}
668		main2 {
669			if {$screenWidth < 800} {
670				set width [NSToplevel::ContentWidth $win $screenWidth]
671			} else {
672				set width [NSToplevel::TotalWidth $winMain]
673				if {$width > 600} {
674					set width 600
675				}
676				set width [NSToplevel::ContentWidth $win $width]
677			}
678		}
679		reqwidth {
680			set width [winfo reqwidth $win]
681		}
682		screen {
683			if {$screenWidth > 600} {
684				set width 600
685			} else {
686				set width $screenWidth
687			}
688			set width [NSToplevel::ContentWidth $win $width]
689		}
690		default {
691			set width [NSToplevel::ContentWidth $win $reqWidth]
692		}
693	}
694
695	# Calculate the height
696	switch -- $reqHeight {
697		main {
698			set dy [expr {$y - [NSToplevel::FrameTop $winMain]}]
699			set height [expr {[NSToplevel::TotalHeight $winMain] - $dy}]
700			if {$height > 400} {
701				set height 400
702			}
703			set height [NSToplevel::ContentHeight $win $height]
704		}
705		reqheight {
706			set height [winfo reqheight $win]
707		}
708		default {
709			set height [NSToplevel::ContentHeight $win $reqHeight]
710		}
711	}
712
713	return ${width}x$height+$x+$y
714}
715
716
717# StripCommon --
718#
719#	Remove matching elements in path2 from path1.
720#
721# Arguments:
722#	arg1					about arg1
723#
724# Results:
725#	What happened.
726
727proc StripCommon {path1 path2} {
728
729	if {[file exists $path1]} {
730		set path1 [LongName $path1]
731	}
732	if {[file exists $path2]} {
733		set path2 [LongName $path2]
734	}
735
736	set list1 [file split $path1]
737	set list2 [file split $path2]
738	set len [llength $list2]
739	return [lrange $list1 $len end]
740}
741
742# IsFileInX --
743#
744#	Determine whether path1 is a child of path2.
745#
746# Arguments:
747#	arg1					about arg1
748#
749# Results:
750#	What happened.
751
752proc IsFileInX {path1 path2 {deep 1}} {
753
754	if {[file exists $path1]} {
755		set path1 [LongName $path1]
756	}
757	if {[file exists $path2]} {
758		set path2 [LongName $path2]
759	}
760
761	foreach elem1 [file split $path1] elem2 [file split $path2] {
762		if {[Platform windows]} {
763			set elem1 [string tolower $elem1]
764			set elem2 [string tolower $elem2]
765		}
766		if {![string length $elem1]} {
767			return 0
768		}
769		if {![string length $elem2]} {
770			if {$deep} {
771				return 1
772			}
773			if {[llength [file split $path1]] == [llength [file split $path2]] + 1} {
774				return 1
775			}
776			return 0
777		}
778		if {[string compare $elem1 $elem2]} {
779			return 0
780		}
781	}
782
783	return 1
784}
785
786# IsUserFile --
787#
788#	Determine whether the given file is inside the lib/user directory.
789#
790# Arguments:
791#	arg1					about arg1
792#
793# Results:
794#	What happened.
795
796proc IsUserFile {path} {
797
798	return [IsFileInX $path [PathUser] 0]
799}
800
801# IsFileInPath --
802#
803#	Determine whether the given file is a child of the [Path] directory.
804#
805# Arguments:
806#	arg1					about arg1
807#
808# Results:
809#	What happened.
810
811proc IsFileInPath {path} {
812
813	return [IsFileInX $path [PathTk]]
814}
815
816
817proc InitModules {} {
818
819	NSModule::IndexLoad [PathTk moduleIndex.tcl]
820
821	return
822}
823
824# InitOther --
825#
826#	The main initialization command.
827#
828# Arguments:
829#	arg1					about arg1
830#
831# Results:
832#	What happened.
833
834proc InitOther {} {
835
836	global Angband
837
838	InitLoadWindow
839
840	angband_load progress 0.25
841	angband_load note "Sourcing scripts..."
842
843	Source keypress.tcl
844	Source angband.tcl
845
846	angband_load progress 0.45
847	angband_load note "Initializing icons..."
848
849	# Load the configuration files from the "current" set
850	NSConfig::Load
851
852	angband_load progress 0.75
853
854	angband_load note "Initializing modules..."
855	InitModules
856
857	angband_load note "Initializing: Main Window"
858	NSModule::LoadIfNeeded NSMainWindow
859	angband_load progress 0.80
860
861	angband_load note "Initializing: Aux Windows"
862	NSModule::LoadIfNeeded NSMiscWindow
863	angband_load progress 0.85
864
865	angband_load note "Initializing: Recall"
866	NSModule::LoadIfNeeded NSRecall
867
868	angband_load note "Initializing: Info"
869	NSObject::New NSInfoWindow
870
871	# Synch windows with options
872	if {[Value message,float]} {
873		grid remove [Window main].message
874	} else {
875		Global message,message [Window main].message.message
876	}
877	if {[Value misc,float]} {
878		grid remove [Window main].misc
879	} else {
880		Value misc,layout tall ; # Paranoia
881		Global misc,canvas [Window main].misc.misc
882	}
883
884	if {[Platform unix]} {
885		if {![file exists [PathTk config geometry]]} {
886			wm geometry [Window main] +0+0
887			wm geometry [Window message] +0+0
888			wm geometry [Window recall] +0+0
889			wm geometry [Window misc] +0+0
890			wm geometry [Window progress] +0+0
891			update idletasks
892
893			wm deiconify [Window main]
894			if {[Value message,float]} {
895				wm state [Window message] normal
896			}
897			if {[Value recall,show]} {
898#				wm state [Window recall] normal
899				NSWindowManager::Display recall
900			}
901			if {[Value misc,float]} {
902				wm state [Window misc] normal
903				if {[Value misc,layout] == "wide"} {
904					wm state [Window progress] normal
905				}
906			}
907		}
908	# unix
909	}
910
911	angband_load progress 0.95
912	if {[file exists [PathTk config geometry]]} {
913		angband_load note "Reading geometry file..."
914		ReadGeometryFile
915#		FixWindows
916	} else {
917		angband_load note "Setting default window positions..."
918		HardcodeGeometry
919	}
920	update idletasks
921
922#	if {$::DEBUG} {
923#		NSModule::AddModule NSDebug [PathTk debug.tcl]
924#		NSModule::LoadIfNeeded NSDebug
925#	}
926
927	# The load window is obscured below
928	angband_load progress 1.0
929
930	# Show windows which should be shown
931	if {[Platform unix]} {
932		if {[file exists [PathTk config geometry]]} {
933			wmDeiconify [Window main]
934			if {[Value recall,show]} {
935#				wmStateNormal [Window recall]
936				NSWindowManager::Display recall
937			}
938			if {[Value misc,float]} {
939				wmStateNormal [Window misc]
940				if {[Value misc,layout] == "wide"} {
941					wmStateNormal [Window progress]
942				}
943			}
944			if {[Value message,float]} {
945				wmStateNormal [Window message]
946			}
947		}
948	}
949	if {[Platform windows]} {
950		wm deiconify [Window main]
951		update
952		if {[Value recall,show]} {
953			NSWindowManager::Display recall
954#			wm state [Window recall] normal
955			update
956		}
957		if {[Value misc,float]} {
958			wm state [Window misc] normal
959			update
960			if {[Value misc,layout] == "wide"} {
961				wm state [Window progress] normal
962				update
963			}
964		}
965		if {[Value message,float]} {
966			wm state [Window message] normal
967			update
968		}
969	}
970	if {[Value choicewindow,show]} {
971		NSModule::LoadIfNeeded NSChoiceWindow
972		NSWindowManager::Display choice
973	}
974	if {[Value message2window,show]} {
975		NSModule::LoadIfNeeded NSMessageWindow
976		NSWindowManager::Display message2
977	}
978
979	update
980
981	# Focus on Main Window
982	# It seems important to do this before hiding the Load Window,
983	# otherwise the application swaps into the background
984	focus [Window main]
985
986	# Done with "load" window
987	angband_load kill
988
989	# Show the Tips Window if desired
990	if {[Value tip,show]} {
991		NSModule::LoadIfNeeded NSTips
992	}
993
994	return
995}
996
997# Main initialization command
998InitOther
999