diff --git a/main.go b/main.go index 231828a..7a7d245 100644 --- a/main.go +++ b/main.go @@ -6,18 +6,26 @@ import ( "os" "time" + "sync" + "github.com/atotto/clipboard" "github.com/limetext/qml-go" ) +const ( + timeoutTickDuration = 10 * time.Millisecond + clipboardTimeout = 15 * time.Second +) + // UI is the model for the password UI type UI struct { Status string query string - Countdown float64 - countingDown bool - countdownDone chan bool + lock sync.Mutex + Countdown float64 + countingDown bool + resetCountdown chan bool ShowMetadata bool @@ -29,6 +37,18 @@ type UI struct { } } +func (ui *UI) isCountingDown() bool { + ui.lock.Lock() + defer ui.lock.Unlock() + return ui.countingDown +} + +func (ui *UI) setCountingDown(value bool) { + ui.lock.Lock() + defer ui.lock.Unlock() + ui.countingDown = value +} + // Passwords is the model for the password list type Passwords struct { Selected int @@ -66,33 +86,35 @@ func (p *Passwords) Get(index int) Password { // ClearClipboard clears the clipboard func (ui *UI) ClearClipboard() { - if ui.countingDown { - ui.countdownDone <- true + + if ui.isCountingDown() { + ui.resetCountdown <- true + return } - ui.countingDown = true - tick := 10 * time.Millisecond - t := time.NewTicker(tick) - remaining := 15.0 - for { - select { - case <-ui.countdownDone: - t.Stop() - ui.countingDown = false - return - case <-t.C: - ui.setCountdown(remaining) - ui.setStatus(fmt.Sprintf("Will clear in %.f seconds", remaining)) - remaining -= tick.Seconds() - if remaining <= 0 { - clipboard.WriteAll("") - ui.Clearmetadata() - ui.setStatus("Clipboard cleared") - ui.countingDown = false - t.Stop() - return + + ui.setCountingDown(true) + go func() { + defer ui.setCountingDown(false) + t := time.NewTicker(timeoutTickDuration) + remaining := clipboardTimeout + for { + select { + case <-ui.resetCountdown: + remaining = clipboardTimeout + case <-t.C: + ui.setCountdown(remaining.Seconds()) + ui.setStatus(fmt.Sprintf("Will clear in %.f seconds", remaining.Seconds())) + remaining -= timeoutTickDuration + if remaining <= 0 { + clipboard.WriteAll("") + ui.Clearmetadata() + ui.setStatus("Clipboard cleared") + t.Stop() + return + } } } - } + }() } // CopyToClipboard copies the selected password to the system clipboard @@ -112,7 +134,7 @@ func (p *Passwords) CopyToClipboard(selected int) { panic(err) } ui.setStatus("Copied to clipboard") - go ui.ClearClipboard() + ui.ClearClipboard() p.Update("") // Trigger a manual update, since the key is probably unlocked now } @@ -183,7 +205,7 @@ var passwords Passwords var ps *PasswordStore func main() { - ui.countdownDone = make(chan bool) + ui.resetCountdown = make(chan bool, 1) ps = NewPasswordStore() passwords.store = ps ps.Subscribe(passwords.Update)