gitk: Merge branch 'dev' into master
authorPaul Mackerras <paulus@samba.org>
Sat, 14 Nov 2009 10:26:31 +0000 (21:26 +1100)
committerPaul Mackerras <paulus@samba.org>
Sat, 14 Nov 2009 10:26:31 +0000 (21:26 +1100)
Signed-off-by: Paul Mackerras <paulus@samba.org>
1  2 
gitk
diff --combined gitk
index d5f0a88d78784accc3c45bea4fd02f98428b09b7,c0f38adb9b3774f00cc1f0810589b5906cea8d77..ff6b680c7bca141bad805bc0b5a36e4bac5c3028
--- 1/gitk
--- 2/gitk
+++ b/gitk
@@@ -2,11 -2,13 +2,13 @@@
  # Tcl ignores the next line -*- tcl -*- \
  exec wish "$0" -- "$@"
  
- # Copyright © 2005-2008 Paul Mackerras.  All rights reserved.
+ # Copyright © 2005-2009 Paul Mackerras.  All rights reserved.
  # This program is free software; it may be used, copied, modified
  # and distributed under the terms of the GNU General Public Licence,
  # either version 2, or (at your option) any later version.
  
+ package require Tk
  proc gitdir {} {
      global env
      if {[info exists env(GIT_DIR)]} {
@@@ -265,7 -267,7 +267,7 @@@ proc parseviewrevs {view revs} 
                }
                lappend badrev $line
            }
-       }                   
+       }
        error_popup "[mc "Error parsing revisions:"] $err"
        return {}
      }
@@@ -987,6 -989,18 +989,18 @@@ proc removefakerow {id} 
      drawvisible
  }
  
+ proc real_children {vp} {
+     global children nullid nullid2
+     set kids {}
+     foreach id $children($vp) {
+       if {$id ne $nullid && $id ne $nullid2} {
+           lappend kids $id
+       }
+     }
+     return $kids
+ }
  proc first_real_child {vp} {
      global children nullid nullid2
  
@@@ -1769,6 -1783,15 +1783,15 @@@ proc removehead {id name} 
      unset headids($name)
  }
  
+ proc ttk_toplevel {w args} {
+     global use_ttk
+     eval [linsert $args 0 ::toplevel $w]
+     if {$use_ttk} {
+         place [ttk::frame $w._toplevel_background] -x 0 -y 0 -relwidth 1 -relheight 1
+     }
+     return $w
+ }
  proc make_transient {window origin} {
      global have_tk85
  
      }
  }
  
 -proc show_error {w top msg} {
 +proc show_error {w top msg {mc mc}} {
+     global NS
+     if {![info exists NS]} {set NS ""}
+     if {[wm state $top] eq "withdrawn"} { wm deiconify $top }
      message $w.m -text $msg -justify center -aspect 400
      pack $w.m -side top -fill x -padx 20 -pady 20
-     button $w.ok -text [$mc OK] -command "destroy $top"
 -    ${NS}::button $w.ok -default active -text [mc OK] -command "destroy $top"
++    ${NS}::button $w.ok -default active -text [$mc OK] -command "destroy $top"
      pack $w.ok -side bottom -fill x
      bind $top <Visibility> "grab $top; focus $top"
      bind $top <Key-Return> "destroy $top"
  }
  
  proc error_popup {msg {owner .}} {
-     set w .error
-     toplevel $w
-     make_transient $w $owner
-     show_error $w $w $msg
+     if {[tk windowingsystem] eq "win32"} {
+         tk_messageBox -icon error -type ok -title [wm title .] \
+             -parent $owner -message $msg
+     } else {
+         set w .error
+         ttk_toplevel $w
+         make_transient $w $owner
+         show_error $w $w $msg
+     }
  }
  
  proc confirm_popup {msg {owner .}} {
-     global confirm_ok
+     global confirm_ok NS
      set confirm_ok 0
      set w .confirm
-     toplevel $w
+     ttk_toplevel $w
      make_transient $w $owner
      message $w.m -text $msg -justify center -aspect 400
      pack $w.m -side top -fill x -padx 20 -pady 20
-     button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
+     ${NS}::button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
      pack $w.ok -side left -fill x
-     button $w.cancel -text [mc Cancel] -command "destroy $w"
+     ${NS}::button $w.cancel -text [mc Cancel] -command "destroy $w"
      pack $w.cancel -side right -fill x
      bind $w <Visibility> "grab $w; focus $w"
      bind $w <Key-Return> "set confirm_ok 1; destroy $w"
      bind $w <Key-space>  "set confirm_ok 1; destroy $w"
      bind $w <Key-Escape> "destroy $w"
+     tk::PlaceWindow $w widget $owner
      tkwait window $w
      return $confirm_ok
  }
  
  proc setoptions {} {
-     option add *Panedwindow.showHandle 1 startupFile
-     option add *Panedwindow.sashRelief raised startupFile
+     if {[tk windowingsystem] ne "win32"} {
+         option add *Panedwindow.showHandle 1 startupFile
+         option add *Panedwindow.sashRelief raised startupFile
+         if {[tk windowingsystem] ne "aqua"} {
+             option add *Menu.font uifont startupFile
+         }
+     } else {
+         option add *Menu.TearOff 0 startupFile
+     }
      option add *Button.font uifont startupFile
      option add *Checkbutton.font uifont startupFile
      option add *Radiobutton.font uifont startupFile
-     if {[tk windowingsystem] ne "aqua"} {
-       option add *Menu.font uifont startupFile
-     }
      option add *Menubutton.font uifont startupFile
      option add *Label.font uifont startupFile
      option add *Message.font uifont startupFile
      option add *Entry.font uifont startupFile
+     option add *Labelframe.font uifont startupFile
  }
  
  # Make a menu and submenus.
@@@ -1895,6 -1932,22 +1932,22 @@@ proc mca {str} 
      return [string map {&& & & {}} [mc $str]]
  }
  
+ proc makedroplist {w varname args} {
+     global use_ttk
+     if {$use_ttk} {
+         set width 0
+         foreach label $args {
+             set cx [string length $label]
+             if {$cx > $width} {set width $cx}
+         }
+       set gm [ttk::combobox $w -width $width -state readonly\
+                   -textvariable $varname -values $args]
+     } else {
+       set gm [eval [linsert $args 0 tk_optionMenu $w $varname]]
+     }
+     return $gm
+ }
  proc makewindow {} {
      global canv canv2 canv3 linespc charspc ctext cflist cscroll
      global tabstop
      global headctxmenu progresscanv progressitem progresscoords statusw
      global fprogitem fprogcoord lastprogupdate progupdatepending
      global rprogitem rprogcoord rownumsel numcommits
-     global have_tk85
+     global have_tk85 use_ttk NS
  
      # The "mc" arguments here are purely so that xgettext
      # sees the following string as needing to be translated
      makemenu .bar $bar
      . configure -menu .bar
  
+     if {$use_ttk} {
+         # cover the non-themed toplevel with a themed frame.
+         place [ttk::frame ._main_background] -x 0 -y 0 -relwidth 1 -relheight 1
+     }
      # the gui has upper and lower half, parts of a paned window.
-     panedwindow .ctop -orient vertical
+     ${NS}::panedwindow .ctop -orient vertical
  
      # possibly use assumed geometry
      if {![info exists geometry(pwsash0)]} {
          set geometry(topwidth) [expr {80 * $charspc}]
          set geometry(botheight) [expr {15 * $linespc}]
          set geometry(botwidth) [expr {50 * $charspc}]
-         set geometry(pwsash0) "[expr {40 * $charspc}] 2"
-         set geometry(pwsash1) "[expr {60 * $charspc}] 2"
+         set geometry(pwsash0) [list [expr {40 * $charspc}] 2]
+         set geometry(pwsash1) [list [expr {60 * $charspc}] 2]
      }
  
      # the upper half will have a paned window, a scroll bar to the right, and some stuff below
-     frame .tf -height $geometry(topheight) -width $geometry(topwidth)
-     frame .tf.histframe
-     panedwindow .tf.histframe.pwclist -orient horizontal -sashpad 0 -handlesize 4
+     ${NS}::frame .tf -height $geometry(topheight) -width $geometry(topwidth)
+     ${NS}::frame .tf.histframe
+     ${NS}::panedwindow .tf.histframe.pwclist -orient horizontal
+     if {!$use_ttk} {
+       .tf.histframe.pwclist configure -sashpad 0 -handlesize 4
+     }
  
      # create three canvases
      set cscroll .tf.histframe.csb
        -selectbackground $selectbgcolor \
        -background $bgcolor -bd 0 -yscrollincr $linespc
      .tf.histframe.pwclist add $canv3
-     eval .tf.histframe.pwclist sash place 0 $geometry(pwsash0)
-     eval .tf.histframe.pwclist sash place 1 $geometry(pwsash1)
+     if {$use_ttk} {
+       bind .tf.histframe.pwclist <Map> {
+           bind %W <Map> {}
+           .tf.histframe.pwclist sashpos 1 [lindex $::geometry(pwsash1) 0]
+           .tf.histframe.pwclist sashpos 0 [lindex $::geometry(pwsash0) 0]
+       }
+     } else {
+       eval .tf.histframe.pwclist sash place 0 $geometry(pwsash0)
+       eval .tf.histframe.pwclist sash place 1 $geometry(pwsash1)
+     }
  
      # a scroll bar to rule them
-     scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
+     ${NS}::scrollbar $cscroll -command {allcanvs yview}
+     if {!$use_ttk} {$cscroll configure -highlightthickness 0}
      pack $cscroll -side right -fill y
      bind .tf.histframe.pwclist <Configure> {resizeclistpanes %W %w}
      lappend bglist $canv $canv2 $canv3
      pack .tf.histframe.pwclist -fill both -expand 1 -side left
  
      # we have two button bars at bottom of top frame. Bar 1
-     frame .tf.bar
-     frame .tf.lbar -height 15
+     ${NS}::frame .tf.bar
+     ${NS}::frame .tf.lbar -height 15
  
      set sha1entry .tf.bar.sha1
      set entries $sha1entry
        -command gotocommit -width 8
      $sha1but conf -disabledforeground [$sha1but cget -foreground]
      pack .tf.bar.sha1label -side left
-     entry $sha1entry -width 40 -font textfont -textvariable sha1string
+     ${NS}::entry $sha1entry -width 40 -font textfont -textvariable sha1string
      trace add variable sha1string write sha1change
      pack $sha1entry -side left -pady 2
  
        0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
        0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
      }
