charmbracelet / charmbracelet/bubbletea
Windows centering
- Dominant language
- Go
- Stars
- 44.9k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Description
**Describe the bug**
On windows, if you try to get the width and height of the terminal and then use `lipgloss.Place` to have one string in the center of your terminal while resizing, once you resize higher and wider than the initial dimension, the centered string will go up.
**Setup**
Please complete the following information along with version numbers, if applicable.
- Windows
- Command Prompt
**To Reproduce**
Steps to reproduce the behavior:
Simply get the resize width and height, make sure it is updated, center a string the most basic and classic way `return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, fmt.Sprintf("%v-%v", m.width, m.height))`.
If it works on Linux and MacOs, perfect, now try on W10 on the Command Prompt. You should see the string going up.
**Additional context**
I've looked at `github.com/gdamore/tcell/v2` (through look at `tview`), it uses a `tcell.Screen` that always correctly match the size. The example "frame" on `tview` way working PERFECTLY on all OS. So I was surprised! Why know trying, right?
**Source Code**
This is the code with the faulty Command Prompt
```go
package main
import (
"bytes"
"fmt"
"log"
"os"
"time"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"golang.org/x/term"
)
type sizeTickMsg struct {
size tea.WindowSizeMsg
err error
}
var sizeTick = tea.Tick(time.Second/33, func(time.Time) tea.Msg {
w, h, err := term.GetSize(int(os.Stdout.Fd()))
return sizeTickMsg{
size: tea.WindowSizeMsg{
Width: w,
Height: h,
},
err: err,
}
})
func main() {
var err error
bb := BlubbleState{}
p := tea.NewProgram(bb, tea.WithAltScreen())
_, err = p.Run()
if err != nil {
log.Fatalln(err)
}
}
type BlubbleState struct {
Dimension struct {
w int
h int
}
size tea.WindowSizeMsg
style lipgloss.Style
}
func (m BlubbleState) Init() tea.Cmd {
return sizeTick
}
func (m BlubbleState) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case sizeTickMsg:
if msg.err == nil {
m.size = msg.size
m.style = m.style.Width(m.size.Width - 2).Height(m.size.Height - 2)
}
return m, sizeTick
case tea.WindowSizeMsg:
m.size = msg
m.style = m.style.Width(m.size.Width - 2).Height(m.size.Height - 2)
return m, sizeTick
case tea.KeyMsg:
switch msg.Type {
case tea.KeyCtrlC:
return m, tea.Quit
}
}
cmds := []tea.Cmd{
sizeTick,
}
return m, tea.Batch(cmds...)
}
func (m BlubbleState) View() string {
b := bytes.NewBufferString("")
b.WriteString(
lipgloss.Place(m.style.GetWidth(), m.style.GetHeight(), lipgloss.Center, lipgloss.Center,
fmt.Sprintf("%v-%v", m.style.GetWidth(), m.style.GetHeight())))
return b.String()
}
```
Well, I did it in a stupid way but it "works". It fixes it on Command Prompt... it dirty though
```go
package main
import (
"fmt"
"log"
"time"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
tcell "github.com/gdamore/tcell/v2"
)
type model struct {
width, height int
}
func (m model) Init() tea.Cmd {
return resizeCmd
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds := []tea.Cmd{}
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.width = msg.Width
m.height = msg.Height
cmds = append(cmds, resizeCmd)
case tea.KeyMsg:
switch msg.Type {
case tea.KeyCtrlC:
return m, tea.Quit
}
}
return m, tea.Batch(cmds...)
}
func (m model) View() string {
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center,
fmt.Sprintf("%v-%v", m.width, m.height))
}
var resizeCmd = tea.Tick(time.Second/33, func(time.Time) tea.Msg {
screen, _ := tcell.NewScreen()
if err := screen.Init(); err != nil {
return nil
}
defer screen.Fini()
w, h := screen.Size()
return tea.WindowSizeMsg{
Width: w,
Height: h,
}
})
func main() {
p := tea.NewProgram(model{}, tea.WithAltScreen())
if _, err := p.Run(); err != nil {
log.Fatal(err)
}
}
```
**Screenshots**
Here an example of behavior when you write a basic code that center the string.
Strangely, the `tcell.Screen` fix it.
I just thought that maybe it wasn't on your radar and thought it would help 😄
Contributor guide
Research direction
Start with the reported term.GetSize call and Bubble Tea's tea.WindowSizeMsg handling, comparing them with the tcell.Screen size path shown in the issue. Reproduce the resizing behavior on Windows Command Prompt and verify that centered output remains correctly positioned after enlarging the terminal.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100