git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 2/2] gitk: make Tags and Heads window geometry sticky

From
Johannes Sixt <j6t@kdbg.org>
Date
Oct 4, 2025, 17:36 UTC
Message-ID
<fd6450e2-cf56-4b99-b0ed-37a174d7ce9c@kdbg.org>
In-Reply-To
<20250928135435.59623-3-rappazzo@gmail.com>
Am 28.09.25 um 15:54 schrieb Michael Rappazzo:
Show 99 quoted lines
> 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 <rappazzo@gmail.com>
> ---
>  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 <Key-Escape> [list destroy $top]
> +    ttk::button $top.close -command [list destroy_showrefs $top] -text [mc "Close"]
> +    bind $top <Key-Escape> [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 <ButtonRelease-1> {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 <Map> [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 <Configure> [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 <ButtonRelease-1> {sel_reflist %W %x %y; break}
     set reflist {}
     refill_reflist
+    if {[info exists geometry(showrefs)]} {
+        after idle [list wm geometry $top $geometry(showrefs)]
+    }
+    # avoid <Configure> being bound to child windows
+    bindtags $top [linsert [bindtags $top] 1 bind$top]
+    bind bind$top <Configure> {set geometry(showrefs) [wm geometry %W]}
 }

 proc sel_reflist {w x y} {
Previous: Junio C HamanoNext: Johannes Sixt
Message 10 of 12 in “gitk: make Tags and Heads window geometry sticky”
  1. 0/2 gitk: make Tags and Heads window geometry stickyMichael Rappazzo, Sep 28, 2025
  2. 1/2 Revert "gitk: Only restore window size from ~/.gitk, not position"Michael Rappazzo, Sep 28, 2025
  3. Mark LevedahlSep 28, 2025
  4. Mike RappazzoSep 28, 2025
  5. Johannes SixtOct 17, 2025
  6. Mark LevedahlOct 17, 2025
  7. Junio C HamanoSep 28, 2025
  8. 2/2 gitk: make Tags and Heads window geometry stickyMichael Rappazzo, Sep 28, 2025
  9. Junio C HamanoSep 28, 2025
  10. Johannes SixtOct 4, 2025
  11. gitk: persist position and size of the Tags and Heads windowJohannes Sixt, Oct 4, 2025
  12. gitk: persist position and size of the Tags and Heads windowJohannes Sixt, Oct 6, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.