-     button .tf.bar.leftbut -image bm-left -command goback \
+     ${NS}::button .tf.bar.leftbut -image bm-left -command goback \
        -state disabled -width 26
      pack .tf.bar.leftbut -side left -fill y
-     button .tf.bar.rightbut -image bm-right -command goforw \
+     ${NS}::button .tf.bar.rightbut -image bm-right -command goforw \
        -state disabled -width 26
      pack .tf.bar.rightbut -side left -fill y
  
-     label .tf.bar.rowlabel -text [mc "Row"]
+     ${NS}::label .tf.bar.rowlabel -text [mc "Row"]
      set rownumsel {}
-     label .tf.bar.rownum -width 7 -font textfont -textvariable rownumsel \
+     ${NS}::label .tf.bar.rownum -width 7 -textvariable rownumsel \
        -relief sunken -anchor e
-     label .tf.bar.rowlabel2 -text "/"
-     label .tf.bar.numcommits -width 7 -font textfont -textvariable numcommits \
+     ${NS}::label .tf.bar.rowlabel2 -text "/"
+     ${NS}::label .tf.bar.numcommits -width 7 -textvariable numcommits \
        -relief sunken -anchor e
      pack .tf.bar.rowlabel .tf.bar.rownum .tf.bar.rowlabel2 .tf.bar.numcommits \
        -side left
+     if {!$use_ttk} {
+         foreach w {rownum numcommits} {.tf.bar.$w configure -font textfont}
+     }
      global selectedline
      trace add variable selectedline write selectedline_change
  
      # Status label and progress bar
      set statusw .tf.bar.status
-     label $statusw -width 15 -relief sunken
+     ${NS}::label $statusw -width 15 -relief sunken
      pack $statusw -side left -padx 5
-     set h [expr {[font metrics uifont -linespace] + 2}]
-     set progresscanv .tf.bar.progress
-     canvas $progresscanv -relief sunken -height $h -borderwidth 2
-     set progressitem [$progresscanv create rect -1 0 0 $h -fill green]
-     set fprogitem [$progresscanv create rect -1 0 0 $h -fill yellow]
-     set rprogitem [$progresscanv create rect -1 0 0 $h -fill red]
-     pack $progresscanv -side right -expand 1 -fill x
+     if {$use_ttk} {
+       set progresscanv [ttk::progressbar .tf.bar.progress]
+     } else {
+       set h [expr {[font metrics uifont -linespace] + 2}]
+       set progresscanv .tf.bar.progress
+       canvas $progresscanv -relief sunken -height $h -borderwidth 2
+       set progressitem [$progresscanv create rect -1 0 0 $h -fill green]
+       set fprogitem [$progresscanv create rect -1 0 0 $h -fill yellow]
+       set rprogitem [$progresscanv create rect -1 0 0 $h -fill red]
+     }
+     pack $progresscanv -side right -expand 1 -fill x -padx {0 2}
      set progresscoords {0 0}
      set fprogcoord 0
      set rprogcoord 0
      set progupdatepending 0
  
      # build up the bottom bar of upper window
-     label .tf.lbar.flabel -text "[mc "Find"] "
-     button .tf.lbar.fnext -text [mc "next"] -command {dofind 1 1}
-     button .tf.lbar.fprev -text [mc "prev"] -command {dofind -1 1}
-     label .tf.lbar.flab2 -text " [mc "commit"] "
+     ${NS}::label .tf.lbar.flabel -text "[mc "Find"] "
+     ${NS}::button .tf.lbar.fnext -text [mc "next"] -command {dofind 1 1}
+     ${NS}::button .tf.lbar.fprev -text [mc "prev"] -command {dofind -1 1}
+     ${NS}::label .tf.lbar.flab2 -text " [mc "commit"] "
      pack .tf.lbar.flabel .tf.lbar.fnext .tf.lbar.fprev .tf.lbar.flab2 \
        -side left -fill y
      set gdttype [mc "containing:"]
-     set gm [tk_optionMenu .tf.lbar.gdttype gdttype \
+     set gm [makedroplist .tf.lbar.gdttype gdttype \
                [mc "containing:"] \
                [mc "touching paths:"] \
                [mc "adding/removing string:"]]
      set findstring {}
      set fstring .tf.lbar.findstring
      lappend entries $fstring
-     entry $fstring -width 30 -font textfont -textvariable findstring
+     ${NS}::entry $fstring -width 30 -font textfont -textvariable findstring
      trace add variable findstring write find_change
      set findtype [mc "Exact"]
-     set findtypemenu [tk_optionMenu .tf.lbar.findtype \
-                     findtype [mc "Exact"] [mc "IgnCase"] [mc "Regexp"]]
+     set findtypemenu [makedroplist .tf.lbar.findtype \
+                         findtype [mc "Exact"] [mc "IgnCase"] [mc "Regexp"]]
      trace add variable findtype write findcom_change
      set findloc [mc "All fields"]
-     tk_optionMenu .tf.lbar.findloc findloc [mc "All fields"] [mc "Headline"] \
+     makedroplist .tf.lbar.findloc findloc [mc "All fields"] [mc "Headline"] \
        [mc "Comments"] [mc "Author"] [mc "Committer"]
      trace add variable findloc write find_change
      pack .tf.lbar.findloc -side right
      pack .tf.bar -in .tf -side bottom -fill x
      pack .tf.histframe -fill both -side top -expand 1
      .ctop add .tf
-     .ctop paneconfigure .tf -height $geometry(topheight)
-     .ctop paneconfigure .tf -width $geometry(topwidth)
+     if {!$use_ttk} {
+       .ctop paneconfigure .tf -height $geometry(topheight)
+       .ctop paneconfigure .tf -width $geometry(topwidth)
+     }
  
      # now build up the bottom
-     panedwindow .pwbottom -orient horizontal
+     ${NS}::panedwindow .pwbottom -orient horizontal
  
      # lower left, a text box over search bar, scroll bar to the right
      # if we know window height, then that will set the lower text height, otherwise
      # we set lower text height which will drive window height
      if {[info exists geometry(main)]} {
-         frame .bleft -width $geometry(botwidth)
+       ${NS}::frame .bleft -width $geometry(botwidth)
      } else {
-         frame .bleft -width $geometry(botwidth) -height $geometry(botheight)
+       ${NS}::frame .bleft -width $geometry(botwidth) -height $geometry(botheight)
      }
-     frame .bleft.top
-     frame .bleft.mid
-     frame .bleft.bottom
+     ${NS}::frame .bleft.top
+     ${NS}::frame .bleft.mid
+     ${NS}::frame .bleft.bottom
  
-     button .bleft.top.search -text [mc "Search"] -command dosearch
+     ${NS}::button .bleft.top.search -text [mc "Search"] -command dosearch
      pack .bleft.top.search -side left -padx 5
      set sstring .bleft.top.sstring
-     entry $sstring -width 20 -font textfont -textvariable searchstring
+     set searchstring ""
+     ${NS}::entry $sstring -width 20 -font textfont -textvariable searchstring
      lappend entries $sstring
      trace add variable searchstring write incrsearch
      pack $sstring -side left -expand 1 -fill x
-     radiobutton .bleft.mid.diff -text [mc "Diff"] \
+     ${NS}::radiobutton .bleft.mid.diff -text [mc "Diff"] \
        -command changediffdisp -variable diffelide -value {0 0}
-     radiobutton .bleft.mid.old -text [mc "Old version"] \
+     ${NS}::radiobutton .bleft.mid.old -text [mc "Old version"] \
        -command changediffdisp -variable diffelide -value {0 1}
-     radiobutton .bleft.mid.new -text [mc "New version"] \
+     ${NS}::radiobutton .bleft.mid.new -text [mc "New version"] \
        -command changediffdisp -variable diffelide -value {1 0}
-     label .bleft.mid.labeldiffcontext -text "      [mc "Lines of context"]: "
+     ${NS}::label .bleft.mid.labeldiffcontext -text "      [mc "Lines of context"]: "
      pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
      spinbox .bleft.mid.diffcontext -width 5 -font textfont \
        -from 0 -increment 1 -to 10000000 \
      trace add variable diffcontextstring write diffcontextchange
      lappend entries .bleft.mid.diffcontext
      pack .bleft.mid.labeldiffcontext .bleft.mid.diffcontext -side left
-     checkbutton .bleft.mid.ignspace -text [mc "Ignore space change"] \
+     ${NS}::checkbutton .bleft.mid.ignspace -text [mc "Ignore space change"] \
        -command changeignorespace -variable ignorespace
      pack .bleft.mid.ignspace -side left -padx 5
      set ctext .bleft.bottom.ctext
      if {$have_tk85} {
        $ctext conf -tabstyle wordprocessor
      }
-     scrollbar .bleft.bottom.sb -command "$ctext yview"
-     scrollbar .bleft.bottom.sbhorizontal -command "$ctext xview" -orient h \
-       -width 10
+     ${NS}::scrollbar .bleft.bottom.sb -command "$ctext yview"
+     ${NS}::scrollbar .bleft.bottom.sbhorizontal -command "$ctext xview" -orient h
      pack .bleft.top -side top -fill x
      pack .bleft.mid -side top -fill x
      grid $ctext .bleft.bottom.sb -sticky nsew
      $ctext tag conf found -back yellow
  
      .pwbottom add .bleft
-     .pwbottom paneconfigure .bleft -width $geometry(botwidth)
+     if {!$use_ttk} {
+       .pwbottom paneconfigure .bleft -width $geometry(botwidth)
+     }
  
      # lower right
-     frame .bright
-     frame .bright.mode
-     radiobutton .bright.mode.patch -text [mc "Patch"] \
+     ${NS}::frame .bright
+     ${NS}::frame .bright.mode
+     ${NS}::radiobutton .bright.mode.patch -text [mc "Patch"] \
        -command reselectline -variable cmitmode -value "patch"
-     radiobutton .bright.mode.tree -text [mc "Tree"] \
+     ${NS}::radiobutton .bright.mode.tree -text [mc "Tree"] \
        -command reselectline -variable cmitmode -value "tree"
      grid .bright.mode.patch .bright.mode.tree -sticky ew
      pack .bright.mode -side top -fill x
        -spacing1 1 -spacing3 1
      lappend bglist $cflist
      lappend fglist $cflist
-     scrollbar .bright.sb -command "$cflist yview"
+     ${NS}::scrollbar .bright.sb -command "$cflist yview"
      pack .bright.sb -side right -fill y
      pack $cflist -side left -fill both -expand 1
      $cflist tag configure highlight \
          set ::BM "2"
      }
  
