Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions internal/ui/coordinator/content/content_reveal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,22 @@ func TestRevealState_IsBoundToCurrentWebViewAcrossReplacementPaths(t *testing.T)
assert.False(t, c.WebViewRevealed(paneID), "popup registration must not inherit a prior WebView reveal")
}

func TestRevealState_StoresIdentityAsTheOnlyStateValue(t *testing.T) {
paneID := entity.PaneID("pane-1")
wv := revealTestWebView(t, 101, 1)
c := newRevealTestCoordinator()
c.setWebViewLocked(paneID, wv)
identity, _ := identityForWebView(wv)

c.markPendingReveal(paneID, identity)
c.markWebViewRevealed(paneID, identity)

c.revealMu.Lock()
defer c.revealMu.Unlock()
assert.Equal(t, identity, c.pendingReveal[paneID])
assert.Equal(t, identity, c.revealedWebViews[paneID])
}

func TestRevealState_ReleaseClearsStateWithoutWebViewMapping(t *testing.T) {
paneID := entity.PaneID("pane-1")
wv := revealTestWebView(t, 101, 1)
Expand Down
58 changes: 22 additions & 36 deletions internal/ui/coordinator/content/coordinator.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,9 @@ type Coordinator struct {

// revealMu is always acquired after webViewsMu. Reveal state is keyed by the
// WebView identity (ID plus pool-reuse generation), never by pane alone.
revealMu sync.Mutex
pendingReveal map[entity.PaneID]bool
revealedWebViews map[entity.PaneID]bool
revealedWebViewIdentity map[entity.PaneID]webViewIdentity
pendingRevealIdentity map[entity.PaneID]webViewIdentity
revealMu sync.Mutex
pendingReveal map[entity.PaneID]webViewIdentity
revealedWebViews map[entity.PaneID]webViewIdentity

appearanceMu sync.Mutex
pendingScriptRefresh map[entity.PaneID]bool
Expand Down Expand Up @@ -149,25 +147,23 @@ func NewCoordinator(
log.Debug().Msg("creating content coordinator")

return &Coordinator{
logger: log.With().Str("component", "content-coordinator").Logger(),
pool: pool,
injector: injector,
widgetFactory: widgetFactory,
faviconAdapter: faviconAdapter,
zoomUC: zoomUC,
permissionUC: permissionUC,
webViews: make(map[entity.PaneID]port.WebView),
webViewPaneIDs: make(map[port.WebViewID]entity.PaneID),
paneTitles: make(map[entity.PaneID]string),
navOrigins: make(map[entity.PaneID]string),
pendingReveal: make(map[entity.PaneID]bool),
revealedWebViews: make(map[entity.PaneID]bool),
revealedWebViewIdentity: make(map[entity.PaneID]webViewIdentity),
pendingRevealIdentity: make(map[entity.PaneID]webViewIdentity),
pendingScriptRefresh: make(map[entity.PaneID]bool),
pendingThemePanes: make(map[entity.PaneID]bool),
getActiveWS: getActiveWS,
popups: newPopupManager(),
logger: log.With().Str("component", "content-coordinator").Logger(),
pool: pool,
injector: injector,
widgetFactory: widgetFactory,
faviconAdapter: faviconAdapter,
zoomUC: zoomUC,
permissionUC: permissionUC,
webViews: make(map[entity.PaneID]port.WebView),
webViewPaneIDs: make(map[port.WebViewID]entity.PaneID),
paneTitles: make(map[entity.PaneID]string),
navOrigins: make(map[entity.PaneID]string),
pendingReveal: make(map[entity.PaneID]webViewIdentity),
revealedWebViews: make(map[entity.PaneID]webViewIdentity),
pendingScriptRefresh: make(map[entity.PaneID]bool),
pendingThemePanes: make(map[entity.PaneID]bool),
getActiveWS: getActiveWS,
popups: newPopupManager(),
}
}

Expand Down Expand Up @@ -334,16 +330,10 @@ func identityForWebView(wv port.WebView) (webViewIdentity, bool) {

func (c *Coordinator) ensureRevealMapsLocked() {
if c.pendingReveal == nil {
c.pendingReveal = make(map[entity.PaneID]bool)
c.pendingReveal = make(map[entity.PaneID]webViewIdentity)
}
if c.revealedWebViews == nil {
c.revealedWebViews = make(map[entity.PaneID]bool)
}
if c.revealedWebViewIdentity == nil {
c.revealedWebViewIdentity = make(map[entity.PaneID]webViewIdentity)
}
if c.pendingRevealIdentity == nil {
c.pendingRevealIdentity = make(map[entity.PaneID]webViewIdentity)
c.revealedWebViews = make(map[entity.PaneID]webViewIdentity)
}
}

Expand All @@ -368,9 +358,7 @@ func (c *Coordinator) setWebViewLocked(paneID entity.PaneID, wv port.WebView) {
}
c.ensureRevealMapsLocked()
delete(c.pendingReveal, paneID)
delete(c.pendingRevealIdentity, paneID)
delete(c.revealedWebViews, paneID)
delete(c.revealedWebViewIdentity, paneID)
}

// deleteWebViewLocked removes both the mapping and any presentation state,
Expand All @@ -389,9 +377,7 @@ func (c *Coordinator) deleteWebViewLocked(paneID entity.PaneID) port.WebView {
}
c.ensureRevealMapsLocked()
delete(c.pendingReveal, paneID)
delete(c.pendingRevealIdentity, paneID)
delete(c.revealedWebViews, paneID)
delete(c.revealedWebViewIdentity, paneID)
return wv
}

Expand Down
17 changes: 8 additions & 9 deletions internal/ui/coordinator/content/navigation.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,20 +255,19 @@ func (c *Coordinator) markPendingReveal(paneID entity.PaneID, identity webViewId
return
}
c.ensureRevealMapsLocked()
c.pendingReveal[paneID] = true
c.pendingRevealIdentity[paneID] = identity
c.pendingReveal[paneID] = identity
}

