wails icon indicating copy to clipboard operation
wails copied to clipboard

Multiple Containers in the same Window

Open SamHennessy opened this issue 2 years ago • 9 comments

Is your feature request related to a problem? Please describe.

I want to have two web views (containers) in one Window, allowing me to show an external website.

Many sites block iframe usage, and I assume that's true with something like Wails. In addition, when using an iframe, you can't use JavaScript to interact with the contents frame, for example, being able to read the title of the page.

Use case one is a live-reload app that will run a Go web app and rebuild, then reload it when something changes. In the app, I will have buttons and a log viewer. The Go app is running as a web server and is shown inside the app but is not part of it.

Use case two, a hacker news client, where I'd like to show the comments with the linked external website. The comments are part of the local app, and the website is not.

Describe the solution you'd like

For a window, I'd like to have a way to indicate that I want another container and how I want the containers laid out. For example, I want to add a container to the left of the "main" container or the new container below the main container.

  • For the added container, I want to be able to set the initial URL.
  • For the added container, I want to be able to change the URL.
  • For the added container, I want to execute arbitrary JavaScript and receive a response.
  • I want to be able to show and hide the added container without removing the container (keeping the website as is)
  • When the added container is hidden, I want the main container to resize to cover the whole window or have a way to do that manually.

Describe alternatives you've considered

With an iframe, I can load local sites, but it doesn't allow me to read things like the page title or to use JavaScript to reload the page. In my current web app, I use a reverse proxy, which makes the web app and iframe contents appear on the same domain and port, and I can use JavaScript to interact with the iframe's contents.

Additional context

It's common for desktop apps to show websites in a web view so the user doesn't need to leave the app to view the external website. For example, news aggregators show news articles. To show pages for help and support. To show an e-commerce site.

While not considered the best practice anymore (a web vire is less capable than a real browser) it is a feature often required by less technical decision makers in companies. Not having this feature could prevent a developer from using Wails as they would not be able to implement this feature.

SamHennessy avatar Oct 20 '22 02:10 SamHennessy

Thanks for taking the time to write this detailed ticket. If you were to code to the perfect API l, what would it look like?

The direction we're heading is programmatic creation, so imagine you create a main window as such:

mainWindow := application.NewWindow(...options)

What would be in the options? Maybe the current concept of a window should be NewWebview(options) and this would be for blank windows? Would you define the layout in the options or as methods?

This is great as we need a more flexible API for what we have and this is a great opportunity to shape that 👍

leaanthony avatar Oct 20 '22 08:10 leaanthony

Sorry if I get the terms wrong. I assume the terms Application, Window, and Container. An Application can have multiple Windows. A Window can have multiple Containers.

It's tempting to have this work like CSS Flex or Grid, but that seems more complex than needed. I'd suggest the containers act like absolutely positioned divs. The developer must specify the X, Y, width, and height of each of the Containers. The Containers can overlap and cover one another. Each Container would have a Z index to indicate stacking order.

I'd also suggest having your application.NewWindow being the beginner friend option with reasonable sensible defaults, much like how Wails works now. Then have an application.NewWindowAdvanced option for people trying to do more complex projects. This function acts as a gatekeeper when it's not possible to have sensible defaults. The advanced function could then be empty by default.

Here is the pseudo Go code API:

type ContainerOptions struct {
    X int
    Y int
    Z int
    Height int
    Width int
    URL string
}

mainWindow := application.NewWindowAdvanced(...options)

left := mainWindow.NewContainer(ContainerOptions{URL: "index.html", Height:mainWindow.GetHeight(), Width: mainWindow.GetWidth() / 2})
right := mainWindow.NewContainer(ContainerOptions{URL: "https://wails.io", X: mainWindow.GetWidth() / 2, Height:mainWindow.GetHeight(), Width: mainWindow.GetWidth() / 2})

mainWindow.SetOnResize(func(ctx context.Context) {
    left.SetWidth(mainWindow.GetWidth() / 2)

    right.SetX(mainWindow.GetWidth() / 2)
    right.SetWidth(mainWindow.GetWidth() / 2)
})

SamHennessy avatar Oct 20 '22 12:10 SamHennessy

@leaanthony What he means is that he wants to place multiple webviews in the same window and can customize the location of the webview.

misitebao avatar Oct 20 '22 14:10 misitebao

@SamHennessy thanks for the ideas. Looking good so far. One thing to consider is that a lot of UI APIs often define containers as vbox or hbox with % splits (default is equal spacing so for 2, 50%). This allows auto layout and resizing. We could still support manual override of that though

leaanthony avatar Oct 20 '22 18:10 leaanthony

@misitebao yes, exactly.

@leaanthony you're welcome. As you can tell I don't know anything about desktop development.

SamHennessy avatar Oct 21 '22 01:10 SamHennessy

I'd like to see this. Electron has a BrowserView that is embedded into the container window but not the DOM, and runs in its own process.

blarney2000 avatar Jan 29 '23 16:01 blarney2000

I'd also like to use this feature if it will be implemented. I was wondering, in fact, if one window could fit multiple webviews

Zorgatone avatar Jul 26 '23 19:07 Zorgatone

If you're willing to make a proposal we could look at something like this for v3.5? It would also need contributors.

leaanthony avatar Jul 26 '23 22:07 leaanthony

Hey folks, just wanted to chime in and say that I would love this feature as I have a product in mind that I want to build that would require something like this. Don't mind contributing to help get something working.

sno6 avatar Jan 31 '24 01:01 sno6