+     if {$use_ttk} {
+         bind .ctop <Map> {
+             bind %W <Map> {}
+             %W sashpos 0 $::geometry(topheight)
+         }
+         bind .pwbottom <Map> {
+             bind %W <Map> {}
+             %W sashpos 0 $::geometry(botwidth)
+         }
+     }
      bind .pwbottom <Configure> {resizecdetpanes %W %w}
      pack .ctop -fill both -expand 1
      bindall <1> {selcanvline %W %x %y}
@@@ -2484,7 -2576,12 +2576,12 @@@ proc click {w} 
  proc adjustprogress {} {
      global progresscanv progressitem progresscoords
      global fprogitem fprogcoord lastprogupdate progupdatepending
-     global rprogitem rprogcoord
+     global rprogitem rprogcoord use_ttk
+     if {$use_ttk} {
+       $progresscanv configure -value [expr {int($fprogcoord * 100)}]
+       return
+     }
  
      set w [expr {[winfo width $progresscanv] - 4}]
      set x0 [expr {$w * [lindex $progresscoords 0]}]
@@@ -2519,14 -2616,13 +2616,14 @@@ proc savestuff {w} 
      global maxwidth showneartags showlocalchanges
      global viewname viewfiles viewargs viewargscmd viewperm nextviewnum
      global cmitmode wrapcomment datetimeformat limitdiffs
 -    global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor
 +    global colors uicolor bgcolor fgcolor diffcolors diffcontext selectbgcolor
-     global autoselect extdifftool perfile_attrs markbgcolor
-     global hideremotes
+     global autoselect extdifftool perfile_attrs markbgcolor use_ttk
+     global hideremotes want_ttk
  
      if {$stuffsaved} return
      if {![winfo viewable .]} return
      catch {
 +      if {[file exists ~/.gitk-new]} {file delete -force ~/.gitk-new}
        set f [open "~/.gitk-new" w]
        if {$::tcl_platform(platform) eq {windows}} {
            file attributes "~/.gitk-new" -hidden true
        puts $f [list set showlocalchanges $showlocalchanges]
        puts $f [list set datetimeformat $datetimeformat]
        puts $f [list set limitdiffs $limitdiffs]
 +      puts $f [list set uicolor $uicolor]
+       puts $f [list set want_ttk $want_ttk]
        puts $f [list set bgcolor $bgcolor]
        puts $f [list set fgcolor $fgcolor]
        puts $f [list set colors $colors]
        puts $f "set geometry(state) [wm state .]"
        puts $f "set geometry(topwidth) [winfo width .tf]"
        puts $f "set geometry(topheight) [winfo height .tf]"
-         puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sash coord 0]\""
-         puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sash coord 1]\""
+       if {$use_ttk} {
+           puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sashpos 0] 1\""
+           puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sashpos 1] 1\""
+       } else {
+           puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sash coord 0]\""
+           puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sash coord 1]\""
+       }
        puts $f "set geometry(botwidth) [winfo width .bleft]"
        puts $f "set geometry(botheight) [winfo height .bleft]"
  
  }
  
  proc resizeclistpanes {win w} {
-     global oldwidth
+     global oldwidth use_ttk
      if {[info exists oldwidth($win)]} {
-       set s0 [$win sash coord 0]
-       set s1 [$win sash coord 1]
+       if {$use_ttk} {
+           set s0 [$win sashpos 0]
+           set s1 [$win sashpos 1]
+       } else {
+           set s0 [$win sash coord 0]
+           set s1 [$win sash coord 1]
+       }
        if {$w < 60} {
            set sash0 [expr {int($w/2 - 2)}]
            set sash1 [expr {int($w*5/6 - 2)}]
                }
            }
        }
-       $win sash place 0 $sash0 [lindex $s0 1]
-       $win sash place 1 $sash1 [lindex $s1 1]
+       if {$use_ttk} {
+           $win sashpos 0 $sash0
+           $win sashpos 1 $sash1
+       } else {
+           $win sash place 0 $sash0 [lindex $s0 1]
+           $win sash place 1 $sash1 [lindex $s1 1]
+       }
      }
      set oldwidth($win) $w
  }
  
  proc resizecdetpanes {win w} {
-     global oldwidth
+     global oldwidth use_ttk
      if {[info exists oldwidth($win)]} {
-       set s0 [$win sash coord 0]
+       if {$use_ttk} {
+           set s0 [$win sashpos 0]
+       } else {
+           set s0 [$win sash coord 0]
+       }
        if {$w < 60} {
            set sash0 [expr {int($w*3/4 - 2)}]
        } else {
                set sash0 [expr {$w - 15}]
            }
        }
-       $win sash place 0 $sash0 [lindex $s0 1]
+       if {$use_ttk} {
+           $win sashpos 0 $sash0
+       } else {
+           $win sash place 0 $sash0 [lindex $s0 1]
+       }
      }
      set oldwidth($win) $w
  }