func (c *Coordinator) clearPendingReveal(paneID entity.PaneID, identity webViewIdentity) {
c.webViewsMu.RLock()
c.revealMu.Lock()
defer c.revealMu.Unlock()
defer c.webViewsMu.RUnlock()
if c.pendingRevealIdentity[paneID] != identity {
pendingIdentity, pending := c.pendingReveal[paneID]
if !pending || pendingIdentity != identity {
return
}
delete(c.pendingReveal, paneID)
delete(c.pendingRevealIdentity, paneID)
}

// WebViewRevealed reports whether this pane's current WebView has completed a
Expand All @@ -293,7 +292,8 @@ func (c *Coordinator) webViewRevealed(paneID entity.PaneID, expected port.WebVie
return false
}
}
return c.revealedWebViews[paneID] && c.revealedWebViewIdentity[paneID] == identity
revealedIdentity, revealed := c.revealedWebViews[paneID]
return revealed && revealedIdentity == identity
}

func (c *Coordinator) markWebViewRevealed(paneID entity.PaneID, identity webViewIdentity) bool {
Expand All @@ -306,8 +306,7 @@ func (c *Coordinator) markWebViewRevealed(paneID entity.PaneID, identity webView
return false
}
c.ensureRevealMapsLocked()
c.revealedWebViews[paneID] = true
c.revealedWebViewIdentity[paneID] = identity
c.revealedWebViews[paneID] = identity
return true
}

Expand All @@ -321,7 +320,8 @@ func (c *Coordinator) revealIfPending(

c.webViewsMu.RLock()
c.revealMu.Lock()
if c.pendingRevealIdentity[paneID] != identity || !c.pendingReveal[paneID] {
pendingIdentity, pending := c.pendingReveal[paneID]
if !pending || pendingIdentity != identity {
c.revealMu.Unlock()
c.webViewsMu.RUnlock()
c.revealMutationMu.Unlock()
Expand All @@ -335,7 +335,6 @@ func (c *Coordinator) revealIfPending(
return
}
delete(c.pendingReveal, paneID)
delete(c.pendingRevealIdentity, paneID)
c.revealMu.Unlock()
c.webViewsMu.RUnlock()

Expand Down