Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fight with Ghost windows. Actively check for closed windows on every "refresh session" #445

Closed
nikitabobko opened this issue Aug 22, 2024 · 29 comments
Labels
bug Something isn't working as expected problem Neither a bug, nor a feature request triaged The issue makes sense to maintainers

Comments

@nikitabobko
Copy link
Owner

nikitabobko commented Aug 22, 2024

macOS AX callbacks are unreliable. Sometimes windows can close but the kAXUIElementDestroyedNotification callback is not invoked (e.g. if user quickly closes several windows in a row)

AeroSpace already checks for new appeared windows on every "refresh session" to fight unreliable kAXWindowCreatedNotification callback.

The only window state that AeroSpace doesn't actively check for is when the window is closed. Currently AeroSpace "forgets" about windows only if kAXUIElementDestroyedNotification is invoked for them.

The reason for it is because I didn't find yet a reliable way to detect that AXUIElement is no longer valid. One approach that I tried before is to check that _AXUIElementGetWindow returns nil. Unfortunately, _AXUIElementGetWindow returns nil for every AXUIElement when the screen is locked


This issue should fix the problem that sometimes windows are "stuck", and AeroSpace thinks that they still exist when they don't


UPD: In Sequoia, using some apps may cause macOS to (completely?) stop sending kAXUIElementDestroyedNotification. Known apps, that interfere with AeroSpace: contexts app, Amazon Q

@nikitabobko nikitabobko added the problem Neither a bug, nor a feature request label Aug 22, 2024
@nikitabobko nikitabobko changed the title Check closed windows on every "refresh session" Actively check for closed windows on every "refresh session" Aug 22, 2024
@graywolf
Copy link

Since the format string for list-windows allows to list process ID, can you ignore AXUIElement and just check whether the process connected to window still lives? Sure, it would not be perfect due to pid reuse, but should probably work well enough?

@nikitabobko nikitabobko added the bug Something isn't working as expected label Sep 10, 2024
@aaftre

This comment was marked as spam.

@ezhang7423
Copy link

I am also having this issue. Concretely, I noticed that running
aerospace list-windows --workspace 1
return

Screenshot 2024-09-23 at 12 10 28 PM

However, the only open windows at this point is Warp. I have closed all of the code windows.

@aintyourcupoftea
Copy link

I think i am having this issue too.. Sometimes what happens is : When I open a browser and some other app (lets say notes) in same workspace. It runs fine. But, when I close the notes, the browser doesn't automatically resize to fill the screen..It stays as it is. I have to quite aerospace and open it again to fix it again and again.

@ezhang7423

This comment was marked as abuse.

@nikitabobko nikitabobko pinned this issue Oct 11, 2024
@nikitabobko nikitabobko changed the title Actively check for closed windows on every "refresh session" Fight with Ghost windows. Actively check for closed windows on every "refresh session" Oct 11, 2024
@dhruvasagar
Copy link

As a stop gap, would it be possible to add a separate command such as 'aerospace kill-ghost-windows' ? Restarting aerospace is a bummer because I have to manually move all windows to correct workspaces...

@dhruvasagar
Copy link

Alternatively, aerospace close --window-id <window-id> would also help

@aintyourcupoftea
Copy link

aintyourcupoftea commented Oct 14, 2024

Restarting aerospace is a bummer because I have to manually move all windows to correct workspaces...

That's true.

But, this can make your life easier till it gets fixed.

Add lines like these for your frequently used apps in aerospace.toml

[[on-window-detected]]
if.app-id = 'com.apple.finder'
run = "move-node-to-workspace E"

[[on-window-detected]]
if.app-id = 'com.apple.Notes'
run = "move-node-to-workspace N"

[[on-window-detected]]
if.app-id = 'net.whatsapp.WhatsApp'
run = "move-node-to-workspace W"

It will automatically keep those apps in that specific workspace all the time.

Also use option+x for closing windows instead of Cmd+W..

by adding this in your aerospace.toml

alt-x = 'close'

PS: I am using raycast so I can easily restart aerospace as I have assigned a shortcut [Control+~] for restart script

@jknetl
Copy link

jknetl commented Oct 16, 2024

Hi, I hit this issue quite often and it started to drive me crazy. I often take one of my browser tab to a separate window to see it side by side and every time I close it via cmd-w or clicking the close button It turns into ghost window. Effectively leaving a blank space on half of the screen.

