nikitabobko / AeroSpace

AeroSpace is an i3-like tiling window manager for macOS
https://nikitabobko.github.io/AeroSpace/guide
MIT License
5.64k stars 89 forks source link

Newly opened unconventional windows not focused #409

Closed chungyinleo closed 2 weeks ago

chungyinleo commented 1 month ago

Hi, thanks for the great work!

When unconventional windows are opened, the original focused window gets focused instead of the newly opened windows. Examples include windows opened with

mpv --no-native-fs some_video_file

and

qlmanage -p some_photo

I encountered this problem when running these commands from the terminal (kitty). Instead of the MPV player or the preview pane being focused, the terminal window is focused, blocking the player and the preview pane. A cmd + tab can bring the focus back to the desired window, but this does not seem to be the desired behaviour.

Can this issue be resolved with proper configurations or will it need a more complex solution?

Edit: Adding screenshots

image image

As you can see, only the latest focused window is blocking, other windows do not block.

nikitabobko commented 1 month ago

Does the windows show up in the aerospace debug-windows?

Does it look like duplicate of #202 ?

chungyinleo commented 1 month ago

Sorry for the confusion. The two examples I listed behave the same on the surface, but should be separate problems based on the output of aerospace debug-windows.

qlmanage -p does not show up in aerospace debug-windows. Only info of kitty, in which I ran the debug command appears.

mpv --no-native-fs does show up

