Skip to content

Commit ce6628e

Browse files
committed
Improve isWindow logic
I'm afraid to push such improved logic for all apps in the patch release. So I will do it only for Firefox for now. _closes #1115
1 parent 0c721df commit ce6628e

File tree

1 file changed

+44
-5
lines changed

1 file changed

+44
-5
lines changed

Sources/AppBundle/tree/MacWindow.swift

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,45 @@ final class MacWindow: Window, CustomStringConvertible {
211211
}
212212

213213
/// Alternative name: !isPopup
214+
///
215+
/// Why do we need to filter out non-windows?
216+
/// - "floating by default" workflow
217+
/// - It's annoying that the focus command treats these popups as floating windows
218+
private func isWindowNew(_ axWindow: AXUIElement, _ app: MacApp) -> Bool {
219+
// Just don't do anything with "Ghostty Quick Terminal" windows.
220+
// Its position and size are managed by the Ghostty itself
221+
// https://github.com/nikitabobko/AeroSpace/issues/103
222+
// https://github.com/ghostty-org/ghostty/discussions/3512
223+
if app.id == "com.mitchellh.ghostty" && axWindow.get(Ax.identifierAttr) == "com.mitchellh.ghostty.quickTerminal" {
224+
return false
225+
}
226+
227+
// Try to filter out incredibly weird popup like AXWindows without any buttons.
228+
// E.g.
229+
// - Sonoma (macOS 14) keyboard layout switch (AXSubrole == AXDialog)
230+
// - IntelliJ context menu (right mouse click)
231+
// - Telegram context menu (right mouse click)
232+
// - Share window purple "pill" indicator https://github.com/nikitabobko/AeroSpace/issues/1101. Title is not empty
233+
// - Tooltips on links mouse hover in browsers (Chrome, Firefox)
234+
// - Tooltips on buttons (e.g. new tab, Extensions) mouse hover in browsers (Chrome, Firefox). Title is not empty
235+
// Make sure that the following AXWindow remain windows:
236+
// - macOS native file picker ("Open..." menu) (subrole == kAXDialogSubrole)
237+
// - telegram image viewer (subrole == kAXFloatingWindowSubrole)
238+
// - Finder preview (hit space) (subrole == "Quick Look")
239+
// - Firefox non-native video fullscreen (about:config -> full-screen-api.macos-native-full-screen -> false, subrole == AXUnknown)
240+
return axWindow.get(Ax.closeButtonAttr) != nil ||
241+
axWindow.get(Ax.fullscreenButtonAttr) != nil ||
242+
axWindow.get(Ax.zoomButtonAttr) != nil ||
243+
axWindow.get(Ax.minimizeButtonAttr) != nil ||
244+
245+
axWindow.get(Ax.isFocused) == true || // 3 different ways to detect if the window is focused
246+
axWindow.get(Ax.isMainAttr) == true ||
247+
app.getFocusedAxWindow()?.containingWindowId() == axWindow.containingWindowId() ||
248+
249+
axWindow.get(Ax.subroleAttr) == kAXStandardWindowSubrole
250+
}
251+
252+
/// Compatibility. Replace isWindow -> isWindowNew in 0.18.0
214253
func isWindow(_ axWindow: AXUIElement, _ app: MacApp) -> Bool {
215254
let subrole = axWindow.get(Ax.subroleAttr)
216255

@@ -222,6 +261,10 @@ func isWindow(_ axWindow: AXUIElement, _ app: MacApp) -> Bool {
222261
return false
223262
}
224263

264+
if app.id == "org.mozilla.firefox" {
265+
return isWindowNew(axWindow, app)
266+
}
267+
225268
lazy var title = axWindow.get(Ax.titleAttr) ?? ""
226269

227270
// Try to filter out incredibly weird popup like AXWindows without any buttons.
@@ -247,11 +290,7 @@ func isWindow(_ axWindow: AXUIElement, _ app: MacApp) -> Bool {
247290
return subrole == kAXStandardWindowSubrole ||
248291
subrole == kAXDialogSubrole || // macOS native file picker ("Open..." menu) (kAXDialogSubrole value)
249292
subrole == kAXFloatingWindowSubrole || // telegram image viewer
250-
app.id == "com.apple.finder" && subrole == "Quick Look" || // Finder preview (hit space) is a floating window
251-
252-
// Firefox non-native video fullscreen
253-
// about:config -> full-screen-api.macos-native-full-screen -> false
254-
app.id == "org.mozilla.firefox" && subrole == kAXUnknownSubrole
293+
app.id == "com.apple.finder" && subrole == "Quick Look" // Finder preview (hit space) is a floating window
255294
}
256295

257296
// This function is referenced in the guide

0 commit comments

Comments
 (0)