🌧 Describe the problem
I'm currently using bubbletea and bubblezone to develop a small console game pet-project. While developing I encountered a strange bug.
When I use lipgloss.place
in a certain way with zone.mark
the whole program and console freezes after responding correctly a few times. Even when I kill the process the console will be stuck without further input being possible. This happens with iterm2 and the default macos terminal. I have to create a new console session to get the console working again.
⛅ Expected behavior
I expected the program to keep processing mouse inputs and not freeze.
🔄 Minimal reproduction
I threw together a minimal example without any of my game logic that keeps freezing on my system:
package main
import (
"fmt"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
zone "github.com/lrstanley/bubblezone"
"github.com/muesli/reflow/wordwrap"
"os"
"strings"
)
const TriggerBug = true
type TestModel struct {
size tea.WindowSizeMsg
selectedCard int
numberCards int
}
func (m TestModel) Init() tea.Cmd {
return nil
}
func (m TestModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
if msg.String() == "ctrl+c" {
return m, tea.Quit
}
case tea.WindowSizeMsg:
m.size = msg
case tea.MouseMsg:
if msg.Type == tea.MouseLeft || msg.Type == tea.MouseMotion {
// Check zones to set selected card
for i := 0; i < m.numberCards; i++ {
if zone.Get(fmt.Sprintf("%s%d", "card_", i)).InBounds(msg) {
m.selectedCard = i
}
}
}
}
return m, nil
}
func (m TestModel) View() string {
cardStyle := lipgloss.NewStyle().Width(30).Padding(1, 2).Margin(0, 2)
var cardBoxes []string
for i := 0; i < m.numberCards; i++ {
selected := i == m.selectedCard
style := cardStyle.
Border(lipgloss.NormalBorder(), selected, false, false, false).
BorderBackground(lipgloss.Color("#cccccc")).
Background(lipgloss.Color("#cccccc")).
BorderForeground(lipgloss.Color("#ffffff")).
Foreground(lipgloss.Color("#ffffff"))
// If the card is selected we give it a bit more height
if selected {
cardBoxes = append(cardBoxes,
style.
Height(min(m.size.Height-1, m.size.Height/2+5)).
Render(wordwrap.String(fmt.Sprintf("%s\n\n%s\n\n%s", strings.Repeat("•", 3), "Example Card", "Hello World... Hello World... Hello World.."), 20)),
)
continue
}
// Non-selected card style
cardBoxes = append(cardBoxes,
style.
Height(m.size.Height/2).
Render(wordwrap.String(fmt.Sprintf("%s\n\n%s\n\n%s", strings.Repeat("•", 3), "Example Card", "Hello World... Hello World... Hello World.."), 20)),
)
}
for i := range cardBoxes {
cardBoxes[i] = zone.Mark(fmt.Sprintf("%s%d", "card_", i), cardBoxes[i])
}
// EDIT: also breaks after a while
if !TriggerBug {
return zone.Scan(lipgloss.JoinHorizontal(lipgloss.Bottom, cardBoxes...))
}
// Freeze:
return zone.Scan(lipgloss.Place(m.size.Width, m.size.Height, lipgloss.Center, lipgloss.Bottom, lipgloss.JoinHorizontal(lipgloss.Bottom, cardBoxes...)))
}
func main() {
zone.NewGlobal()
p := tea.NewProgram(TestModel{
numberCards: 3,
}, tea.WithAltScreen(), tea.WithMouseAllMotion())
if _, err := p.Run(); err != nil {
fmt.Printf("Alas, there's been an error: %v", err)
os.Exit(1)
}
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
💠 Version: bubblezone
v0.0.0-20230303230241-08f906ff62a9
🖥 Version: Operating system
macos
⚙ Additional context
Video showing the working lipgloss.JoinHorizontal
vs the freezing lipgloss.Place
. When the second terminal tab stops responding it's completely frozen. ctrl+c
does nothing and I manually need to restart it.
https://streamable.com/65dklc
EDIT: lipgloss.JoinHorizontal
also breaks for me after a while
🤝 Requirements