net.kovidgoyal.kitty.window.1543 windowId: 1543
net.kovidgoyal.kitty.window.1543 workspace: T
net.kovidgoyal.kitty.window.1543 treeNodeParent: AppBundle.TilingContainer
net.kovidgoyal.kitty.window.1543 recognizedAsDialog: false
net.kovidgoyal.kitty.window.1543 AXTitle: Optional(aerospace debug-wind ~/Downloads)
net.kovidgoyal.kitty.window.1543 AXRole: Optional(AXWindow)
net.kovidgoyal.kitty.window.1543 AXSubrole: Optional(AXStandardWindow)
net.kovidgoyal.kitty.window.1543 AXFocused: Optional(0)
net.kovidgoyal.kitty.window.1543 AXFullScreen: Optional(0)
net.kovidgoyal.kitty.window.1543 AXFrame: Optional(<AXValue 0x600000cbd0c0> {value = x:4.000000 y:48.000000 w:1792.000000 h:1076.000000 type = kAXValueCGRectType})
net.kovidgoyal.kitty.window.1543 AXPosition: Optional(<AXValue 0x6000017bc3f0> {value = x:4.000000 y:48.000000 type = kAXValueCGPointType})
net.kovidgoyal.kitty.window.1543 AXGrowArea: nil
net.kovidgoyal.kitty.window.1543 AXMinimizeButton: AXUIElement {
net.kovidgoyal.kitty.window.1543      AXRole: Optional(AXButton)
net.kovidgoyal.kitty.window.1543      AXTitle: nil
net.kovidgoyal.kitty.window.1543      AXSubrole: Optional(AXMinimizeButton)
net.kovidgoyal.kitty.window.1543      AXEnabled: Optional(1)
net.kovidgoyal.kitty.window.1543      AXParent: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      AXTopLevelUIElement: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      AXWindow: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      Ignored: AXFrame, AXSize, AXFocused, AXHelp, AXPosition, AXRoleDescription
net.kovidgoyal.kitty.window.1543 }
net.kovidgoyal.kitty.window.1543 AXDocument: nil
net.kovidgoyal.kitty.window.1543 AXSections: [
net.kovidgoyal.kitty.window.1543         Optional({
net.kovidgoyal.kitty.window.1543             SectionDescription = Content;
net.kovidgoyal.kitty.window.1543             SectionObject = "<AXUIElement 0x6000017bd6b0> {pid=95327}";
net.kovidgoyal.kitty.window.1543             SectionUniqueID = AXContent;
net.kovidgoyal.kitty.window.1543         })
net.kovidgoyal.kitty.window.1543 ]
net.kovidgoyal.kitty.window.1543 AXCloseButton: AXUIElement {
net.kovidgoyal.kitty.window.1543      AXRole: Optional(AXButton)
net.kovidgoyal.kitty.window.1543      AXTitle: nil
net.kovidgoyal.kitty.window.1543      AXSubrole: Optional(AXCloseButton)
net.kovidgoyal.kitty.window.1543      AXEnabled: Optional(1)
net.kovidgoyal.kitty.window.1543      AXParent: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      AXTopLevelUIElement: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      AXWindow: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      Ignored: AXFrame, AXSize, AXFocused, AXHelp, AXPosition, AXRoleDescription, AXEdited
net.kovidgoyal.kitty.window.1543 }
net.kovidgoyal.kitty.window.1543 AXMain: Optional(1)
net.kovidgoyal.kitty.window.1543 AXActivationPoint: Optional(<AXValue 0x600001741e90> {value = x:14.000000 y:62.000000 type = kAXValueCGPointType})
net.kovidgoyal.kitty.window.1543 AXFullScreenButton: AXUIElement {
net.kovidgoyal.kitty.window.1543      AXRole: Optional(AXButton)
net.kovidgoyal.kitty.window.1543      AXTitle: nil
net.kovidgoyal.kitty.window.1543      AXSubrole: Optional(AXFullScreenButton)
net.kovidgoyal.kitty.window.1543      AXEnabled: Optional(1)
net.kovidgoyal.kitty.window.1543      AXParent: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      AXTopLevelUIElement: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      AXWindow: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      Ignored: AXFrame, AXSize, AXFocused, AXChildren, AXHelp, AXPosition, AXRoleDescription
net.kovidgoyal.kitty.window.1543 }
net.kovidgoyal.kitty.window.1543 AXProxy: nil
net.kovidgoyal.kitty.window.1543 AXDefaultButton: nil
net.kovidgoyal.kitty.window.1543 AXMinimized: Optional(0)
net.kovidgoyal.kitty.window.1543 AXParent: Optional(<AXUIElement Application 0x6000017bc3f0> {pid=95327})
net.kovidgoyal.kitty.window.1543 AXTitleUIElement: nil
net.kovidgoyal.kitty.window.1543 AXCancelButton: nil
net.kovidgoyal.kitty.window.1543 AXModal: Optional(0)
net.kovidgoyal.kitty.window.1543 AXZoomButton: AXUIElement {
net.kovidgoyal.kitty.window.1543      AXRole: Optional(AXButton)
net.kovidgoyal.kitty.window.1543      AXTitle: nil
net.kovidgoyal.kitty.window.1543      AXSubrole: Optional(AXFullScreenButton)
net.kovidgoyal.kitty.window.1543      AXEnabled: Optional(1)
net.kovidgoyal.kitty.window.1543      AXParent: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      AXTopLevelUIElement: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      AXWindow: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty.window.1543      Ignored: AXFrame, AXSize, AXFocused, AXChildren, AXHelp, AXPosition, AXRoleDescription
net.kovidgoyal.kitty.window.1543 }
net.kovidgoyal.kitty.window.1543 AXSize: Optional(<AXValue 0x600001741e90> {value = w:1792.000000 h:1076.000000 type = kAXValueCGSizeType})
net.kovidgoyal.kitty.window.1543 AXToolbarButton: nil
net.kovidgoyal.kitty.window.1543 Ignored: AXChildrenInNavigationOrder, AXChildren, AXRoleDescription
net.kovidgoyal.kitty             AXRole: Optional(AXApplication)
net.kovidgoyal.kitty             AXTitle: Optional(kitty)
net.kovidgoyal.kitty             AXFunctionRowTopLevelElements: [
net.kovidgoyal.kitty             ]
net.kovidgoyal.kitty             AXFrame: nil
net.kovidgoyal.kitty             AXFocusedUIElement: AXUIElement(windowId=1543, title=nil, role="AXTextArea", subrole=nil)
net.kovidgoyal.kitty             AXFrontmost: Optional(1)
net.kovidgoyal.kitty             AXExtrasMenuBar: nil
net.kovidgoyal.kitty             AXMainWindow: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty             AXFocusedWindow: AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty             AXMenuBar: Optional(<AXUIElement 0x600001742cd0> {pid=95327})
net.kovidgoyal.kitty             AXWindows: [
net.kovidgoyal.kitty                 AXUIElement(windowId=1543, title="aerospace debug-wind ~/Downloads", role="AXWindow", subrole="AXStandardWindow")
net.kovidgoyal.kitty             ]
net.kovidgoyal.kitty             AXSize: nil
net.kovidgoyal.kitty             AXPosition: nil
net.kovidgoyal.kitty             Ignored: AXChildren, AXChildrenInNavigationOrder, AXEnhancedUserInterface, AXPreferredLanguage, AXRoleDescription, AXHidden

