Make Find/Replace topmost only while main window has focus#11243
Conversation
Avoids the Find/Replace dialogs floating above other applications on macOS, where Avalonia maps Topmost to NSWindowLevel.Floating process-wide. Topmost is now toggled dynamically based on owner/child activation, giving the same behavior on Windows, Linux, and macOS without an OS-specific branch. Alternative to #11234. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Updates Find/Replace tool-window behavior so they are only Topmost while Subtitle Edit (or the tool window itself) is active, preventing the dialogs from floating above other applications on macOS due to Avalonia’s Topmost mapping.
Changes:
- Added
WindowService.KeepTopmostWhileOwnerActive(child, owner)to dynamically recomputeTopmostbased on window activation state. - Updated
MainViewModel.ShowFind/ShowReplaceto use the new helper instead of unconditionalTopmost = true. - Simplified wrap-around MessageBox handling by removing manual
Topmosttoggling aroundMessageBox.Show.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/ui/Logic/WindowsService.cs | Adds helper to keep owned tool windows topmost only while owner/child is active. |
| src/ui/Features/Main/MainViewModel.cs | Switches Find/Replace to the helper and removes manual topmost flipping around wrap-around MessageBox. |
IsLoaded reflects the logical tree and can still be true briefly after the native window is torn down, so a queued Dispatcher callback could touch Topmost on a disposed window. IsClosing() (IsVisible + PlatformImpl null check) is the pattern used elsewhere in the UI layer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
This business of windows hovering over others sounds a lot like it's related to a comment I added to #11229. I don't know if you noticed it. It seems to me like what you're dealing with here, with certain windows allowed to & not allowed to hover over certain other windows is very closely related to the issue I raised in the other pull request. I'm speculating that the work you're doing here is applicable there as well. |
Apply WindowService.KeepTopmostWhileOwnerActive — introduced for Find/Replace in SubtitleEdit#11243 — to the undocked video player and audio visualizer windows. They now stay visually above SE main while either SE window is the active app, and drop behind when SE loses focus to another application. This addresses GrampaWildWilly's follow-up on SubtitleEdit#11229 ("the audio visualizer doesn't stay visible, floating on top of the main window") without touching Alt+Tab behavior — KeepTopmost… is just a Z-order knob; the two undocked windows remain independent top-levels in the Alt+Tab list, which was the point of SubtitleEdit#11229. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Topmostdynamically based on owner/child window activation instead of being unconditionally topmost.TopmosttoNSWindowLevel.Floatingprocess-wide), without needing anOperatingSystem.IsMacOS()branch.Implementation
WindowService.KeepTopmostWhileOwnerActive(child, owner)helper subscribes toActivated/Deactivatedon both windows and recomputeschild.Topmost = owner.IsActive || child.IsActive. Handlers are removed onchild.Closed.ShowFindandShowReplaceinMainViewModelcall the helper instead of settingwindow.Topmost = true.ShowWrapAroundDialogno longer needs to manually flipTopmostaroundMessageBox.Show— the message box stealing focus already triggers the helper to drop the dialog out of topmost.Test plan
🤖 Generated with Claude Code