[client] Seed a cold main window with its target URL

ShowMainAt created the main window with URL "/" and navigated with SetURL
right after; if the initial load is dispatched asynchronously the two can
race and strand the user on "/". The main-window factory now takes the
start URL, so a cold window is built directly on the requested page and
SetURL only runs on an already-live window.
This commit is contained in:
Zoltán Papp
2026-08-18 15:17:51 +02:00
parent 2070a1b9ce
commit d6a8ebe7d3
2 changed files with 25 additions and 13 deletions

View File

@@ -140,8 +140,8 @@ func main() {
})
windowManager := services.NewWindowManager(app, nil, bundle, prefStore, iconWindow)
windowManager.SetMainFactory(func() *application.WebviewWindow {
return newMainWindow(app, prefStore, windowManager)
windowManager.SetMainFactory(func(startURL string) *application.WebviewWindow {
return newMainWindow(app, prefStore, windowManager, startURL)
})
registerDockReopenHook(app, windowManager)
// Minimal WMs (XEmbed-tray path) neither center small windows nor restore
@@ -338,7 +338,7 @@ func registerServices(app *application.App, conn *Conn, s registeredServices) {
app.RegisterService(application.NewService(s.compat))
}
func newMainWindow(app *application.App, prefStore *preferences.Store, wm *services.WindowManager) *application.WebviewWindow {
func newMainWindow(app *application.App, prefStore *preferences.Store, wm *services.WindowManager, startURL string) *application.WebviewWindow {
// Width matches the last view mode so Advanced-mode users don't see the
// window pop from 380px to 900px on launch. Height is mode-agnostic.
initialWidth := 380
@@ -355,7 +355,7 @@ func newMainWindow(app *application.App, prefStore *preferences.Store, wm *servi
InitialPosition: application.WindowCentered,
Hidden: true,
BackgroundColour: services.WindowBackgroundColour,
URL: "/",
URL: startURL,
DisableResize: true,
MinimiseButtonState: application.ButtonHidden,
MaximiseButtonState: application.ButtonHidden,

View File

@@ -115,7 +115,7 @@ type WindowManager struct {
hiddenForLogin []application.Window
mu sync.Mutex
createMu sync.Mutex
newMain func() *application.WebviewWindow
newMain func(startURL string) *application.WebviewWindow
ready map[uint]bool
showPending map[uint]bool
pendingTab map[uint]string
@@ -192,7 +192,7 @@ func (s *WindowManager) OpenSettings(tab string) {
target = "general"
}
w := s.ensureWindow(&s.settings, s.newSettingsWindow)
w, _ := s.ensureWindow(&s.settings, s.newSettingsWindow)
s.mu.Lock()
ready := s.ready[w.ID()]
@@ -494,13 +494,23 @@ func (s *WindowManager) ShowMainAndEmit(event string) {
}
func (s *WindowManager) MainWindow() *application.WebviewWindow {
w, _ := s.ensureMain("/")
return w
}
func (s *WindowManager) ensureMain(startURL string) (*application.WebviewWindow, bool) {
s.mu.Lock()
factory := s.newMain
s.mu.Unlock()
return s.ensureWindow(&s.mainWindow, factory)
if factory == nil {
return s.ensureWindow(&s.mainWindow, nil)
}
return s.ensureWindow(&s.mainWindow, func() *application.WebviewWindow {
return factory(startURL)
})
}
func (s *WindowManager) ensureWindow(slot **application.WebviewWindow, factory func() *application.WebviewWindow) *application.WebviewWindow {
func (s *WindowManager) ensureWindow(slot **application.WebviewWindow, factory func() *application.WebviewWindow) (*application.WebviewWindow, bool) {
s.createMu.Lock()
defer s.createMu.Unlock()
@@ -508,7 +518,7 @@ func (s *WindowManager) ensureWindow(slot **application.WebviewWindow, factory f
w := *slot
s.mu.Unlock()
if w != nil || factory == nil {
return w
return w, false
}
w = factory()
@@ -517,7 +527,7 @@ func (s *WindowManager) ensureWindow(slot **application.WebviewWindow, factory f
s.mu.Lock()
*slot = w
s.mu.Unlock()
return w
return w, true
}
func (s *WindowManager) armReady(w *application.WebviewWindow) {
@@ -639,15 +649,17 @@ func (s *WindowManager) showNow(w *application.WebviewWindow) {
}
func (s *WindowManager) ShowMainAt(url string) {
w := s.MainWindow()
w, created := s.ensureMain(url)
if w == nil {
return
}
w.SetURL(url)
if !created {
w.SetURL(url)
}
s.showWhenReady(w)
}
func (s *WindowManager) SetMainFactory(f func() *application.WebviewWindow) {
func (s *WindowManager) SetMainFactory(f func(startURL string) *application.WebviewWindow) {
s.mu.Lock()
defer s.mu.Unlock()
s.newMain = f