Skip to content
Closed
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
6 changes: 3 additions & 3 deletions .github/swift-file-length-budget.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
17894 Sources/AppDelegate.swift
16714 Sources/ContentView.swift
14829 Sources/TerminalController.swift
13358 Sources/Panels/BrowserPanel.swift
13017 Sources/Workspace.swift
13381 Sources/Panels/BrowserPanel.swift
13048 Sources/Workspace.swift
12124 Sources/GhosttyTerminalView.swift
12115 cmuxTests/AppDelegateShortcutRoutingTests.swift
9331 cmuxTests/CLINotifyProcessIntegrationRegressionTests.swift
Expand Down Expand Up @@ -96,7 +96,7 @@
926 Sources/DockPanelView.swift
920 Sources/CommandPalette/CommandPaletteSettingsToggle.swift
918 cmuxTests/WorkspaceGroupTests.swift
912 Sources/WorkspaceContentView.swift
914 Sources/WorkspaceContentView.swift
905 Sources/CmuxSSHURLRequest.swift
901 Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/AppSection.swift
878 Sources/Panels/TerminalPanel.swift
Expand Down
22 changes: 18 additions & 4 deletions Sources/Canvas/CanvasPaneContent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ final class CanvasPaneContentMount: CanvasPaneContentMounting {
// to the pane hierarchy.
if let browserPanel = panel as? BrowserPanel {
browserPanel.canvasInlineHostingActive = true
_ = browserPanel.setWorkspaceVisibilityProtectsHiddenWebViewDiscard(
false,
reason: "canvas.mount"
)
browserPanel.noteWebViewVisibility(true, reason: "canvas.mount")
}
}
Expand Down Expand Up @@ -110,10 +114,16 @@ final class CanvasPaneContentMount: CanvasPaneContentMounting {
case .hosted(let panel, _):
// Offscreen browsers may hidden-discard their webview; coming
// back into the render region restores it.
(panel as? BrowserPanel)?.noteWebViewVisibility(
rendering,
reason: rendering ? "canvas.render" : "canvas.occlude"
)
if let browserPanel = panel as? BrowserPanel {
_ = browserPanel.setWorkspaceVisibilityProtectsHiddenWebViewDiscard(
false,
reason: rendering ? "canvas.render" : "canvas.occlude"
)
browserPanel.noteWebViewVisibility(
rendering,
reason: rendering ? "canvas.render" : "canvas.occlude"
)
}
}
}