@@@ -2646,31 -2765,33 +2767,33 @@@ proc bindall {event action} 
  }
  
  proc about {} {
-     global uifont
+     global uifont NS
      set w .about
      if {[winfo exists $w]} {
        raise $w
        return
      }
-     toplevel $w
+     ttk_toplevel $w
      wm title $w [mc "About gitk"]
      make_transient $w .
      message $w.m -text [mc "
  Gitk - a commit viewer for git
  
- Copyright © 2005-2008 Paul Mackerras
+ Copyright \u00a9 2005-2009 Paul Mackerras
  
  Use and redistribute under the terms of the GNU General Public License"] \
            -justify center -aspect 400 -border 2 -bg white -relief groove
      pack $w.m -side top -fill x -padx 2 -pady 2
-     button $w.ok -text [mc "Close"] -command "destroy $w" -default active
+     ${NS}::button $w.ok -text [mc "Close"] -command "destroy $w" -default active
      pack $w.ok -side bottom
      bind $w <Visibility> "focus $w.ok"
      bind $w <Key-Escape> "destroy $w"
      bind $w <Key-Return> "destroy $w"
+     tk::PlaceWindow $w widget .
  }
  
  proc keys {} {
+     global NS
      set w .keys
      if {[winfo exists $w]} {
        raise $w
      } else {
        set M1T Ctrl
      }
-     toplevel $w
+     ttk_toplevel $w
      wm title $w [mc "Gitk key bindings"]
      make_transient $w .
      message $w.m -text "
  " \
            -justify left -bg white -border 2 -relief groove
      pack $w.m -side top -fill both -padx 2 -pady 2
-     button $w.ok -text [mc "Close"] -command "destroy $w" -default active
+     ${NS}::button $w.ok -text [mc "Close"] -command "destroy $w" -default active
      bind $w <Key-Escape> [list destroy $w]
      pack $w.ok -side bottom
      bind $w <Visibility> "focus $w.ok"
@@@ -3378,9 -3499,6 +3501,9 @@@ proc index_sha1 {fname} 
  
  # Turn an absolute path into one relative to the current directory
  proc make_relative {f} {
 +    if {[file pathtype $f] eq "relative"} {
 +      return $f
 +    }
      set elts [file split $f]
      set here [file split [pwd]]
      set ei 0
@@@ -3843,16 -3961,16 +3966,16 @@@ proc editview {} 
  
  proc vieweditor {top n title} {
      global newviewname newviewopts viewfiles bgcolor
-     global known_view_options
+     global known_view_options NS
  
-     toplevel $top
+     ttk_toplevel $top
      wm title $top [concat $title [mc "-- criteria for selecting revisions"]]
      make_transient $top .
  
      # View name
-     frame $top.nfr
-     label $top.nl -text [mc "View Name:"]
-     entry $top.name -width 20 -textvariable newviewname($n)
+     ${NS}::frame $top.nfr
+     ${NS}::label $top.nl -text [mc "View Name"]
+     ${NS}::entry $top.name -width 20 -textvariable newviewname($n)
      pack $top.nfr -in $top -fill x -pady 5 -padx 3
      pack $top.nl -in $top.nfr -side left -padx {0 5}
      pack $top.name -in $top.nfr -side left -padx {0 25}
        if {$flags eq "+" || $flags eq "*"} {
            set cframe $top.fr$cnt
            incr cnt
-           frame $cframe
+           ${NS}::frame $cframe
            pack $cframe -in $top -fill x -pady 3 -padx 3
            set cexpand [expr {$flags eq "*"}]
          } elseif {$flags eq ".." || $flags eq "*."} {
            set cframe $top.fr$cnt
            incr cnt
-           frame $cframe
+           ${NS}::frame $cframe
            pack $cframe -in $top -fill x -pady 3 -padx [list 15 3]
            set cexpand [expr {$flags eq "*."}]
        } else {
        }
  
        if {$type eq "l"} {
-             label $cframe.l_$id -text $title
+             ${NS}::label $cframe.l_$id -text $title
              pack $cframe.l_$id -in $cframe -side left -pady [list 3 0] -anchor w
        } elseif {$type eq "b"} {
-           checkbutton $cframe.c_$id -text $title -variable newviewopts($n,$id)
+           ${NS}::checkbutton $cframe.c_$id -text $title -variable newviewopts($n,$id)
            pack $cframe.c_$id -in $cframe -side left \
                -padx [list $lxpad 0] -expand $cexpand -anchor w
        } elseif {[regexp {^r(\d+)$} $type type sz]} {
            regexp {^(.*_)} $id uselessvar button_id
-           radiobutton $cframe.c_$id -text $title -variable newviewopts($n,$button_id) -value $sz
+           ${NS}::radiobutton $cframe.c_$id -text $title -variable newviewopts($n,$button_id) -value $sz
            pack $cframe.c_$id -in $cframe -side left \
                -padx [list $lxpad 0] -expand $cexpand -anchor w
        } elseif {[regexp {^t(\d+)$} $type type sz]} {
-           message $cframe.l_$id -aspect 1500 -text $title
-           entry $cframe.e_$id -width $sz -background $bgcolor \
+           ${NS}::label $cframe.l_$id -text $title
+           ${NS}::entry $cframe.e_$id -width $sz -background $bgcolor \
                -textvariable newviewopts($n,$id)
            pack $cframe.l_$id -in $cframe -side left -padx [list $lxpad 0]
            pack $cframe.e_$id -in $cframe -side left -expand 1 -fill x
        } elseif {[regexp {^t(\d+)=$} $type type sz]} {
-           message $cframe.l_$id -aspect 1500 -text $title
-           entry $cframe.e_$id -width $sz -background $bgcolor \
+           ${NS}::label $cframe.l_$id -text $title
+           ${NS}::entry $cframe.e_$id -width $sz -background $bgcolor \
                -textvariable newviewopts($n,$id)
            pack $cframe.l_$id -in $cframe -side top -pady [list 3 0] -anchor w
            pack $cframe.e_$id -in $cframe -side top -fill x
        } elseif {$type eq "path"} {
-           message $top.l -aspect 1500 -text $title
+           ${NS}::label $top.l -text $title
            pack $top.l -in $top -side top -pady [list 3 0] -anchor w -padx 3
            text $top.t -width 40 -height 5 -background $bgcolor -font uifont
            if {[info exists viewfiles($n)]} {
        }
      }
  
-     frame $top.buts
-     button $top.buts.ok -text [mc "OK"] -command [list newviewok $top $n]
-     button $top.buts.apply -text [mc "Apply (F5)"] -command [list newviewok $top $n 1]
-     button $top.buts.can -text [mc "Cancel"] -command [list destroy $top]
+     ${NS}::frame $top.buts
+     ${NS}::button $top.buts.ok -text [mc "OK"] -command [list newviewok $top $n]
+     ${NS}::button $top.buts.apply -text [mc "Apply (F5)"] -command [list newviewok $top $n 1]
+     ${NS}::button $top.buts.can -text [mc "Cancel"] -command [list destroy $top]
      bind $top <Control-Return> [list newviewok $top $n]
      bind $top <F5> [list newviewok $top $n 1]
      bind $top <Escape> [list destroy $top]
@@@ -6791,14 -6909,13 +6914,13 @@@ proc selectline {l isnew {desired_loc {
      make_secsel $id
  
      if {$isnew} {
-       addtohistory [list selbyid $id]
+       addtohistory [list selbyid $id 0] savecmitpos
      }
  
      $sha1entry delete 0 end
      $sha1entry insert 0 $id
      if {$autoselect} {
-       $sha1entry selection from 0
-       $sha1entry selection to end
+       $sha1entry selection range 0 end
      }
      rhighlight_sel $id
  
@@@ -6943,10 -7060,12 +7065,12 @@@ proc reselectline {} 
      }
  }
  
- proc addtohistory {cmd} {
+ proc addtohistory {cmd {saveproc {}}} {
      global history historyindex curview
  
-     set elt [list $curview $cmd]
+     unset_posvars
+     save_position
+     set elt [list $curview $cmd $saveproc {}]
      if {$historyindex > 0
        && [lindex $history [expr {$historyindex - 1}]] == $elt} {
        return
      .tf.bar.rightbut conf -state disabled
  }
  
+ # save the scrolling position of the diff display pane
+ proc save_position {} {
+     global historyindex history
+     if {$historyindex < 1} return
+     set hi [expr {$historyindex - 1}]
+     set fn [lindex $history $hi 2]
+     if {$fn ne {}} {
+       lset history $hi 3 [eval $fn]
+     }
+ }
+ proc unset_posvars {} {
+     global last_posvars
+     if {[info exists last_posvars]} {
+       foreach {var val} $last_posvars {
+           global $var
+           catch {unset $var}
+       }
+       unset last_posvars
+     }
+ }
  proc godo {elt} {
-     global curview
+     global curview last_posvars
  
      set view [lindex $elt 0]
      set cmd [lindex $elt 1]
+     set pv [lindex $elt 3]
      if {$curview != $view} {
        showview $view
      }
+     unset_posvars
+     foreach {var val} $pv {
+       global $var
+       set $var $val
+     }
+     set last_posvars $pv
      eval $cmd
  }
  
@@@ -6982,6 -7132,7 +7137,7 @@@ proc goback {} 
      focus .
  
      if {$historyindex > 1} {
+       save_position
        incr historyindex -1
        godo [lindex $history [expr {$historyindex - 1}]]
        .tf.bar.rightbut conf -state normal
@@@ -6996,6 -7147,7 +7152,7 @@@ proc goforw {} 
      focus .
  
      if {$historyindex < [llength $history]} {
+       save_position
        set cmd [lindex $history $historyindex]
        incr historyindex
        godo $cmd
@@@ -7228,7 -7380,7 +7385,7 @@@ proc diffcmd {ids flags} 
        set cmd [concat | git diff-index --cached $flags]
        if {[llength $ids] > 1} {
            # comparing index with specific revision
 -          if {$i == 0} {
 +          if {$j == 0} {
                lappend cmd -R [lindex $ids 1]
            } else {
                lappend cmd [lindex $ids 0]
@@@ -7347,11 -7499,7 +7504,11 @@@ proc getblobdiffs {ids} 
      if {[package vcompare $git_version "1.6.1"] >= 0} {
        set textconv "--textconv"
      }
 -    set cmd [diffcmd $ids "-p $textconv -C --cc --no-commit-id -U$diffcontext"]
 +    set submodule {}
 +    if {[package vcompare $git_version "1.6.6"] >= 0} {
 +      set submodule "--submodule"
 +    }
 +    set cmd [diffcmd $ids "-p $textconv $submodule  -C --cc --no-commit-id -U$diffcontext"]
      if {$ignorespace} {
        append cmd " -w"
      }
      filerun $bdf [list getblobdiffline $bdf $diffids]
  }
  
+ proc savecmitpos {} {
+     global ctext cmitmode
+     if {$cmitmode eq "tree"} {
+       return {}
+     }
+     return [list target_scrollpos [$ctext index @0,0]]
+ }
+ proc savectextpos {} {
+     global ctext
+     return [list target_scrollpos [$ctext index @0,0]]
+ }
+ proc maybe_scroll_ctext {ateof} {
+     global ctext target_scrollpos
+     if {![info exists target_scrollpos]} return
+     if {!$ateof} {
+       set nlines [expr {[winfo height $ctext]
+                         / [font metrics textfont -linespace]}]
+       if {[$ctext compare "$target_scrollpos + $nlines lines" <= end]} return
+     }
+     $ctext yview $target_scrollpos
+     unset target_scrollpos
+ }
  proc setinlist {var i val} {
      global $var
  
@@@ -7489,21 -7665,6 +7674,21 @@@ proc getblobdiffline {bdf ids} 
            set diffnparents [expr {[string length $ats] - 1}]
            set diffinhdr 0
  
 +      } elseif {![string compare -length 10 "Submodule " $line]} {
 +          # start of a new submodule
 +          if {[string compare [$ctext get "end - 4c" end] "\n \n\n"]} {
 +              $ctext insert end "\n";     # Add newline after commit message
 +          }
 +          set curdiffstart [$ctext index "end - 1c"]
 +          lappend ctext_file_names ""
 +          set fname [string range $line 10 [expr [string last " " $line] - 1]]
 +          lappend ctext_file_lines $fname
 +          makediffhdr $fname $ids
 +          $ctext insert end "\n$line\n" filesep
 +      } elseif {![string compare -length 3 "  >" $line]} {
 +          $ctext insert end "$line\n" dresult
 +      } elseif {![string compare -length 3 "  <" $line]} {
 +          $ctext insert end "$line\n" d0
        } elseif {$diffinhdr} {
            if {![string compare -length 12 "rename from " $line]} {
                set fname [string range $line [expr 6 + [string first " from " $line] ] end]
      if {[info exists seehere]} {
        mark_ctext_line [lindex [split $seehere .] 0]
      }
+     maybe_scroll_ctext [eof $bdf]
      $ctext conf -state disabled
      if {[eof $bdf]} {
        catch {close $bdf}
@@@ -8080,7 -8242,7 +8266,7 @@@ proc lineclick {x y id isnew} 
      }
  
      if {$isnew} {
-       addtohistory [list lineclick $x $y $id 0]
+       addtohistory [list lineclick $x $y $id 0] savectextpos
      }
      # fill the details pane with info about this line
      $ctext conf -state normal
            $ctext insert end "\n\t[mc "Date"]:\t$date\n"
        }
      }
+     maybe_scroll_ctext 1
      $ctext conf -state disabled
      init_flist {}
  }
@@@ -8124,10 -8287,10 +8311,10 @@@ proc normalline {} 
      }
  }
  
- proc selbyid {id} {
+ proc selbyid {id {isnew 1}} {
      global curview
      if {[commitinview $id $curview]} {
-       selectline [rowofcommit $id] 1
+       selectline [rowofcommit $id] $isnew
      }
  }
  
@@@ -8312,23 -8475,23 +8499,23 @@@ proc do_cmp_commits {a b} 
            }
        }
        if {$skipa} {
-           if {[llength $children($curview,$a)] != 1} {
+           set kids [real_children $curview,$a]
+           if {[llength $kids] != 1} {
                $ctext insert end "\n"
                appendshortlink $a [mc "Commit "] \
-                   [mc " has %s children - stopping\n" \
-                        [llength $children($curview,$a)]]
+                   [mc " has %s children - stopping\n" [llength $kids]]
                break
            }
-           set a [lindex $children($curview,$a) 0]
+           set a [lindex $kids 0]
        }
        if {$skipb} {
-           if {[llength $children($curview,$b)] != 1} {
+           set kids [real_children $curview,$b]
+           if {[llength $kids] != 1} {
                appendshortlink $b [mc "Commit "] \
-                   [mc " has %s children - stopping\n" \
-                        [llength $children($curview,$b)]]
+                   [mc " has %s children - stopping\n" [llength $kids]]
                break
            }
-           set b [lindex $children($curview,$b) 0]
+           set b [lindex $kids 0]
        }
      }
      $ctext conf -state disabled
@@@ -8370,7 -8533,7 +8557,7 @@@ proc diffvssel {dirn} 
        set oldid $rowmenuid
        set newid [commitonrow $selectedline]
      }
-     addtohistory [list doseldiff $oldid $newid]
+     addtohistory [list doseldiff $oldid $newid] savectextpos
      doseldiff $oldid $newid
  }
  
@@@ -8398,7 -8561,7 +8585,7 @@@ proc doseldiff {oldid newid} 
  }
  
  proc mkpatch {} {
-     global rowmenuid currentid commitinfo patchtop patchnum
+     global rowmenuid currentid commitinfo patchtop patchnum NS
  
      if {![info exists currentid]} return
      set oldid $currentid
      set top .patch
      set patchtop $top
      catch {destroy $top}
-     toplevel $top
+     ttk_toplevel $top
      make_transient $top .
-     label $top.title -text [mc "Generate patch"]
+     ${NS}::label $top.title -text [mc "Generate patch"]
      grid $top.title - -pady 10
-     label $top.from -text [mc "From:"]
-     entry $top.fromsha1 -width 40 -relief flat
+     ${NS}::label $top.from -text [mc "From:"]
+     ${NS}::entry $top.fromsha1 -width 40
      $top.fromsha1 insert 0 $oldid
      $top.fromsha1 conf -state readonly
      grid $top.from $top.fromsha1 -sticky w
-     entry $top.fromhead -width 60 -relief flat
+     ${NS}::entry $top.fromhead -width 60
      $top.fromhead insert 0 $oldhead
      $top.fromhead conf -state readonly
      grid x $top.fromhead -sticky w
-     label $top.to -text [mc "To:"]
-     entry $top.tosha1 -width 40 -relief flat
+     ${NS}::label $top.to -text [mc "To:"]
+     ${NS}::entry $top.tosha1 -width 40
      $top.tosha1 insert 0 $newid
      $top.tosha1 conf -state readonly
      grid $top.to $top.tosha1 -sticky w
-     entry $top.tohead -width 60 -relief flat
+     ${NS}::entry $top.tohead -width 60
      $top.tohead insert 0 $newhead
      $top.tohead conf -state readonly
      grid x $top.tohead -sticky w
-     button $top.rev -text [mc "Reverse"] -command mkpatchrev -padx 5
-     grid $top.rev x -pady 10
-     label $top.flab -text [mc "Output file:"]
-     entry $top.fname -width 60
+     ${NS}::button $top.rev -text [mc "Reverse"] -command mkpatchrev
+     grid $top.rev x -pady 10 -padx 5
+     ${NS}::label $top.flab -text [mc "Output file:"]
+     ${NS}::entry $top.fname -width 60
      $top.fname insert 0 [file normalize "patch$patchnum.patch"]
      incr patchnum
      grid $top.flab $top.fname -sticky w
-     frame $top.buts
-     button $top.buts.gen -text [mc "Generate"] -command mkpatchgo
-     button $top.buts.can -text [mc "Cancel"] -command mkpatchcan
+     ${NS}::frame $top.buts
+     ${NS}::button $top.buts.gen -text [mc "Generate"] -command mkpatchgo
+     ${NS}::button $top.buts.can -text [mc "Cancel"] -command mkpatchcan
      bind $top <Key-Return> mkpatchgo
      bind $top <Key-Escape> mkpatchcan
      grid $top.buts.gen $top.buts.can
@@@ -8490,30 -8653,30 +8677,30 @@@ proc mkpatchcan {} 
  }
  
  proc mktag {} {
-     global rowmenuid mktagtop commitinfo
+     global rowmenuid mktagtop commitinfo NS
  
      set top .maketag
      set mktagtop $top
      catch {destroy $top}
-     toplevel $top
+     ttk_toplevel $top
      make_transient $top .
-     label $top.title -text [mc "Create tag"]
+     ${NS}::label $top.title -text [mc "Create tag"]
      grid $top.title - -pady 10
-     label $top.id -text [mc "ID:"]
-     entry $top.sha1 -width 40 -relief flat
+     ${NS}::label $top.id -text [mc "ID:"]
+     ${NS}::entry $top.sha1 -width 40
      $top.sha1 insert 0 $rowmenuid
      $top.sha1 conf -state readonly
      grid $top.id $top.sha1 -sticky w
-     entry $top.head -width 60 -relief flat
+     ${NS}::entry $top.head -width 60
      $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
      $top.head conf -state readonly
      grid x $top.head -sticky w
-     label $top.tlab -text [mc "Tag name:"]
-     entry $top.tag -width 60
+     ${NS}::label $top.tlab -text [mc "Tag name:"]
+     ${NS}::entry $top.tag -width 60
      grid $top.tlab $top.tag -sticky w
-     frame $top.buts
-     button $top.buts.gen -text [mc "Create"] -command mktaggo
-     button $top.buts.can -text [mc "Cancel"] -command mktagcan
+     ${NS}::frame $top.buts
+     ${NS}::button $top.buts.gen -text [mc "Create"] -command mktaggo
+     ${NS}::button $top.buts.can -text [mc "Cancel"] -command mktagcan
      bind $top <Key-Return> mktaggo
      bind $top <Key-Escape> mktagcan
      grid $top.buts.gen $top.buts.can
@@@ -8596,34 -8759,34 +8783,34 @@@ proc mktaggo {} 
  }
  
  proc writecommit {} {
-     global rowmenuid wrcomtop commitinfo wrcomcmd
+     global rowmenuid wrcomtop commitinfo wrcomcmd NS
  
      set top .writecommit
      set wrcomtop $top
      catch {destroy $top}
-     toplevel $top
+     ttk_toplevel $top
      make_transient $top .
-     label $top.title -text [mc "Write commit to file"]
+     ${NS}::label $top.title -text [mc "Write commit to file"]
      grid $top.title - -pady 10
-     label $top.id -text [mc "ID:"]
-     entry $top.sha1 -width 40 -relief flat
+     ${NS}::label $top.id -text [mc "ID:"]
+     ${NS}::entry $top.sha1 -width 40
      $top.sha1 insert 0 $rowmenuid
      $top.sha1 conf -state readonly
      grid $top.id $top.sha1 -sticky w
-     entry $top.head -width 60 -relief flat
+     ${NS}::entry $top.head -width 60
      $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
      $top.head conf -state readonly
      grid x $top.head -sticky w
-     label $top.clab -text [mc "Command:"]
-     entry $top.cmd -width 60 -textvariable wrcomcmd
+     ${NS}::label $top.clab -text [mc "Command:"]
+     ${NS}::entry $top.cmd -width 60 -textvariable wrcomcmd
      grid $top.clab $top.cmd -sticky w -pady 10
-     label $top.flab -text [mc "Output file:"]
-     entry $top.fname -width 60
+     ${NS}::label $top.flab -text [mc "Output file:"]
+     ${NS}::entry $top.fname -width 60
      $top.fname insert 0 [file normalize "commit-[string range $rowmenuid 0 6]"]
      grid $top.flab $top.fname -sticky w
-     frame $top.buts
-     button $top.buts.gen -text [mc "Write"] -command wrcomgo
-     button $top.buts.can -text [mc "Cancel"] -command wrcomcan
+     ${NS}::frame $top.buts
+     ${NS}::button $top.buts.gen -text [mc "Write"] -command wrcomgo
+     ${NS}::button $top.buts.can -text [mc "Cancel"] -command wrcomcan
      bind $top <Key-Return> wrcomgo
      bind $top <Key-Escape> wrcomcan
      grid $top.buts.gen $top.buts.can
@@@ -8654,25 -8817,25 +8841,25 @@@ proc wrcomcan {} 
  }
  
  proc mkbranch {} {
-     global rowmenuid mkbrtop
+     global rowmenuid mkbrtop NS
  
      set top .makebranch
      catch {destroy $top}
-     toplevel $top
+     ttk_toplevel $top
      make_transient $top .
-     label $top.title -text [mc "Create new branch"]
+     ${NS}::label $top.title -text [mc "Create new branch"]
      grid $top.title - -pady 10
-     label $top.id -text [mc "ID:"]
-     entry $top.sha1 -width 40 -relief flat
+     ${NS}::label $top.id -text [mc "ID:"]
+     ${NS}::entry $top.sha1 -width 40
      $top.sha1 insert 0 $rowmenuid
      $top.sha1 conf -state readonly
      grid $top.id $top.sha1 -sticky w
-     label $top.nlab -text [mc "Name:"]
-     entry $top.name -width 40
+     ${NS}::label $top.nlab -text [mc "Name:"]
+     ${NS}::entry $top.name -width 40
      grid $top.nlab $top.name -sticky w
-     frame $top.buts
-     button $top.buts.go -text [mc "Create"] -command [list mkbrgo $top]
-     button $top.buts.can -text [mc "Cancel"] -command "catch {destroy $top}"
+     ${NS}::frame $top.buts
+     ${NS}::button $top.buts.go -text [mc "Create"] -command [list mkbrgo $top]
+     ${NS}::button $top.buts.can -text [mc "Cancel"] -command "catch {destroy $top}"
      bind $top <Key-Return> [list mkbrgo $top]
      bind $top <Key-Escape> "catch {destroy $top}"
      grid $top.buts.go $top.buts.can
@@@ -8817,34 -8980,31 +9004,31 @@@ proc cherrypick {} 
  }
  
  proc resethead {} {
-     global mainhead rowmenuid confirm_ok resettype
+     global mainhead rowmenuid confirm_ok resettype NS
  
      set confirm_ok 0
      set w ".confirmreset"
-     toplevel $w
+     ttk_toplevel $w
      make_transient $w .
      wm title $w [mc "Confirm reset"]
-     message $w.m -text \
-       [mc "Reset branch %s to %s?" $mainhead [string range $rowmenuid 0 7]] \
-       -justify center -aspect 1000
+     ${NS}::label $w.m -text \
+       [mc "Reset branch %s to %s?" $mainhead [string range $rowmenuid 0 7]]
      pack $w.m -side top -fill x -padx 20 -pady 20
-     frame $w.f -relief sunken -border 2
-     message $w.f.rt -text [mc "Reset type:"] -aspect 1000
-     grid $w.f.rt -sticky w
+     ${NS}::labelframe $w.f -text [mc "Reset type:"]
      set resettype mixed
-     radiobutton $w.f.soft -value soft -variable resettype -justify left \
+     ${NS}::radiobutton $w.f.soft -value soft -variable resettype \
        -text [mc "Soft: Leave working tree and index untouched"]
      grid $w.f.soft -sticky w
-     radiobutton $w.f.mixed -value mixed -variable resettype -justify left \
+     ${NS}::radiobutton $w.f.mixed -value mixed -variable resettype \
        -text [mc "Mixed: Leave working tree untouched, reset index"]
      grid $w.f.mixed -sticky w
-     radiobutton $w.f.hard -value hard -variable resettype -justify left \
+     ${NS}::radiobutton $w.f.hard -value hard -variable resettype \
        -text [mc "Hard: Reset working tree and index\n(discard ALL local changes)"]
      grid $w.f.hard -sticky w
-     pack $w.f -side top -fill x
-     button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
+     pack $w.f -side top -fill x -padx 4
+     ${NS}::button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
      pack $w.ok -side left -fill x -padx 20 -pady 20
-     button $w.cancel -text [mc Cancel] -command "destroy $w"
+     ${NS}::button $w.cancel -text [mc Cancel] -command "destroy $w"
      bind $w <Key-Escape> [list destroy $w]
      pack $w.cancel -side right -fill x -padx 20 -pady 20
      bind $w <Visibility> "grab $w; focus $w"
@@@ -8900,9 -9060,6 +9084,9 @@@ proc headmenu {x y id head} 
      set headmenuid $id
      set headmenuhead $head
      set state normal
 +    if {[string match "remotes/*" $head]} {
 +      set state disabled
 +    }
      if {$head eq $mainhead} {
        set state disabled
      }
@@@ -8995,7 -9152,7 +9179,7 @@@ proc rmbranch {} 
  
  # Display a list of tags and heads
  proc showrefs {} {
-     global showrefstop bgcolor fgcolor selectbgcolor
+     global showrefstop bgcolor fgcolor selectbgcolor NS
      global bglist fglist reflistfilter reflist maincursor
  
      set top .showrefs
        refill_reflist
        return
      }
-     toplevel $top
+     ttk_toplevel $top
      wm title $top [mc "Tags and heads: %s" [file tail [pwd]]]
      make_transient $top .
      text $top.list -background $bgcolor -foreground $fgcolor \
      $top.list tag configure highlight -background $selectbgcolor
      lappend bglist $top.list
      lappend fglist $top.list
-     scrollbar $top.ysb -command "$top.list yview" -orient vertical
-     scrollbar $top.xsb -command "$top.list xview" -orient horizontal
+     ${NS}::scrollbar $top.ysb -command "$top.list yview" -orient vertical
+     ${NS}::scrollbar $top.xsb -command "$top.list xview" -orient horizontal
      grid $top.list $top.ysb -sticky nsew
      grid $top.xsb x -sticky ew
-     frame $top.f
-     label $top.f.l -text "[mc "Filter"]: "
-     entry $top.f.e -width 20 -textvariable reflistfilter
+     ${NS}::frame $top.f
+     ${NS}::label $top.f.l -text "[mc "Filter"]: "
+     ${NS}::entry $top.f.e -width 20 -textvariable reflistfilter
      set reflistfilter "*"
      trace add variable reflistfilter write reflistfilter_change
      pack $top.f.e -side right -fill x -expand 1
      pack $top.f.l -side left
      grid $top.f - -sticky ew -pady 2
-     button $top.close -command [list destroy $top] -text [mc "Close"]
+     ${NS}::button $top.close -command [list destroy $top] -text [mc "Close"]
      bind $top <Key-Escape> [list destroy $top]
      grid $top.close -
      grid columnconfigure $top 0 -weight 1
@@@ -9226,7 -9383,7 +9410,7 @@@ proc getallclines {fd} 
      global allparents allchildren idtags idheads nextarc
      global arcnos arcids arctags arcout arcend arcstart archeads growing
      global seeds allcommits cachedarcs allcupdate
-     
      set nid 0
      while {[incr nid] <= 1000 && [gets $fd line] >= 0} {
        set id [lindex $line 0]
@@@ -10288,7 -10445,7 +10472,7 @@@ proc showtag {tag isnew} 
      global ctext tagcontents tagids linknum tagobjid
  
      if {$isnew} {
-       addtohistory [list showtag $tag 0]
+       addtohistory [list showtag $tag 0] savectextpos
      }
      $ctext conf -state normal
      clear_ctext
        set text "[mc "Tag"]: $tag\n[mc "Id"]:  $tagids($tag)"
      }
      appendwithlinks $text {}
+     maybe_scroll_ctext
      $ctext conf -state disabled
      init_flist {}
  }
@@@ -10323,19 -10481,20 +10508,20 @@@ proc doquit {} 
  }
  
  proc mkfontdisp {font top which} {
-     global fontattr fontpref $font
+     global fontattr fontpref $font NS use_ttk
  
      set fontpref($font) [set $font]
-     button $top.${font}but -text $which -font optionfont \
+     ${NS}::button $top.${font}but -text $which \
        -command [list choosefont $font $which]
-     label $top.$font -relief flat -font $font \
+     if {!$use_ttk} {$top.${font}but configure  -font optionfont}
+     ${NS}::label $top.$font -relief flat -font $font \
        -text $fontattr($font,family) -justify left
      grid x $top.${font}but $top.$font -sticky w
  }
  
  proc choosefont {font which} {
      global fontparam fontlist fonttop fontattr
-     global prefstop
+     global prefstop NS
  
      set fontparam(which) $which
      set fontparam(font) $font
      if {![winfo exists $top]} {
        font create sample
        eval font config sample [font actual $font]
-       toplevel $top
+       ttk_toplevel $top
        make_transient $top $prefstop
        wm title $top [mc "Gitk font chooser"]
-       label $top.l -textvariable fontparam(which)
+       ${NS}::label $top.l -textvariable fontparam(which)
        pack $top.l -side top
        set fontlist [lsort [font families]]
-       frame $top.f
+       ${NS}::frame $top.f
        listbox $top.f.fam -listvariable fontlist \
            -yscrollcommand [list $top.f.sb set]
        bind $top.f.fam <<ListboxSelect>> selfontfam
-       scrollbar $top.f.sb -command [list $top.f.fam yview]
+       ${NS}::scrollbar $top.f.sb -command [list $top.f.fam yview]
        pack $top.f.sb -side right -fill y
        pack $top.f.fam -side left -fill both -expand 1
        pack $top.f -side top -fill both -expand 1
-       frame $top.g
+       ${NS}::frame $top.g
        spinbox $top.g.size -from 4 -to 40 -width 4 \
            -textvariable fontparam(size) \
            -validatecommand {string is integer -strict %s}
            -fill black -tags text
        bind $top.c <Configure> [list centertext $top.c]
        pack $top.c -side top -fill x
-       frame $top.buts
-       button $top.buts.ok -text [mc "OK"] -command fontok -default active
-       button $top.buts.can -text [mc "Cancel"] -command fontcan -default normal
+       ${NS}::frame $top.buts
+       ${NS}::button $top.buts.ok -text [mc "OK"] -command fontok -default active
+       ${NS}::button $top.buts.can -text [mc "Cancel"] -command fontcan -default normal
        bind $top <Key-Return> fontok
        bind $top <Key-Escape> fontcan
        grid $top.buts.ok $top.buts.can
@@@ -10418,7 -10577,7 +10604,7 @@@ proc fontok {} 
      }
      set w $prefstop.$f
      $w conf -text $fontparam(family) -font $fontpref($f)
-       
      fontcan
  }
  
@@@ -10433,6 -10592,28 +10619,28 @@@ proc fontcan {} 
      }
  }
  
+ if {[package vsatisfies [package provide Tk] 8.6]} {
+     # In Tk 8.6 we have a native font chooser dialog. Overwrite the above
+     # function to make use of it.
+     proc choosefont {font which} {
+       tk fontchooser configure -title $which -font $font \
+           -command [list on_choosefont $font $which]
+       tk fontchooser show
+     }
+     proc on_choosefont {font which newfont} {
+       global fontparam
+       puts stderr "$font $newfont"
+       array set f [font actual $newfont]
+       set fontparam(which) $which
+       set fontparam(font) $font
+       set fontparam(family) $f(-family)
+       set fontparam(size) $f(-size)
+       set fontparam(weight) $f(-weight)
+       set fontparam(slant) $f(-slant)
+       fontok
+     }
+ }
  proc selfontfam {} {
      global fonttop fontparam
  
@@@ -10449,11 -10630,11 +10657,11 @@@ proc chg_fontparam {v sub op} 
  }
  
  proc doprefs {} {
-     global maxwidth maxgraphpct
+     global maxwidth maxgraphpct use_ttk NS
      global oldprefs prefstop showneartags showlocalchanges
 -    global bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor
 +    global uicolor bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor
      global tabstop limitdiffs autoselect extdifftool perfile_attrs
-     global hideremotes
+     global hideremotes want_ttk have_ttk
  
      set top .gitkprefs
      set prefstop $top
        return
      }
      foreach v {maxwidth maxgraphpct showneartags showlocalchanges \
-                  limitdiffs tabstop perfile_attrs hideremotes} {
+                  limitdiffs tabstop perfile_attrs hideremotes want_ttk} {
        set oldprefs($v) [set $v]
      }
-     toplevel $top
+     ttk_toplevel $top
      wm title $top [mc "Gitk preferences"]
      make_transient $top .
-     label $top.ldisp -text [mc "Commit list display options"]
+     ${NS}::label $top.ldisp -text [mc "Commit list display options"]
      grid $top.ldisp - -sticky w -pady 10
-     label $top.spacer -text " "
-     label $top.maxwidthl -text [mc "Maximum graph width (lines)"] \
-       -font optionfont
+     ${NS}::label $top.spacer -text " "
+     ${NS}::label $top.maxwidthl -text [mc "Maximum graph width (lines)"]
      spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
      grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w
-     label $top.maxpctl -text [mc "Maximum graph width (% of pane)"] \
-       -font optionfont
+     ${NS}::label $top.maxpctl -text [mc "Maximum graph width (% of pane)"]
      spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
      grid x $top.maxpctl $top.maxpct -sticky w
-     checkbutton $top.showlocal -text [mc "Show local changes"] \
-       -font optionfont -variable showlocalchanges
+     ${NS}::checkbutton $top.showlocal -text [mc "Show local changes"] \
+       -variable showlocalchanges
      grid x $top.showlocal -sticky w
-     checkbutton $top.autoselect -text [mc "Auto-select SHA1"] \
-       -font optionfont -variable autoselect
+     ${NS}::checkbutton $top.autoselect -text [mc "Auto-select SHA1"] \
+       -variable autoselect
      grid x $top.autoselect -sticky w
+     ${NS}::checkbutton $top.hideremotes -text [mc "Hide remote refs"] \
+       -variable hideremotes
+     grid x $top.hideremotes -sticky w
  
-     label $top.ddisp -text [mc "Diff display options"]
+     ${NS}::label $top.ddisp -text [mc "Diff display options"]
      grid $top.ddisp - -sticky w -pady 10
-     label $top.tabstopl -text [mc "Tab spacing"] -font optionfont
+     ${NS}::label $top.tabstopl -text [mc "Tab spacing"]
      spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop
      grid x $top.tabstopl $top.tabstop -sticky w
-     checkbutton $top.ntag -text [mc "Display nearby tags"] \
-       -font optionfont -variable showneartags
+     ${NS}::checkbutton $top.ntag -text [mc "Display nearby tags"] \
+       -variable showneartags
      grid x $top.ntag -sticky w
-     checkbutton $top.hideremotes -text [mc "Hide remote refs"] \
-       -font optionfont -variable hideremotes
-     grid x $top.hideremotes -sticky w
-     checkbutton $top.ldiff -text [mc "Limit diffs to listed paths"] \
-       -font optionfont -variable limitdiffs
+     ${NS}::checkbutton $top.ldiff -text [mc "Limit diffs to listed paths"] \
+       -variable limitdiffs
      grid x $top.ldiff -sticky w
-     checkbutton $top.lattr -text [mc "Support per-file encodings"] \
-       -font optionfont -variable perfile_attrs
+     ${NS}::checkbutton $top.lattr -text [mc "Support per-file encodings"] \
+       -variable perfile_attrs
      grid x $top.lattr -sticky w
  
-     entry $top.extdifft -textvariable extdifftool
-     frame $top.extdifff
-     label $top.extdifff.l -text [mc "External diff tool" ] -font optionfont \
-       -padx 10
-     button $top.extdifff.b -text [mc "Choose..."] -font optionfont \
-       -command choose_extdiff
+     ${NS}::entry $top.extdifft -textvariable extdifftool
+     ${NS}::frame $top.extdifff
+     ${NS}::label $top.extdifff.l -text [mc "External diff tool" ]
+     ${NS}::button $top.extdifff.b -text [mc "Choose..."] -command choose_extdiff
      pack $top.extdifff.l $top.extdifff.b -side left
-     grid x $top.extdifff $top.extdifft -sticky w
+     pack configure $top.extdifff.l -padx 10
+     grid x $top.extdifff $top.extdifft -sticky ew
+     ${NS}::label $top.lgen -text [mc "General options"]
+     grid $top.lgen - -sticky w -pady 10
+     ${NS}::checkbutton $top.want_ttk -variable want_ttk \
+       -text [mc "Use themed widgets"]
+     if {$have_ttk} {
+       ${NS}::label $top.ttk_note -text [mc "(change requires restart)"]
+     } else {
+       ${NS}::label $top.ttk_note -text [mc "(currently unavailable)"]
+     }
+     grid x $top.want_ttk $top.ttk_note -sticky w
  
-     label $top.cdisp -text [mc "Colors: press to choose"]
+     ${NS}::label $top.cdisp -text [mc "Colors: press to choose"]
      grid $top.cdisp - -sticky w -pady 10
 +    label $top.ui -padx 40 -relief sunk -background $uicolor
 +    button $top.uibut -text [mc "Interface"] -font optionfont \
 +       -command [list choosecolor uicolor {} $top.ui [mc "interface"] setui]
 +    grid x $top.uibut $top.ui -sticky w
      label $top.bg -padx 40 -relief sunk -background $bgcolor
-     button $top.bgbut -text [mc "Background"] -font optionfont \
+     ${NS}::button $top.bgbut -text [mc "Background"] \
        -command [list choosecolor bgcolor {} $top.bg [mc "background"] setbg]
      grid x $top.bgbut $top.bg -sticky w
      label $top.fg -padx 40 -relief sunk -background $fgcolor
-     button $top.fgbut -text [mc "Foreground"] -font optionfont \
+     ${NS}::button $top.fgbut -text [mc "Foreground"] \
        -command [list choosecolor fgcolor {} $top.fg [mc "foreground"] setfg]
      grid x $top.fgbut $top.fg -sticky w
      label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0]
-     button $top.diffoldbut -text [mc "Diff: old lines"] -font optionfont \
+     ${NS}::button $top.diffoldbut -text [mc "Diff: old lines"] \
        -command [list choosecolor diffcolors 0 $top.diffold [mc "diff old lines"] \
                      [list $ctext tag conf d0 -foreground]]
      grid x $top.diffoldbut $top.diffold -sticky w
      label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1]
