Repository navigation
fix(v2): show the pill and menu bar panel over full screen apps - #142
gauravlonari wants to merge 3 commits into
Conversation
|
This is the right fix and it brings SpeakType 2 back in line with what SpeakType 1 did. The platform layer is used properly, all three systems get the new functions, every unsafe block carries a SAFETY note, and swapping One thing to fix before merge. Swapping the class to plain The fix is a small extension of what you already built: give the non-focusable case its own subclass whose Two smaller notes:
The Windows and Linux stubs are the right call. I'd soften the comment to say nothing extra is needed today, rather than that those systems never hide floating windows, which isn't reliably true for exclusive-fullscreen games or some Wayland compositors. Your second commit, the hotkey logging, is good and independent of all this. Happy to take it either way. |
On macOS both windows only appeared on an empty desktop. Three things are needed for a window to join another app's full screen Space, and Tauri gives none of them: - `visibleOnAllWorkspaces` only sets `canJoinAllSpaces`, which covers regular Spaces, so `fullScreenAuxiliary` is set here. - `alwaysOnTop` only reaches `NSFloatingWindowLevel`, too low to be admitted, so the level is raised to `NSStatusWindowLevel`. - a plain `NSWindow` of an inactive app is kept out whatever its flags say, so both windows become nonactivating `NSPanel`s, as SpeakType 1's recorder already was. Opening the panel no longer calls `set_focus`: it activates the app, which switched the user to whichever Space the main window was on and dismissed the full screen app's menu bar. `show()` already sends `makeKeyAndOrderFront:`, and a nonactivating panel takes focus without activating. The panel also needs `canBecomeKeyWindow`, which tao overrides for borderless windows and which is lost with its class, so it becomes an `NSPanel` subclass that restores it. Without that the panel never becomes key, never resigns key, and so never closes on click-away. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The event tap retries every two seconds and said nothing when it failed, so a missing Accessibility permission looked like a hotkey that simply did nothing. Report the first failure, and say when it starts working. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Swapping the class left `"focusable": false` meaning nothing: tao answers canBecomeKeyWindow and canBecomeMainWindow from an ivar on the class the window no longer has. Give each kind its own NSPanel subclass that answers for itself, so the pill can't take key status from the app someone is dictating into. Say in the doc comment what changing the class actually costs: tao's two focus overrides, its sendEvent: override for drag-by-background, and set_focusable, which would now abort. Soften the Windows and Linux stubs to say nothing extra is needed today, rather than claiming those systems never cover floating windows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
f99d319 to
eb6fc68
Compare
|
@karansinghgit Done, and rebased on The non-focusable case now has its own subclass. Verified at runtime rather than assumed: One correction on the mechanism, since it may matter elsewhere. I probed the previous build before changing it, and a borderless nonactivating So the pill wasn't taking key status in practice, and I couldn't reproduce swallowed keystrokes while clicking it mid-recording. The change is still right, for the reason underneath your point: that NO was an undocumented AppKit default, not Both smaller notes are in the doc comment, which now describes what changing the class costs in terms of tao's behaviour rather than instance variables: the two focus overrides, the Windows and Linux stubs softened to say nothing extra is needed today, noting exclusive full screen apps and some Wayland compositors as where that would change. Checks are green on the rebase: Happy to squash the three commits, or drop the hotkey logging one, whichever you prefer. 🤖 Generated with Claude Code |
What and why
On macOS the recorder pill and the menu bar panel only appeared on an empty desktop. As soon as any app was full screen, neither showed, so dictation gave no visual feedback at all in the case where you most want it — transcription and pasting worked, you just couldn't see anything.
Three things are needed for a window to join another app's full screen Space. Tauri exposes none of them, and the window stays invisible if any one is missing:
NSWindowCollectionBehaviorFullScreenAuxiliaryvisibleOnAllWorkspacesonly setscanJoinAllSpaces, which covers regular SpacesNSStatusWindowLevelalwaysOnToponly reachesNSFloatingWindowLevel, too low to be admittedNSPanelNSWindowof an inactive app is kept out whatever its flags sayI confirmed each one is necessary rather than assuming: with the first two applied,
isOnActiveSpacewas stillfalseover a full screen app, and only becametrueonce the windows were panels.SpeakType 1's recorder was already a nonactivating
NSPanelwith[.canJoinAllSpaces, .fullScreenAuxiliary](speaktype/Controllers/MiniRecorderWindowController.swift), so this brings SpeakType 2 back in line with it.Two follow-on changes come from the panel conversion:
set_focus. tao implements it asmakeKeyAndOrderFront:followed byactivateIgnoringOtherApps:, and that activation switched the user to whichever Space the main window was on and dismissed the full screen app's menu bar.show()already sendsmakeKeyAndOrderFront:, and a nonactivating panel takes focus without activating the app.NSPanelsubclass restoringcanBecomeKeyWindow. tao overrides that for borderless windows, and the override goes with the class. Without it the panel never becomes key, so it never resigns key, so it never closed on click-away.Tested on
macOS 26.6.2, Apple Silicon. Not tested on Windows or Linux: both get no-op stubs, so behaviour there is unchanged by construction, but a second pair of eyes on that would be welcome.
Note for review
float_over_fullscreenchanges the window's class in place withobject_setClass. It is the same approachtauri-nspaneltakes, andNSPaneldeclares no instance variables of its own, so it is sound — but it is undocumented, and it silently dropped tao'scanBecomeKeyWindowoverride, which is what the subclass above restores. If a future tao version puts more behaviour on its window class, this would need revisiting. I'm happy to switch totauri-nspanelinstead if you'd rather have the maintained version, at the cost of a new dependency.The second commit is unrelated housekeeping and can be dropped if you prefer: the modifier-hotkey event tap retried every two seconds and logged nothing when it failed, so a missing Accessibility permission was indistinguishable from a hotkey that did nothing. It now reports the first failure and says when it recovers.
🤖 Generated with Claude Code