Skip to content

Commit

Permalink
Merge pull request #4986 from andydotxyz/fix/2740
Browse files Browse the repository at this point in the history
Add support for multiple windows in web driver
  • Loading branch information
andydotxyz authored Jul 10, 2024
2 parents c69fd43 + e3f1bec commit fcb4085
Show file tree
Hide file tree
Showing 8 changed files with 733 additions and 616 deletions.
12 changes: 0 additions & 12 deletions cmd/fyne_demo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,6 @@ func makeTray(a fyne.App) {
}
}

func unsupportedTutorial(t tutorials.Tutorial) bool {
return !t.SupportWeb && fyne.CurrentDevice().IsBrowser()
}

func makeNav(setTutorial func(tutorial tutorials.Tutorial), loadPrevious bool) fyne.CanvasObject {
a := fyne.CurrentApp()

Expand All @@ -229,17 +225,9 @@ func makeNav(setTutorial func(tutorial tutorials.Tutorial), loadPrevious bool) f
return
}
obj.(*widget.Label).SetText(t.Title)
if unsupportedTutorial(t) {
obj.(*widget.Label).TextStyle = fyne.TextStyle{Italic: true}
} else {
obj.(*widget.Label).TextStyle = fyne.TextStyle{}
}
},
OnSelected: func(uid string) {
if t, ok := tutorials.Tutorials[uid]; ok {
if unsupportedTutorial(t) {
return
}
a.Preferences().SetString(preferenceCurrentTutorial, uid)
setTutorial(t)
}
Expand Down
36 changes: 1 addition & 35 deletions cmd/fyne_demo/tutorials/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,182 +8,148 @@ import (
type Tutorial struct {
Title, Intro string
View func(w fyne.Window) fyne.CanvasObject
SupportWeb bool
}

var (
// Tutorials defines the metadata for each tutorial
Tutorials = map[string]Tutorial{
"welcome": {"Welcome", "", welcomeScreen, true},
"welcome": {"Welcome", "", welcomeScreen},
"canvas": {"Canvas",
"See the canvas capabilities.",
canvasScreen,
true,
},
"animations": {"Animations",
"See how to animate components.",
makeAnimationScreen,
true,
},
"icons": {"Theme Icons",
"Browse the embedded icons.",
iconScreen,
true,
},
"containers": {"Containers",
"Containers group other widgets and canvas objects, organising according to their layout.\n" +
"Standard containers are illustrated in this section, but developers can also provide custom " +
"layouts using the fyne.NewContainerWithLayout() constructor.",
containerScreen,
true,
},
"apptabs": {"AppTabs",
"A container to help divide up an application into functional areas.",
makeAppTabsTab,
true,
},
"border": {"Border",
"A container that positions items around a central content.",
makeBorderLayout,
true,
},
"box": {"Box",
"A container arranges items in horizontal or vertical list.",
makeBoxLayout,
true,
},
"center": {"Center",
"A container to that centers child elements.",
makeCenterLayout,
true,
},
"doctabs": {"DocTabs",
"A container to display a single document from a set of many.",
makeDocTabsTab,
true,
},
"grid": {"Grid",
"A container that arranges all items in a grid.",
makeGridLayout,
true,
},
"split": {"Split",
"A split container divides the container in two pieces that the user can resize.",
makeSplitTab,
true,
},
"scroll": {"Scroll",
"A container that provides scrolling for it's content.",
makeScrollTab,
true,
},
"innerwindow": {"InnerWindow",
"A window that can be used inside a traditional window to contain a document or content.",
makeInnerWindowTab,
true,
},
"widgets": {"Widgets",
"In this section you can see the features available in the toolkit widget set.\n" +
"Expand the tree on the left to browse the individual tutorial elements.",
widgetScreen,
true,
},
"accordion": {"Accordion",
"Expand or collapse content panels.",
makeAccordionTab,
true,
},
"activity": {"Activity",
"A spinner indicating activity used in buttons etc.",
makeActivityTab,
true,
},
"button": {"Button",
"Simple widget for user tap handling.",
makeButtonTab,
true,
},
"card": {"Card",
"Group content and widgets.",
makeCardTab,
true,
},
"entry": {"Entry",
"Different ways to use the entry widget.",
makeEntryTab,
true,
},
"form": {"Form",
"Gathering input widgets for data submission.",
makeFormTab,
true,
},
"input": {"Input",
"A collection of widgets for user input.",
makeInputTab,
true,
},
"text": {"Text",
"Text handling widgets.",
makeTextTab,
true,
},
"toolbar": {"Toolbar",
"A row of shortcut icons for common tasks.",
makeToolbarTab,
true,
},
"progress": {"Progress",
"Show duration or the need to wait for a task.",
makeProgressTab,
true,
},
"collections": {"Collections",
"Collection widgets provide an efficient way to present lots of content.\n" +
"The List, Table, and Tree provide a cache and re-use mechanism that make it possible to scroll through thousands of elements.\n" +
"Use this for large data sets or for collections that can expand as users scroll.",
collectionScreen,
true,
},
"list": {"List",
"A vertical arrangement of cached elements with the same styling.",
makeListTab,
true,
},
"table": {"Table",
"A two dimensional cached collection of cells.",
makeTableTab,
true,
},
"tree": {"Tree",
"A tree based arrangement of cached elements with the same styling.",
makeTreeTab,
true,
},
"gridwrap": {"GridWrap",
"A grid based arrangement of cached elements that wraps rows to fit.",
makeGridWrapTab,
true,
},
"dialogs": {"Dialogs",
"Work with dialogs.",
dialogScreen,
true,
},
"windows": {"Windows",
"Window function demo.",
windowScreen,
false,
},
"binding": {"Data Binding",
"Connecting widgets to a data source.",
bindingScreen,
true,
},
"advanced": {"Advanced",
"Debug and advanced information.",
advancedScreen,
true,
},
}

Expand Down
7 changes: 6 additions & 1 deletion internal/driver/glfw/canvas.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/internal"
"fyne.io/fyne/v2/internal/app"
"fyne.io/fyne/v2/internal/build"
Expand Down Expand Up @@ -34,7 +35,8 @@ type glCanvas struct {

scale, detectedScale, texScale float32

context driver.WithContext
context driver.WithContext
webExtraWindows *container.MultipleWindows
}

func (c *glCanvas) Capture() image.Image {
Expand Down Expand Up @@ -116,6 +118,9 @@ func (c *glCanvas) Resize(size fyne.Size) {
c.size = nearestSize
c.Unlock()

if c.webExtraWindows != nil {
c.webExtraWindows.Resize(size)
}
for _, overlay := range c.Overlays().List() {
if p, ok := overlay.(*widget.PopUp); ok {
// TODO: remove this when #707 is being addressed.
Expand Down
2 changes: 1 addition & 1 deletion internal/driver/glfw/loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func (d *gLDriver) runGL() {
w.shouldExpand = false
view := w.viewport
w.viewLock.Unlock()
if shouldExpand {
if shouldExpand && runtime.GOOS != "js" {
view.SetSize(w.shouldWidth, w.shouldHeight)
}
}
Expand Down
40 changes: 38 additions & 2 deletions internal/driver/glfw/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package glfw

import (
"context"
"image/color"
_ "image/png" // for the icon
"math"
"runtime"
"time"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/internal/app"
"fyne.io/fyne/v2/internal/build"
Expand Down Expand Up @@ -62,7 +65,9 @@ func (w *window) Resize(size fyne.Size) {
}
w.viewLock.Unlock()
w.requestedWidth, w.requestedHeight = width, height
w.view().SetSize(width, height)
if runtime.GOOS != "js" {
w.view().SetSize(width, height)
}
})
}

Expand Down Expand Up @@ -944,7 +949,38 @@ func (w *window) runOnMainWhenCreated(fn func()) {
}

func (d *gLDriver) CreateWindow(title string) fyne.Window {
return d.createWindow(title, true)
if runtime.GOOS != "js" {
return d.createWindow(title, true)
}

// handling multiple windows by overlaying on the root for web
var root fyne.Window
d.windowLock.RLock()
hasVisible := false
for _, w := range d.windows {
if w.(*window).visible {
hasVisible = true
root = w
break
}
}
d.windowLock.RUnlock()

if !hasVisible {
return d.createWindow(title, true)
}

c := root.Canvas().(*glCanvas)
multi := c.webExtraWindows
if multi == nil {
multi = container.NewMultipleWindows()
multi.Resize(c.Size())
c.webExtraWindows = multi
}
inner := container.NewInnerWindow(title, canvas.NewRectangle(color.Transparent))
multi.Add(inner)

return wrapInnerWindow(inner, root, d)
}

func (d *gLDriver) createWindow(title string, decorate bool) fyne.Window {
Expand Down
6 changes: 6 additions & 0 deletions internal/driver/glfw/window_desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/internal/build"
"fyne.io/fyne/v2/internal/driver/common"
Expand Down Expand Up @@ -811,3 +812,8 @@ func (w *window) view() *glfw.Window {
}
return w.viewport
}

// wrapInnerWindow is a no-op to match what the web driver provides
func wrapInnerWindow(*container.InnerWindow, fyne.Window, *gLDriver) fyne.Window {
return nil
}
Loading

0 comments on commit fcb4085

Please sign in to comment.