Repository navigation
Releases: lingyired/tauri-plugin-multiline-menubar
Release list
v1.10.2 — Stable status-item identity + confirmed removals
v1.10.2 — Stable status-item identity + confirmed removals
Two menu bar reliability fixes: items finally carry a name macOS can key on, and
a removal is no longer reported on the first visible = NO observation.
Fixed
- Status items had no stable identity —
statusItemWithLength:leavesautosaveNameunset, so macOS named every itemItem-Nby creation order. That name drifts between launches (anything keyed to it —NSStatusItem Preferred Positionincluded — can never be found again), and since every app's first item isItem-0, a host had no way to recognise its own item. Items are now named<bundle id>.<instance key>: the bundle id keeps different hosts apart, the instance key keeps the instances of one host apart. Bare binaries (tauri dev) have no bundle id and fall back to the process name, which is still per-app and stable. onRemovecould fire on a transient visibility flip — a singlevisible = NOwas reported to the host as "the user dragged the item out", but macOS also flips it while it re-lays out the bar (inserting/removing any item, display changes, hiding items to make room). A host that reacts by tearing its item down is what makes the menu bar look like it shuffles icons around by itself. The removal is now confirmed 1.5 s later and reported only if the item is still gone; the transient case is logged so the next occurrence leaves a trace instead of having to be inferred.
Changed
API.mddocuments the newonRemovetiming (fires only once the removal is confirmed).
Backward compatible — no signatures changed; onRemove just fires later and less often. Version: plugin 1.10.1 → 1.10.2.
📦 crates.io / npm not published for this release yet — GitHub tag only.
v1.10.1 — Upright tinted icons + 30 pt leading-icon size
v1.10.1 — Upright tinted icons + 30 pt leading-icon size
A rendering fix and a small clamp raise on top of v1.10.0's leading-column icon.
Fixed
- Tinted icons rendered upside down —
MultilineMenubarViewnever overridesisFlipped, so its drawing context is unflipped (bottom-left origin) whereCGContextDrawImagealready draws upright; the tint path unconditionally flipped the CTM first, mirroring everytint: trueicon vertically (inline and leading-column alike). The flip is now applied only when the currentNSGraphicsContextactually reports flipped, so the helper stays correct even if the view ever becomes flipped.
Changed
- Leading-column icon
sizeclamp 12–20 → 12–30 pt (default 18 unchanged) — verified rendering fine above the nominal bar height. Docs (API.md, rustdoc, guest-js types, new-apis reference) and the demo size input updated in lockstep.
Demo
- Added the WorkBuddy provider logo to the icon preset dropdowns (monochrome
currentColormark,tint: true— follows the line color). Registered once inPROVIDER_ICONS; all three preset selects (top / bottom / leading column) pick it up.
Backward compatible — no existing signatures changed. Version: plugin 1.10.0 → 1.10.1 (demo stays 0.3.0).
📦 crates.io / npm not published for this release yet — GitHub tag only.
v1.10.0 — Instance-level leading-column icon (setLeadingIcon)
v1.10.0 — setLeadingIcon({ id, icon }): a larger icon in its own column
Adds a second icon mechanism alongside the per-line inline icons: one larger icon occupying its own vertically centered column on the left of the item, with both text lines rendering to its right — the "app icon + stats" layout.
Highlights
setLeadingIcon({ id, icon })— instance-level (one icon per item, not per line).icon: nullclears it.IconSpecgainssize— display height in points, clamped 12–20 pt (default 18 ≈ full bar height minus padding). Only used by the column icon; per-line icons keep matching their line's text height.- Template-image tint —
tint: truepaints the icon in the line color resolved at paint time, so a monochrome icon follows light/dark mode with zero host code (same as inline icons). - Composes with inline icons —
setIconkeeps working inside the (narrower) text region; per-line alignment applies there too. - Width-correct —
updateWidthadds the column width (icon + 4 pt gap); measurement and paint share one helper, andsizeparticipates in the origin-key dedup so resizing re-measures while identical re-sends skip the decode. - Plays well with visibility — with both lines hidden via
setLineVisible(false, false)and a leading icon set, the item stays in the bar and renders the icon alone, horizontally centered; clearing the icon removes it again. - Permission
allow-set-leading-iconis in the default set; the demo popup gained a "Column icon" block (preset dropdown incl. provider logos + size field, applies instantly).
Docs
- New one-page reference:
docs/new-apis-v1.8.0-v1.10.0.mdcoveringsetIcon,setLineVisibleandsetLeadingIcon. API.mdupdated (setLeadingIcon rows,IconSpec&SetLeadingIconOptionstypes section, v1.10.0 changelog).
Backward compatible — no existing signatures changed. Version: plugin 1.9.0 → 1.10.0 (demo stays 0.3.0).
📦 crates.io / npm not published for this release yet — GitHub tag only.
v1.9.0 — Per-line visibility with solo-line centering
v1.9.0 — Per-line visibility with solo-line centering
Also ships v1.8.0 (per-line leading icon support, merged but unreleased — see below).
New in v1.9.0: setLineVisible({ id, top, bottom })
Hide either line independently, with macOS-native semantics:
- Hide one line → the remaining line takes over the whole block and is vertically centered in the menu bar.
- Hide both lines → the status item leaves the menu bar (visually the same as
setVisible(false)), but the host-level visibility decision is preserved — showing either line again restores the item without anothersetVisible(true). updateWidthmeasures only the visible line(s), so the item width shrinks to fit (text and leading icon both skipped).- Solo font-size range: a solo line's font size range widens to 5–16pt regardless of role (
small/equalpreviously capped at 11 for the two-line fit). Role values are stored as the host set them — nothing is lost across visibility/layout changes (a 15pt solo small line drops back to 11pt while both lines show, and pops back to 15 when solo again).FONT_SIZE_RANGEgains asolo: { min: 5, max: 16 }entry. - Permission
allow-set-line-visibleis in the default set; demo popup gained a Visibility fieldset (Apply/Reset, pre-filled from instance state) whose size sliders widen while a solo state is active.
Also in this release (v1.8.0): per-line leading icons
setIcon({ id, top, bottom })withIconSpec { path | data, tint }(path/data mutually exclusive;nullclears the line), aligned 1:1 with taskband'ssetIcon.tint: true= macOS template image semantics: alpha-only mask painted in the line color, so icons follow light/dark mode live via the existing appearance KVO;tint: falsekeeps asset colors.- Icon height matches the line cell, width follows aspect ratio,
updateWidthaccounts for the icon; identical specs are deduplicated by origin key (no re-decode/re-paint). - Permission
allow-set-iconis in the default set; demo popup gained a Leading icon block with bundled presets.
Backward compatible — no existing signatures changed. Versions: plugin 1.8.0 → 1.9.0, demo 0.2.0 → 0.3.0.
v1.7.0
v1.7.0 — System color following + popup color settings
defaultcolor now follows macOS light/dark mode live — the native layer observesNSApp.effectiveAppearance(KVO, event-driven) and repaints every instance on a mode flip; resolves toNSColor.labelColor(visually equivalent to the oldtextColorfor a menu-bar label, matches taskband semantics).- Popup color form upgraded to a System / Custom segmented control (taskband-aligned); the popup now echoes each instance current color mode via the extended
popup-openpayload (topColor/bottomColor+ align/monospaced snapshot). - API alignment with
tauri-plugin-multiline-taskband:MenuItemDescriptor.enabled(legacydisableddeprecated but still accepted) and subscription helpersonClick/onReady/onEnter/onLeave/onPopupOpen/onPopupClose. - Backward compatible — no signatures changed; popup-open payload fields are optional additions.
v1.6.1 — fix right-click menu quit hang (macOS 26)
v1.6.1 — 修复右键菜单退出挂起(macOS 26)
问题
右键点击菜单栏状态项 → 点击「Quit」退出时,app 长时间不退出(进程 100% CPU、内存持续增长),手动点击一下 menubar 后才关闭。
根因
右键菜单弹出(popUpMenuPositioningItem:)的 modal tracking loop 消费了本次点击的 rightMouseUp,导致状态按钮外层 trackMouse:untilMouseUp: 卡死在 NSEventTrackingRunLoopMode(菜单已关、tracking 未死)。此时菜单 action 里同步 app.exit(0) 会与之无限竞争(tao 的 BeforeWaiting observer 持续向事件队列投递 dummy 事件)→ 忙转挂起。
修复(两个改动,缺一不可)
- native(
multiline_menubar.mm):右键菜单关闭后补发一个rightMouseUp,让按钮外层 tracking 正常收尾,run loop 回到 default mode。 - Rust(
desktop.rs):quit/quit2改为延迟 ~200ms 异步退出(std::thread+ sleep,无新依赖),不再在菜单 action 内同步app.exit(0)。
行为变更
quit/quit2语义 = 异步退出(约 200ms 延迟),宿主不应假设菜单事件回调内 app 已同步退出。- 宿主可改回标准
quitid +app.exit(0)(此前需要 workaround 绕开挂起)。
验证
- demo 右键 → Quit 立即退出,无 100% CPU、无内存增长(✅ 用户实测通过)。
- 回归:右键 Esc / 点击外部关闭菜单、左键 popup、hover、⌘-拖出 remove 均不受影响。
v1.6.0
新增:用户移除事件(⌘+拖出菜单栏)
- 第三方 NSStatusItem 默认不可移除,现已设置
NSStatusItemBehaviorRemovalAllowed启用系统自带的 ⌘+拖拽移除手势。 - 通过 KVO 观察
visible(macOS 13+)/button.window(<13)检测移除,翻到 NO 或脱离 window 即触发。 - 用
programmaticHide+removedByUser双标志区分「用户移除」与「程序化 hide/destroy」,并去重已知的 KVO 连发两次。 - 新增事件
multiline-menubar://{id}//remove,guest-js 暴露onRemove(id, handler)。 API.md与 demo 同步更新;版本 1.5.0 → 1.6.0。
注意:菜单栏内**移动位置(reorder)**由系统内部管理,macOS 不提供任何 API 可观测,本插件不、也无法监听该行为。
Commits
- a4832a1 feat: emit a "remove" event when the user ⌘-drags the item out of the menu bar
v1.5.0
What's new
- Per-line horizontal alignment for the two menubar lines:
left(default),center, orright— set independently for the top and bottom line. - New
set_alignmentcommand (nativemultiline_menubar_set_alignment) and the JS wrappersetAlignment, withALIGN_LEFT/ALIGN_CENTER/ALIGN_RIGHTconstants. allow-set-alignmentadded to thedefaultpermission set.- Demo and popup control panel updated with alignment controls (per-line
left/center/rightselects).
Notes
- Alignment values:
0= left,1= center,2= right (any other value is treated as left, preserving the historical default). - Alignment does not change the measured item width, so the status item is simply repainted in the new alignment.
- See
API.mdfor the full command reference and examples.
Full diff
21 files changed, 616 insertions(+), 17 deletions(-)
v1.4.0
v1.4.0
New: per-line monospaced digits — setMonospaced
Render the top and/or bottom line with the system monospaced-digit font
(monospacedDigitSystemFont) so every digit keeps a constant width:
frequently-updating numeric text (e.g. a network speed readout) no longer
jitters as values change. Each line is controlled independently, and an
explicit font family set via setFontFamily takes precedence over this
toggle.
await setMonospaced({ id: "main", top: false, bottom: true });New: render dedup cache
set_text now skips the repaint and width re-measure entirely when both
lines are unchanged — previously only the Rust-side IPC round-trip was
skipped. Hosts that push the same value repeatedly (per-second refreshes,
racing updaters) no longer burn main-thread time on frames that paint
nothing new.
Also in this release
allow-set-monospacedadded to the default permission set- Guest JS API:
setMonospaced/SetMonospacedOptions - Demo: new Monospaced card + a Speed simulation harness (random
up/down per second) to test both features; popup controls synced - Docs:
API.md/README.mdupdated
v1.3.0
What's new
Per-line font family — setFontFamily
The top and bottom lines can now each render in a specific font family (the name shown in macOS Font Book, e.g. Menlo, PingFang SC):
await setFontFamily({ id: "main", top: null, bottom: "Menlo" }); // value line in a monospace fonttop/bottomaccept a font family name;nullor''restores the system font.- Unknown names silently fall back to the system font.
- The weight from
layout/setBoldis still honored — the closest face of the family is used. - Orthogonal to
setFontSizes,setColorsandsetBold. - The status item re-measures its width on every call, so a wider family never clips.
- New permission
allow-set-font-familyis part of thedefaultset (autogenerated).
Demo (examples/demo) gained a Font family card in the main window and matching controls in the popup window.
Notes
Cargo.tomlandpackage.jsonboth bumped to 1.3.0.- This release intentionally does not include the previously reverted "narrow per-role font ranges" change — font size ranges stay at small 5–11 / large 8–16 / equal 5–11.
Full API reference: API.md