Skip to content

feat: anchor tabs#2384

Open
VictorVow wants to merge 9 commits into
mbnuqw:v5from
VictorVow:feat/anchor-tabs
Open

feat: anchor tabs#2384
VictorVow wants to merge 9 commits into
mbnuqw:v5from
VictorVow:feat/anchor-tabs

Conversation

@VictorVow
Copy link
Copy Markdown
Contributor

@VictorVow VictorVow commented Mar 31, 2026

Summary

Adds an anchor tabs feature. An anchored tab remembers its current URL and title as a "home" URL. When the user navigates the tab to a different URL, a configurable reset indicator appears between the favicon and the tab title. Hovering the favicon area shows a "Back to <title>" affordance and clicking it navigates back to the anchor URL. Unanchoring clears the saved data.

Screenshots

Anchor tabs get a small permanent highlight around the favicon to show that it's anchored:

2026-03-31T16 22 55 453Z

When you navigate to a different URL the tab shows a "reset indicator". You can use whatever you want for this (defaults to \):

2026-03-31T16 20 51 801Z

Mouseover the highlighted area and the favicon will change icon, and you'll see "Back to <title>". Clicking this button will return the tab to it's anchor URL:

2026-03-31T16 26 33 360Z

Behaviour

  • Anchor / Unanchor — right-click context menu entry below Pin; also available as a keybinding (toggle_anchor_tab, no default shortcut)
  • Permanent highlight — anchored tabs show a persistent highlight on the favicon area so they are visually distinct at a glance
  • Reset indicator — configurable text/emoji indicator (default \) appears between the favicon and title when the tab has navigated away from its anchor URL
  • Hover to return — hovering the highlighted area on an anchored-away tab swaps the favicon to an undo icon, shows "Back to <title>" in place of the tab title, and changes the cursor to a pointer; clicking anywhere in that area navigates back to the anchor URL
  • Persistence — anchor URL and title are stored in tabsDataCache and restored across browser restarts

Settings

Settings → Tabs → Anchor tabs — a text field to customise the reset indicator character (accepts text and emojis).

Files changed

Area Files
Types src/types/tabs.ts, src/types/settings.ts
Defaults src/defaults/settings.ts, src/defaults/menu.ts
Services src/services/tabs.fg.ts, src/services/tabs.fg.handlers.ts, src/services/keybindings.fg.ts, src/services/menu.fg.options.tabs.ts, src/services/setup-page.fg.ts
UI src/sidebar/components/tab.vue, src/styles/sidebar/tab.styl
Settings page src/page.setup/components/settings.tabs.vue, src/page.setup/components/keybindings.vue
Manifest / i18n src/manifest.json, src/_locales/dict.browser.json, src/_locales/dict.common.ts, src/_locales/dict.setup-page.ts
Mocks src/defaults/mocks.tabs.fg.ts

Closes

#1715
#2086

@FurkanKambay
Copy link
Copy Markdown
Contributor

A design consideration: having separate actions for 'anchor' and 'pin' might be undesirable and/or unexpected for some users, for these reasons:

  1. Complexity: it's one more thing to keep track of regarding a tab's state, both in the codebase and from the user's perspective. Basically I think that it's not good UX.
  2. Familiarity: they might be used to or expect the Zen/Arc behavior where all Pinned tabs are 'anchored'. That way is also more battle-tested and proven as a good design, in my opinion.

Personally, I'd prefer all pinned tabs be anchored to their initial URL and have actions to either "re-anchor to current URL" or "return to anchored URL".

@VictorVow
Copy link
Copy Markdown
Contributor Author

Fair point, I didn't want to alter such a well-known feature but I agree it may be better UX simply modifying it. Thoughts @mbnuqw?

@mbnuqw
Copy link
Copy Markdown
Owner

mbnuqw commented Apr 13, 2026

Thanks, a few thoughts on this:

Naming: "Anchor/Unanchor" clashes with the terminology chosen in #1007. How about "Bind/Unbind URL" instead?

UI: Favicon area of tab is already used for "expand/fold" button in normal tabs. For pinned tabs, clicking should only activate the tab; changing the URL would be unexpected behavior for the user. Additionally, pinned tab has a clickable "audio" badge showed in its top-right corner so we can't just add another interactive element without increasing min-size of the pinned tab (which may happen in the future though). Anyway, unfortunately there is no vacant place for the new clickable button in the tab component right now. Technically it's possible but this will increase misclick rate or it will overlay other interactive zones, so I'd rather not.