After reading this issue commends the great hint is to use alt-x = 'close' as mentioned by @aintyourcupoftea. But habit is habit and I still often find myself closing window via MacOS native way...

As a workaround I wrote little script to move all ghost windows to a designated workspace (called BIN) in my case. Then I have keyboard mapping alt-g to execute that script. Which means any time I hit the issue I just press alt-g and it is gone.

Edit: the script would be better if it could kill the windows but when I try to kill a ghost window with aerospace close --window-id XY command I get: Can't close 'Firefox' window. Probably the window doesn't have a close button

@dhruvasagar
Copy link

@jknetl For me this script does not work since aerospace move-node-to-workspace does not support --window-id

@jknetl
Copy link

jknetl commented Oct 21, 2024

@dhruvasagar it does: https://nikitabobko.github.io/AeroSpace/commands#move-node-to-workspace Maybe it was added in a recent version? Have you tried upgrading?

I am have version 0.15.2-Beta installed

@dhruvasagar
Copy link

@jknetl I get the following error :

λ aerospace-remove-ghost-windows
Invalid <window-id> 38241 passed to --window-id
Invalid <window-id> 38967 passed to --window-id
Invalid <window-id> 38967 passed to --window-id
Invalid <window-id> 37558 passed to --window-id

@litszwaiboris
Copy link

don't blindly uses other's scripts, that's the thing you should know.
(basically you got some windows that are not open, and aerospace knows they are ghost windows but they can't do nothing about it since they aren't present physically on your desktop (not even the one pixel), so the window-id is not valid)

@dhruvasagar
Copy link

@litszwaiboris I never use any script blindly, I inspected and tested each command and looked at the documentation very carefully. I was sharing the error so someone would know that it doesn't work.

@nikitabobko nikitabobko added the triaged The issue makes sense to maintainers label Oct 27, 2024
@whaley
Copy link

whaley commented Oct 29, 2024

Is this reproducible over certain MacOS and/or aerospace versions? I have two Apple computers with the following versions

Mac Mini - no ghost window issues observed yet

❯ aerospace --version
aerospace CLI client version: 0.14.2-Beta 0cb8dbdfc5ee73b8cbc200f175f467ebead55201
AeroSpace.app server version: 0.14.2-Beta 0cb8dbdfc5ee73b8cbc200f175f467ebead55201

MacOS Version: 15.0.1 (24A348)

Macbook Pro - ghost windows happens anytime I cmd+w

❯ aerospace --version
aerospace CLI client version: 0.15.2-Beta b6cf82771f245ab7349a93baf8709e171537ff58
AeroSpace.app server version: 0.15.2-Beta b6cf82771f245ab7349a93baf8709e171537ff58

MacOS Version: 15.1 (24B83)

@FelixLisczyk
Copy link

Ghost windows also appear in Xcode when using the new Xcode extension for GitHub Copilot.

Should we report this issue to the developers of the affected apps? Is this something they can fix?

nikitabobko added a commit that referenced this issue Nov 1, 2024
nikitabobko added a commit that referenced this issue Nov 1, 2024
…ook lid

The problem with the MacBook lid is not 100% reproducible, it's flaky

A follow up on #445

The change in MacApp.swift is insignificant, it just further reduces the
chance of detecting problematic ax events.
@nikitabobko
Copy link
Owner Author

The potential fix was committed to main branch 405dec8 964e5b1

I am going to test it for a few days before making the release. I encourage everyone to do the same and report back. Please follow https://github.com/nikitabobko/AeroSpace/blob/main/dev-docs/development.md for the project setup, you can use install-from-sources.sh script to install AeroSpace as aerospace-dev brew cask.

I'm especially interested to see if something breaks if macOS goes to sleep, MacBook lid closes, screensaver activates, and you can add monitor configuration changes on top of it while everything mentioned is happening. These kind of circumstances.

The problem here is that when you lock the screen, go to sleep, etc. all windows are indistinguishable from closed, and AeroSpace has to restrain itself from destroying those windows if it detects sleep/locked_screen, detecting of which is itself turned out being fragile.

nikitabobko added a commit that referenced this issue Nov 2, 2024
#445

This commit is not necessary, it just makes me sleep better
@FelixLisczyk
Copy link

Hi @nikitabobko,

Thank you for your continued work on resolving this issue. I appreciate the detailed instructions and the potential fix you've committed to the main branch.