Expand All @@ -129,6 +139,10 @@ final class CanvasPaneContentMount: CanvasPaneContentMounting {
case .hosted(let panel, let view):
if let browserPanel = panel as? BrowserPanel {
browserPanel.canvasInlineHostingActive = false
_ = browserPanel.setWorkspaceVisibilityProtectsHiddenWebViewDiscard(
false,
reason: "canvas.unmount"
)
browserPanel.noteWebViewVisibility(false, reason: "canvas.unmount")
}
view.removeFromSuperview()
Expand Down
44 changes: 44 additions & 0 deletions Sources/Panels/BrowserHiddenWebViewDiscardManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ protocol BrowserHiddenWebViewDiscardManagerDelegate: AnyObject {
final class BrowserHiddenWebViewDiscardManager {
struct BlockerSnapshot {
let isClosing: Bool
let isProtectedByWorkspaceVisibility: Bool
let isVisibleInUI: Bool
let shouldRenderWebView: Bool
let hasPendingRemoteNavigation: Bool
Expand All @@ -38,6 +39,48 @@ final class BrowserHiddenWebViewDiscardManager {
let hasPopups: Bool
let isCapturingMedia: Bool
let isPlayingMedia: Bool

init(
isClosing: Bool,
isProtectedByWorkspaceVisibility: Bool = false,
isVisibleInUI: Bool,
shouldRenderWebView: Bool,
hasPendingRemoteNavigation: Bool,
hasCurrentURL: Bool,
isLoading: Bool,
webViewIsLoading: Bool,
hasActiveMainFrameProvisionalNavigation: Bool,
isDownloading: Bool,
activeDownloadCount: Int,
preferredDeveloperToolsVisible: Bool,
isDeveloperToolsVisible: Bool,
isElementFullscreenActive: Bool,
isReactGrabActive: Bool,
isVisualAutomationCaptureActive: Bool,
hasPopups: Bool,
isCapturingMedia: Bool,
isPlayingMedia: Bool
) {
self.isClosing = isClosing
self.isProtectedByWorkspaceVisibility = isProtectedByWorkspaceVisibility
self.isVisibleInUI = isVisibleInUI
self.shouldRenderWebView = shouldRenderWebView
self.hasPendingRemoteNavigation = hasPendingRemoteNavigation
self.hasCurrentURL = hasCurrentURL
self.isLoading = isLoading
self.webViewIsLoading = webViewIsLoading
self.hasActiveMainFrameProvisionalNavigation = hasActiveMainFrameProvisionalNavigation
self.isDownloading = isDownloading
self.activeDownloadCount = activeDownloadCount
self.preferredDeveloperToolsVisible = preferredDeveloperToolsVisible
self.isDeveloperToolsVisible = isDeveloperToolsVisible
self.isElementFullscreenActive = isElementFullscreenActive
self.isReactGrabActive = isReactGrabActive
self.isVisualAutomationCaptureActive = isVisualAutomationCaptureActive
self.hasPopups = hasPopups
self.isCapturingMedia = isCapturingMedia
self.isPlayingMedia = isPlayingMedia
}
}

weak var delegate: BrowserHiddenWebViewDiscardManagerDelegate?
Expand Down Expand Up @@ -71,6 +114,7 @@ final class BrowserHiddenWebViewDiscardManager {
if isSystemSleeping { blockers.append("system_sleeping") }
if snapshot.isClosing { blockers.append("closing") }
if isDiscardedForMemory { blockers.append("already_discarded") }
if snapshot.isProtectedByWorkspaceVisibility { blockers.append("workspace_visible") }
if snapshot.isVisibleInUI { blockers.append("visible") }
if !snapshot.shouldRenderWebView { blockers.append("not_rendered") }
if snapshot.hasPendingRemoteNavigation { blockers.append("pending_remote_navigation") }
Expand Down
23 changes: 23 additions & 0 deletions Sources/Panels/BrowserPanel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3132,6 +3132,7 @@ final class BrowserPanel: Panel, ObservableObject {
private var pendingInteractiveBrowserPrompts: [PendingInteractiveBrowserPrompt] = []
private var isPresentingPendingInteractiveBrowserPrompt = false
private var isWebViewVisibleInUI: Bool = false
private var isProtectedByWorkspaceVisibilityForResourceCleanup: Bool = false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Stale flag if layout transitions don't call the reconciler

isProtectedByWorkspaceVisibilityForResourceCleanup is a cached copy of workspace-level state kept on BrowserPanel. Its correctness depends entirely on every layout transition eventually calling reconcileBrowserPortalVisibilityForCurrentRenderedLayout. There are currently three call sites (layout change, toggleSplitZoom, canvas layout), but if a future transition is added and the reconcile call is missed — or if a panel is moved between windows in a multi-window path that lacks its own reconcile call — the flag remains true and the panel is silently exempt from discard indefinitely. The source of truth (renderedVisiblePanelIdsForCurrentLayout) lives in Workspace, not in BrowserPanel, so the panel can represent the wrong visibility without any compile-time or runtime signal.

Rule Used: Flag Swift fixes that patch symptoms while leaving... (source)

private var isClosingWebViewLifecycle: Bool = false

/// True while a canvas pane hosts this browser's webview inline (in the
Expand Down Expand Up @@ -3453,6 +3454,23 @@ final class BrowserPanel: Panel, ObservableObject {
}
}

@discardableResult
func setWorkspaceVisibilityProtectsHiddenWebViewDiscard(
_ isProtected: Bool,
reason: String,
now: Date = Date()
) -> Bool {
guard isProtectedByWorkspaceVisibilityForResourceCleanup != isProtected else { return false }
isProtectedByWorkspaceVisibilityForResourceCleanup = isProtected
if !isProtected && !isWebViewVisibleInUI {
webViewLastHiddenAt = now
webViewLastVisibilityChangeAt = now
webViewLastVisibilityChangeReason = "workspace_visibility.\(reason)"
}
reevaluateHiddenWebViewDiscardScheduling(reason: "workspace_visibility.\(reason)")
return true
}

func webViewLifecycleTopPayload(now: Date = Date()) -> [String: Any] {
let discardBlockers = hiddenWebViewDiscardBlockers()
return [
Expand Down Expand Up @@ -6105,6 +6123,7 @@ extension BrowserPanel: BrowserHiddenWebViewDiscardManagerDelegate {
var hiddenWebViewDiscardSnapshot: BrowserHiddenWebViewDiscardManager.BlockerSnapshot {
BrowserHiddenWebViewDiscardManager.BlockerSnapshot(
isClosing: isClosingWebViewLifecycle,
isProtectedByWorkspaceVisibility: isProtectedByWorkspaceVisibilityForResourceCleanup,
isVisibleInUI: isWebViewVisibleInUI,
shouldRenderWebView: shouldRenderWebView,
hasPendingRemoteNavigation: pendingRemoteNavigation != nil,
Expand Down Expand Up @@ -8426,6 +8445,10 @@ private extension BrowserPanel {

extension BrowserPanel {
func hideBrowserPortalView(source: String) {
_ = setWorkspaceVisibilityProtectsHiddenWebViewDiscard(
false,
reason: "portal.\(source)"
)
Comment on lines +8448 to +8451

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don’t clear workspace protection from the generic portal-hide path.

Line 8442 removes the new blocker before recording the webview as hidden, so a workspace-visible browser can still become discard-eligible during the transient hide this PR is meant to tolerate. Clear this only from the authoritative workspace-retirement/removal path, not every portal hide.

🐛 Proposed fix
-    func hideBrowserPortalView(source: String) {
-        _ = setWorkspaceVisibilityProtectsHiddenWebViewDiscard(
-            false,
-            reason: "portal.\(source)"
-        )
+    func hideBrowserPortalView(
+        source: String,
+        clearWorkspaceVisibilityProtection: Bool = false
+    ) {
+        if clearWorkspaceVisibilityProtection {
+            _ = setWorkspaceVisibilityProtectsHiddenWebViewDiscard(
+                false,
+                reason: "portal.\(source)"
+            )
+        }
         noteWebViewVisibility(
             false,
             reason: "portal.\(source)",
             recordIfUnchanged: true
         )

Update the workspace-retirement caller to pass clearWorkspaceVisibilityProtection: true; leave transient portal hides at the default false.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/Panels/BrowserPanel.swift` around lines 8442 - 8445, The call to
setWorkspaceVisibilityProtectsHiddenWebViewDiscard in the generic portal-hide
path at line 8442 is prematurely clearing the workspace protection during
transient hides. Remove this call from the transient portal-hide path in
BrowserPanel.swift, and instead add a call to
setWorkspaceVisibilityProtectsHiddenWebViewDiscard with
clearWorkspaceVisibilityProtection: true in the authoritative
workspace-retirement or workspace-removal code path to ensure protection is only
cleared when the workspace is actually being retired or removed, not during
temporary portal visibility changes.

noteWebViewVisibility(
false,
reason: "portal.\(source)",
Expand Down
37 changes: 34 additions & 3 deletions Sources/Workspace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3656,6 +3656,7 @@ final class Workspace: Identifiable, ObservableObject {
private var layoutFollowUpStalledAttemptCount = 0
private var pendingReparentFocusSuppressionViews: [ObjectIdentifier: GhosttySurfaceScrollView] = [:]
private var portalRenderingEnabled = true
private var workspacePresentationVisible = false
private var agentHibernationAutoResumePresentationVisible = true
private var isAttemptingLayoutFollowUp = false
private var isNormalizingPinnedTabOrder = false
Expand Down Expand Up @@ -9882,6 +9883,12 @@ final class Workspace: Identifiable, ObservableObject {
reconcileTerminalPortalVisibilityForCurrentRenderedLayout()
}

func setWorkspacePresentationVisible(_ isVisible: Bool) {
guard workspacePresentationVisible != isVisible else { return }
workspacePresentationVisible = isVisible
reconcileBrowserPortalVisibilityForCurrentRenderedLayout(reason: "workspace.presentationVisibility")
}

// MARK: - Utility

/// Writes a small shell wrapper that keeps a disconnected remote terminal visible.
Expand Down Expand Up @@ -10611,6 +10618,10 @@ final class Workspace: Identifiable, ObservableObject {
return renderedVisiblePanelIdsForCurrentLayout()
}

private func presentationVisiblePanelIdsForCurrentLayout() -> Set<UUID> {
workspacePresentationVisible ? renderedVisiblePanelIdsForCurrentLayout() : []
}

@discardableResult
func reconcileTerminalPortalVisibilityForCurrentRenderedLayout() -> Bool {
let visiblePanelIds = renderedVisiblePanelIdsForCurrentLayout()
Expand Down Expand Up @@ -10674,15 +10685,29 @@ final class Workspace: Identifiable, ObservableObject {

@discardableResult
func reconcileBrowserPortalVisibilityForCurrentRenderedLayout(reason: String) -> Bool {
let visiblePanelIds = renderedVisiblePanelIdsForCurrentLayout()
let visiblePanelIds = presentationVisiblePanelIdsForCurrentLayout()
var didChange = false

for panel in panels.values {
guard let browserPanel = panel as? BrowserPanel else { continue }
// Canvas-inline-hosted webviews live in the pane hierarchy; portal
// rebinds/refreshes here would steal them back into the portal.
if browserPanel.canvasInlineHostingActive { continue }
if browserPanel.canvasInlineHostingActive {
if browserPanel.setWorkspaceVisibilityProtectsHiddenWebViewDiscard(
false,
reason: "canvasInline.\(reason)"
) {
didChange = true
}
continue
Comment on lines +10695 to +10702

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Skip canvas-inline browsers in the follow-up predicate too.

Line 10665 now intentionally bypasses portal reconciliation for canvasInlineHostingActive, but browserPortalVisibilityNeedsFollowUp() still expects those visible panels to be portal-bound. That mismatch can leave layout follow-up non-converging until timeout.

Proposed fix
     private func browserPortalVisibilityNeedsFollowUp() -> Bool {
         let visiblePanelIds = renderedVisiblePanelIdsForCurrentLayout()
 
         for panel in panels.values {
             guard let browserPanel = panel as? BrowserPanel else { continue }
+            if browserPanel.canvasInlineHostingActive { continue }
             guard visiblePanelIds.contains(browserPanel.id) else { continue }
             let anchorView = browserPanel.portalAnchorView

Also applies to: 10737-10750

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/Workspace.swift` around lines 10665 - 10672, The code at line 10665
intentionally bypasses portal reconciliation for canvas-inline browsers, but the
follow-up predicate browserPortalVisibilityNeedsFollowUp() (around lines
10737-10750) still expects those visible panels to be portal-bound, creating a
mismatch. Add a check in the browserPortalVisibilityNeedsFollowUp() predicate to
skip canvas-inline browsers (checking canvasInlineHostingActive) the same way
they are skipped during the main visibility update, so that layout follow-up
converges properly instead of timing out.

}
let shouldBeVisible = visiblePanelIds.contains(browserPanel.id)
if browserPanel.setWorkspaceVisibilityProtectsHiddenWebViewDiscard(
shouldBeVisible,
reason: reason
) {
didChange = true
}
Comment on lines +10704 to +10710

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Clear the workspace-visibility blocker when a tab is deselected.

reconcileBrowserPortalVisibilityForCurrentRenderedLayout updates the new blocker, but normal tab selection hides deselected browser portals through hideBrowserPortalsForDeselectedTabs without clearing it. A previously visible browser tab can therefore keep the "workspace_visible" blocker after it is hidden, suppressing hidden-WebView discard for inactive tabs.

Proposed fix
     private func hideBrowserPortalsForDeselectedTabs(inPane pane: PaneID, selectedTabId: TabID) {
         for tab in bonsplitController.tabs(inPane: pane) {
             guard tab.id != selectedTabId else { continue }
             guard let panelId = panelIdFromSurfaceId(tab.id),
                   let browserPanel = panels[panelId] as? BrowserPanel else { continue }
+            _ = browserPanel.setWorkspaceVisibilityProtectsHiddenWebViewDiscard(
+                false,
+                reason: "tabDeselected"
+            )
             browserPanel.hideBrowserPortalView(source: "tabDeselected")
         }
     }

Also applies to: 11541-11547

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/Workspace.swift` around lines 10667 - 10673, The workspace-visibility
blocker "workspace_visible" is not being cleared when browser tabs are
deselected, preventing hidden-WebView discard for inactive tabs. In the
`hideBrowserPortalsForDeselectedTabs` function (and the related location at
lines 11541-11547), when hiding deselected browser portals, call
`setWorkspaceVisibilityProtectsHiddenWebViewDiscard` with `shouldBeVisible` set
to false and an appropriate reason to clear the blocker, ensuring that
previously visible tabs don't retain the blocker after being hidden.

let anchorView = browserPanel.portalAnchorView
let snapshot = BrowserWindowPortalRegistry.debugSnapshot(for: browserPanel.webView)
if shouldBeVisible {
Expand Down Expand Up @@ -10737,7 +10762,7 @@ final class Workspace: Identifiable, ObservableObject {
}

private func browserPortalVisibilityNeedsFollowUp() -> Bool {
let visiblePanelIds = renderedVisiblePanelIdsForCurrentLayout()
let visiblePanelIds = presentationVisiblePanelIdsForCurrentLayout()

for panel in panels.values {
guard let browserPanel = panel as? BrowserPanel else { continue }
Expand All @@ -10759,6 +10784,12 @@ final class Workspace: Identifiable, ObservableObject {
return false
}

#if DEBUG
func debugBrowserPortalVisibilityNeedsFollowUpForTesting() -> Bool {
browserPortalVisibilityNeedsFollowUp()
}
#endif

private func scheduleMovedTerminalRefresh(panelId: UUID) {
guard terminalPanel(for: panelId) != nil else { return }

Expand Down
2 changes: 2 additions & 0 deletions Sources/WorkspaceContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ struct WorkspaceContentView: View {
updateAgentHibernationPresentationVisibility()
}
.onDisappear {
workspace.setWorkspacePresentationVisible(false)
workspace.setAgentHibernationAutoResumePresentationVisible(false)
}
.onChange(of: notificationStore.notifications) { _, _ in
Expand Down Expand Up @@ -626,6 +627,7 @@ struct WorkspaceContentView: View {
}

private func updateAgentHibernationPresentationVisibility() {
workspace.setWorkspacePresentationVisible(isWorkspaceVisible)
workspace.setAgentHibernationAutoResumePresentationVisible(isWorkspaceVisible && isWorkspaceInputActive)
}

Expand Down
4 changes: 4 additions & 0 deletions cmux.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
C0DE49870000000000000001 /* BrowserWebContentProcessTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DE49870000000000000002 /* BrowserWebContentProcessTests.swift */; };
C0DE58990000000000000003 /* BrowserWebKitKeyDownDispatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DE58990000000000000001 /* BrowserWebKitKeyDownDispatch.swift */; };
A5001534 /* BrowserWindowPortal.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5001533 /* BrowserWindowPortal.swift */; };
B6189001000000000000001 /* BrowserWorkspaceVisibleDiscardTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6189001000000000000002 /* BrowserWorkspaceVisibleDiscardTests.swift */; };
C0DE35530000000000000101 /* BundledCLILinkageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DE35530000000000000102 /* BundledCLILinkageTests.swift */; };
CA52B0010000000000000000 /* CanvasAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA52C0010000000000000000 /* CanvasAction.swift */; };
CA52B0050000000000000000 /* CanvasHostedPanelContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA52C0050000000000000000 /* CanvasHostedPanelContentView.swift */; };
Expand Down Expand Up @@ -1144,6 +1145,7 @@
C0DE49870000000000000002 /* BrowserWebContentProcessTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserWebContentProcessTests.swift; sourceTree = "<group>"; };
C0DE58990000000000000001 /* BrowserWebKitKeyDownDispatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Panels/BrowserWebKitKeyDownDispatch.swift; sourceTree = "<group>"; };
A5001533 /* BrowserWindowPortal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserWindowPortal.swift; sourceTree = "<group>"; };
B6189001000000000000002 /* BrowserWorkspaceVisibleDiscardTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserWorkspaceVisibleDiscardTests.swift; sourceTree = "<group>"; };
C0DE35530000000000000102 /* BundledCLILinkageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundledCLILinkageTests.swift; sourceTree = "<group>"; };
CA52C0010000000000000000 /* CanvasAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CanvasAction.swift"; sourceTree = "<group>"; };
CA52C0050000000000000000 /* CanvasHostedPanelContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CanvasHostedPanelContentView.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2804,6 +2806,7 @@
43F90FAF3FD44F11BF547BE9 /* CmuxWebViewMouseNavigationButtonTests.swift */,
D3622001A1B2C3D4E5F60718 /* BrowserArrowKeyForwardingTests.swift */,
D3622101A1B2C3D4E5F60718 /* EditableTextViewArrowKeyForwardingTests.swift */,
B6189001000000000000002 /* BrowserWorkspaceVisibleDiscardTests.swift */,
58C7B1B978620BE162CC057E /* BrowserPanelTests.swift */,
19D536229C6194FD62B44503 /* BrowserHistorySuggestionCacheTests.swift */,
48D6AE11906A4DF3BEB8CDFE /* OmnibarSubmitDecisionTests.swift */,
Expand Down Expand Up @@ -4092,6 +4095,7 @@
1F14445B9627DE9D3AF4FD2E /* BrowserPanelTests.swift in Sources */,
C7B800062D4202A13C962D2D /* BrowserSystemProxyMirrorTests.swift in Sources */,
C0DE49870000000000000001 /* BrowserWebContentProcessTests.swift in Sources */,
B6189001000000000000001 /* BrowserWorkspaceVisibleDiscardTests.swift in Sources */,
C0DE35530000000000000101 /* BundledCLILinkageTests.swift in Sources */,
F3000000A1B2C3D4E5F60718 /* CJKIMEInputTests.swift in Sources */,
D3571002A1B2C3D4E5F60718 /* CJKIMEMarkedSelectionTests.swift in Sources */,
Expand Down
Loading
Loading