bubbletea
bubbletea copied to clipboard
Allow WindowSizeMsg to be sent on sub-model Init
When attempting to format content that is reliant on the width/height you must listen for WindowSizeMsg
and store those values in the model:
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.width = msg.Width
m.height = msg.Height
}
}
This presents a challenge when switching to a different model, as the WindowSizeMsg
msg is never sent again.
This means that you must either use global variables to keep track of the width/height, or pass around width/height variables to all of your sub models:
func newOtherModel(width int, height int) otherModel {
return otherModel{
width: width,
height: height,
}
}
Describe the solution you'd like Either allow a way to manually request the current WindowSize at say, Init(), or maybe provide a way to update the current model without using a mainmodel-submodels type architecture.
Maybe this is a non-issue for most, just something I found :)
Hi! So technically speaking you shouldn't use Init
to initialize your model; its job is just to return an initial command.
To pass the window width and height when switching to a new model you can simply set properties on the new model before returning it like you say:
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.width = msg.Width
m.height = msg.Height
return m, nil
case switchModelsMsg:
newModel := NewModel()
newModel.width = m.width
newModel.height = m.height
return newModel, newModel.Init() // switch models
}
}
In bubbleo's navstack when pushing a new model on the stack I call Init and send the new model and Update with the window size msg for exactly the reason you mention. We need the model now in charge of the application to know what its size is.
Reading this again, perhaps a Cmd
for requesting the window size would indeed be useful.
@meowgorithm the main issue with that is I find having width
/height
properties in 4+ models gets really annoying. Especially when I'm moving from one model to another AND back (main menu and submenus), I had about 7 spots where im passing width
height
properties.
My initial thought was to just run WindowSizeMsg
when any Init()
is ran, however a request Cmd
would probably be most useful in a vareity of circumstances
@meowgorithm the main issue with that is I find having width/height properties in 4+ models gets really annoying. Especially when I'm moving from one model to another AND back (main menu and submenus), I had about 7 spots where im passing width height properties.
I ran into the same exact issue. My solution was to give my new "sub" model structs a optional field with a pointer to a wrapper around the window state. Maybe not the best solution but it worked for me. 🤷🏼