I've installed the latest commit 0ab5fde using the aerospace-dev cask and reinstalled the Contexts app. Here are my observations so far:

  • When I open two Finder windows on an empty space and close the second one immediately, the first window expands as expected to fill the width of the screen. This is working well!
  • However, I encountered an issue when I open a second window, move focus to the first window, and then close the second window using the mouse. In this scenario, the first window does not expand. To resolve this, I have to switch to another space and back (or execute another AeroSpace command) to clean up the ghost window.

I'll continue testing under different conditions, including those you mentioned (e.g., sleep mode, screen locking, etc.), and will report back with any further findings. Let me know if there's anything specific you'd like me to test.

Thanks again for your efforts!

@nikitabobko
Copy link
Owner Author

nikitabobko commented Nov 4, 2024

@FelixLisczyk thanks for letting me know. The problem in your second bullet point should be fixed in 00cbb63

You can update by running git pull + install-from-sources.sh once again

@aintyourcupoftea
Copy link

@nikitabobko Just Installed from sources..
Currently this is what I am facing..
Suppose I open App 1 and after that open App 2 in same workspace.
Now suppose I close App 1. Then App 2 won't resize automatically, I have to click on App 2's window or bring it to focus only then it will resize automatically.
But, still, this is so much better. I just have to click on the App 2 to bring it in focus and it will resize automatically.

@FelixLisczyk
Copy link

FelixLisczyk commented Nov 5, 2024

@aintyourcupoftea I haven't been able to reproduce this issue yet. Are you using the latest commit 00cbb63? You can check by looking at the top of the AeroSpace menu bar app. Also make sure that both the server and the client are using the same version:

aerospace --version
aerospace CLI client version: 0.0.0-SNAPSHOT 00cbb633178066858edb42c0c60ba8625da38976
AeroSpace.app server version: 0.0.0-SNAPSHOT 00cbb633178066858edb42c0c60ba8625da38976

My steps for reproducing the issue were:

  1. Open the Contexts app (to trigger ghost windows)
  2. Go to a new workspace
  3. Open the first app
  4. Open the second app
  5. Use AeroSpace to move focus back to the first app
  6. Quit the first app using Command + Q.

@aohoyd
Copy link

aohoyd commented Nov 6, 2024

@nikitabobko The problem looks fixed for me, thank you!

@aintyourcupoftea
Copy link

@FelixLisczyk I am sorry.. I am not able to produce the problem consistently. It just happens sometimes. So, I think that this commit can be released.

@mkutsevol
Copy link

mkutsevol commented Nov 8, 2024

I ran it for a day. I did have a window (vscode) that didn't expand until a mouse click. I forgot how I got there and what exactly I did. But it fixed itself, so not a problem. Sleeping / logging off / update to 15.1. It works. Thanks @nikitabobko !

@thalesmello
Copy link

thalesmello commented Nov 11, 2024

I've been using the debug version as well and the issue with ghost windows appears to be gone. Occasionally, after closing a window, the windows will only resize after I hit a shortcut key. I couldn't figure out the steps to reproduce it yet, but it's a lot less intrusive than the ghost windows sticking around.

Now the main issue with ghost windows appear to be go, I'm wondering when a release with the fix will be officially launched?

@lazywei
Copy link

lazywei commented Nov 13, 2024

I wasn't able to build locally so I leverage the GitHub actions and uploaded the built artifect here https://github.com/lazywei/AeroSpace/actions/runs/11826773439

In case anyone also interested in getting the latest build before the release is made.

(download link for AeroSpace.app and the binary https://github.com/lazywei/AeroSpace/actions/runs/11826773439/artifacts/2184714023)

@FelixLisczyk

This comment was marked as off-topic.

@kaustubh-walokar
Copy link

kaustubh-walokar commented Nov 22, 2024

I was able workaround by adding a alt-w = 'close' in the config and adding (clicking + under all apps) a different close window combination (I have it as shift-cmd-w) under mac keyboard shortcuts.

Works until the bug is released!

Example setup

image

nikitabobko added a commit that referenced this issue Nov 27, 2024
The cache is used restore windows that were mistakenly garbage collected
because of lock screen

#445
@nikitabobko
Copy link
Owner Author

The fix is released in 0.16.0-Beta

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working as expected problem Neither a bug, nor a feature request triaged The issue makes sense to maintainers
Projects
None yet
Development

No branches or pull requests