diff --git a/addons/web/static/src/webclient/navbar/navbar.js b/addons/web/static/src/webclient/navbar/navbar.js index bbc64f80cf1..ad96358f9e9 100644 --- a/addons/web/static/src/webclient/navbar/navbar.js +++ b/addons/web/static/src/webclient/navbar/navbar.js @@ -2,7 +2,7 @@ import { Dropdown } from "@web/core/dropdown/dropdown"; import { DropdownItem } from "@web/core/dropdown/dropdown_item"; -import { useEffect, useService, onDestroyed } from "@web/core/utils/hooks"; +import { useEffect, useService, onDestroyed, useBus } from "@web/core/utils/hooks"; import { registry } from "@web/core/registry"; import { debounce } from "@web/core/utils/timing"; import { ErrorHandler, NotUpdatable } from "@web/core/utils/components"; @@ -11,6 +11,8 @@ const { Component, hooks } = owl; const { useExternalListener, useRef } = hooks; const systrayRegistry = registry.category("systray"); +const getBoundingClientRect = Element.prototype.getBoundingClientRect; + export class MenuDropdown extends Dropdown { setup() { super.setup(); @@ -55,21 +57,18 @@ export class NavBar extends Component { const debouncedAdapt = debounce(this.adapt.bind(this), 250); onDestroyed(() => debouncedAdapt.cancel()); useExternalListener(window, "resize", debouncedAdapt); - } - mounted() { - this.adapt(); - const renderAndAdapt = async () => { - await this.render(); - await this.adapt(); + let adaptCounter = 0; + const renderAndAdapt = () => { + adaptCounter++; + this.render(); }; - systrayRegistry.on("UPDATE", this, renderAndAdapt); - this.env.bus.on("MENUS:APP-CHANGED", this, renderAndAdapt); - } - willUnmount() { - systrayRegistry.off("UPDATE", this); - this.env.bus.off("MENUS:APP-CHANGED", this); + useBus(systrayRegistry, "UPDATE", renderAndAdapt); + useBus(this.env.bus, "MENUS:APP-CHANGED", renderAndAdapt); + // We don't want to adapt every time we are patched + // rather, we adapt only when menus or systrays have changed. + useEffect(() => {this.adapt();}, () => [adaptCounter]); } handleItemError(error, item) { @@ -138,8 +137,10 @@ export class NavBar extends Component { this.currentAppSectionsExtra = []; // ------- Check overflowing sections ------- - const sectionsAvailableWidth = sectionsMenu.offsetWidth; - const sectionsTotalWidth = sections.reduce((sum, s) => sum + s.offsetWidth, 0); + // use getBoundingClientRect to get unrounded values for width in order to avoid rounding problem + // with offsetWidth. + const sectionsAvailableWidth = getBoundingClientRect.call(sectionsMenu).width; + const sectionsTotalWidth = sections.reduce((sum, s) => sum + getBoundingClientRect.call(s).width, 0); if (sectionsAvailableWidth < sectionsTotalWidth) { // Sections are overflowing // Initial width is harcoded to the width the more menu dropdown will take