-     button $top.diffnewbut -text [mc "Diff: new lines"] -font optionfont \
+     ${NS}::button $top.diffnewbut -text [mc "Diff: new lines"] \
        -command [list choosecolor diffcolors 1 $top.diffnew [mc "diff new lines"] \
                      [list $ctext tag conf dresult -foreground]]
      grid x $top.diffnewbut $top.diffnew -sticky w
      label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2]
-     button $top.hunksepbut -text [mc "Diff: hunk header"] -font optionfont \
+     ${NS}::button $top.hunksepbut -text [mc "Diff: hunk header"] \
        -command [list choosecolor diffcolors 2 $top.hunksep \
                      [mc "diff hunk header"] \
                      [list $ctext tag conf hunksep -foreground]]
      grid x $top.hunksepbut $top.hunksep -sticky w
      label $top.markbgsep -padx 40 -relief sunk -background $markbgcolor
-     button $top.markbgbut -text [mc "Marked line bg"] -font optionfont \
+     ${NS}::button $top.markbgbut -text [mc "Marked line bg"] \
        -command [list choosecolor markbgcolor {} $top.markbgsep \
                      [mc "marked line background"] \
                      [list $ctext tag conf omark -background]]
      grid x $top.markbgbut $top.markbgsep -sticky w
      label $top.selbgsep -padx 40 -relief sunk -background $selectbgcolor
