Skip to content

Commit

Permalink
git-gui: Use proper Windows shortcuts instead of bat files
Browse files Browse the repository at this point in the history
On Windows its better to use a shortcut (.lnk file) over a batch
script (.bat) as we can specify the icon file for the .lnk and
thus have these git specific objects appear on the desktop with
that git specific icon file.

Unfortunately the authors of Tcl did not bless us with the APIs
needed to create shortcuts from within Tcl.  But Microsoft did
give us Windows Scripting Host which allows us to execute some
JavaScript that calls some sort of COM object that can operate
on a .lnk file.

We now build both Cygwin and non-Cygwin "desktop icons" as proper
Windows .lnk files, using the "Start in" property of these files
to indicate the working directory of the repository the user wants
to launch.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
  • Loading branch information
Shawn O. Pearce committed Oct 13, 2007
1 parent d6db1ad commit 51a41ac
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 35 deletions.
10 changes: 6 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ GITGUI_MAIN := git-gui
GITGUI_BUILT_INS = git-citool
ALL_LIBFILES = $(wildcard lib/*.tcl)
PRELOAD_FILES = lib/class.tcl
NONTCL_LIBFILES = \
lib/git-gui.ico \
$(wildcard lib/win32_*.js) \
#end NONTCL_LIBFILES

ifndef SHELL_PATH
SHELL_PATH = /bin/sh
Expand Down Expand Up @@ -255,12 +259,11 @@ ifdef GITGUI_WINDOWS_WRAPPER
endif
$(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(libdir_SQ)' $(INSTALL_D1)
$(QUIET)$(INSTALL_R0)lib/tclIndex $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)'
$(QUIET)$(INSTALL_R0)lib/git-gui.ico $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)'
ifdef GITGUI_MACOSXAPP
$(QUIET)$(INSTALL_A0)'Git Gui.app' $(INSTALL_A1) '$(DESTDIR_SQ)$(libdir_SQ)'
$(QUIET)$(INSTALL_X0)git-gui.tcl $(INSTALL_X1) '$(DESTDIR_SQ)$(libdir_SQ)'
endif
$(QUIET)$(foreach p,$(ALL_LIBFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' &&) true
$(QUIET)$(foreach p,$(ALL_LIBFILES) $(NONTCL_LIBFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' &&) true
$(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(msgsdir_SQ)' $(INSTALL_D1)
$(QUIET)$(foreach p,$(ALL_MSGFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(msgsdir_SQ)' &&) true

Expand All @@ -273,12 +276,11 @@ ifdef GITGUI_WINDOWS_WRAPPER
endif
$(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(libdir_SQ)'
$(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/tclIndex $(REMOVE_F1)
$(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/git-gui.ico $(REMOVE_F1)
ifdef GITGUI_MACOSXAPP
$(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)/Git Gui.app' $(REMOVE_F1)
$(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/git-gui.tcl $(REMOVE_F1)
endif
$(QUIET)$(foreach p,$(ALL_LIBFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true
$(QUIET)$(foreach p,$(ALL_LIBFILES) $(NONTCL_LIBFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true
$(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(msgsdir_SQ)'
$(QUIET)$(foreach p,$(ALL_MSGFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(msgsdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true
$(QUIET)$(REMOVE_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(REMOVE_D1)
Expand Down
49 changes: 18 additions & 31 deletions lib/shortcut.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,22 @@
# Copyright (C) 2006, 2007 Shawn Pearce

proc do_windows_shortcut {} {
global argv0

set fn [tk_getSaveFile \
-parent . \
-title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
-initialfile "Git [reponame].bat"]
-initialfile "Git [reponame].lnk"]
if {$fn != {}} {
if {[file extension $fn] ne {.bat}} {
set fn ${fn}.bat
if {[file extension $fn] ne {.lnk}} {
set fn ${fn}.lnk
}
if {[catch {
set ge [file normalize [file dirname $::_git]]
set fd [open $fn w]
puts $fd "@ECHO Entering [reponame]"
puts $fd "@ECHO Starting git-gui... please wait..."
puts $fd "@SET PATH=$ge;%PATH%"
puts $fd "@SET GIT_DIR=[file normalize [gitdir]]"
puts -nonewline $fd "@\"[info nameofexecutable]\""
puts $fd " \"[file normalize $argv0]\""
close $fd
win32_create_lnk $fn [list \
[info nameofexecutable] \
[file normalize $::argv0] \
] \
[file dirname [file normalize [gitdir]]]
} err]} {
error_popup [strcat [mc "Cannot write script:"] "\n\n$err"]
error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]
}
}
}
Expand All @@ -44,13 +38,12 @@ proc do_cygwin_shortcut {} {
-parent . \
-title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
-initialdir $desktop \
-initialfile "Git [reponame].bat"]
-initialfile "Git [reponame].lnk"]
if {$fn != {}} {
if {[file extension $fn] ne {.bat}} {
set fn ${fn}.bat
if {[file extension $fn] ne {.lnk}} {
set fn ${fn}.lnk
}
if {[catch {
set fd [open $fn w]
set sh [exec cygpath \
--windows \
--absolute \
Expand All @@ -59,19 +52,13 @@ proc do_cygwin_shortcut {} {
--unix \
--absolute \
$argv0]
set gd [exec cygpath \
--unix \
--absolute \
[gitdir]]
puts $fd "@ECHO Entering [reponame]"
puts $fd "@ECHO Starting git-gui... please wait..."
puts -nonewline $fd "@\"$sh\" --login -c \""
puts -nonewline $fd "GIT_DIR=[sq $gd]"
puts -nonewline $fd " [sq $me]"
puts $fd " &\""
close $fd
win32_create_lnk $fn [list \
$sh -c \
"CHERE_INVOKING=1 source /etc/profile;[sq $me]" \
] \
[file dirname [file normalize [gitdir]]]
} err]} {
error_popup [strcat [mc "Cannot write script:"] "\n\n$err"]
error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions lib/win32.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# git-gui Misc. native Windows 32 support
# Copyright (C) 2007 Shawn Pearce

proc win32_read_lnk {lnk_path} {
return [exec cscript.exe \
/E:jscript \
/nologo \
[file join $::oguilib win32_shortcut.js] \
$lnk_path]
}

proc win32_create_lnk {lnk_path lnk_exec lnk_dir} {
global oguilib

set lnk_args [lrange $lnk_exec 1 end]
set lnk_exec [lindex $lnk_exec 0]

eval [list exec wscript.exe \
/E:jscript \
/nologo \
[file join $oguilib win32_shortcut.js] \
$lnk_path \
[file join $oguilib git-gui.ico] \
$lnk_dir \
$lnk_exec] $lnk_args
}
34 changes: 34 additions & 0 deletions lib/win32_shortcut.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// git-gui Windows shortcut support
// Copyright (C) 2007 Shawn Pearce

var WshShell = WScript.CreateObject("WScript.Shell");
var argv = WScript.Arguments;
var argi = 0;
var lnk_path = argv.item(argi++);
var ico_path = argi < argv.length ? argv.item(argi++) : undefined;
var dir_path = argi < argv.length ? argv.item(argi++) : undefined;
var lnk_exec = argi < argv.length ? argv.item(argi++) : undefined;
var lnk_args = '';
while (argi < argv.length) {
var s = argv.item(argi++);
if (lnk_args != '')
lnk_args += ' ';
if (s.indexOf(' ') >= 0) {
lnk_args += '"';
lnk_args += s;
lnk_args += '"';
} else {
lnk_args += s;
}
}

var lnk = WshShell.CreateShortcut(lnk_path);
if (argv.length == 1) {
WScript.echo(lnk.TargetPath);
} else {
lnk.TargetPath = lnk_exec;
lnk.Arguments = lnk_args;
lnk.IconLocation = ico_path + ", 0";
lnk.WorkingDirectory = dir_path;
lnk.Save();
}

0 comments on commit 51a41ac

Please sign in to comment.