Skip to content

fix: lock user menu position when sidebar is resized#21853

Merged
tjbck merged 1 commit intoopen-webui:devfrom
silentoplayz:fix/user-menu-position-on-sidebar-resize
Feb 25, 2026
Merged

fix: lock user menu position when sidebar is resized#21853
tjbck merged 1 commit intoopen-webui:devfrom
silentoplayz:fix/user-menu-position-on-sidebar-resize

Conversation

@silentoplayz
Copy link
Collaborator

Pull Request Checklist

Note to first-time contributors: Please open a discussion post in Discussions to discuss your idea/fix with the community before creating a pull request, and describe your changes before submitting a pull request.

This is to ensure large feature PRs are discussed with the community first, before starting work on it. If the community does not want this feature or it is not relevant for Open WebUI as a project, it can be identified in the discussion before working on the feature and submitting the PR.

Before submitting, make sure you've checked the following:

  • Target branch: Verify that the pull request targets the dev branch. PRs targeting main will be immediately closed.
  • Description: Provide a concise description of the changes made in this pull request down below.
  • Changelog: Ensure a changelog entry following the format of Keep a Changelog is added at the bottom of the PR description.
  • Documentation: Add docs in Open WebUI Docs Repository. Document user-facing behavior, environment variables, public APIs/interfaces, or deployment steps.
  • Dependencies: Are there any new or upgraded dependencies? If so, explain why, update the changelog/docs, and include any compatibility notes. Actually run the code/function that uses updated library to ensure it doesn't crash.
  • Testing: Perform manual tests to verify the implemented fix/feature works as intended AND does not break any other functionality. Include reproducible steps to demonstrate the issue before the fix. Test edge cases (URL encoding, HTML entities, types). Take this as an opportunity to make screenshots of the feature/fix and include them in the PR description.
  • Agentic AI Code: Confirm this Pull Request is not written by any AI Agent or has at least gone through additional human review AND manual testing. If any AI Agent is the co-author of this PR, it may lead to immediate closure of the PR.
  • Code review: Have you performed a self-review of your code, addressing any coding standard issues and ensuring adherence to the project's coding standards?
  • Design & Architecture: Prefer smart defaults over adding new settings; use local state for ephemeral UI logic. Open a Discussion for major architectural or UX changes.
  • Git Hygiene: Keep PRs atomic (one logical change). Clean up commits and rebase on dev to ensure no unrelated commits (e.g. from main) are included. Push updates to the existing PR branch instead of closing and reopening.
  • Title Prefix: fix: user menu drifts rightward when sidebar is resized

Changelog Entry

Description

  • The sidebar user menu was drifting rightward when the sidebar was resized wider, because the dropdown was right-anchored (align="end") to the full-width trigger row. Switched to align="start" with avoidCollisions={false} to keep the menu pinned to the left edge of the trigger regardless of sidebar width.

Fixed

  • Sidebar user menu no longer shifts position when the sidebar is resized.

Additional Information

  • No new dependencies. No visual changes at default sidebar width.

Screenshots or Videos

Before

image

After

image

Contributor License Agreement

By submitting this pull request, I confirm that I have read and fully agree to the Contributor License Agreement (CLA), and I am providing my contributions under its terms.

Note

Deleting the CLA section will lead to immediate closure of your PR and it will not be merged in.

Use align="start" (left-anchor) instead of align="end" (right-anchor) on
the user menu DropdownMenu.Content, combined with avoidCollisions={false}
to prevent Floating UI from auto-flipping back to end-alignment when the
menu's left edge is near the viewport boundary.

Previously, the right edge of the full-width trigger row tracked the
right edge of the sidebar, so resizing the sidebar wider caused the menu
to drift rightward. With start alignment the menu is anchored to the
left edge of the trigger, which is stable regardless of sidebar width.
@pr-validator-bot
Copy link

👋 Welcome and Thank You for Contributing!

We appreciate you taking the time to submit a pull request to Open WebUI!