-     button $top.selbgbut -text [mc "Select bg"] -font optionfont \
+     ${NS}::button $top.selbgbut -text [mc "Select bg"] \
        -command [list choosecolor selectbgcolor {} $top.selbgsep [mc "background"] setselbg]
      grid x $top.selbgbut $top.selbgsep -sticky w
  
-     label $top.cfont -text [mc "Fonts: press to choose"]
+     ${NS}::label $top.cfont -text [mc "Fonts: press to choose"]
      grid $top.cfont - -sticky w -pady 10
      mkfontdisp mainfont $top [mc "Main font"]
      mkfontdisp textfont $top [mc "Diff display font"]
      mkfontdisp uifont $top [mc "User interface font"]
  
-     frame $top.buts
-     button $top.buts.ok -text [mc "OK"] -command prefsok -default active
-     button $top.buts.can -text [mc "Cancel"] -command prefscan -default normal
+     if {!$use_ttk} {
+       foreach w {maxpctl maxwidthl showlocal autoselect tabstopl ntag
+           ldiff lattr extdifff.l extdifff.b bgbut fgbut
+           diffoldbut diffnewbut hunksepbut markbgbut selbgbut
+           want_ttk ttk_note} {
+           $top.$w configure -font optionfont
+       }
+     }
+     ${NS}::frame $top.buts
+     ${NS}::button $top.buts.ok -text [mc "OK"] -command prefsok -default active
+     ${NS}::button $top.buts.can -text [mc "Cancel"] -command prefscan -default normal
      bind $top <Key-Return> prefsok
      bind $top <Key-Escape> prefscan
      grid $top.buts.ok $top.buts.can
      grid columnconfigure $top.buts 0 -weight 1 -uniform a
      grid columnconfigure $top.buts 1 -weight 1 -uniform a
      grid $top.buts - - -pady 10 -sticky ew