We can only passively indicate tab state e.g. show something at the bottom-left corner of the favicon. And for example use some mouse actions (long/double/middle clicks) for fast bind/unbind/return. + keybinding and context menu opt for returning to the bound url.

VictorVow added 3 commits May 23, 2026 14:04
Introduces "anchor tabs" — a tab can be anchored to a URL+title, and
when the user navigates away a visual reset indicator appears between
the favicon and title. Hovering the favicon reveals a "Back to <title>"
affordance (normal weight prefix, bold title) and clicking it returns
the tab to its anchor URL. Unanchoring via the context menu or keybind
clears all anchor state.

Key behaviours:
- Right-click menu: Anchor / Unanchor (below Pin), using the undo icon
- Keybinding: Toggle anchor tab (no default shortcut, in Tabs section)
- Settings → Tabs → Anchor tabs: configurable Reset indicator (default \)
  with note that it accepts text and emojis
- Anchor data (URL + title) persisted in tabsDataCache and restored on
  extension reload
- For anchored-away tabs the full-tab hover highlight is suppressed;
  only the favicon area is highlighted and clickable
- Wrap .fav in a .fav-anchor container; its padding extends the
  hit-test area to match the permanent highlight box, replacing the
  previous per-element margins on .fav
- Show a permanent highlight (clicked-level color) on .fav-anchor
  for anchored tabs via a ::before pseudo-element
- On hover of an anchored-away tab's .fav-anchor:
  - Swap favicon to undo icon via CSS opacity (preserves renderFavicon()
    display value; v-show/display:none would wipe it)
  - Show "Back to <title>" text inside .fav-anchor in place of t-box
  - Suppress the permanent highlight and hide the title box (.t-box)
  - Show a tighter highlight around the favicon
  - Change cursor to pointer
- Use opacity:0 (not display:none) on the reset indicator during hover
  so .fav-anchor's layout stays stable and :hover doesn't flicker
- Remove JS favHovered ref and mouseenter/mouseleave handlers; all
  effects are pure CSS driven by .fav-anchor:hover
- Add data-anchored attribute to .Tab for the permanent highlight selector
- Add pointer-events:none to .body::before to stop it intercepting hover
- Align "Back to" text left edge with normal tab title via margin-left
- Add de/fr/hu/pl/ru/zh_CN/zh_TW/ja translations for menu.tab.anchor,
  menu.tab.unanchor, settings.nav_settings_anchor_tabs,
  settings.anchor_tabs_reset_indicator, and
  settings.anchor_tabs_reset_indicator_note
- Add v-if="tab.reactive.anchored" to svg.fav-icon.-anchor-hover so the
  undo icon SVG is only rendered for anchored tabs, not every tab
VictorVow added a commit to VictorVow/sidebery that referenced this pull request May 23, 2026
Address maintainer feedback on PR mbnuqw#2384 (mbnuqw/sidebery) by replacing the
clickable in-tab anchor UI with a passive indicator plus configurable
gestures, menu entries and keybindings.

- Remove the clickable .anchor-badge, favicon hover-to-undo swap, "Back to
  <title>" affordance and reset-indicator text; the favicon click now only
  activates the tab (no new interactive zones).
- Add a passive bottom-left corner marker (.bind-mark) driven by
  data-anchored/data-anchored-away, with a distinct colour when navigated
  away. Works for normal and pinned tabs.
- Expose bind/unbind/return as configurable actions (toggle_bind_url,
  return_to_bound) in the double/long/middle-click action lists and wire
  them up in tab.vue.
- Add a "Return to bound URL" context-menu entry (shown only when navigated
  away) and a return_to_bound_url keybinding; rename keybinding command
  toggle_anchor_tab -> toggle_bind_url and menu id anchor -> bind_url.
- Retire the now-redundant anchorTabsResetIndicator setting and its
  settings field, nav entry and locale strings.
@VictorVow
Copy link
Copy Markdown
Contributor Author

VictorVow commented May 23, 2026

Implemented all the feedback, and the indicator now looks like this when a user is on the bound URL:
image

And this when the user has navigated to another URL:
image

