hints kitten: Fix regression causing editing of favorites to sometimes hang
This commit is contained in:
parent
93a5107e79
commit
6a07435bb0
@ -441,13 +441,7 @@ func (self *handler) handle_favorites_key_event(event *loop.KeyEvent) {
|
|||||||
self.lp.Quit(1)
|
self.lp.Quit(1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resume, err := self.lp.Suspend()
|
err = self.lp.SuspendAndRun(func() error {
|
||||||
if err != nil {
|
|
||||||
self.err = err
|
|
||||||
self.lp.Quit(1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resume()
|
|
||||||
cmd := exec.Command(exe, "edit-in-kitty", "--type=overlay", fp)
|
cmd := exec.Command(exe, "edit-in-kitty", "--type=overlay", fp)
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
@ -461,6 +455,13 @@ func (self *handler) handle_favorites_key_event(event *loop.KeyEvent) {
|
|||||||
var ln string
|
var ln string
|
||||||
fmt.Scanln(&ln)
|
fmt.Scanln(&ln)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
self.err = err
|
||||||
|
self.lp.Quit(1)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,8 +66,9 @@ type Loop struct {
|
|||||||
style_ctx style.Context
|
style_ctx style.Context
|
||||||
atomic_update_active bool
|
atomic_update_active bool
|
||||||
|
|
||||||
// Suspend the loop restoring terminal state. Call the return resume function to restore the loop
|
// Suspend the loop restoring terminal state, and run the provided function. When it returns terminal state is
|
||||||
Suspend func() (func() error, error)
|
// put back to what it was before suspending unless the function returns an error or an error occurs saving/restoring state.
|
||||||
|
SuspendAndRun func(func() error) error
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
|
|
||||||
|
|||||||
@ -271,10 +271,8 @@ func (self *Loop) run() (err error) {
|
|||||||
|
|
||||||
self.keep_going = true
|
self.keep_going = true
|
||||||
self.pending_mouse_events = utils.NewRingBuffer[MouseEvent](4)
|
self.pending_mouse_events = utils.NewRingBuffer[MouseEvent](4)
|
||||||
tty_read_channel := make(chan []byte)
|
|
||||||
tty_write_channel := make(chan *write_msg, 1) // buffered so there is no race between initial queueing and startup of writer thread
|
tty_write_channel := make(chan *write_msg, 1) // buffered so there is no race between initial queueing and startup of writer thread
|
||||||
write_done_channel := make(chan IdType)
|
write_done_channel := make(chan IdType)
|
||||||
tty_reading_done_channel := make(chan byte)
|
|
||||||
self.wakeup_channel = make(chan byte, 256)
|
self.wakeup_channel = make(chan byte, 256)
|
||||||
self.pending_writes = make([]*write_msg, 0, 256)
|
self.pending_writes = make([]*write_msg, 0, 256)
|
||||||
err_channel := make(chan error, 8)
|
err_channel := make(chan error, 8)
|
||||||
@ -286,25 +284,49 @@ func (self *Loop) run() (err error) {
|
|||||||
no_timeout_channel := make(<-chan time.Time)
|
no_timeout_channel := make(<-chan time.Time)
|
||||||
finalizer := ""
|
finalizer := ""
|
||||||
|
|
||||||
w_r, w_w, err := os.Pipe()
|
var r_r, r_w, w_r, w_w *os.File
|
||||||
var r_r, r_w *os.File
|
var tty_reading_done_channel chan byte
|
||||||
if err == nil {
|
var tty_read_channel chan []byte
|
||||||
|
|
||||||
|
start_tty_reader := func() (err error) {
|
||||||
r_r, r_w, err = os.Pipe()
|
r_r, r_w, err = os.Pipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w_r.Close()
|
|
||||||
w_w.Close()
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
tty_read_channel = make(chan []byte)
|
||||||
|
tty_reading_done_channel = make(chan byte)
|
||||||
|
go read_from_tty(r_r, controlling_term, tty_read_channel, err_channel, tty_reading_done_channel)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = start_tty_reader()
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
w_r, w_w, err = os.Pipe() // these are closed in the writer thread and the shutdown defer in this thread
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
self.QueueWriteString(self.terminal_options.SetStateEscapeCodes())
|
self.QueueWriteString(self.terminal_options.SetStateEscapeCodes())
|
||||||
needs_reset_escape_codes := true
|
needs_reset_escape_codes := true
|
||||||
|
|
||||||
defer func() {
|
shutdown_tty_reader := func() {
|
||||||
// notify tty reader that we are shutting down
|
// notify tty reader that we are shutting down
|
||||||
|
if r_w != nil {
|
||||||
r_w.Close()
|
r_w.Close()
|
||||||
close(tty_reading_done_channel)
|
close(tty_reading_done_channel)
|
||||||
|
r_w = nil
|
||||||
|
tty_reading_done_channel = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wait_for_tty_reader_to_quit := func() {
|
||||||
|
// wait for tty reader to exit cleanly
|
||||||
|
for range tty_read_channel {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
shutdown_tty_reader()
|
||||||
|
|
||||||
if self.OnFinalize != nil {
|
if self.OnFinalize != nil {
|
||||||
finalizer += self.OnFinalize()
|
finalizer += self.OnFinalize()
|
||||||
@ -318,13 +340,10 @@ func (self *Loop) run() (err error) {
|
|||||||
// flush queued data and wait for it to be written for a timeout, then wait for writer to shutdown
|
// flush queued data and wait for it to be written for a timeout, then wait for writer to shutdown
|
||||||
flush_writer(w_w, tty_write_channel, write_done_channel, self.pending_writes, 2*time.Second)
|
flush_writer(w_w, tty_write_channel, write_done_channel, self.pending_writes, 2*time.Second)
|
||||||
self.pending_writes = nil
|
self.pending_writes = nil
|
||||||
// wait for tty reader to exit cleanly
|
wait_for_tty_reader_to_quit()
|
||||||
for range tty_read_channel {
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go write_to_tty(w_r, controlling_term, tty_write_channel, err_channel, write_done_channel)
|
go write_to_tty(w_r, controlling_term, tty_write_channel, err_channel, write_done_channel)
|
||||||
go read_from_tty(r_r, controlling_term, tty_read_channel, err_channel, tty_reading_done_channel)
|
|
||||||
|
|
||||||
if self.OnInitialize != nil {
|
if self.OnInitialize != nil {
|
||||||
finalizer, err = self.OnInitialize()
|
finalizer, err = self.OnInitialize()
|
||||||
@ -333,27 +352,30 @@ func (self *Loop) run() (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.Suspend = func() (func() error, error) {
|
self.SuspendAndRun = func(run func() error) (err error) {
|
||||||
write_id := self.QueueWriteString(self.terminal_options.ResetStateEscapeCodes())
|
write_id := self.QueueWriteString(self.terminal_options.ResetStateEscapeCodes())
|
||||||
needs_reset_escape_codes = false
|
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 = self.wait_for_write_to_complete(write_id, tty_write_channel, write_done_channel, 2*time.Second); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
shutdown_tty_reader()
|
||||||
|
wait_for_tty_reader_to_quit()
|
||||||
resume, err := controlling_term.Suspend()
|
resume, err := controlling_term.Suspend()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
return func() (err error) {
|
if err = run(); err != nil {
|
||||||
err = resume()
|
return err
|
||||||
if err != nil {
|
}
|
||||||
return
|
if err = start_tty_reader(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = resume(); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
write_id = self.QueueWriteString(self.terminal_options.SetStateEscapeCodes())
|
write_id = self.QueueWriteString(self.terminal_options.SetStateEscapeCodes())
|
||||||
needs_reset_escape_codes = true
|
needs_reset_escape_codes = true
|
||||||
return self.wait_for_write_to_complete(write_id, tty_write_channel, write_done_channel, 2*time.Second)
|
return self.wait_for_write_to_complete(write_id, tty_write_channel, write_done_channel, 2*time.Second)
|
||||||
}, nil
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.on_SIGTSTP = func() error {
|
self.on_SIGTSTP = func() error {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user