diff --git a/sixel.go b/sixel.go index 36ca8c88..92aba117 100644 --- a/sixel.go +++ b/sixel.go @@ -15,55 +15,49 @@ const ( // - rarely used: the filler is used to trick tcell into redrawing, if the // filler character appears in the user's preview, that cell might not // be cleaned up properly - // - ideally renders as empty space: the filler alternates between bold - // and regular, using a non-space would look weird to the user. + // - ideally renders as empty space gSixelFiller = '\u2000' ) type sixelScreen struct { - xprev, yprev int - sixel *string - altFill bool - lastFile string // TODO maybe use hash of sixels instead to flip altFill + win *win + sixel *string + lastFile string // TODO maybe use hash of sixels instead } -func (sxs *sixelScreen) fillerStyle(filePath string) tcell.Style { - if sxs.lastFile != filePath { - sxs.altFill = !sxs.altFill - } - - if sxs.altFill { - return tcell.StyleDefault.Bold(true) - } - return tcell.StyleDefault -} - -func (sxs *sixelScreen) showSixels() { +func (sxs *sixelScreen) clearSixels(screen tcell.Screen) { if sxs.sixel == nil { return } - // XXX: workaround for bug where quitting lf might leave the terminal in bold - fmt.Fprint(os.Stderr, "\033[0m") + filler := strings.Repeat(string(gSixelFiller), sxs.win.w) + for y := 0; y < sxs.win.h; y++ { + sxs.win.print(screen, 0, y, tcell.StyleDefault, filler) + } + + sxs.sixel = nil +} - fmt.Fprint(os.Stderr, "\0337") // Save cursor position - fmt.Fprintf(os.Stderr, "\033[%d;%dH", sxs.yprev, sxs.xprev) // Move cursor to position - fmt.Fprint(os.Stderr, *sxs.sixel) // - fmt.Fprint(os.Stderr, "\0338") // Restore cursor position +func (sxs *sixelScreen) setSixels(win *win, sixel *string) { + sxs.win = win + sxs.sixel = sixel } -func (sxs *sixelScreen) printSixel(win *win, screen tcell.Screen, reg *reg) { - if reg.sixel == nil { +func (sxs *sixelScreen) showSixels(screen tcell.Screen, path string) { + if sxs.sixel == nil { return } - // HACK: fillers are used to control when tcell redraws the region where a sixel image is drawn. - // alternating between bold and regular is to clear the image before drawing a new one. - st := sxs.fillerStyle(reg.path) - for y := 0; y < win.h; y++ { - st = win.print(screen, 0, y, st, strings.Repeat(string(gSixelFiller), win.w)) + if path != sxs.lastFile { + tmp := sxs.sixel + sxs.clearSixels(screen) + sxs.sixel = tmp } - sxs.xprev, sxs.yprev = win.x+1, win.y+1 - sxs.sixel = reg.sixel + fmt.Fprint(os.Stderr, "\0337") // Save cursor position + fmt.Fprintf(os.Stderr, "\033[%d;%dH", sxs.win.y+1, sxs.win.x+1) // Move cursor to position + fmt.Fprint(os.Stderr, *sxs.sixel) // + fmt.Fprint(os.Stderr, "\0338") // Restore cursor position + + sxs.lastFile = path } diff --git a/ui.go b/ui.go index f7684ece..ddd031cc 100644 --- a/ui.go +++ b/ui.go @@ -267,6 +267,12 @@ func (win *win) printReg(screen tcell.Screen, reg *reg, previewLoading bool, sxs return } + if reg.sixel != nil { + sxs.setSixels(win, reg.sixel) + } else { + sxs.clearSixels(screen) + } + for i, l := range reg.lines { if i > win.h-1 { break @@ -274,8 +280,6 @@ func (win *win) printReg(screen tcell.Screen, reg *reg, previewLoading bool, sxs st = win.print(screen, 2, i, st, l) } - - sxs.printSixel(win, screen, reg) } var gThisYear = time.Now().Year() @@ -1026,14 +1030,7 @@ func (ui *ui) draw(nav *nav) { st := tcell.StyleDefault context := dirContext{selections: nav.selections, saves: nav.saves, tags: nav.tags} - // XXX: manual clean without flush to avoid flicker on Windows - wtot, htot := ui.screen.Size() - for i := 0; i < wtot; i++ { - for j := 0; j < htot; j++ { - ui.screen.SetContent(i, j, ' ', nil, st) - } - } - ui.sxScreen.sixel = nil + ui.screen.Clear() ui.drawPromptLine(nav) @@ -1077,7 +1074,12 @@ func (ui *ui) draw(nav *nav) { if err == nil { preview := ui.wins[len(ui.wins)-1] + if ui.menuBuf != nil { + ui.sxScreen.clearSixels(ui.screen) + } + if curr.IsDir() { + ui.sxScreen.clearSixels(ui.screen) preview.printDir(ui, ui.dirPrev, &context, &dirStyle{colors: ui.styles, icons: ui.icons, role: Preview}, nav.previewLoading) @@ -1112,9 +1114,8 @@ func (ui *ui) draw(nav *nav) { } ui.screen.Show() - if ui.menuBuf == nil && ui.cmdPrefix == "" && ui.sxScreen.sixel != nil { - ui.sxScreen.lastFile = ui.regPrev.path - ui.sxScreen.showSixels() + if ui.menuBuf == nil && ui.sxScreen.sixel != nil { + ui.sxScreen.showSixels(ui.screen, ui.regPrev.path) } }