fix(macos): raise capsule window level to 25 so it overlays fullscreen apps

v1.3.6-5 fixed cross-desktop following but not fullscreen: FULL_SCREEN_AUXILIARY only lets the capsule JOIN the fullscreen Space; at alwaysOnTop's floating level (~3) it still renders behind the fullscreen window. setLevel(25) (above the menu bar, matching show_less_computer_glow which does overlay fullscreen) makes it render on top. Add a contract assertion to lock it in.

Runtime-verify on macOS: enter a fullscreen app, trigger dictation, capsule should now appear over it.
This commit is contained in:
Andy Jiang committed 2026-06-13 23:59:43 +08:00
1 parent 2e27f70472
commit 12fa110795
2 files changed
+11 -1

No files matched your search

@@ -35,6 +35,12 @@ assertMatch(
'macOS capsule should join fullscreen Spaces as an auxiliary window before showing without activation',
);
assertMatch(
macosNoActivateFunction,
/setLevel:\s*25[\s\S]*?orderFrontRegardless/,
'macOS capsule must raise window level above the menu bar (25) so it renders over fullscreen apps, not just behind them',
);
for (const forbidden of ['window.show()', 'set_focus', 'NSApp.activate', 'makeKeyAndOrderFront']) {
if (executableMacosNoActivateFunction.includes(forbidden)) {
throw new Error(`macOS capsule no-activate path must not call ${forbidden}`);
@@ -6619,13 +6619,17 @@ fn show_capsule_window_no_activate<R: tauri::Runtime>(
// (CanJoinAllSpaces / Managed / Transient 三选一,→ 切桌面跟随不稳)。glow 窗口从不
// 调它、直接写绝对值,跨 Space + 全屏都正常 —— 胶囊对齐它。
// - CAN_JOIN_ALL_SPACES:出现在所有桌面/Space,切桌面/全屏时跟随。
// - FULL_SCREEN_AUXILIARY:能叠加在全屏 app 之上。
// - FULL_SCREEN_AUXILIARY:被允许进入全屏 app 的 Space。
// - STATIONARY:Mission Control / Exposé 时不跟着乱飞。
// 外加 setLevel(25):光有 FULL_SCREEN_AUXILIARY 只是「被允许」进全屏 Space,但窗口层级
// 若停在 alwaysOnTop 的浮动层(~3) 仍会被全屏 app 的窗口盖住而看不见;抬到菜单栏(24)之上
// 的 25(与 show_less_computer_glow 同款)才能真正叠在全屏之上。
unsafe {
const CAN_JOIN_ALL_SPACES: usize = 1 << 0;
const STATIONARY: usize = 1 << 4;
const FULL_SCREEN_AUXILIARY: usize = 1 << 8;
let behavior = CAN_JOIN_ALL_SPACES | STATIONARY | FULL_SCREEN_AUXILIARY;
let _: () = msg_send![ns_window, setLevel: 25i64];
let _: () = msg_send![ns_window, setCollectionBehavior: behavior];
let _: () = msg_send![ns_window, orderFrontRegardless];
}