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

Fix window creation thread handling #5328

Merged
merged 13 commits into from
Dec 22, 2024
2 changes: 1 addition & 1 deletion internal/driver/glfw/canvas.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type glCanvas struct {

func (c *glCanvas) Capture() image.Image {
var img image.Image
runOnMainWithContext(c.context.(*window), func() {
c.context.(*window).RunWithContext(func() {
img = c.Painter().Capture(c)
})
return img
Expand Down
12 changes: 4 additions & 8 deletions internal/driver/glfw/clipboard_goxjs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
package glfw

import (
"fyne.io/fyne/v2"
glfw "github.com/fyne-io/glfw-js"

"fyne.io/fyne/v2"
)

// Declare conformity with Clipboard interface
Expand All @@ -21,16 +22,11 @@ type clipboard struct {

// Content returns the clipboard content
func (c clipboard) Content() string {
content := ""
runOnMain(func() {
content, _ = c.window.GetClipboardString()
})
content, _ := c.window.GetClipboardString()
return content
}

// SetContent sets the clipboard content
func (c clipboard) SetContent(content string) {
runOnMain(func() {
c.window.SetClipboardString(content)
})
c.window.SetClipboardString(content)
}
20 changes: 4 additions & 16 deletions internal/driver/glfw/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"image"
"os"
"runtime"
"sync"

"github.com/fyne-io/image/ico"

Expand All @@ -33,10 +32,8 @@ var curWindow *window
var _ fyne.Driver = (*gLDriver)(nil)

type gLDriver struct {
windowLock sync.RWMutex
windows []fyne.Window
done chan struct{}
waitForStart chan struct{}
windows []fyne.Window
done chan struct{}

animation animation.Runner

Expand Down Expand Up @@ -104,21 +101,15 @@ func (d *gLDriver) Quit() {
}

func (d *gLDriver) addWindow(w *window) {
d.windowLock.Lock()
defer d.windowLock.Unlock()
d.windows = append(d.windows, w)
}

// a trivial implementation of "focus previous" - return to the most recently opened, or master if set.
// This may not do the right thing if your app has 3 or more windows open, but it was agreed this was not much
// of an issue, and the added complexity to track focus was not needed at this time.
func (d *gLDriver) focusPreviousWindow() {
d.windowLock.RLock()
wins := d.windows
d.windowLock.RUnlock()

var chosen *window
for _, w := range wins {
for _, w := range d.windows {
win := w.(*window)
if !win.visible {
continue
Expand All @@ -136,8 +127,6 @@ func (d *gLDriver) focusPreviousWindow() {
}

func (d *gLDriver) windowList() []fyne.Window {
d.windowLock.RLock()
defer d.windowLock.RUnlock()
return d.windows
}

Expand Down Expand Up @@ -174,7 +163,6 @@ func NewGLDriver() *gLDriver {
repository.Register("file", intRepo.NewFileRepository())

return &gLDriver{
done: make(chan struct{}),
waitForStart: make(chan struct{}),
done: make(chan struct{}),
}
}
26 changes: 12 additions & 14 deletions internal/driver/glfw/driver_desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ func (d *gLDriver) SetSystemTrayMenu(m *fyne.Menu) {
}

// it must be refreshed after init, so an earlier call would have been ineffective
d.refreshSystray(m)
runOnMain(func() {
d.refreshSystray(m)
})
}, func() {
// anything required for tear-down
})
Expand Down Expand Up @@ -135,14 +137,12 @@ func itemForMenuItem(i *fyne.MenuItem, parent *systray.MenuItem) *systray.MenuIt
}

func (d *gLDriver) refreshSystray(m *fyne.Menu) {
runOnMain(func() {
d.systrayMenu = m
d.systrayMenu = m

systray.ResetMenu()
d.refreshSystrayMenu(m, nil)
systray.ResetMenu()
d.refreshSystrayMenu(m, nil)

addMissingQuitForMenu(m, d)
})
addMissingQuitForMenu(m, d)
}

func (d *gLDriver) refreshSystrayMenu(m *fyne.Menu, parent *systray.MenuItem) {
Expand Down Expand Up @@ -175,13 +175,11 @@ func (d *gLDriver) SetSystemTrayIcon(resource fyne.Resource) {
return
}

runOnMain(func() {
if _, ok := resource.(*theme.ThemedResource); ok {
systray.SetTemplateIcon(img, img)
} else {
systray.SetIcon(img)
}
})
if _, ok := resource.(*theme.ThemedResource); ok {
systray.SetTemplateIcon(img, img)
} else {
systray.SetIcon(img)
}
}

func (d *gLDriver) SystemTrayMenu() *fyne.Menu {
Expand Down
6 changes: 1 addition & 5 deletions internal/driver/glfw/glfw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,7 @@ func ensureCanvasSize(t *testing.T, w *window, size fyne.Size) {
}

func repaintWindow(w *window) {
// Wait for GLFW loop to be running.
// If we try to paint windows before the context is created, we will end up on the wrong thread.
<-w.driver.waitForStart

runOnMainWithContext(w, func() {
w.RunWithContext(func() {
d.repaintWindow(w)
})

Expand Down
12 changes: 2 additions & 10 deletions internal/driver/glfw/loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@ func runOnMain(f func()) {
<-done
}

// force a function f to run on the draw thread
func runOnMainWithContext(w *window, f func()) {
runOnMain(func() { w.RunWithContext(f) }) // TODO remove this completely
}

// Preallocate to avoid allocations on every drawSingleFrame.
// Note that the capacity of this slice can only grow,
// but its length will never be longer than the total number of
Expand Down Expand Up @@ -91,14 +86,13 @@ func (d *gLDriver) runGL() {
if !running.CompareAndSwap(false, true) {
return // Run was called twice.
}
close(d.waitForStart) // Signal that execution can continue.

d.initGLFW()
if d.trayStart != nil {
d.trayStart()
}
if f := fyne.CurrentApp().Lifecycle().(*app.Lifecycle).OnStarted(); f != nil {
go f() // don't block main, we don't have window event queue
f()
}

settingsChange := make(chan fyne.Settings)
Expand Down Expand Up @@ -172,9 +166,7 @@ func (d *gLDriver) runGL() {
newWindows = append(newWindows, win)
}

d.windowLock.Lock()
d.windows = newWindows
d.windowLock.Unlock()

if len(newWindows) == 0 {
d.Quit()
Expand All @@ -189,7 +181,7 @@ func (d *gLDriver) runGL() {
return
}
c.applyThemeOutOfTreeObjects()
go c.reloadScale()
c.reloadScale()
})

}
Expand Down
2 changes: 1 addition & 1 deletion internal/driver/glfw/loop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ func BenchmarkRunOnDraw(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
runOnMainWithContext(w, f)
w.RunWithContext(f)
}
}
Loading
Loading