content: apply simplify cleanup
- commit
- 93cde2a4cc302183afda5ac716b4f9194d589057
- author
- brice · · 2026-04-22 13:16 UTC
- parent
- c21009b
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
4 files · +54 -22
M internal/infrastructure/cef/webview.go +4 -0
| @@ -952,12 +952,16 @@ func (wv *WebView) Destroy() { | |||
| 952 | 952 | wv.mu.Lock() | |
| 953 | 953 | wv.closeCallbacks = nil | |
| 954 | 954 | wv.navigationCallbacks = nil | |
| 955 | + | wv.openerMessageCallbacks = nil | |
| 956 | + | wv.openerNavigationCallbacks = nil | |
| 955 | 957 | wv.popupReadyToShow = nil | |
| 956 | 958 | wv.pendingNativePopups = nil | |
| 957 | 959 | wv.nativePopupParent = nil | |
| 958 | 960 | wv.nativePopupCandidate = false | |
| 959 | 961 | wv.nativePopupID = 0 | |
| 960 | 962 | wv.nativePopupFallbackStarted = false | |
| 963 | + | wv.popupOpenerBridgeParent = nil | |
| 964 | + | wv.popupOpenerBridgeParentURI = "" | |
| 961 | 965 | wv.mu.Unlock() | |
| 962 | 966 | wv.stopNativePopupFallbackTimer() | |
| 963 | 967 | wv.cancelSelectionDebounce() | |
| @@ -952,12 +952,16 @@ func (wv *WebView) Destroy() { | |||||
| 952 | wv.mu.Lock() | 952 | wv.mu.Lock() | ||
| 953 | wv.closeCallbacks = nil | 953 | wv.closeCallbacks = nil | ||
| 954 | wv.navigationCallbacks = nil | 954 | wv.navigationCallbacks = nil | ||
| 955 | + | wv.openerMessageCallbacks = nil | |||
| 956 | + | wv.openerNavigationCallbacks = nil | |||
| 955 | wv.popupReadyToShow = nil | 957 | wv.popupReadyToShow = nil | ||
| 956 | wv.pendingNativePopups = nil | 958 | wv.pendingNativePopups = nil | ||
| 957 | wv.nativePopupParent = nil | 959 | wv.nativePopupParent = nil | ||
| 958 | wv.nativePopupCandidate = false | 960 | wv.nativePopupCandidate = false | ||
| 959 | wv.nativePopupID = 0 | 961 | wv.nativePopupID = 0 | ||
| 960 | wv.nativePopupFallbackStarted = false | 962 | wv.nativePopupFallbackStarted = false | ||
| 963 | + | wv.popupOpenerBridgeParent = nil | |||
| 964 | + | wv.popupOpenerBridgeParentURI = "" | |||
| 961 | wv.mu.Unlock() | 965 | wv.mu.Unlock() | ||
| 962 | wv.stopNativePopupFallbackTimer() | 966 | wv.stopNativePopupFallbackTimer() | ||
| 963 | wv.cancelSelectionDebounce() | 967 | wv.cancelSelectionDebounce() | ||
M internal/infrastructure/cef/webview_popup_proxy.go +15 -10
| @@ -22,7 +22,10 @@ func (wv *WebView) syntheticPopupState(proxyID string) *syntheticPopupState { | |||
| 22 | 22 | ||
| 23 | 23 | wv.syntheticPopupMu.Lock() | |
| 24 | 24 | defer wv.syntheticPopupMu.Unlock() | |
| 25 | - | return wv.syntheticPopupStateLocked(proxyID) | |
| 25 | + | if wv.syntheticPopups == nil { | |
| 26 | + | return nil | |
| 27 | + | } | |
| 28 | + | return wv.syntheticPopups[proxyID] | |
| 26 | 29 | } | |
| 27 | 30 | ||
| 28 | 31 | func (wv *WebView) syntheticPopupStateLocked(proxyID string) *syntheticPopupState { | |
| @@ -134,12 +137,8 @@ func (wv *WebView) handleSyntheticPopupNavigate(proxyID, targetURL string) { | |||
| 134 | 137 | } | |
| 135 | 138 | ||
| 136 | 139 | trimmedURI := strings.TrimSpace(targetURL) | |
| 137 | - | state := wv.syntheticPopupState(proxyID) | |
| 138 | - | if state == nil { | |
| 139 | - | return | |
| 140 | - | } | |
| 141 | - | ||
| 142 | 140 | wv.syntheticPopupMu.Lock() | |
| 141 | + | state := wv.syntheticPopupStateLocked(proxyID) | |
| 143 | 142 | if state.Closed { | |
| 144 | 143 | wv.syntheticPopupMu.Unlock() | |
| 145 | 144 | return | |
| @@ -175,12 +174,18 @@ func (wv *WebView) handleSyntheticPopupClose(proxyID string) { | |||
| 175 | 174 | } | |
| 176 | 175 | ||
| 177 | 176 | wv.syntheticPopupMu.Lock() | |
| 178 | - | state := wv.syntheticPopupStateLocked(proxyID) | |
| 177 | + | if wv.syntheticPopups == nil { | |
| 178 | + | wv.syntheticPopupMu.Unlock() | |
| 179 | + | return | |
| 180 | + | } | |
| 181 | + | state := wv.syntheticPopups[proxyID] | |
| 182 | + | if state == nil { | |
| 183 | + | wv.syntheticPopupMu.Unlock() | |
| 184 | + | return | |
| 185 | + | } | |
| 179 | 186 | state.Closed = true | |
| 180 | 187 | popupWV := state.WebView | |
| 181 | - | if popupWV != nil { | |
| 182 | - | delete(wv.syntheticPopups, proxyID) | |
| 183 | - | } | |
| 188 | + | delete(wv.syntheticPopups, proxyID) | |
| 184 | 189 | wv.syntheticPopupMu.Unlock() | |
| 185 | 190 | if popupWV == nil { | |
| 186 | 191 | return | |
| @@ -22,7 +22,10 @@ func (wv *WebView) syntheticPopupState(proxyID string) *syntheticPopupState { | |||||
| 22 | 22 | ||||
| 23 | wv.syntheticPopupMu.Lock() | 23 | wv.syntheticPopupMu.Lock() | ||
| 24 | defer wv.syntheticPopupMu.Unlock() | 24 | defer wv.syntheticPopupMu.Unlock() | ||
| 25 | - | return wv.syntheticPopupStateLocked(proxyID) | 25 | + | if wv.syntheticPopups == nil { |
| 26 | + | return nil | |||
| 27 | + | } | |||
| 28 | + | return wv.syntheticPopups[proxyID] | |||
| 26 | } | 29 | } | ||
| 27 | 30 | ||||
| 28 | func (wv *WebView) syntheticPopupStateLocked(proxyID string) *syntheticPopupState { | 31 | func (wv *WebView) syntheticPopupStateLocked(proxyID string) *syntheticPopupState { | ||
| @@ -134,12 +137,8 @@ func (wv *WebView) handleSyntheticPopupNavigate(proxyID, targetURL string) { | |||||
| 134 | } | 137 | } | ||
| 135 | 138 | ||||
| 136 | trimmedURI := strings.TrimSpace(targetURL) | 139 | trimmedURI := strings.TrimSpace(targetURL) | ||
| 137 | - | state := wv.syntheticPopupState(proxyID) | |||
| 138 | - | if state == nil { | |||
| 139 | - | return | |||
| 140 | - | } | |||
| 141 | - | ||||
| 142 | wv.syntheticPopupMu.Lock() | 140 | wv.syntheticPopupMu.Lock() | ||
| 141 | + | state := wv.syntheticPopupStateLocked(proxyID) | |||
| 143 | if state.Closed { | 142 | if state.Closed { | ||
| 144 | wv.syntheticPopupMu.Unlock() | 143 | wv.syntheticPopupMu.Unlock() | ||
| 145 | return | 144 | return | ||
| @@ -175,12 +174,18 @@ func (wv *WebView) handleSyntheticPopupClose(proxyID string) { | |||||
| 175 | } | 174 | } | ||
| 176 | 175 | ||||
| 177 | wv.syntheticPopupMu.Lock() | 176 | wv.syntheticPopupMu.Lock() | ||
| 178 | - | state := wv.syntheticPopupStateLocked(proxyID) | 177 | + | if wv.syntheticPopups == nil { |
| 178 | + | wv.syntheticPopupMu.Unlock() | |||
| 179 | + | return | |||
| 180 | + | } | |||
| 181 | + | state := wv.syntheticPopups[proxyID] | |||
| 182 | + | if state == nil { | |||
| 183 | + | wv.syntheticPopupMu.Unlock() | |||
| 184 | + | return | |||
| 185 | + | } | |||
| 179 | state.Closed = true | 186 | state.Closed = true | ||
| 180 | popupWV := state.WebView | 187 | popupWV := state.WebView | ||
| 181 | - | if popupWV != nil { | 188 | + | delete(wv.syntheticPopups, proxyID) |
| 182 | - | delete(wv.syntheticPopups, proxyID) | |||
| 183 | - | } | |||
| 184 | wv.syntheticPopupMu.Unlock() | 189 | wv.syntheticPopupMu.Unlock() | ||
| 185 | if popupWV == nil { | 190 | if popupWV == nil { | ||
| 186 | return | 191 | return | ||
M internal/ui/coordinator/content/coordinator.go +23 -2
| @@ -29,8 +29,9 @@ type Coordinator struct { | |||
| 29 | 29 | settingsApplier port.SettingsApplier // optional: nil if engine doesn't support | |
| 30 | 30 | filterApplier port.FilterApplier // optional: nil if engine doesn't support | |
| 31 | 31 | ||
| 32 | - | webViews map[entity.PaneID]port.WebView | |
| 33 | - | webViewsMu sync.RWMutex | |
| 32 | + | webViews map[entity.PaneID]port.WebView | |
| 33 | + | webViewPaneIDs map[port.WebViewID]entity.PaneID | |
| 34 | + | webViewsMu sync.RWMutex | |
| 34 | 35 | ||
| 35 | 36 | activePaneOverride entity.PaneID | |
| 36 | 37 | activePaneOverrideMu sync.RWMutex | |
| @@ -165,6 +166,7 @@ func NewCoordinator( | |||
| 165 | 166 | zoomUC: zoomUC, | |
| 166 | 167 | permissionUC: permissionUC, | |
| 167 | 168 | webViews: make(map[entity.PaneID]port.WebView), | |
| 169 | + | webViewPaneIDs: make(map[port.WebViewID]entity.PaneID), | |
| 168 | 170 | paneTitles: make(map[entity.PaneID]string), | |
| 169 | 171 | navOrigins: make(map[entity.PaneID]string), | |
| 170 | 172 | pendingReveal: make(map[entity.PaneID]bool), | |
| @@ -311,7 +313,16 @@ func (c *Coordinator) getWebViewLocked(paneID entity.PaneID) port.WebView { | |||
| 311 | 313 | ||
| 312 | 314 | func (c *Coordinator) setWebViewLocked(paneID entity.PaneID, wv port.WebView) { | |
| 313 | 315 | c.webViewsMu.Lock() | |
| 316 | + | if c.webViews == nil { | |
| 317 | + | c.webViews = make(map[entity.PaneID]port.WebView) | |
| 318 | + | } | |
| 319 | + | if existing := c.webViews[paneID]; existing != nil && c.webViewPaneIDs != nil { | |
| 320 | + | delete(c.webViewPaneIDs, existing.ID()) | |
| 321 | + | } | |
| 314 | 322 | c.webViews[paneID] = wv | |
| 323 | + | if wv != nil && c.webViewPaneIDs != nil { | |
| 324 | + | c.webViewPaneIDs[wv.ID()] = paneID | |
| 325 | + | } | |
| 315 | 326 | c.webViewsMu.Unlock() | |
| 316 | 327 | } | |
| 317 | 328 | ||
| @@ -320,5 +331,15 @@ func (c *Coordinator) deleteWebViewLocked(paneID entity.PaneID) port.WebView { | |||
| 320 | 331 | defer c.webViewsMu.Unlock() | |
| 321 | 332 | wv := c.webViews[paneID] | |
| 322 | 333 | delete(c.webViews, paneID) | |
| 334 | + | if wv != nil && c.webViewPaneIDs != nil { | |
| 335 | + | delete(c.webViewPaneIDs, wv.ID()) | |
| 336 | + | } | |
| 323 | 337 | return wv | |
| 324 | 338 | } | |
| 339 | + | ||
| 340 | + | func (c *Coordinator) paneIDByWebViewID(webViewID port.WebViewID) (entity.PaneID, bool) { | |
| 341 | + | c.webViewsMu.RLock() | |
| 342 | + | defer c.webViewsMu.RUnlock() | |
| 343 | + | paneID, ok := c.webViewPaneIDs[webViewID] | |
| 344 | + | return paneID, ok | |
| 345 | + | } | |
| @@ -29,8 +29,9 @@ type Coordinator struct { | |||||
| 29 | settingsApplier port.SettingsApplier // optional: nil if engine doesn't support | 29 | settingsApplier port.SettingsApplier // optional: nil if engine doesn't support | ||
| 30 | filterApplier port.FilterApplier // optional: nil if engine doesn't support | 30 | filterApplier port.FilterApplier // optional: nil if engine doesn't support | ||
| 31 | 31 | ||||
| 32 | - | webViews map[entity.PaneID]port.WebView | 32 | + | webViews map[entity.PaneID]port.WebView |
| 33 | - | webViewsMu sync.RWMutex | 33 | + | webViewPaneIDs map[port.WebViewID]entity.PaneID |
| 34 | + | webViewsMu sync.RWMutex | |||
| 34 | 35 | ||||
| 35 | activePaneOverride entity.PaneID | 36 | activePaneOverride entity.PaneID | ||
| 36 | activePaneOverrideMu sync.RWMutex | 37 | activePaneOverrideMu sync.RWMutex | ||
| @@ -165,6 +166,7 @@ func NewCoordinator( | |||||
| 165 | zoomUC: zoomUC, | 166 | zoomUC: zoomUC, | ||
| 166 | permissionUC: permissionUC, | 167 | permissionUC: permissionUC, | ||
| 167 | webViews: make(map[entity.PaneID]port.WebView), | 168 | webViews: make(map[entity.PaneID]port.WebView), | ||
| 169 | + | webViewPaneIDs: make(map[port.WebViewID]entity.PaneID), | |||
| 168 | paneTitles: make(map[entity.PaneID]string), | 170 | paneTitles: make(map[entity.PaneID]string), | ||
| 169 | navOrigins: make(map[entity.PaneID]string), | 171 | navOrigins: make(map[entity.PaneID]string), | ||
| 170 | pendingReveal: make(map[entity.PaneID]bool), | 172 | pendingReveal: make(map[entity.PaneID]bool), | ||
| @@ -311,7 +313,16 @@ func (c *Coordinator) getWebViewLocked(paneID entity.PaneID) port.WebView { | |||||
| 311 | 313 | ||||
| 312 | func (c *Coordinator) setWebViewLocked(paneID entity.PaneID, wv port.WebView) { | 314 | func (c *Coordinator) setWebViewLocked(paneID entity.PaneID, wv port.WebView) { | ||
| 313 | c.webViewsMu.Lock() | 315 | c.webViewsMu.Lock() | ||
| 316 | + | if c.webViews == nil { | |||
| 317 | + | c.webViews = make(map[entity.PaneID]port.WebView) | |||
| 318 | + | } | |||
| 319 | + | if existing := c.webViews[paneID]; existing != nil && c.webViewPaneIDs != nil { | |||
| 320 | + | delete(c.webViewPaneIDs, existing.ID()) | |||
| 321 | + | } | |||
| 314 | c.webViews[paneID] = wv | 322 | c.webViews[paneID] = wv | ||
| 323 | + | if wv != nil && c.webViewPaneIDs != nil { | |||
| 324 | + | c.webViewPaneIDs[wv.ID()] = paneID | |||
| 325 | + | } | |||
| 315 | c.webViewsMu.Unlock() | 326 | c.webViewsMu.Unlock() | ||
| 316 | } | 327 | } | ||
| 317 | 328 | ||||
| @@ -320,5 +331,15 @@ func (c *Coordinator) deleteWebViewLocked(paneID entity.PaneID) port.WebView { | |||||
| 320 | defer c.webViewsMu.Unlock() | 331 | defer c.webViewsMu.Unlock() | ||
| 321 | wv := c.webViews[paneID] | 332 | wv := c.webViews[paneID] | ||
| 322 | delete(c.webViews, paneID) | 333 | delete(c.webViews, paneID) | ||
| 334 | + | if wv != nil && c.webViewPaneIDs != nil { | |||
| 335 | + | delete(c.webViewPaneIDs, wv.ID()) | |||
| 336 | + | } | |||
| 323 | return wv | 337 | return wv | ||
| 324 | } | 338 | } | ||
| 339 | + | ||||
| 340 | + | func (c *Coordinator) paneIDByWebViewID(webViewID port.WebViewID) (entity.PaneID, bool) { | |||
| 341 | + | c.webViewsMu.RLock() | |||
| 342 | + | defer c.webViewsMu.RUnlock() | |||
| 343 | + | paneID, ok := c.webViewPaneIDs[webViewID] | |||
| 344 | + | return paneID, ok | |||
| 345 | + | } | |||
M internal/ui/coordinator/content/popup.go +12 -10
| @@ -704,18 +704,20 @@ func (c *Coordinator) handlePopupClose(ctx context.Context, popupID port.WebView | |||
| 704 | 704 | return | |
| 705 | 705 | } | |
| 706 | 706 | ||
| 707 | - | // Find pane by WebView ID | |
| 708 | - | var paneID entity.PaneID | |
| 709 | - | c.webViewsMu.RLock() | |
| 710 | - | for pid, wv := range c.webViews { | |
| 711 | - | if wv != nil && wv.ID() == popupID { | |
| 712 | - | paneID = pid | |
| 713 | - | break | |
| 707 | + | // Find pane by WebView ID. | |
| 708 | + | paneID, ok := c.paneIDByWebViewID(popupID) | |
| 709 | + | if (!ok || paneID == "") && popupID != 0 { | |
| 710 | + | c.webViewsMu.RLock() | |
| 711 | + | for pid, wv := range c.webViews { | |
| 712 | + | if wv != nil && wv.ID() == popupID { | |
| 713 | + | paneID = pid | |
| 714 | + | ok = true | |
| 715 | + | break | |
| 716 | + | } | |
| 714 | 717 | } | |
| 718 | + | c.webViewsMu.RUnlock() | |
| 715 | 719 | } | |
| 716 | - | c.webViewsMu.RUnlock() | |
| 717 | - | ||
| 718 | - | if paneID == "" { | |
| 720 | + | if !ok || paneID == "" { | |
| 719 | 721 | c.handlePopupOAuthClose(ctx, popupID) | |
| 720 | 722 | c.clearReusableNamedPopupByWebViewID(popupID) | |
| 721 | 723 | log.Warn().Msg("popup close: could not find pane for webview") | |
| @@ -704,18 +704,20 @@ func (c *Coordinator) handlePopupClose(ctx context.Context, popupID port.WebView | |||||
| 704 | return | 704 | return | ||
| 705 | } | 705 | } | ||
| 706 | 706 | ||||
| 707 | - | // Find pane by WebView ID | 707 | + | // Find pane by WebView ID. |
| 708 | - | var paneID entity.PaneID | 708 | + | paneID, ok := c.paneIDByWebViewID(popupID) |
| 709 | - | c.webViewsMu.RLock() | 709 | + | if (!ok || paneID == "") && popupID != 0 { |
| 710 | - | for pid, wv := range c.webViews { | 710 | + | c.webViewsMu.RLock() |
| 711 | - | if wv != nil && wv.ID() == popupID { | 711 | + | for pid, wv := range c.webViews { |
| 712 | - | paneID = pid | 712 | + | if wv != nil && wv.ID() == popupID { |
| 713 | - | break | 713 | + | paneID = pid |
| 714 | + | ok = true | |||
| 715 | + | break | |||
| 716 | + | } | |||
| 714 | } | 717 | } | ||
| 718 | + | c.webViewsMu.RUnlock() | |||
| 715 | } | 719 | } | ||
| 716 | - | c.webViewsMu.RUnlock() | 720 | + | if !ok || paneID == "" { |
| 717 | - | ||||
| 718 | - | if paneID == "" { | |||
| 719 | c.handlePopupOAuthClose(ctx, popupID) | 721 | c.handlePopupOAuthClose(ctx, popupID) | ||
| 720 | c.clearReusableNamedPopupByWebViewID(popupID) | 722 | c.clearReusableNamedPopupByWebViewID(popupID) | ||
| 721 | log.Warn().Msg("popup close: could not find pane for webview") | 723 | log.Warn().Msg("popup close: could not find pane for webview") | ||