NULL-APP-BUNDLE-ID.window.2001 windowId: 2001
NULL-APP-BUNDLE-ID.window.2001 workspace: nil
NULL-APP-BUNDLE-ID.window.2001 treeNodeParent: AppBundle.MacosPopupWindowsContainer
NULL-APP-BUNDLE-ID.window.2001 recognizedAsDialog: true
NULL-APP-BUNDLE-ID.window.2001 AXTitle: Optional(AeroSpace tiling window manager for macOS Demo [UOl7ErqWbrk].webm - mpv)
NULL-APP-BUNDLE-ID.window.2001 AXRole: Optional(AXWindow)
NULL-APP-BUNDLE-ID.window.2001 AXSubrole: Optional(AXUnknown)
NULL-APP-BUNDLE-ID.window.2001 AXFocused: Optional(1)
NULL-APP-BUNDLE-ID.window.2001 AXFullScreen: Optional(0)
NULL-APP-BUNDLE-ID.window.2001 AXFrame: Optional(<AXValue 0x600000ca7700> {value = x:0.000000 y:0.000000 w:1800.000000 h:1169.000000 type = kAXValueCGRectType})
NULL-APP-BUNDLE-ID.window.2001 AXPosition: Optional(<AXValue 0x600001763ae0> {value = x:0.000000 y:0.000000 type = kAXValueCGPointType})
NULL-APP-BUNDLE-ID.window.2001 AXGrowArea: nil
NULL-APP-BUNDLE-ID.window.2001 AXMinimizeButton: nil
NULL-APP-BUNDLE-ID.window.2001 AXDocument: nil
NULL-APP-BUNDLE-ID.window.2001 AXSections: [
NULL-APP-BUNDLE-ID.window.2001 ]
NULL-APP-BUNDLE-ID.window.2001 AXCloseButton: nil
NULL-APP-BUNDLE-ID.window.2001 AXMain: Optional(1)
NULL-APP-BUNDLE-ID.window.2001 AXActivationPoint: Optional(<AXValue 0x600001763ae0> {value = x:-1.000000 y:1170.000000 type = kAXValueCGPointType})
NULL-APP-BUNDLE-ID.window.2001 AXFullScreenButton: nil
NULL-APP-BUNDLE-ID.window.2001 AXProxy: nil
NULL-APP-BUNDLE-ID.window.2001 AXDefaultButton: nil
NULL-APP-BUNDLE-ID.window.2001 AXMinimized: Optional(0)
NULL-APP-BUNDLE-ID.window.2001 AXParent: Optional(<AXUIElement Application 0x6000017bff00> {pid=80296})
NULL-APP-BUNDLE-ID.window.2001 AXTitleUIElement: nil
NULL-APP-BUNDLE-ID.window.2001 AXCancelButton: nil
NULL-APP-BUNDLE-ID.window.2001 AXModal: Optional(0)
NULL-APP-BUNDLE-ID.window.2001 AXZoomButton: nil
NULL-APP-BUNDLE-ID.window.2001 AXSize: Optional(<AXValue 0x600001733f00> {value = w:1800.000000 h:1169.000000 type = kAXValueCGSizeType})
NULL-APP-BUNDLE-ID.window.2001 AXToolbarButton: nil
NULL-APP-BUNDLE-ID.window.2001 Ignored: AXChildrenInNavigationOrder, AXChildren, AXRoleDescription
NULL-APP-BUNDLE-ID             AXRole: Optional(AXApplication)
NULL-APP-BUNDLE-ID             AXTitle: Optional(mpv)
NULL-APP-BUNDLE-ID             AXFunctionRowTopLevelElements: [
NULL-APP-BUNDLE-ID             ]
NULL-APP-BUNDLE-ID             AXFrame: nil
NULL-APP-BUNDLE-ID             AXFocusedUIElement: AXUIElement(windowId=2001, title="AeroSpace tiling window manager for macOS Demo [UOl7ErqWbrk].webm - mpv", role="AXWindow", subrole="AXUnknown")
NULL-APP-BUNDLE-ID             AXFrontmost: Optional(1)
NULL-APP-BUNDLE-ID             AXExtrasMenuBar: nil
NULL-APP-BUNDLE-ID             AXMainWindow: AXUIElement(windowId=2001, title="AeroSpace tiling window manager for macOS Demo [UOl7ErqWbrk].webm - mpv", role="AXWindow", subrole="AXUnknown")
NULL-APP-BUNDLE-ID             AXFocusedWindow: AXUIElement(windowId=2001, title="AeroSpace tiling window manager for macOS Demo [UOl7ErqWbrk].webm - mpv", role="AXWindow", subrole="AXUnknown")
NULL-APP-BUNDLE-ID             AXMenuBar: Optional(<AXUIElement 0x6000017404b0> {pid=80296})
NULL-APP-BUNDLE-ID             AXWindows: [
NULL-APP-BUNDLE-ID                 AXUIElement(windowId=2001, title="AeroSpace tiling window manager for macOS Demo [UOl7ErqWbrk].webm - mpv", role="AXWindow", subrole="AXUnknown")
NULL-APP-BUNDLE-ID             ]
NULL-APP-BUNDLE-ID             AXSize: nil
NULL-APP-BUNDLE-ID             AXPosition: nil
NULL-APP-BUNDLE-ID             Ignored: AXChildren, AXChildrenInNavigationOrder, AXEnhancedUserInterface, AXPreferredLanguage, AXRoleDescription, AXHidden

