koekeishiya / yabai

A tiling window manager for macOS based on binary space partitioning
MIT License
24.2k stars 645 forks source link

Delay when unstacking windows #2188

Closed diocletiann closed 8 months ago

diocletiann commented 8 months ago

This is my "unstack" command:

yabai -m window --insert [SIDE] --toggle float --toggle float

It's been working great for a long time. Recently I'm noticing a ~1s delay under certain conditions, for example when there are multiple windows that get resized as a result and they are not full display width. I tried using two separate commands for insert and the two toggles and it didn't change the behavior.

koekeishiya commented 8 months ago

Resize is just a slow operation for some windows depending on which content they are drawing, and how the window frame changes. See for example this comment https://github.com/koekeishiya/yabai/issues/2137#issuecomment-1980643218

diocletiann commented 8 months ago

Fair enough. Only bringing this up because it happens in a space with only Alacritty windows which hadn't caused issues before.

koekeishiya commented 8 months ago

Nothing code-wise has changed for these operations that I can think of, so I'm not sure what exactly would be the cause if it is now happening a lot more frequently than before.

You can build yabai from source with profiling information if you want to try to identify patterns, and see where time is spent. Basically, when compiling the code run make install CLI_FLAGS=-DPROFILE=2 instead of just make install. You can do brew edit yabai and change the make install line in the formula if you brefer to use homebrew.

Sample outout when built with profiling samples, like with window_animation_duration enabled:

EVENT_HANDLER_DAEMON_MESSAGE: window --insert east --toggle float --toggle float
Total time: 129.8613ms (timer freq 24000000)
    EVENT_HANDLER_DAEMON_MESSAGE[1]: 761 (0.02%, 100.00% w/children)
    parse_window_selector[1]: 135 (0.00%)
    handle_domain_window[1]: 362 (0.01%, 99.97% w/children)
    window_manager_animate_window_list_async___prep_proxies[2]: 153151 (4.91%)
    window_manager_animate_window_list_async___wait_for_threads[2]: 1549814 (49.73%)
    window_manager_animate_window_list_async___swap_proxy_in[2]: 14875 (0.48%)
    window_manager_animate_window_list_async___notify_jb[2]: 19383 (0.62%)
    window_manager_animate_window_list_async___set_frame[2]: 535353 (17.18%)
    window_manager_animate_window_list[2]: 196952 (6.32%, 79.24% w/children)
    window_manager_focused_application[2]: 888 (0.03%)
    window_manager_focused_window[2]: 54307 (1.74%, 1.77% w/children)
    window_manager_set_window_insertion[1]: 319597 (10.25%)
    window_manager_make_window_floating[2]: 271070 (8.70%, 88.02% w/children)

and without animations:

EVENT_HANDLER_DAEMON_MESSAGE: window --insert east --toggle float --toggle float
Total time: 62.8209ms (timer freq 24000000)
    EVENT_HANDLER_DAEMON_MESSAGE[1]: 1177 (0.08%, 100.00% w/children)
    parse_window_selector[1]: 77 (0.01%)
    handle_domain_window[1]: 321 (0.02%, 99.92% w/children)
    window_manager_animate_window_list[2]: 672735 (44.62%)
    window_manager_focused_application[2]: 859 (0.06%)
    window_manager_focused_window[2]: 27365 (1.82%, 1.87% w/children)
    window_manager_set_window_insertion[1]: 508561 (33.73%)
    window_manager_make_window_floating[2]: 296543 (19.67%, 64.54% w/children)

In the latter case, 44.62% of time spent (out of 62ms), was spent calling the AX API to reposition and resize windows, and this is time we cannot reduce. The other operations that happen here can likely be improved somewhat. I haven't yet cataloged all this and identified where optimizations can take place yet.

Obviously these numbers can vary between runs for the exact same operations for various reasons; systems today are complex.

The long term goal is of course to try and look at these things in detail to identify commonly used areas that are feasible to make more performant.

diocletiann commented 8 months ago

Thanks for the details and for all the work on Yabai.

diocletiann commented 8 months ago

Sorry, hit the wrong button and closed the ticket. It seems macOS "freezes" during this pause, even a terminal window that isn't getting resized doesn't print anything until the pause ends. It also happens when using insert + warp. I'll try to build with profiling enabled and repro.

koekeishiya commented 8 months ago

Something with the --insert command sometimes causes the system API SLSCopyWindowsWithOptionsAndTags to take an insane amount of time, but only if the warp command happen rapidly and sequentially. Invoking yabai -m window --insert .. && yabai -m window --warp .. does not cause the system API to take forever to respond. Weird.

diocletiann commented 8 months ago

Hmm, I am sending insert followed by a warp in rapid succession to the yabai socket...

koekeishiya commented 8 months ago

Of course running the exact same command, running the exact same code/commit on my x86 Big Sur machine, the issue does not exist. Friggin Sonoma..

This output is from Sonoma:

EVENT_HANDLER_DAEMON_MESSAGE: window --insert east --warp east
Total time: 523.4631ms (timer freq 24000000)
    EVENT_HANDLER_DAEMON_MESSAGE[1]: 3131 (0.02%, 100.00% w/children)
    parse_window_selector[2]: 876 (0.01%, 96.12% w/children)
    handle_domain_window[1]: 223 (0.00%, 99.97% w/children)
    space_window_list_for_connection[1]: 9119 (0.07%, 96.11% w/children)
-->      **CopyWindowsWithOptionsAndTags[1]: 11907365 (94.78%)**    <--
    space_window_iterator[1]: 158351 (1.26%)
    view_find_window_node_in_direction[1]: 84 (0.00%, 96.11% w/children)
    window_manager_find_closest_managed_window_in_direction[1]: 114 (0.00%, 96.11% w/children)
    window_manager_focused_application[1]: 537 (0.00%)
    window_manager_focused_window[1]: 146967 (1.17%, 1.17% w/children)
    window_manager_set_window_insertion[1]: 336307 (2.68%)
koekeishiya commented 8 months ago

I think the --insert .. --warp .. chain should be resolved on master. Not sure what is going on with the --insert .. --toggle float part. If you could get some profiling information for that sequence, it could prove helpful.

diocletiann commented 8 months ago

Thank you. I tried to reproduce with HEAD using both --insert .. --warp .. and --insert .. --toggle float and I'm not seeing any delays. I'll rebuild with profiling enabled later today.

koekeishiya commented 8 months ago

Released 7.0.4. Hopefully this is resolved. Feel free to create a new issue if you happen to notice such issues in the future.

diocletiann commented 8 months ago

Released 7.0.4. Hopefully this is resolved. Feel free to create a new issue if you happen to notice such issues in the future.

I'm not able to repro this issue anymore, thank you!