nikitabobko / AeroSpace

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

3s+ lag when switching to space with unity editor #497

Open devidw opened 1 week ago

devidw commented 1 week ago

When switching to a space that has a window of Unity Editor open it takes 3s or longer until the space switch actually takes place visually.

Checklist

aerospace CLI client version: 0.14.2-Beta 0cb8dbdfc5ee73b8cbc200f175f467ebead55201
AeroSpace.app server version: 0.14.2-Beta 0cb8dbdfc5ee73b8cbc200f175f467ebead55201
RW21 commented 3 days ago

Probably duplicate of #131 . I'm facing the same issue with games on the Love2d Engine.

voidpointer0 commented 1 day ago

I have the same issue with Unity. The moment I launch it, AeroSpace starts lagging (around 10 seconds to switch between workspaces). Hope this gets fixed, I'm running Unity 90% of the time. Loving AeroSpace otherwise.

Edit: added aerospace version.

Config: Macbook Pro M1 2020 16GB macOS 14.6.1 aerospace CLI client version: 0.14.2-Beta AeroSpace.app server version: 0.14.2-Beta

jakenvac commented 23 hours ago

Also getting this when Godot (another game engine) is open. I'll try to investigate this later on today. Think this is also a duplicate of #483

jakenvac commented 23 hours ago

Using the accessibility inspector on the Godot window also lags a lot. I'm guessing the hang up in Aerospace is the accessibility API on certain apps. Possibly something to do with OpenGL, but that's just a guess at this point.

jakenvac commented 23 hours ago

I can confirm this also happens with Love2D. Although seems significantly more severe with Godot.

Edit: Updating here instead of spamming with more comments.

I ran a hyperfine benchmark of aerospace list-apps with and without godot running. No other changes:

Godot running:

hyperfine "aerospace list-apps"
Benchmark 1: aerospace list-apps
  Time (mean ± σ):     988.1 ms ±  34.3 ms    [User: 6.0 ms, System: 6.1 ms]
  Range (min … max):   892.2 ms … 1008.2 ms    10 runs

Godot not running:

hyperfine "aerospace list-apps"
Benchmark 1: aerospace list-apps
  Time (mean ± σ):      32.4 ms ±   3.9 ms    [User: 3.7 ms, System: 3.0 ms]
  Range (min … max):    24.9 ms …  42.4 ms    73 runs

When navigating between windows, the delay with godot seems to 'stack'. The more I navigate into and out of the godot window, the worse the lag gets until all my window management freezes for a while and then all the buffered inputs execute at the same time.

Hopefully I'll get some time to do some actual profiling on AeroSpace tonight.

-- Update: 2024-09-18

I've done some profiling, but I can't seem to pinpoint the cause of the slowdowns. It does indeed seem to happen when interacting with the accessibility APIs, and this aligns with my experience using the accessibility inspector.

Using Xcode instruments, I've found that the hangs occur during calls to the apis, but the apis themselves don't seem to take more than a few ms to complete, so I'm still not sure what's happening. My experience with instruments is limited so I might be missing something obvious.

One thing that has become apparent though is that, if possible, some of the accessibility logic could be taken off the main thread - Any slowdown in AeroSpace can completely halt further usage and even lock up the system because it's trying to catch up with switching windows, listen to inputs etc.

--

Okay so I've found at least one of the problematic accessibility calls. While inspecting a 4 second hang, I can see a call to AXUIElementCopyAttributeValue that takes 1.87s to complete. That's half of the hang accounted for at least.

Screenshot 2024-09-18 at 13 32 28

I think that another problematic call is NSWorkspace.shared.runningAppications combined with the filter that checks the computed property activationPolicy. This is used when iterating over all of the manageable apps. It's not as impactful, but as activationPolicy is 'called' in a closure during an iteration, it adds up.

--

Not really discovered anything more, other than running godot in headless mode also causes the lag (maybe worse?), despite not having a window.

jakenvac commented 40 minutes ago

I've found a workaround for Godot, maybe there's something similar for Unity. In the godot editor settings, under Interface -> Editor, right at the bottom there is a Update Continuously checkbox. Enabling this seems to solve the issue.

No idea why.

Also seeing this slowdown with the Bevy game engine, too - I've spent an entire day researching this and the most I've come up with is that these game engines are running the game loops on the main thread, which is also where a traditional window loop (that answers to the AX api requests) runs, so it ends up competing and the AX api's have to wait until the app has time to respond. But I've not been able to confirm any of this.