!!! DISCLAIMER !!!
!!! 'debug-windows' command is not stable API. Please don't rely on the command existence and output format !!!
!!! The only intended use case is to report bugs about incorrect windows handling !!!

Debug session finished

where NULL-APP-BUNDLE-ID is the app id of mpv from aerospace list-apps.

nikitabobko commented 1 month ago

According the logs, AeroSpace mistakenly detects mpv window as a popup because the window has no decorations, and non-standart AXSubrole, but I couldn't reproduce the issue locally when I do mpv --no-native-fs some_video_file or even mpv --border=no --no-native-fs some_video_file, you somehow hid the window decorations. Please attach your mpv config

nikitabobko commented 1 month ago

I reproduced the problem with qlmanage

When AeroSpace asks accessibility API about existing windows, macOS doesn't report about the qlmanage window. Even built-in Accessibility Inspector.app cannot capture the window. Remarkably, if you try to use quick preview from finder by hiting space, everything works. It's a macOS bug and unfortunately nothing can be done

chungyinleo commented 1 month ago

That is indeed unfortunate. I do hope the mpv will have a solution. Below is my mpv config.

no-native-fs
fs
save-position-on-quit
force-window
sub-auto=fuzzy

I believe the difference is related to the option fs

nikitabobko commented 4 weeks ago

I still can't reproduce. I put your text to ~/.config/mpv/mpv.conf and mpv window I still being tiled. My mpv version is 0.38.0.

There is something with your mpv setup, please try to minimize it and understand what the exact config causes the issue. I'm not an mpv user, so please make sure to make your instruction clear for non-mpv users. Like what is in your config, what is the config location, what cli flags did you use, what mpv version you use, try to update to the latest mpv version, etc

chungyinleo commented 4 weeks ago

The problem should be reproduced by mpv --fs --no-native-fs video_file with no other configs. These are the only two flags that matter. The mpv version is 0.38.0, installed with brew install mpv.

The fs flag tells mpv to start fullscreen, while the no-native-fs flag tells mpv not to use macOS native fullscreen.

One thing I do not understand from your comment is that with the fs flag, the desired behaviour is the window not getting tiled and being on top of all other windows. It should look like if you focus on mpv, then press "f". If your window is still being tiled like a normal window, I wonder if the fs flag functioned properly for you.

I checked the debug info again with and without the flags. AXSubrole: Optional(AXUnknown) appears only if both of the above flags are used. Without one or both of the flags, the debug info shows them as standard windows. Please make sure the fs flag is used and that mpv starts fullscreen, then you can try to reproduce the problem that the terminal window is obscuring the supposedly fullscreen player with the no-native-fs flag.

chungyinleo commented 2 weeks ago

I accidentally found the real culprit. The problem is caused by aerospace sub-command being called when the front app is switched. Whenever it is called, the windows get reorganized and since the mpv and qlmanage -p windows are not recognized as usual windows, they get obscured.

This happened to me because I use sketchybar. I have an item subscribed to front_app_switched, which calls aerospace list-workspaces --focused to update the item. So the windows actually get focused correctly, but then the event front_app_switched is triggered, calling aerospace, which reorganizes the windows. For now, I get around this by not using aerospace to update the item, which limits the integration between aerospace and sketchybar. This is unfortunate, but allows me to use a terminal file manager to preview images just like what Finder is capable of. Now both mpv and qlmanage -p are working properly with aerospace

Note: previewing with Finder works fine because the app is still Finder when the preview pane is opened.

I wonder if you also use sketchybar and if you could reproduce this behaviour. I also wonder can aerospace sub-command be called without reorganizing the windows. With these questions answered this issue can be closed.

nikitabobko commented 2 weeks ago

I wonder if you also use sketchybar and if you could reproduce this behaviour

I don't use sketchybar

I also wonder can aerospace sub-command be called without reorganizing the windows

Probably #317