Operating system
Windows
Version
0.19.3.1
Have you tested that this is not an upstream issue or an issue with your configuration?
- I have tried reproducing this issue in Chrome and it could not be reproduced there
- I have tried reproducing this issue in ungoogled-chromium and it could not be reproduced there
- I have tried reproducing this issue in Helium with a new and empty profile using
--user-data-dircommand line argument and it could not be reproduced there
Description
With "Centered address bar" and "Minimal URL in the address bar" enabled and an empty omnibox, focusing the omnibox paints the caret in the center of the bar for one frame before it snaps to the left. The centered steady-state alignment should never be painted once the bar is engaged.
Crash ID
No response
How to Reproduce?
- Enable Settings -> Appearance -> "Centered address bar" and "Minimal URL in the address bar".
- Open any page and make sure the omnibox is not focused (click into the page).
- Click the empty omnibox.
- Observe the caret position on the first frame it is visible.
Actual behavior
The caret appears in the center of the address bar for roughly one frame, then jumps to the left edge.
With "Minimal URL in the address bar" enabled, the omnibox RenderText is
ALIGN_CENTER while idle. views::Textfield draws its caret in a separate child view
(cursor_view_) whose bounds are only recomputed inside
UpdateAfterChange(..., cursor_changed=true, ...) → UpdateCursorViewPosition().
SetHorizontalAlignment() only invalidates the text layout and never repositions that
caret view (OnPropertyChanged(..., PropertyEffects::kNone)).
On focus, the patch's UpdateSteadyStateTextAlignment() ran after
SetCursorEnabled() had already placed and shown the caret under the still-centered
alignment, so one frame painted a centered caret, which then snapped left on the next
UpdateAfterChange (selection restore / SelectAll / Update()).
Expected behavior
The caret appears at the left inset immediately; the centered alignment is never painted once the user engages the omnibox.
Additional context
Cause: in OmniboxViewViews::UpdateSteadyStateTextAlignment() (added by patches/helium/ui/layout/minimal-location-bar.patch), the alignment flip runs after the caret has already been positioned under the old (centered) alignment.
views::Textfield draws its caret in a separate child view (cursor_view_); its bounds are only recomputed in UpdateAfterChange(..., cursor_changed=true, ...) → UpdateCursorViewPosition(). Textfield::SetHorizontalAlignment() only invalidates the text layout (OnPropertyChanged(..., kNone)) and never repositions the caret view.
On focus, ApplyCaretVisibility() does:
SetCursorEnabled(true)→UpdateCursorViewPosition()— caret placed while alignment is stillALIGN_CENTER(centered caret, now visible);UpdateSteadyStateTextAlignment()— flipsRenderTexttoALIGN_LEFTwithout touching the caret view. One frame paints: text left-aligned, caret centered. It snaps left later, on the nextUpdateAfterChange(selection restore / SelectAll / Update()).
Suggested fix (2 changes in omnibox_view_views.cc):
UpdateSteadyStateTextAlignment():
- early-return when the alignment is unchanged;
- after changing it, call
UpdateAfterChange(TextChangeType::kNone, /*cursor_changed=*/true, /*notify_caret_bounds_changed=*/false)so the caret bounds are recomputed under the new alignment.
ApplyCaretVisibility():
- move the
UpdateSteadyStateTextAlignment()call to the top of the function, beforeSetCursorEnabled(...), so the caret is positioned under the already-correct alignment. This also covers the Ctrl+L / focus-traversal paths, which never go through OnMousePressed.
Blur is unaffected: FocusManager::SetFocusedViewWithReason() swaps focused_view_ before calling Blur(), so during OnBlur the state is OMNIBOX_FOCUS_NONE with HasFocus() false and the bar re-centers as before.
Activity
0No activity yet.