Anonymous avatar Anonymous committed 39fa2a9

git-gui: Save geometry before the window layout is damaged

Because Tk does not assure us the order that it will process
children in before it destroys the main toplevel we cannot safely
save our geometry data during a "bind . <Destroy>" event binding.
The geometry may have already changed as a result of a one or
more children being removed from the layout. This was pointed
out in gitk by Mark Levedahl, and patched over there by commit

So we now also use "wm protocol . WM_DELETE_WINDOW" to detect when
the window is closed by the user, and forward that close event to
our main do_quit routine.

Signed-off-by: Shawn O. Pearce <>;

Comments (0)

Files changed (6)

 # -- Standard bindings
-bind .   <Destroy> {if {{%W} eq {.}} do_quit}
+wm protocol . WM_DELETE_WINDOW do_quit
 bind all <$M1B-Key-q> do_quit
 bind all <$M1B-Key-Q> do_quit
 bind all <$M1B-Key-w> {destroy [winfo toplevel %W]}
 	bind $w_cviewer <Button-1> [list focus $w_cviewer]
 	bind $top <Visibility> [list focus $top]
-	bind $w_file <Destroy> [list delete_this $this]
 	grid configure $w.header -sticky ew
 	grid configure $w.file_pane -sticky nsew
 	bind $w_list <Right>           break
 	bind $w_list <Visibility> [list focus $w_list]
-	bind $w_list <Destroy> [list delete_this $this]
 	set w $w_list
 	_ls $this $browser_commit
 	return $this
 	if {[namespace exists $t]} {namespace delete $t}
-proc make_toplevel {t w} {
-	upvar $t top $w pfx
+proc make_toplevel {t w args} {
+	upvar $t top $w pfx this this
+	if {[llength $args] % 2} {
+		error "make_toplevel topvar winvar {options}"
+	}
+	set autodelete 1
+	foreach {name value} $args {
+		switch -exact -- $name {
+		-autodelete {set autodelete $value}
+		default     {error "unsupported option $name"}
+		}
+	}
 	if {[winfo ismapped .]} {
-		upvar this this
 		regsub -all {::} $this {__} w
 		set top .$w
 		set pfx $top
 		set top .
 		set pfx {}
+	if {$autodelete} {
+		wm protocol $top WM_DELETE_WINDOW "
+			[list delete_this $this]
+			[list destroy $top]
+		"
+	}
 method _init {} {
 	global M1B
-	make_toplevel top w
+	make_toplevel top w -autodelete 0
 	wm title $top "[appname] ([reponame]): $t_short"
 	set console_cr 1.0
 	set cons [console::new "Merge" $msg]
 	console::exec $cons $cmd \
 		[namespace code [list _finish $revcnt $cons]]
-	bind $w <Destroy> {}
+	wm protocol $w WM_DELETE_WINDOW {}
 	destroy $w
 	bind $w <$M1B-Key-Return> $_start
 	bind $w <Visibility> "grab $w; focus $w.source.l"
 	bind $w <Key-Escape> "unlock_index;destroy $w"
-	bind $w <Destroy> unlock_index
+	wm protocol $w WM_DELETE_WINDOW "unlock_index;destroy $w"
 	wm title $w "[appname] ([reponame]): Merge"
 	tkwait window $w
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.