From: Johannes Sixt Date: Sat, 04 Oct 2025 17:36:35 GMT Subject: Re: [PATCH v3 2/2] gitk: make Tags and Heads window geometry sticky Message-ID: In-Reply-To: <20250928135435.59623-3-rappazzo@gmail.com> Am 28.09.25 um 15:54 schrieb Michael Rappazzo: > Currently, the Tags and Heads window always opens at a default position > and size, requiring users to reposition it each time. This patch makes > the window remember its geometry between sessions. > > This change saves and restores the Tags and Heads window size and position > relative to the main gitk window. The geometry is stored in the config file > as `geometry(showrefs)` and persists between gitk sessions. The window > position is stored relative to the main window, so it maintains the same > spatial relationship when the main window is moved or when gitk is restarted > on different monitors. > > Signed-off-by: Michael Rappazzo > --- > gitk | 39 +++++++++++++++++++++++++++++++++++++-- > 1 file changed, 37 insertions(+), 2 deletions(-) > > diff --git a/gitk b/gitk > index 275f353811..79a6dcdb4c 100755 > --- a/gitk > +++ b/gitk > @@ -3106,6 +3106,11 @@ proc savestuff {w} { > puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sashpos 1] 1\"" > puts $f "set geometry(botwidth) [winfo width .bleft]" > puts $f "set geometry(botheight) [winfo height .bleft]" > + if {[winfo exists .showrefs]} { > + puts $f "set geometry(showrefs) \"[wm geometry .showrefs]\"" > + } elseif {[info exists geometry(showrefs)]} { > + puts $f "set geometry(showrefs) \"$geometry(showrefs)\"" > + } > > array set view_save {} > array set views {} > @@ -10199,11 +10204,13 @@ proc showrefs {} { > if {[winfo exists $top]} { > raise $top > refill_reflist > + wm protocol $top WM_DELETE_WINDOW [list destroy_showrefs $top] > return > } > ttk_toplevel $top > wm title $top [mc "Tags and heads: %s" [file tail [pwd]]] > make_transient $top . > + wm protocol $top WM_DELETE_WINDOW [list destroy_showrefs $top] > text $top.list -background $bgcolor -foreground $fgcolor \ > -selectbackground $selectbgcolor -font mainfont \ > -xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \ > @@ -10229,8 +10236,8 @@ proc showrefs {} { > ttk::checkbutton $top.sort -text [mc "Sort refs by type"] \ > -variable sortrefsbytype -command {refill_reflist} > grid $top.sort - -sticky w -pady 2 > - ttk::button $top.close -command [list destroy $top] -text [mc "Close"] > - bind $top [list destroy $top] > + ttk::button $top.close -command [list destroy_showrefs $top] -text [mc "Close"] > + bind $top [list destroy_showrefs $top] > grid $top.close - > grid columnconfigure $top 0 -weight 1 > grid rowconfigure $top 0 -weight 1 > @@ -10239,6 +10246,9 @@ proc showrefs {} { > bind $top.list {sel_reflist %W %x %y; break} > set reflist {} > refill_reflist > + # Restore geometry after the window is fully created and mapped > + # Delay Configure binding to avoid overwriting restored geometry > + bind $top [list after idle [list setup_showrefs_geometry_tracking $top]] > } > > proc sel_reflist {w x y} { > @@ -10271,6 +10281,31 @@ proc reflistfilter_change {n1 n2 op} { > after 200 refill_reflist > } > > +proc save_showrefs_geometry {top} { > + global geometry > + if {[winfo exists $top]} { > + set geometry(showrefs) [wm geometry $top] > + } > +} > + > +proc restore_showrefs_geometry {top} { > + global geometry > + if {[info exists geometry(showrefs)] && [winfo exists $top]} { > + wm geometry $top $geometry(showrefs) > + } > +} > + > +proc setup_showrefs_geometry_tracking {top} { > + restore_showrefs_geometry $top > + bind $top [list save_showrefs_geometry $top] > +} > + > +proc destroy_showrefs {top} { > + save_showrefs_geometry $top > + savestuff . > + destroy $top > +} > + > proc refill_reflist {} { > global reflist reflistfilter showrefstop headids tagids otherrefids sortrefsbytype > global curview upstreamofref A patch should be much smaller than this. I was thinking along the lines of the below diff. However, it doesn't work for some reason: the variable that is updated from the Configure handler is not the same that is serialized in proc savestuff, and I don't know why. Nevertheless, within a session, the window geometry *is* preserved, just not across sessions. diff --git a/gitk b/gitk index 275f353..77d5acc 100755 --- a/gitk +++ b/gitk @@ -3058,7 +3058,7 @@ proc config_variable_change_cb {name name2 op} { } proc savestuff {w} { - global stuffsaved + global stuffsaved geometry global config_file config_file_tmp global config_variables config_variable_changed global viewchanged @@ -3106,6 +3106,9 @@ proc savestuff {w} { puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sashpos 1] 1\"" puts $f "set geometry(botwidth) [winfo width .bleft]" puts $f "set geometry(botheight) [winfo height .bleft]" + if {[info exists geometry(showrefs)]} { + puts $f "set geometry(showrefs) \"$geometry(showrefs)\"" + } array set view_save {} array set views {} @@ -10193,6 +10196,7 @@ proc rmbranch {} { proc showrefs {} { global showrefstop bgcolor fgcolor selectbgcolor global bglist fglist reflistfilter reflist maincursor + global geometry set top .showrefs set showrefstop $top @@ -10239,6 +10243,12 @@ proc showrefs {} { bind $top.list {sel_reflist %W %x %y; break} set reflist {} refill_reflist + if {[info exists geometry(showrefs)]} { + after idle [list wm geometry $top $geometry(showrefs)] + } + # avoid being bound to child windows + bindtags $top [linsert [bindtags $top] 1 bind$top] + bind bind$top {set geometry(showrefs) [wm geometry %W]} } proc sel_reflist {w x y} {