From 67436a48cdebf23d08292704aa057ff1b4bd2713 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 14 Feb 2023 22:27:41 +0530 Subject: [PATCH] New API to suspend a loop --- tools/tty/tty.go | 22 ++++++++++++++++------ tools/tui/loop/api.go | 3 ++- tools/tui/loop/run.go | 23 +++++++++++++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/tools/tty/tty.go b/tools/tty/tty.go index 1542a59f5..88391f361 100644 --- a/tools/tty/tty.go +++ b/tools/tty/tty.go @@ -209,20 +209,30 @@ func (self *Term) RestoreAndClose() error { return self.Close() } -func (self *Term) SuspendAndRun(callback func() error) error { +func (self *Term) Suspend() (resume func() error, err error) { var state unix.Termios - err := self.Tcgetattr(&state) + err = self.Tcgetattr(&state) if err != nil { - return err + return nil, err } if len(self.states) > 0 { err := self.Tcsetattr(TCSANOW, &self.states[0]) if err != nil { - return err + return nil, err } } - defer self.Tcsetattr(TCSANOW, &state) - return callback() + return func() error { return self.Tcsetattr(TCSANOW, &state) }, nil + +} + +func (self *Term) SuspendAndRun(callback func() error) error { + resume, err := self.Suspend() + if err != nil { + return err + } + err = callback() + resume() + return err } func clamp(v, lo, hi int64) int64 { diff --git a/tools/tui/loop/api.go b/tools/tui/loop/api.go index ecef2ef01..040f9eacc 100644 --- a/tools/tui/loop/api.go +++ b/tools/tui/loop/api.go @@ -58,7 +58,8 @@ type Loop struct { pending_writes []*write_msg on_SIGTSTP func() error - // Send strings to this channel to queue writes in a thread safe way + // Suspend the loop restoring terminal state. Call the return resume function to restore the loop + Suspend func() (func() error, error) // Callbacks diff --git a/tools/tui/loop/run.go b/tools/tui/loop/run.go index d0dfd91da..4832c4f07 100644 --- a/tools/tui/loop/run.go +++ b/tools/tui/loop/run.go @@ -290,6 +290,29 @@ func (self *Loop) run() (err error) { } } + self.Suspend = func() (func() error, error) { + write_id := self.QueueWriteString(self.terminal_options.ResetStateEscapeCodes()) + needs_reset_escape_codes = false + err := self.wait_for_write_to_complete(write_id, tty_write_channel, write_done_channel, 2*time.Second) + if err != nil { + return nil, err + } + resume, err := controlling_term.Suspend() + if err != nil { + return nil, err + } + return func() (err error) { + err = resume() + if err != nil { + return + } + write_id = self.QueueWriteString(self.terminal_options.SetStateEscapeCodes()) + needs_reset_escape_codes = true + return self.wait_for_write_to_complete(write_id, tty_write_channel, write_done_channel, 2*time.Second) + }, nil + + } + self.on_SIGTSTP = func() error { write_id := self.QueueWriteString(self.terminal_options.ResetStateEscapeCodes()) needs_reset_escape_codes = false