⚠️ Important: Testing Requirements

We've recently seen an increase in PRs that have significant issues:

  • PRs that don't actually fix the bug they claim to fix
  • PRs that don't implement the feature they describe
  • PRs that break existing functionality
  • PRs that are clearly AI-generated without proper testing being done by the author
  • PRs that simply don't work as intended

These untested PRs consume significant time from maintainers and volunteer contributors who review and test PRs in their free time.
Time that could be spent testing other PRs or improving Open WebUI in other ways.

Before marking your PR as "Ready for Review":

Please explicitly confirm:

  1. ✅ You have personally tested ALL changes in this PR
  2. How you tested it (specific steps you took to verify it works)
  3. Visual evidence where applicable (screenshots or videos showing the feature/fix working) - if applicable to your specific PR

If you're not certain your PR works exactly as intended, please leave it in DRAFT mode until you've thoroughly tested it.

Thank you for helping us maintain quality and respecting the time of our community! 🙏

@tjbck tjbck merged commit 39e3f8f into open-webui:dev Feb 25, 2026
1 of 2 checks passed
@silentoplayz silentoplayz deleted the fix/user-menu-position-on-sidebar-resize branch February 25, 2026 21:11
GrayXu pushed a commit to GrayXu/open-webui that referenced this pull request Mar 2, 2026
…ebui#21853)

Use align="start" (left-anchor) instead of align="end" (right-anchor) on
the user menu DropdownMenu.Content, combined with avoidCollisions={false}
to prevent Floating UI from auto-flipping back to end-alignment when the
menu's left edge is near the viewport boundary.

Previously, the right edge of the full-width trigger row tracked the
right edge of the sidebar, so resizing the sidebar wider caused the menu
to drift rightward. With start alignment the menu is anchored to the
left edge of the trigger, which is stable regardless of sidebar width.
lentiann added a commit to ZalaziumGmbh/anox that referenced this pull request Mar 4, 2026
…30)

* i18n: improve zh-CN translation

* i18n: improve zh-TW translation

* fix: dictation toggle shortcuts i18n

