Not logged in · Please run /login
[2026-05-21] vault sync
This commit is contained in:
@@ -25,14 +25,20 @@
|
||||
**Status:** ✅ Fixed *(2026-05-21)*
|
||||
**Repro:** UTI + experiment flags enabled → complete fire step → NTP shows "You've got this" completion dialog → subscription promo appears → dismiss promo → NTP is blank (no Dax background) and UTI address bar stays collapsed and inactive.
|
||||
**Root cause:** `showDuckAIOnboardingCompletionWithActiveAddressBar` calls `chromeDelegate?.omniBar.beginEditing(animated: true)` before showing the completion dialog. In non-UTI mode this creates an `OmniBarEditingStateViewController` (the modal editing state). In UTI mode there is no editing state VC; instead, `omniBar.beginEditing()` may present a conflicting modal OR trigger the UTI to enter `.aiTab(.expanded)` state, causing `coordinator.isOmnibarSession` to return `false` on the next run loop. `showDuckAIOnboardingCompletionDialog` then falls through to the `OmniBarEditingStateViewController` guard, fails, leaves `view.alpha = 0`, and shows no dialog. Additionally, after the subscription promo is dismissed, `launchNewSearch()` calls `omniBar.beginEditing()` which does not expand the UTI pill.
|
||||
**Fix:** In `showDuckAIOnboardingCompletionWithActiveAddressBar`, detect UTI omnibar mode and call `coordinator.activateInput()` instead of `omniBar.beginEditing()`. Same check in `launchNewSearch()`.
|
||||
**Fix:** In `launchNewSearch()` (called after subscription promo dismissal), detect `coordinator.isOmnibarSession` and call `coordinator.activateInput()` to re-show the keyboard without resetting the omnibar session. (The completion dialog activation path — `showDuckAIOnboardingCompletionWithActiveAddressBar` — was separately fixed in D2's follow-up: always use `omniBar.beginEditing()` which is correctly intercepted by the UTI.)
|
||||
**Files:** `NewTabPageViewController.swift`
|
||||
|
||||
### D2 — Trackers-blocked "Got it": dialog not dismissed on original tab + tab switcher broken *(2026-05-21)*
|
||||
**Status:** ✅ Fixed (same root cause as D1) *(2026-05-21)*
|
||||
**Repro:** UTI + experiment flags enabled + bottom bar position selected → visit a site (trackers detected) → trackers-blocked dialog appears → tap "Got it" → new NTP tab is opened, but the dialog in the original website tab is not dismissed, and the tab switcher button on the new NTP is non-functional.
|
||||
**Root cause (hypothesis):** `showDuckAIOnboardingCompletionWithActiveAddressBar` calls `omniBar.beginEditing()` which in UTI mode may present an `OmniBarEditingStateViewController` on top of the view hierarchy. This modal presentation covers the UTI content container and intercepts touches, making the tab switcher (rendered below the modal) unreachable. The "dialog not dismissed" on the original tab is likely a follow-on: when `newTab()` calls `currentTab?.dismiss()` immediately after `dismissContextualOnboardingIfNeeded()` starts its 0.3 s fade-out animation, the tab VC is removed from the view hierarchy before the animation completes. If the user switches back within that 300 ms window they may briefly see the dialog still present; or the animation callback on the off-screen view leaves `daxContextualOnboardingController` pointing to a stale reference.
|
||||
**Relation to D1:** Both D1 and D2 are symptoms of the same root cause — `omniBar.beginEditing()` in UTI mode. Fixing D1 should also resolve D2.
|
||||
### D2 — Bottom bar: completion dialog invisible + tab switcher broken after trackers-blocked "Got it" *(2026-05-21)*
|
||||
**Status:** ✅ Fixed *(2026-05-21)*
|
||||
**Repro:** UTI + experiment flags enabled + **bottom bar** position → fire step → visit site → trackers-blocked dialog → tap "Got it" → new NTP opens → completion ("You've got this!") dialog blinks and disappears; tab switcher button stops working permanently.
|
||||
**Root cause (two parts):**
|
||||
1. **Zero-height dialog.** `showDuckAIOnboardingCompletionDialogInUTI` constrained the dialog with `topAnchor = coordinator.viewController.view.bottomAnchor` and `bottomAnchor = container.bottomAnchor`. In bottom bar mode both of those Y-positions equal `toolbar.topAnchor`, so the dialog has ~0 pt height and is never visible.
|
||||
2. **Tab switcher permanently blocked.** `showUnifiedToggleInputOmnibar` sets `navigationBarCollectionView.isUserInteractionEnabled = false` (standard omnibar transition). It is restored by `finishUnifiedToggleInputOmnibarDismiss()` which is called when the dismiss animation completes via `deactivateToOmnibar()`. With the zero-height dialog the user can never tap "Got it", so `collapseUTI()` → `dismissUnifiedToggleInputToOmnibar` is never called → `finishUnifiedToggleInputOmnibarDismiss` never runs → tab switcher stays non-interactive.
|
||||
|
||||
**Fix:**
|
||||
- `showDuckAIOnboardingCompletionDialogInUTI`: detect `coordinator.cardPosition.isBottom`; in bottom bar mode use `topAnchor = container.topAnchor` / `bottomAnchor = coordinator.viewController.view.topAnchor` so the dialog fills the content area **above** the UTI bar.
|
||||
- `showDuckAIOnboardingCompletionWithActiveAddressBar`: removed the special `coordinator.activateInput()` branch (which only fired when `isOmnibarSession = true`, never the case here since `refreshNonAITab` hid the coordinator). Always use `omniBar.beginEditing()` — in UTI mode this is intercepted by `activateFromOmnibarIfNeeded` → `coordinator.activateFromOmnibar(cardPosition:)`, which correctly sets `cardPosition = .bottom` before the async dialog-setup hop.
|
||||
|
||||
**Files:** `NewTabPageViewController.swift`
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user