+     grid columnconfigure $top 2 -weight 1
      bind $top <Visibility> "focus $top.buts.ok"
  }
  
@@@ -10602,20 -10797,6 +10828,20 @@@ proc setselbg {c} 
      allcanvs itemconf secsel -fill $c
  }
  
 +# This sets the background color and the color scheme for the whole UI.
 +# For some reason, tk_setPalette chooses a nasty dark red for selectColor
 +# if we don't specify one ourselves, which makes the checkbuttons and
 +# radiobuttons look bad.  This chooses white for selectColor if the
 +# background color is light, or black if it is dark.
 +proc setui {c} {
 +    set bg [winfo rgb . $c]
 +    set selc black
 +    if {[lindex $bg 0] + 1.5 * [lindex $bg 1] + 0.5 * [lindex $bg 2] > 100000} {
 +      set selc white
 +    }
 +    tk_setPalette background $c selectColor $selc
 +}
 +
  proc setbg {c} {
      global bglist
  
@@@ -10639,7 -10820,7 +10865,7 @@@ proc prefscan {} 
      global oldprefs prefstop
  
      foreach v {maxwidth maxgraphpct showneartags showlocalchanges \
-                  limitdiffs tabstop perfile_attrs hideremotes} {
+                  limitdiffs tabstop perfile_attrs hideremotes want_ttk} {
        global $v
        set $v $oldprefs($v)
      }
@@@ -11050,8 -11231,8 +11276,8 @@@ proc get_path_encoding {path} 
  
  # First check that Tcl/Tk is recent enough
  if {[catch {package require Tk 8.4} err]} {
 -    show_error {} . [mc "Sorry, gitk cannot run with this version of Tcl/Tk.\n\
 -                   Gitk requires at least Tcl/Tk 8.4."]
 +    show_error {} . "Sorry, gitk cannot run with this version of Tcl/Tk.\n\
 +                   Gitk requires at least Tcl/Tk 8.4." list
      exit 1
  }
  
@@@ -11115,6 -11296,7 +11341,7 @@@ set limitdiffs 
  set datetimeformat "%Y-%m-%d %H:%M:%S"
  set autoselect 1
  set perfile_attrs 0
+ set want_ttk 1
  
  if {[tk windowingsystem] eq "aqua"} {
      set extdifftool "opendiff"
  }
  
  set colors {green red blue magenta darkgrey brown orange}
 +set uicolor grey85
  set bgcolor white
  set fgcolor black
  set diffcolors {red "#00a000" blue}
@@@ -11175,8 -11356,6 +11402,8 @@@ eval font create textfontbold [fontflag
  parsefont uifont $uifont
  eval font create uifont [fontflags uifont]
  
 +setui $uicolor
 +
  setoptions
  
  # check that we can find a .git directory somewhere...
@@@ -11254,6 -11433,12 +11481,12 @@@ set nullid2 "00000000000000000000000000
  set nullfile "/dev/null"
  
  set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
+ if {![info exists have_ttk]} {
+     set have_ttk [llength [info commands ::ttk::style]]
+ }
+ set use_ttk [expr {$have_ttk && $want_ttk}]
+ set NS [expr {$use_ttk ? "ttk" : ""}]
  set git_version [join [lrange [split [lindex [exec git version] end] .] 0 2] .]
  
  set runq {}