Removed "hover to return", customisable reset indicator, permanent highlight. Renamed to "Bind/Unbind URL". Context menu or configurable shortcuts can be used for bind/unbind/return actions.

VictorVow and others added 6 commits May 23, 2026 14:16
- Fix prettier formatting: break long ternary in menu.fg.options.tabs.ts
- Add anchored/anchoredAway to MTab reactive mock (ReactiveTabProps)
- Add anchorUrl/anchorTitle fields to MTab class and TabSessionData
  interface so the restoreTab union type (TabSessionData | TabCache)
  resolves correctly
Update English labels across locale files to use "Bind URL" / "Unbind URL"
instead of "Anchor" / "Unanchor" for clearer user-facing terminology.
Address maintainer feedback on PR mbnuqw#2384 (mbnuqw/sidebery) by replacing the
clickable in-tab anchor UI with a passive indicator plus configurable
gestures, menu entries and keybindings.

- Remove the clickable .anchor-badge, favicon hover-to-undo swap, "Back to
  <title>" affordance and reset-indicator text; the favicon click now only
  activates the tab (no new interactive zones).
- Add a passive bottom-left corner marker (.bind-mark) driven by
  data-anchored/data-anchored-away, with a distinct colour when navigated
  away. Works for normal and pinned tabs.
- Expose bind/unbind/return as configurable actions (toggle_bind_url,
  return_to_bound) in the double/long/middle-click action lists and wire
  them up in tab.vue.
- Add a "Return to bound URL" context-menu entry (shown only when navigated
  away) and a return_to_bound_url keybinding; rename keybinding command
  toggle_anchor_tab -> toggle_bind_url and menu id anchor -> bind_url.
- Retire the now-redundant anchorTabsResetIndicator setting and its
  settings field, nav entry and locale strings.
Refine the bound-URL tab affordances based on follow-up feedback:

- Replace the plain corner dot with a state-aware icon at the favicon's
  bottom-left: the "home" icon while the tab is on its bound URL and the
  "undo" icon once it has navigated away. The marker inherits the favicon
  foreground colour in both states (no accent tint).
- Restore the hover interaction for anchored-away tabs: hovering the favicon
  area reveals "Back to <title>", shows a pointer cursor and a highlight, and
  clicking returns to the bound URL.
- Use the "home" icon for the "Unbind URL" context-menu entry (the bound
  state) while "Bind URL" keeps the "undo" icon.
- Inject home.svg#icon_home into both sidebar and setup pages so the icon is
  available in the live tab marker, the context menu and the menu editor.
Drop the favicon hover affordance for anchored-away tabs. Hovering no longer
reveals "Back to <title>" and clicking the favicon no longer returns to the
bound URL.

- Remove the .fav-anchor wrapper (back to plain .fav), the .title.-anchor-back
  element and the onFavMouseDown/onFavMouseUp handlers in tab.vue.
- Revert the .fav layout rule and delete the hover styles (.fav-anchor:hover,
  .title.-anchor-back and the body-highlight override) in tab.styl.

The passive corner marker (home icon when bound, undo icon when navigated
away) remains. Returning to the bound URL is still available via the context
menu, the return_to_bound_url keybinding and the configurable mouse actions.
- Always use the "home" icon for the corner marker; distinguish the
  navigated-away state with the accent colour instead of swapping to the
  "undo" icon.
- Use the "home" icon for the Bind URL context-menu entry as well (it
  previously showed "undo" in the unbound state).
zh_TW: '取消釘選分頁',
ja: 'ピン留め解除',
},
'menu.tab.anchor': {
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.

"anchor" usage here and in other places should be changed to not mix terminologies

ru: 'Привязать',
zh_CN: '锚定',
zh_TW: '錨定',
ja: 'アンカー設定',
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.

I'd urge against using AI translations and suggest simply leaving most of these out unless you speak the language and are sure that these are correct in context. (anchor probably would've been more problematic than bind though)

The Japanese one, for instance, seems to mean "anchor settings" and not "anchor (this tab)" when back-translated into English and some other languages. Similar problems might occur with translations of bind/unbind without being this obvious.

Also, they all need to say "Bind URL" now

@zelch
Copy link
Copy Markdown
Contributor

zelch commented May 27, 2026

Looked through the changes, and the only issues that I noticed had already been covered by @FurkanKambay. All of the internal references to 'anchor' being the big one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants