bubbletea icon indicating copy to clipboard operation
bubbletea copied to clipboard

Allow WindowSizeMsg to be sent on sub-model Init

Open tylerolson opened this issue 10 months ago • 5 comments

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 :)

tylerolson avatar Apr 21 '24 22:04 tylerolson

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
        }
}

meowgorithm avatar Apr 22 '24 02:04 meowgorithm

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.

KevM avatar Apr 22 '24 03:04 KevM

Reading this again, perhaps a Cmd for requesting the window size would indeed be useful.

meowgorithm avatar Apr 22 '24 04:04 meowgorithm

@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

tylerolson avatar Apr 22 '24 04:04 tylerolson

@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. 🤷🏼

KevM avatar Apr 22 '24 18:04 KevM