Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Treat emacs child frames as popups
Emacs child frames (posframes, corfu completion popups, etc.) are
transient UI elements that should not be managed by Aerospace.

Fixes #776
  • Loading branch information
jperras committed Mar 31, 2026
commit a1c9a67fbed78570eb3bfff5e87669b82b927896
10 changes: 10 additions & 0 deletions Sources/AppBundle/model/AxUiElementWindowType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,16 @@ extension AxUiElementMock {
return false
}

// Emacs child frames (posframes, corfu completion popups, etc.)
// These are transient UI elements that should not be managed as windows.
// https://github.com/nikitabobko/AeroSpace/issues/776
if id == .emacs &&
get(Ax.subroleAttr) == kAXFloatingWindowSubrole &&
get(Ax.isMainAttr) == false
{
return false
}

if id?.isFirefox != true {
return isWindowHeuristicOld(axApp: axApp, id)
}
Expand Down
59 changes: 59 additions & 0 deletions axDumps/emacs_child_frame_corfu.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"AXActivationPoint" : "<AXValue 0x88dc9a940> {value = x:-1.000000 y:1801.000000 type = kAXValueCGPointType}",
"AXCancelButton" : null,
"AXCloseButton" : null,
"AXDefaultButton" : null,
"AXDocument" : null,
"AXFocused" : 0,
"AXFrame" : "<AXValue 0x88c4e4240> {value = x:1518.000000 y:920.000000 w:270.000000 h:242.000000 type = kAXValueCGRectType}",
"AXFullScreen" : 0,
"AXFullScreenButton" : null,
"AXGrowArea" : null,
"AXMain" : 0,
"AXMinimizeButton" : null,
"AXMinimized" : 0,
"AXModal" : 0,
"AXParent" : "<AXUIElement Application 0x88c445200> {pid=39373}",
"AXPosition" : "<AXValue 0x88e0084b0> {value = x:1518.000000 y:920.000000 type = kAXValueCGPointType}",
"AXProxy" : null,
"AXRole" : "AXWindow",
"AXSections" : [],
"AXSize" : "<AXValue 0x88dc9b4e0> {value = w:270.000000 h:242.000000 type = kAXValueCGSizeType}",
"AXSubrole" : "AXFloatingWindow",
"AXTitle" : "EmacsCorfuGUI",
"AXTitleUIElement" : null,
"AXToolbarButton" : null,
"AXZoomButton" : null,
"Aero.AXApp" : {
"AXExtrasMenuBar" : null,
"AXFocusedUIElement" : "AXUIElement(AxWindowId=78408, title=\"test.py – Doom Emacs\", role=\"AXWindow\", subrole=\"AXStandardWindow\")",
"AXFocusedWindow" : "AXUIElement(AxWindowId=78408, title=\"test.py – Doom Emacs\", role=\"AXWindow\", subrole=\"AXStandardWindow\")",
"AXFrame" : null,
"AXFrontmost" : 1,
"AXFunctionRowTopLevelElements" : [],
"AXMainWindow" : "AXUIElement(AxWindowId=78408, title=\"test.py – Doom Emacs\", role=\"AXWindow\", subrole=\"AXStandardWindow\")",
"AXMenuBar" : "<AXUIElement 0x88c445200> {pid=39373}",
"AXPosition" : null,
"AXRole" : "AXApplication",
"AXSize" : null,
"AXTitle" : "Emacs",
"AXWindows" : [
"AXUIElement(AxWindowId=78635, title=\"EmacsCorfuGUI\", role=\"AXWindow\", subrole=\"AXFloatingWindow\")",
"AXUIElement(AxWindowId=78408, title=\"test.py – Doom Emacs\", role=\"AXWindow\", subrole=\"AXStandardWindow\")"
],
"Aero.AxIgnored" : "AXChildren, AXChildrenInNavigationOrder, AXEnhancedUserInterface, AXPreferredLanguage, AXRoleDescription, AXHidden"
},
"Aero.App.appBundleId" : "org.gnu.Emacs",
"Aero.App.nsApp.activationPolicy" : "regular",
"Aero.App.nsApp.execPath" : "file:///opt/homebrew/Cellar/emacs-plus@30/30.2/Emacs.app/Contents/MacOS/Emacs-real",
"Aero.App.version" : "9.0",
"Aero.App.versionShort" : "30.2",
"Aero.AxIgnored" : "AXChildrenInNavigationOrder, AXChildren, AXRoleDescription",
"Aero.axWindowId" : 78635,
"Aero.AxUiElementWindowType_isDialogHeuristic" : true,
"Aero.AxUiElementWindowType" : "popup",
"Aero.on-window-detected" : [],
"Aero.treeNodeParent" : "AppBundle.Workspace",
"Aero.windowLevel" : "normalWindow",
"Aero.workspace" : "1"
}
59 changes: 59 additions & 0 deletions axDumps/emacs_child_frame_posframe.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"AXActivationPoint" : "<AXValue 0x88dc9b4e0> {value = x:-1.000000 y:1801.000000 type = kAXValueCGPointType}",
"AXCancelButton" : null,
"AXCloseButton" : null,
"AXDefaultButton" : null,
"AXDocument" : null,
"AXFocused" : 0,
"AXFrame" : "<AXValue 0x88c4e5900> {value = x:1607.000000 y:873.000000 w:490.000000 h:32.000000 type = kAXValueCGRectType}",
"AXFullScreen" : 0,
"AXFullScreenButton" : null,
"AXGrowArea" : null,
"AXMain" : 0,
"AXMinimizeButton" : null,
"AXMinimized" : 0,
"AXModal" : 0,
"AXParent" : "<AXUIElement Application 0x88c447570> {pid=39373}",
"AXPosition" : "<AXValue 0x88dc9bcf0> {value = x:1607.000000 y:873.000000 type = kAXValueCGPointType}",
"AXProxy" : null,
"AXRole" : "AXWindow",
"AXSections" : [],
"AXSize" : "<AXValue 0x88dc9bab0> {value = w:490.000000 h:32.000000 type = kAXValueCGSizeType}",
"AXSubrole" : "AXFloatingWindow",
"AXTitle" : "posframe",
"AXTitleUIElement" : null,
"AXToolbarButton" : null,
"AXZoomButton" : null,
"Aero.AXApp" : {
"AXExtrasMenuBar" : null,
"AXFocusedUIElement" : "AXUIElement(AxWindowId=78408, title=\"test.py – Doom Emacs\", role=\"AXWindow\", subrole=\"AXStandardWindow\")",
"AXFocusedWindow" : "AXUIElement(AxWindowId=78408, title=\"test.py – Doom Emacs\", role=\"AXWindow\", subrole=\"AXStandardWindow\")",
"AXFrame" : null,
"AXFrontmost" : 0,
"AXFunctionRowTopLevelElements" : [],
"AXMainWindow" : "AXUIElement(AxWindowId=78408, title=\"test.py – Doom Emacs\", role=\"AXWindow\", subrole=\"AXStandardWindow\")",
"AXMenuBar" : "<AXUIElement 0x88c447570> {pid=39373}",
"AXPosition" : null,
"AXRole" : "AXApplication",
"AXSize" : null,
"AXTitle" : "Emacs",
"AXWindows" : [
"AXUIElement(AxWindowId=78636, title=\"posframe\", role=\"AXWindow\", subrole=\"AXFloatingWindow\")",
"AXUIElement(AxWindowId=78408, title=\"test.py – Doom Emacs\", role=\"AXWindow\", subrole=\"AXStandardWindow\")"
],
"Aero.AxIgnored" : "AXChildren, AXChildrenInNavigationOrder, AXEnhancedUserInterface, AXPreferredLanguage, AXRoleDescription, AXHidden"
},
"Aero.App.appBundleId" : "org.gnu.Emacs",
"Aero.App.nsApp.activationPolicy" : "regular",
"Aero.App.nsApp.execPath" : "file:///opt/homebrew/Cellar/emacs-plus@30/30.2/Emacs.app/Contents/MacOS/Emacs-real",
"Aero.App.version" : "9.0",
"Aero.App.versionShort" : "30.2",
"Aero.AxIgnored" : "AXChildrenInNavigationOrder, AXChildren, AXRoleDescription",
"Aero.axWindowId" : 78636,
"Aero.AxUiElementWindowType_isDialogHeuristic" : true,
"Aero.AxUiElementWindowType" : "popup",
"Aero.on-window-detected" : [],
"Aero.treeNodeParent" : "AppBundle.Workspace",
"Aero.windowLevel" : "normalWindow",
"Aero.workspace" : "1"
}
Loading