mirror of https://github.com/liamg/aminal.git
Merge branch 'develop' into hyperlinks
This commit is contained in:
commit
7cadb2f5b4
3
Makefile
3
Makefile
|
@ -78,7 +78,8 @@ launcher-windows: build-windows
|
||||||
if exist "bin\windows\Aminal" rmdir /S /Q "bin\windows\Aminal"
|
if exist "bin\windows\Aminal" rmdir /S /Q "bin\windows\Aminal"
|
||||||
mkdir "bin\windows\Aminal\Versions\${VERSION}"
|
mkdir "bin\windows\Aminal\Versions\${VERSION}"
|
||||||
go build -o "bin\windows\Aminal\${BINARY}.exe" -ldflags "-H windowsgui" "${GEN_SRC_DIR}\launcher"
|
go build -o "bin\windows\Aminal\${BINARY}.exe" -ldflags "-H windowsgui" "${GEN_SRC_DIR}\launcher"
|
||||||
copy ${BINARY}-windows-amd64.exe "bin\windows\Aminal\Versions\${VERSION}\${BINARY}.exe" /Y
|
windres -o aminal.syso aminal.rc
|
||||||
|
go build -o "bin\windows\Aminal\Versions\${VERSION}\${BINARY}.exe" -ldflags "-H windowsgui"
|
||||||
IF "${WINDOWS_CODESIGNING_CERT_PW}"=="" ECHO Environment variable WINDOWS_CODESIGNING_CERT_PW is not defined. & exit 1
|
IF "${WINDOWS_CODESIGNING_CERT_PW}"=="" ECHO Environment variable WINDOWS_CODESIGNING_CERT_PW is not defined. & exit 1
|
||||||
signtool sign /f windows\codesigning_certificate.pfx /p "${WINDOWS_CODESIGNING_CERT_PW}" /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp bin\windows\Aminal\${BINARY}.exe
|
signtool sign /f windows\codesigning_certificate.pfx /p "${WINDOWS_CODESIGNING_CERT_PW}" /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp bin\windows\Aminal\${BINARY}.exe
|
||||||
signtool sign /f windows\codesigning_certificate.pfx /p "${WINDOWS_CODESIGNING_CERT_PW}" /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /as /fd sha256 /td sha256 bin\windows\Aminal\${BINARY}.exe
|
signtool sign /f windows\codesigning_certificate.pfx /p "${WINDOWS_CODESIGNING_CERT_PW}" /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /as /fd sha256 /td sha256 bin\windows\Aminal\${BINARY}.exe
|
||||||
|
|
|
@ -76,7 +76,7 @@ func (buffer *Buffer) GetURLAtPosition(col uint16, viewRow uint16) string {
|
||||||
row := buffer.convertViewLineToRawLine((viewRow)) - uint64(buffer.terminalState.scrollLinesFromBottom)
|
row := buffer.convertViewLineToRawLine((viewRow)) - uint64(buffer.terminalState.scrollLinesFromBottom)
|
||||||
|
|
||||||
cell := buffer.GetRawCell(col, row)
|
cell := buffer.GetRawCell(col, row)
|
||||||
if cell == nil || cell.Rune() == 0x00 {
|
if cell == nil || isRuneURLSelectionMarker(cell.Rune()) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,19 +84,9 @@ func (buffer *Buffer) GetURLAtPosition(col uint16, viewRow uint16) string {
|
||||||
return cell.hyperlink.Uri
|
return cell.hyperlink.Uri
|
||||||
}
|
}
|
||||||
|
|
||||||
candidate := ""
|
candidate := string(cell.Rune())
|
||||||
|
|
||||||
for i := col; i >= uint16(0); i-- {
|
|
||||||
cell := buffer.GetRawCell(i, row)
|
|
||||||
if cell == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if isRuneURLSelectionMarker(cell.Rune()) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
candidate = fmt.Sprintf("%c%s", cell.Rune(), candidate)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// First, move forward
|
||||||
for i := col + 1; i < buffer.terminalState.viewWidth; i++ {
|
for i := col + 1; i < buffer.terminalState.viewWidth; i++ {
|
||||||
cell := buffer.GetRawCell(i, row)
|
cell := buffer.GetRawCell(i, row)
|
||||||
if cell == nil {
|
if cell == nil {
|
||||||
|
@ -108,6 +98,27 @@ func (buffer *Buffer) GetURLAtPosition(col uint16, viewRow uint16) string {
|
||||||
candidate = fmt.Sprintf("%s%c", candidate, cell.Rune())
|
candidate = fmt.Sprintf("%s%c", candidate, cell.Rune())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move backwards
|
||||||
|
protocolMode := strings.Contains(candidate, "://")
|
||||||
|
for i := col - 1; i >= uint16(0); i-- {
|
||||||
|
cell := buffer.GetRawCell(i, row)
|
||||||
|
if cell == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := cell.Rune()
|
||||||
|
if isRuneURLSelectionMarker(c) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// if we're tracking left of :// we want to break on any non-Latin character
|
||||||
|
if protocolMode && !(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
candidate = fmt.Sprintf("%c%s", c, candidate)
|
||||||
|
if !protocolMode && c == ':' {
|
||||||
|
protocolMode = strings.Contains(candidate, "://")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if candidate == "" || candidate[0] == '/' {
|
if candidate == "" || candidate[0] == '/' {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ type Font struct {
|
||||||
vao uint32
|
vao uint32
|
||||||
vbo uint32
|
vbo uint32
|
||||||
program uint32
|
program uint32
|
||||||
|
uniformLocationResolution int32
|
||||||
|
uniformLocationTextColor int32
|
||||||
texture uint32 // Holds the glyph texture id.
|
texture uint32 // Holds the glyph texture id.
|
||||||
color color
|
color color
|
||||||
ttf *truetype.Font
|
ttf *truetype.Font
|
||||||
|
@ -46,15 +48,14 @@ func LoadFont(reader io.Reader, scale float32, windowWidth int, windowHeight int
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate corresponding render state
|
font, err := LoadTrueTypeFont(program, reader, scale)
|
||||||
gl.UseProgram(program)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
//set screen resolution
|
font.UpdateResolution(windowWidth, windowHeight)
|
||||||
resUniform := gl.GetUniformLocation(program, gl.Str("resolution\x00"))
|
|
||||||
gl.Uniform2f(resUniform, float32(windowWidth), float32(windowHeight))
|
|
||||||
gl.UseProgram(0)
|
|
||||||
|
|
||||||
return LoadTrueTypeFont(program, reader, scale)
|
return font, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Font) Free() {
|
func (f *Font) Free() {
|
||||||
|
@ -82,10 +83,8 @@ func (f *Font) SetColor(red float32, green float32, blue float32, alpha float32)
|
||||||
|
|
||||||
func (f *Font) UpdateResolution(windowWidth int, windowHeight int) {
|
func (f *Font) UpdateResolution(windowWidth int, windowHeight int) {
|
||||||
gl.UseProgram(f.program)
|
gl.UseProgram(f.program)
|
||||||
resUniform := gl.GetUniformLocation(f.program, gl.Str("resolution\x00"))
|
gl.Uniform2f(f.uniformLocationResolution, float32(windowWidth), float32(windowHeight))
|
||||||
gl.Uniform2f(resUniform, float32(windowWidth), float32(windowHeight))
|
|
||||||
gl.UseProgram(0)
|
gl.UseProgram(0)
|
||||||
//f.characters = map[rune]*character{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Font) LineHeight() float32 {
|
func (f *Font) LineHeight() float32 {
|
||||||
|
@ -112,13 +111,11 @@ func (f *Font) Print(x, y float32, text string) error {
|
||||||
// Activate corresponding render state
|
// Activate corresponding render state
|
||||||
gl.UseProgram(f.program)
|
gl.UseProgram(f.program)
|
||||||
//set text color
|
//set text color
|
||||||
gl.Uniform4f(gl.GetUniformLocation(f.program, gl.Str("textColor\x00")), f.color.r, f.color.g, f.color.b, f.color.a)
|
gl.Uniform4f(f.uniformLocationTextColor, f.color.r, f.color.g, f.color.b, f.color.a)
|
||||||
//set screen resolution
|
|
||||||
//resUniform := gl.GetUniformLocation(f.program, gl.Str("resolution\x00"))
|
|
||||||
//gl.Uniform2f(resUniform, float32(2560), float32(1440))
|
|
||||||
|
|
||||||
gl.ActiveTexture(gl.TEXTURE0)
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
gl.BindVertexArray(f.vao)
|
gl.BindVertexArray(f.vao)
|
||||||
|
gl.BindBuffer(gl.ARRAY_BUFFER, f.vbo)
|
||||||
|
|
||||||
// Iterate through all characters in string
|
// Iterate through all characters in string
|
||||||
for i := range indices {
|
for i := range indices {
|
||||||
|
@ -145,7 +142,7 @@ func (f *Font) Print(x, y float32, text string) error {
|
||||||
var y2 = ypos + h
|
var y2 = ypos + h
|
||||||
|
|
||||||
//setup quad array
|
//setup quad array
|
||||||
var vertices = []float32{
|
var vertices = [...]float32{
|
||||||
// X, Y, Z, U, V
|
// X, Y, Z, U, V
|
||||||
// Front
|
// Front
|
||||||
x1, y1, 0.0, 0.0,
|
x1, y1, 0.0, 0.0,
|
||||||
|
@ -153,25 +150,24 @@ func (f *Font) Print(x, y float32, text string) error {
|
||||||
x1, y2, 0.0, 1.0,
|
x1, y2, 0.0, 1.0,
|
||||||
x1, y2, 0.0, 1.0,
|
x1, y2, 0.0, 1.0,
|
||||||
x2, y1, 1.0, 0.0,
|
x2, y1, 1.0, 0.0,
|
||||||
x2, y2, 1.0, 1.0}
|
x2, y2, 1.0, 1.0,
|
||||||
|
}
|
||||||
|
|
||||||
// Render glyph texture over quad
|
// Render glyph texture over quad
|
||||||
gl.BindTexture(gl.TEXTURE_2D, ch.textureID)
|
gl.BindTexture(gl.TEXTURE_2D, ch.textureID)
|
||||||
// Update content of VBO memory
|
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, f.vbo)
|
|
||||||
|
|
||||||
//BufferSubData(target Enum, offset int, data []byte)
|
// Update content of VBO memory
|
||||||
gl.BufferSubData(gl.ARRAY_BUFFER, 0, len(vertices)*4, gl.Ptr(vertices)) // Be sure to use glBufferSubData and not glBufferData
|
gl.NamedBufferSubData(f.vbo, 0, len(vertices)*4, gl.Ptr(&vertices[0])) // Be sure to use glBufferSubData and not glBufferData
|
||||||
|
|
||||||
// Render quad
|
// Render quad
|
||||||
gl.DrawArrays(gl.TRIANGLES, 0, 24)
|
gl.DrawArrays(gl.TRIANGLES, 0, 24)
|
||||||
|
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
|
||||||
// Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
// Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
||||||
x += float32((ch.advance >> 6)) // Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
|
x += float32((ch.advance >> 6)) // Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//clear opengl textures and programs
|
//clear opengl textures and programs
|
||||||
|
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||||
gl.BindVertexArray(0)
|
gl.BindVertexArray(0)
|
||||||
gl.BindTexture(gl.TEXTURE_2D, 0)
|
gl.BindTexture(gl.TEXTURE_2D, 0)
|
||||||
gl.UseProgram(0)
|
gl.UseProgram(0)
|
||||||
|
@ -308,6 +304,7 @@ func (f *Font) GetRune(r rune) (*character, error) {
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
||||||
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(rgba.Rect.Dx()), int32(rgba.Rect.Dy()), 0,
|
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(rgba.Rect.Dx()), int32(rgba.Rect.Dy()), 0,
|
||||||
gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix))
|
gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix))
|
||||||
|
gl.BindTexture(gl.TEXTURE_2D, 0)
|
||||||
|
|
||||||
char.textureID = texture
|
char.textureID = texture
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@ func LoadTrueTypeFont(program uint32, r io.Reader, scale float32) (*Font, error)
|
||||||
f.scale = scale
|
f.scale = scale
|
||||||
f.characters = map[rune]*character{}
|
f.characters = map[rune]*character{}
|
||||||
f.program = program //set shader program
|
f.program = program //set shader program
|
||||||
|
f.uniformLocationResolution = gl.GetUniformLocation(program, gl.Str("resolution\x00"))
|
||||||
|
f.uniformLocationTextColor = gl.GetUniformLocation(program, gl.Str("textColor\x00"))
|
||||||
|
|
||||||
// Read the truetype font.
|
// Read the truetype font.
|
||||||
f.ttf, err = truetype.Parse(data)
|
f.ttf, err = truetype.Parse(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -47,3 +47,7 @@ func (gui *GUI) loadFonts(actualWidth int, actualHeight int) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *GUI) updateFontsResolution(actualWidth int, actualHeight int) {
|
||||||
|
gui.fontMap.UpdateResolution(actualWidth, actualHeight)
|
||||||
|
}
|
||||||
|
|
|
@ -321,7 +321,7 @@ func (gui *GUI) resize(w *glfw.Window, width int, height int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.logger.Debugf("Updating font resolutions...")
|
gui.logger.Debugf("Updating font resolutions...")
|
||||||
gui.loadFonts(gui.width, gui.height)
|
gui.updateFontsResolution(gui.width, gui.height)
|
||||||
|
|
||||||
gui.logger.Debugf("Setting renderer area...")
|
gui.logger.Debugf("Setting renderer area...")
|
||||||
gui.renderer.SetArea(0, 0, gui.width-vScrollbarWidth, gui.height)
|
gui.renderer.SetArea(0, 0, gui.width-vScrollbarWidth, gui.height)
|
||||||
|
|
|
@ -412,13 +412,16 @@ func (gui *GUI) emitButtonEventToTerminal(tx int, ty int, button glfw.MouseButto
|
||||||
gui.prevMotionTY = ty
|
gui.prevMotionTY = ty
|
||||||
|
|
||||||
var packet string
|
var packet string
|
||||||
if ext == terminal.MouseExtSGR {
|
switch ext {
|
||||||
|
case terminal.MouseExtSGR:
|
||||||
final := 'M'
|
final := 'M'
|
||||||
if release {
|
if release {
|
||||||
final = 'm'
|
final = 'm'
|
||||||
}
|
}
|
||||||
packet = fmt.Sprintf("\x1b[<%d;%d;%d%c", b, tx, ty, final)
|
packet = fmt.Sprintf("\x1b[<%d;%d;%d%c", b, tx, ty, final)
|
||||||
} else {
|
case terminal.MouseExtURXVT:
|
||||||
|
packet = fmt.Sprintf("\x1b[%d;%d;%dM", b+32, tx, ty)
|
||||||
|
default:
|
||||||
packet = fmt.Sprintf("\x1b[M%c%c%c", (rune(b + 32)), (rune(tx + 32)), (rune(ty + 32)))
|
packet = fmt.Sprintf("\x1b[M%c%c%c", (rune(b + 32)), (rune(tx + 32)), (rune(ty + 32)))
|
||||||
}
|
}
|
||||||
gui.logger.Infof("Sending mouse packet: '%v'", packet)
|
gui.logger.Infof("Sending mouse packet: '%v'", packet)
|
||||||
|
|
|
@ -17,6 +17,7 @@ var ansiSequenceMap = map[rune]escapeSequenceHandler{
|
||||||
'P': sixelHandler,
|
'P': sixelHandler,
|
||||||
'c': risHandler, //RIS
|
'c': risHandler, //RIS
|
||||||
'#': screenStateHandler,
|
'#': screenStateHandler,
|
||||||
|
'^': privacyMessageHandler,
|
||||||
'(': scs0Handler, // select character set into G0
|
'(': scs0Handler, // select character set into G0
|
||||||
')': scs1Handler, // select character set into G1
|
')': scs1Handler, // select character set into G1
|
||||||
'*': swallowHandler(1), // character set bullshit
|
'*': swallowHandler(1), // character set bullshit
|
||||||
|
@ -104,3 +105,24 @@ func tabSetHandler(pty chan rune, terminal *Terminal) error {
|
||||||
terminal.terminalState.TabSetAtCursor()
|
terminal.terminalState.TabSetAtCursor()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func privacyMessageHandler(pty chan rune, terminal *Terminal) error {
|
||||||
|
// Handler should lock the terminal if there will be write operations to any data read by the renderer
|
||||||
|
// terminal.Lock()
|
||||||
|
// defer terminal.Unlock()
|
||||||
|
|
||||||
|
isEscaped := false
|
||||||
|
for {
|
||||||
|
b := <-pty
|
||||||
|
if b == 0x18 /*CAN*/ || b == 0x1a /*SUB*/ || (b == 0x5c /*backslash*/ && isEscaped) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if isEscaped {
|
||||||
|
isEscaped = false
|
||||||
|
} else if b == 0x1b {
|
||||||
|
isEscaped = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -172,6 +172,14 @@ func csiSetMode(modeStr string, enabled bool, terminal *Terminal) error {
|
||||||
terminal.logger.Infof("Turning off SGR ext mouse mode")
|
terminal.logger.Infof("Turning off SGR ext mouse mode")
|
||||||
terminal.SetMouseExtMode(MouseExtNone)
|
terminal.SetMouseExtMode(MouseExtNone)
|
||||||
}
|
}
|
||||||
|
case "?1015":
|
||||||
|
if enabled {
|
||||||
|
terminal.logger.Infof("Turning on URXVT ext mouse mode")
|
||||||
|
terminal.SetMouseExtMode(MouseExtURXVT)
|
||||||
|
} else {
|
||||||
|
terminal.logger.Infof("Turning off URXVT ext mouse mode")
|
||||||
|
terminal.SetMouseExtMode(MouseExtNone)
|
||||||
|
}
|
||||||
case "?1048":
|
case "?1048":
|
||||||
if enabled {
|
if enabled {
|
||||||
terminal.ActiveBuffer().SaveCursor()
|
terminal.ActiveBuffer().SaveCursor()
|
||||||
|
|
|
@ -31,6 +31,7 @@ const (
|
||||||
MouseExtNone MouseExtMode = iota
|
MouseExtNone MouseExtMode = iota
|
||||||
MouseExtUTF
|
MouseExtUTF
|
||||||
MouseExtSGR
|
MouseExtSGR
|
||||||
|
MouseExtURXVT
|
||||||
)
|
)
|
||||||
|
|
||||||
type WindowManipulationInterface interface {
|
type WindowManipulationInterface interface {
|
||||||
|
|
|
@ -23,10 +23,12 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Version struct {
|
type Version struct {
|
||||||
|
@ -42,8 +44,23 @@ func main() {
|
||||||
versionsDir := filepath.Join(executableDir, "Versions")
|
versionsDir := filepath.Join(executableDir, "Versions")
|
||||||
latestVersion, err := getLatestVersion(versionsDir)
|
latestVersion, err := getLatestVersion(versionsDir)
|
||||||
check(err)
|
check(err)
|
||||||
target := filepath.Join(versionsDir, latestVersion, executableName)
|
usr, err := user.Current()
|
||||||
cmd := exec.Command(target, os.Args[1:]...)
|
check(err)
|
||||||
|
cmd := exec.Command("C:\\Windows\\System32\\cmd.exe", "/C", "start", "Aminal", "/B", executableName)
|
||||||
|
cmd.Dir = usr.HomeDir
|
||||||
|
latestVersionDir := filepath.Join(versionsDir, latestVersion)
|
||||||
|
path, pathSet := os.LookupEnv("PATH")
|
||||||
|
if pathSet {
|
||||||
|
path += ";" + latestVersionDir
|
||||||
|
} else {
|
||||||
|
path = latestVersionDir
|
||||||
|
}
|
||||||
|
cmd.Env = append(os.Environ(), "PATH="+path)
|
||||||
|
const CREATE_NO_WINDOW = 0x08000000
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
HideWindow: true,
|
||||||
|
CreationFlags: CREATE_NO_WINDOW,
|
||||||
|
}
|
||||||
check(cmd.Start())
|
check(cmd.Start())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue