Comments (3)
I also use bubblezone for my process, i dont know what made it happen🙏
from bubbletea.
It's expected behavior that the mouse code still output in the console. Use tea.WithMouseAllMotion()
will change the terminal state, when you kill -9 <pid>
, your process can do nothing but stop immediately. Try use kill -SIGINT <pid>
or kill -SIGTERM <pid>
which have registered handler to correctly tear down.
Below code show what happen when you use tea.WithMouseAllMotion()
. r.out.EnableMouseExtendedMode()
changes the behavior of terminal.
https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L506
} else if p.startupOptions&withMouseAllMotion != 0 {
p.renderer.enableMouseAllMotion()
p.renderer.enableMouseSGRMode()
}
https://github.com/charmbracelet/bubbletea/blob/master/standard_renderer.go#L383-L388
func (r *standardRenderer) enableMouseSGRMode() {
r.mtx.Lock()
defer r.mtx.Unlock()
r.out.EnableMouseExtendedMode()
}
Below code show why you can stop your program properly use SIGINT and SIGTERM. tea will shutdown when receiving SIGINT or SIGTERM. During shutdown restoreTerminalState
is called which calls disableMouse
, therefore your terminal works as usual.
https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L212-L246
func (p *Program) handleSignals() chan struct{} {
ch := make(chan struct{})
// Listen for SIGINT and SIGTERM.
//
// In most cases ^C will not send an interrupt because the terminal will be
// in raw mode and ^C will be captured as a keystroke and sent along to
// Program.Update as a KeyMsg. When input is not a TTY, however, ^C will be
// caught here.
//
// SIGTERM is sent by unix utilities (like kill) to terminate a process.
go func() {
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
defer func() {
signal.Stop(sig)
close(ch)
}()
for {
select {
case <-p.ctx.Done():
return
case <-sig:
if atomic.LoadUint32(&p.ignoreSignals) == 0 {
p.msgs <- QuitMsg{}
return
}
}
}
}()
return ch
}
https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L316-L328
case msg := <-p.msgs:
// Filter messages.
if p.filter != nil {
msg = p.filter(model, msg)
}
if msg == nil {
continue
}
// Handle special internal messages.
switch msg := msg.(type) {
case QuitMsg:
return model, nil
https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L572
p.shutdown(killed)
https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L635-649
func (p *Program) shutdown(kill bool) {
if p.renderer != nil {
if kill {
p.renderer.kill()
} else {
p.renderer.stop()
}
}
_ = p.restoreTerminalState()
if p.restoreOutput != nil {
_ = p.restoreOutput()
}
p.finished <- struct{}{}
}
https://github.com/charmbracelet/bubbletea/blob/master/tty.go#L25-L40
func (p *Program) restoreTerminalState() error {
if p.renderer != nil {
p.renderer.disableBracketedPaste()
p.renderer.showCursor()
p.disableMouse()
if p.renderer.altScreen() {
p.renderer.exitAltScreen()
// give the terminal a moment to catch up
time.Sleep(time.Millisecond * 10) //nolint:gomnd
}
}
return p.restoreInput()
}
https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L299-L303
func (p *Program) disableMouse() {
p.renderer.disableMouseCellMotion()
p.renderer.disableMouseAllMotion()
p.renderer.disableMouseSGRMode()
}
from bubbletea.
It's expected behavior that the mouse code still output in the console. Use
tea.WithMouseAllMotion()
will change the terminal state, when youkill -9 <pid>
, your process can do nothing but stop immediately. Try usekill -SIGINT <pid>
orkill -SIGTERM <pid>
which have registered handler to correctly tear down.鼠标代码仍然在控制台中输出是预期的行为。使用tea.WithMouseAllMotion()
将更改终端状态,当您kill -9 <pid>
时,您的进程只能立即停止,而不能执行任何操作。尝试使用kill -SIGINT <pid>
或kill -SIGTERM <pid>
,它们已注册处理程序以正确终止。 Below code show what happen when you usetea.WithMouseAllMotion()
.r.out.EnableMouseExtendedMode()
changes the behavior of terminal.以下代码显示了使用tea.WithMouseAllMotion()
时会发生什么。r.out.EnableMouseExtendedMode()
更改了终端的行为。 https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L506} else if p.startupOptions&withMouseAllMotion != 0 { p.renderer.enableMouseAllMotion() p.renderer.enableMouseSGRMode() }https://github.com/charmbracelet/bubbletea/blob/master/standard_renderer.go#L383-L388
func (r *standardRenderer) enableMouseSGRMode() { r.mtx.Lock() defer r.mtx.Unlock() r.out.EnableMouseExtendedMode() }Below code show why you can stop your program properly use SIGINT and SIGTERM. tea will shutdown when receiving SIGINT or SIGTERM. During shutdown
restoreTerminalState
is called which callsdisableMouse
, therefore your terminal works as usual.以下代码显示了为什么您可以使用 SIGINT 和 SIGTERM 正确停止程序。tea 在收到 SIGINT 或 SIGTERM 时将关闭。在关闭期间调用restoreTerminalState
,它调用disableMouse
,因此您的终端像往常一样工作。 https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L212-L246func (p *Program) handleSignals() chan struct{} { ch := make(chan struct{}) // Listen for SIGINT and SIGTERM. // // In most cases ^C will not send an interrupt because the terminal will be // in raw mode and ^C will be captured as a keystroke and sent along to // Program.Update as a KeyMsg. When input is not a TTY, however, ^C will be // caught here. // // SIGTERM is sent by unix utilities (like kill) to terminate a process. go func() { sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM) defer func() { signal.Stop(sig) close(ch) }() for { select { case <-p.ctx.Done(): return case <-sig: if atomic.LoadUint32(&p.ignoreSignals) == 0 { p.msgs <- QuitMsg{} return } } } }() return ch }https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L316-L328
case msg := <-p.msgs: // Filter messages. if p.filter != nil { msg = p.filter(model, msg) } if msg == nil { continue } // Handle special internal messages. switch msg := msg.(type) { case QuitMsg: return model, nilhttps://github.com/charmbracelet/bubbletea/blob/master/tea.go#L572
p.shutdown(killed)https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L635-649
func (p *Program) shutdown(kill bool) { if p.renderer != nil { if kill { p.renderer.kill() } else { p.renderer.stop() } } _ = p.restoreTerminalState() if p.restoreOutput != nil { _ = p.restoreOutput() } p.finished <- struct{}{} }https://github.com/charmbracelet/bubbletea/blob/master/tty.go#L25-L40
func (p *Program) restoreTerminalState() error { if p.renderer != nil { p.renderer.disableBracketedPaste() p.renderer.showCursor() p.disableMouse() if p.renderer.altScreen() { p.renderer.exitAltScreen() // give the terminal a moment to catch up time.Sleep(time.Millisecond * 10) //nolint:gomnd } } return p.restoreInput() }https://github.com/charmbracelet/bubbletea/blob/master/tea.go#L299-L303
func (p *Program) disableMouse() { p.renderer.disableMouseCellMotion() p.renderer.disableMouseAllMotion() p.renderer.disableMouseSGRMode() }
OK, thanks bro.
from bubbletea.
Related Issues (20)
- First line not rendering until event happens HOT 3
- Part of the screen is not rendering when the view is exactly the size of the screen HOT 3
- Proposal: Model v2, program context
- Exiting fullscreen glitch when also removing a line in output HOT 2
- Proposal: use x/input to handle input events
- `tea.unknownCSISequenceMsg: unknown message type` panics HOT 3
- The visible area in viewport may seem incorrect when content exceed the viewport.Width HOT 10
- Flickering on Windows when using bubbletea >=0.26.0 HOT 2
- Unmanaged Output Truncation (e.g. `tea.Println`) HOT 1
- Show example GIFs on all examples HOT 1
- The input isn't verified before using epoll on it HOT 3
- go version in go.mod is outdated HOT 2
- does Update() get called even when there are no keys being pressed?
- Can't write japanese characters in inputfield HOT 2
- Exit with error message to stderr and non-zero status code
- Async Clipboard
- Automatic command chaining: Cmd -> Cmd -> Msg HOT 1
- Allow WindowSizeMsg to be sent on sub-model Init HOT 5
- Progress bar behaving strangely
- Any support for charts?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bubbletea.