* fix: correct ENABLE_AUDIT_STDOUT stdout filter (open-webui#21777)

* refac

* enh: sbom docker gh action

* refac

* refac

* feat: sort action buttons by valve priority (open-webui#21790)

feat: sort action buttons by valve priority

Action buttons under assistant messages were rendered in
non-deterministic order due to set() deduplication. They now
respect the priority field from function Valves, sorted ascending
(lower value = appears first, default 0), matching the existing
filter priority mechanism.

* Filter by public/private (open-webui#21797)

* enh: access grant level perms

* refac

* fix: tools_dict issue

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* fix: resolve valve priority for actions and filters via class instantiation (open-webui#21841)

fix: resolve valve priority for actions and filters via class instantiation

The priority sorting for action buttons and filter execution order
read valve data directly from the database JSON column using
Functions.get_function_valves_by_id(). This returns only explicitly
saved values — when a developer defines priority as a class default
in their Valves definition (e.g. priority: int = 5) without ever
opening the Valves UI to persist it, the database column remains
empty. Every function then resolves to priority 0, and the preceding
set() deduplication produces non-deterministic iteration order that
the stable sort preserves — resulting in random button placement on
every page load.

The fix instantiates the Valves class with database values as keyword
overrides: Valves(**(db_valves or {})). This merges any persisted
overrides onto the code-defined defaults, matching the pattern already
established in the action execution handler, filter processing
pipeline, and tool module initialization. A secondary sort key (the
function ID) ensures fully deterministic ordering even when multiple
functions share the same priority value.

Affected locations:
- get_action_priority in utils/models.py (action button ordering)
- get_priority in utils/filter.py (filter execution ordering)

* refac

* Update print statement from 'Hello' to 'Goodbye' (open-webui#21842)

* refac

Co-Authored-By: Peter L Jones <1549463+pljones@users.noreply.github.com>

* refac

* Update oauth_sessions.py (open-webui#21794)

* refac

* refac

Co-Authored-By: Johannes Fahrenkrug <16358+jfahrenkrug@users.noreply.github.com>

* refac

* Update SECURITY.md (open-webui#21859)

* refac

* perf: early-return in get_tools() for empty tool_ids (open-webui#21873)

Avoids a needless Groups.get_groups_by_member_id() query when
no tools are attached to the request.

* fix(sidebar): lock user menu position when sidebar is resized (open-webui#21853)

Use align="start" (left-anchor) instead of align="end" (right-anchor) on
the user menu DropdownMenu.Content, combined with avoidCollisions={false}
to prevent Floating UI from auto-flipping back to end-alignment when the
menu's left edge is near the viewport boundary.

Previously, the right edge of the full-width trigger row tracked the
right edge of the sidebar, so resizing the sidebar wider caused the menu
to drift rightward. With start alignment the menu is anchored to the
left edge of the trigger, which is stable regardless of sidebar width.

* refac

* i18n(pt-BR): add translations for newly added UI items + consistency pass (open-webui#21776)

New **pt-BR** translations for items introduced in the latest releases, plus a consistency/quality pass across existing strings (grammar, tone, capitalization, pluralization). Placeholders and hotkeys preserved. No logic changes.

Co-authored-by: Tim Baek <tim@openwebui.com>

* refac

* refac

* refac

Co-Authored-By: Algorithm5838 <108630393+Algorithm5838@users.noreply.github.com>

* refac

* refac

* refac

* feat: experimental open terminal integration

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* fix(ui): fix some broken links (open-webui#21904)

The referenced information was moved to a new location.

Signed-off-by: Stefan Weil <sw@weilnetz.de>

* Update catalan translation.json (open-webui#21895)

* perf: fast-path comparison in ResponseMessage to skip JSON.stringify during streaming (open-webui#21884)

ResponseMessage compared the entire message object via JSON.stringify on every reactive tick to detect changes. During streaming, content changes on every token, making the two O(content_length) JSON.stringify calls always return different results — pure wasted work. Add a fast O(1) comparison on content and done fields first. When either differs (the common streaming case), skip straight to cloning. Only fall through to the expensive JSON.stringify comparison for infrequent changes like sources, annotations, or status updates.

* perf: cache KaTeX module import as singleton across all renderer instances (open-webui#21880)

* perf: cache KaTeX module import as singleton across all renderer instances

KatexRenderer.svelte dynamically imports katex, mhchem, and the CSS on every component mount. When a message contains multiple math expressions, this triggers redundant module resolution for each one. Move the import promise to a module-level singleton using Svelte's context='module' script block so it loads once and is shared across all KatexRenderer instances.

* Update KatexRenderer.svelte

* feat: open terminal integration

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* chore: format

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* refac

* upd:i18n  es-ES language update v0.8.5 (open-webui#21956)

### upd:i18n  es-ES language update v0.8.5

Added new strings and a couple of corrections

* fix: fix missing i18n keys (open-webui#21932)

* fix: Fix Tooltip memory leaking and type define (open-webui#21969)

* fix: Fix memory leaking of MessageInput (open-webui#21968)

* refac

* perf: use structuredClone for message deep copies (open-webui#21948)

* fix: fix memory leaking of Notes.svelte (open-webui#21963)

* perf: batch scrollToBottom during streaming via rAF (open-webui#21946)

* i18n: improve Chinese translation (open-webui#21934)

* i18n: improve zh-CN translation

* i18n: improve zh-TW translation

* refac

* refac

* fix: Fix memory leaking in create model page (open-webui#21966)

* refac

Co-Authored-By: Ingmar van Hulzen <13165062+ingmarvanhulzen@users.noreply.github.com>

* I18n: improve Chinese translation (open-webui#21980)

* i18n: improve zh-CN translation

* i18n: improve zh-TW translation

* refac

Co-Authored-By: Nil Puig <244631886+npuigm@users.noreply.github.com>

* perf: throttle message list rebuild to once per animation frame during streaming (open-webui#21885)

Messages.svelte rebuilds the message list by walking the parent chain and creating spread copies on every history.messages change. During streaming, this runs on every token — hundreds of times per second — even though each ResponseMessage already has its own reactive binding for content updates. Throttle the rebuild to once per animation frame (~60Hz) during content-only updates, while keeping immediate rebuilds for structural changes (currentId changes like chat switches, navigation, or new messages). Adds onDestroy cleanup for the pending rAF.

* chore: Changelog updates (open-webui#21791)

* changelog: add 0.8.6 version with general improvements and translations

* changelog: fix version structure - proper 0.8.6 with today's date

* changelog: add Docker SBOM attestation entry

* changelog: RAG template duplication fix

* changelog: add action button priority sorting feature

* changelog: add public/private model filtering entry

* changelog: fix duplicate model execution, RAG template

* changelog: add USER_PERMISSIONS_ACCESS_GRANTS_ALLOW_USERS env var for user sharing control

* changelog: add reporting-endpoints security header entry

* changelog: add default group share permission env var

* changelog: function valve priority fix

* changelog: german, i18n, translations

* changelog: oauth, session, database-fix

* changelog: models, oauth, cache

* changelog: fix web content knowledge base append

* changelog: password manager autofill fix

* changelog: sidebar menu positioning fix

* changelog: tool query optimization, sidebar menu

* changelog: add 0.8.6 entries for security, models, OAuth, RAG, translations

* changelog: user sharing permission enforcement fix

* changelog: user sharing permission links

* changelog: streaming, performance, rendering

* changelog: database migration execution fix

* changelog: open terminal, tool server

* changelog: terminal, tool-server, optimization

* changelog: add Catalan to translation updates

* changelog: streaming, message comparison, optimization

* changelog: math rendering, performance

* changelog: add Tools to Integrations rename entry

* changelog: add Spanish to translation updates

* changelog: tooltip, performance fix

* changelog: messageinput memory leak fix

* changelog: web search domain filter config fix

* changelog: message cloning performance optimization

* changelog: notes, memory leak, stability

* changelog: streaming scroll optimization performance

* changelog: code block UI fix

* changelog: add model create memory leak fix entry

* changelog: add toast notification to bulk model actions

* changelog: add TailwindCSS gray color theme fix

* changelog: streaming, memory leaks, UI fixes, translations, tools to integrations

* refac

* refac

* refac

* chore: format

* refac

* refac

* fix: Fix memory leaking in MentionList.svelte (open-webui#21965)

* refac

* refac

* refac

* refac

* refac

* chore: format

* refac

* refac

* Update translation.json (open-webui#22096)

* i18n(pt-BR): add translations for newly added UI items + consistency pass (open-webui#22095)

New **pt-BR** translations for items introduced in the latest releases, plus a consistency/quality pass across existing strings (grammar, tone, capitalization, pluralization). Placeholders and hotkeys preserved. No logic changes.

* bugfix: Prevent double toast on single hide/show toggle (open-webui#22079)

* fix: fix memory leaking of SIdebar (open-webui#22082)

* perf: replace JSON.parse(JSON.stringify()) with structuredClone in layout (open-webui#22104)

Replace JSON roundtrip with native structuredClone for tool execution result cloning. Also remove unnecessary JSON roundtrip on a static error object literal that is already a fresh value.

* perf: fast-path length check in StatusHistory comparison (open-webui#22103)

Add O(1) array length check before expensive JSON.stringify comparison. During streaming, status history typically only grows via appends, so a length mismatch catches most updates without serialization.

* perf: fast-path token comparison in CodeBlock (open-webui#22101)

During streaming, every token change triggers a full JSON.stringify comparison on the code block token object. Add an O(1) fast-path check on token.text and token.raw — the fields that actually change during streaming — before falling back to the expensive JSON.stringify comparison for infrequent structural changes.

* perf: replace JSON.parse(JSON.stringify()) with structuredClone in Chat.svelte (open-webui#22102)

Replace 7 instances of JSON.parse(JSON.stringify()) deep cloning with the native structuredClone API. All are on cold paths (model selection, file preparation, history saving) but structuredClone is ~2x faster and more readable.

* refac

Co-Authored-By: Shirasawa <kaguyashirasawa@gmail.com>

* perf: async DB calls, skip intermediate status writes, elif chain in event emitter (open-webui#22107)

Three improvements to the socket event emitter hot path (when realtime chat save is enabled):

1. Wrap all synchronous Chats.* DB calls in asyncio.to_thread() to avoid blocking the event loop during streaming. With N concurrent users, sync DB calls serialize all writes and block socket event delivery.

2. Only persist final (done=True) status events to DB. Intermediate statuses (tool calling progress, web search progress, etc.) are ephemeral UI-only data already delivered via socket — writing every one to DB is unnecessary I/O.

3. Convert if/if/if chain to if/elif since event types are mutually exclusive, avoiding unnecessary string comparisons after a match.

* perf: add fast-path comparison in MultiResponseMessages (open-webui#22100)

Same optimization as ResponseMessage: add O(1) fast-path check on content and done fields before falling back to full JSON.stringify comparison. Avoids expensive serialization when only content changes during streaming.

* perf: skip redundant object spread in buildMessages (open-webui#22086)

* refac

Co-Authored-By: Algorithm5838 <108630393+Algorithm5838@users.noreply.github.com>

* fix: offline model retrieval, re-raise to disable instead of returning useless fallback (open-webui#22106)

Co-authored-by: ahxxm <1286225+ahxxm@users.noreply.github.com>

* chore: changelog (open-webui#22080)

* changelog: MentionList memory leak fix

* changelog: multi-model responses horizontal scroll fix

* changelog: tool, json, error-handling

* changelog: add notification HTML escaping fix

* changelog: fix chat timestamp i18n

* changelog: terminal, file creation, SBOM

* changelog: terminal file editing

* changelog: terminal, toolbar, file-preview

* changelog: terminal, file refresh, automation

* changelog: model toast notification fix

* changelog: sidebar memory leak fix

* changelog: streaming performance optimizations

* changelog: message building, streaming, performance

* changelog: socket, status, event type optimizations

* changelog: offline mode, embedding model fix

* changelog: performance entries reworded for clarity

* chore: bump

* refac

* refac

* refac

* chore: format

* refac

* chore: format

* refac

* fix: suppress internal path leakage in audio transcription errors (GHSA-vvxm-vxmr-624h) (open-webui#22108)

- Use os.path.basename() for filename sanitization instead of fragile blocklist

- Replace ERROR_MESSAGES.DEFAULT(e) with generic error message in both except blocks to prevent CWE-209 information disclosure

- Server-side logging via log.exception(e) is preserved for debugging

* perf: use structuredClone and fast-path comparison in UserMessage (open-webui#22098)

Same optimization as the merged ResponseMessage PR: replace JSON.parse(JSON.stringify()) with structuredClone and add an O(1) fast-path check on content before falling back to full JSON.stringify comparison.

* refac

* refac

* fix: enforce ownership check on user-memory collection queries (open-webui#22109)

* fix: enforce ownership check on user-memory collection queries

fix: enforce ownership check on user-memory collection queries

Prevent authenticated users from querying other users' memory
collections via the /query/doc and /query/collection endpoints.
A new _validate_collection_access helper rejects requests for
user-memory-{UUID} collections where the UUID does not match
the requesting user. Admins bypass the check.

* Update retrieval.py

* Update retrieval.py

* fix: fix memory leaking in Chat.svelte (open-webui#21962)

* fix: fix memory leaking in Chat.svelte

* chore: remove useless chatIdUnsubscriber var

* fix: fix async tick

* refac

* chore: format

* refac

* refac

* perf: use rAF to debounce getContents() during streaming

* refac

* refac

* fix: fix memory leaking in CodeEditor (open-webui#22110)

* fix: pass params when saving a temporary chat

The system prompt and other chat controls overrides were lost after
saving because `params` wasn't included in the `createNewChat` call.

* fix: fix memory leaking of ChatControls (open-webui#22112)

* refac

* doc: changelog

* chore: format

* refac

* refac

* Merge pull request open-webui#22127 from ShirasawaSama/patch-49

fix: Fix TypeScript syntax compilation errors

* refac

* enh: ot move

* refac

* refac

* refac

* i18n: improve Chinese translations (open-webui#22148)

* enh: file nav html rendering

* refac

* fix: add missing lang="ts" to ChatControls module script (open-webui#22131)

The module-level script block uses TypeScript syntax but was missing
the lang="ts" attribute, causing esbuild to fail during vite dev
dependency scanning.

* refac

* i18n: Updated Irish translation (open-webui#22132)

Co-authored-by: Tim Baek <tim@openwebui.com>
Co-authored-by: joaoback <156559121+joaoback@users.noreply.github.com>

* i18n: Update catalan translation.json (open-webui#22129)

* enh: open terminal

* refac

* refac

* refac

* fix: omit None-valued query params in execute_tool_server (open-webui#22144)

* chore: changelog (open-webui#22152)

* changelog: middleware, tool output, chat fix

* changelog: fix chat history pagination

* changelog: add ChatControls reactivity fix for PR open-webui#22127

* changelog: reorder 0.8.8 to top, add middleware fix

* changelog: add second commit to chat history pagination fix

* changelog: terminal file moving feature

* changelog: terminal file moving, general improvements, translations

* changelog: ChatControls TypeScript fix

* changelog: terminal, html-preview, file-browser

* changelog: update translations (Irish, Catalan)

* changelog: terminal websocket proxy

* changelog: terminal, tools, direct-connections

* changelog: terminal feature toggle

* changelog: update terminal feature toggle entry

* changelog: terminal, null parameter handling fix

* chore: format

* chore: format

* fix: grant file access for knowledge attached to shared workspace models (open-webui#22151)

* refac

* chore: format

* Fixing the show=false bug on chat on chatlist event

* Slim chat API responses and auto-repair broken parent chains

---------

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Co-authored-by: Shirasawa <764798966@qq.com>
Co-authored-by: EntropyYue <xiaopa233@qq.com>
Co-authored-by: Tim Baek <tim@openwebui.com>
Co-authored-by: Jannik S. <jannik.streidl@icloud.com>
Co-authored-by: Classic298 <27028174+Classic298@users.noreply.github.com>
Co-authored-by: Peter L Jones <pljones@users.noreply.github.com>
Co-authored-by: Peter L Jones <1549463+pljones@users.noreply.github.com>
Co-authored-by: Johannes Fahrenkrug <16358+jfahrenkrug@users.noreply.github.com>
Co-authored-by: Algorithm5838 <108630393+Algorithm5838@users.noreply.github.com>
Co-authored-by: G30 <50341825+silentoplayz@users.noreply.github.com>
Co-authored-by: joaoback <156559121+joaoback@users.noreply.github.com>
Co-authored-by: Stefan Weil <sw@weilnetz.de>
Co-authored-by: Aleix Dorca <aleixdorca@mac.com>
Co-authored-by: _00_ <131402327+rgaricano@users.noreply.github.com>
Co-authored-by: Ingmar van Hulzen <13165062+ingmarvanhulzen@users.noreply.github.com>
Co-authored-by: Nil Puig <244631886+npuigm@users.noreply.github.com>
Co-authored-by: Shirasawa <kaguyashirasawa@gmail.com>
Co-authored-by: ahxxm <1286225+ahxxm@users.noreply.github.com>
Co-authored-by: Aindriú Mac Giolla Eoin <aindriu80@gmail.com>
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.

3 participants