Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow WindowSizeMsg to be sent on sub-model Init #987

Closed
tylerolson opened this issue Apr 21, 2024 · 5 comments · Fixed by #988
Closed

Allow WindowSizeMsg to be sent on sub-model Init #987

tylerolson opened this issue Apr 21, 2024 · 5 comments · Fixed by #988
Labels
enhancement New feature or request

Comments

@tylerolson
Copy link

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 tylerolson added the enhancement New feature or request label Apr 21, 2024
@meowgorithm
Copy link
Member

meowgorithm commented Apr 22, 2024

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

@KevM
Copy link

KevM commented Apr 22, 2024

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.

@meowgorithm
Copy link
Member

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

@tylerolson
Copy link
Author

@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

@KevM
Copy link

KevM commented Apr 22, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants