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

AltTab not working while (Unity) project compiles #342

Closed
luiskrikey opened this issue May 19, 2020 · 9 comments
Closed

AltTab not working while (Unity) project compiles #342

luiskrikey opened this issue May 19, 2020 · 9 comments
Labels
bug Something isn't working

Comments

@luiskrikey
Copy link

While using Unity, if I jump into the code editor and make any change and then back to Unity, that will force the project to recompile. During that process, AltTab stops working for some reason. It's 100% reproducible.

Steps to reproduce the bug

  1. Open any Unity project
  2. Make a code change in any file with any editor of your choice
  3. AltTab to Unity, which will trigger a project recompilation
  4. AltTab stops working while the project recompiles (see loading animation on the bottom-right corner)
@luiskrikey luiskrikey added the bug Something isn't working label May 19, 2020
@luiskrikey luiskrikey changed the title AltTab not working while app (Unity) compiles AltTab not working while (Unity) project compiles May 19, 2020
@lwouis
Copy link
Owner

lwouis commented May 20, 2020

Hi @luiskrikey! That's a very peculiar issue. Thanks for taking the time to share it here!

I'll try to download Unity and reproduce this when I have some time. It is very intriguing that recompiling would affect AltTab somehow.

Is the rest of the OS responsive? It could be global lag perhaps? I know for instance that if I open the Finder, then press cmd+n a dozen times, then press alt+tab quickly after, it will wait for the all the windows to finish opening before AltTab shows. However it is clearly the whole OS lagging while the cmd+n are queued and executed. Some of these things are just macOS having poor design on some aspects, and just poorly handling multi-tasking at times.

@luiskrikey
Copy link
Author

Hey @lwouis, thanks for the reply.
The rest of the OS is responsive while Unity is compiling and AltTab is not affected unless we "land" on Unity while the compilation is happening.
To test this you can:

  1. Open any Unity project
  2. Right-click a code file (C#) and select reimport. This will trigger the recompilation.
  3. AltTab into any other program and see that it works as expected.
  4. AltTab into Unity while the reimport is still happening, and you will see that AltTab stops working until Unity finishes compilation.

This looks as if AltTab "grabs" itself to the current process and becomes unresponsive until that same process is responsive again. I've seen a few other issues that seem to report a behaviour where AltTab stops responding. Maybe it's all the same issue and here it's just simpler to replicate?

P.S.: My recommendation is to use a reasonably complex project to make sure the recompilation takes enough time to test this out. This sample from Unity should do it: https://github.com/Unity-Technologies/arfoundation-samples

@lwouis
Copy link
Owner

lwouis commented May 20, 2020

Oh! Thanks for providing more details. Based on what you described, I'm now guessing that the issue is this:

When releasing the shortcut, AltTab will send a raise/focus signal to the (Unity) window. I can imagine that if Unity is busy with something like recompiling, AltTab is blocking on that focus call until Unity finishes recompiling, and answers the call.

This is what i guess is happening. I'll try to reproduce soon. If i'm right then it may be possible to reproduce with a terminal but making it busy with some infinite loop then focusing its window.

I'm surprised by this though, as i thought i put the focus calls on another thread to avoid blocking AltTab on focus, in the past. This may be a regression

@lwouis
Copy link
Owner

lwouis commented May 21, 2020

I installed Unity, downloaded the sample project you shared, and after a few other steps, I was able to reproduce the issue!

It turns out it's not what I suspected. There are 2 distinct issues, that can both be generalized as such:

The Unity window that's recompiling was frozen, as proved by the fact that the mouse becomes a spinning wheel on that window, while it's recompiling. When we ask the OS for some info on the window, the OS blocks the calls until Unity is no longer busy and responds. These calls happen on AltTab main thread, thus freezing it.

There is no easy fix to this, as we have simply no way to get the info we need until the Unity window stops freezing. There are multiple scenarios where this issue happens:

  1. When invoking AltTab, we check all windows. This is why it is freezing globally when using AltTab when the unity window is frozen. For this one, I'll just remove that code. I added it to hopefully prevent Phantom windows created by app Optimus Player #200, but it was not a clear need, so I'll remove until other people open tickets about buggy windows being displayed (hopefully not 🤞).

  2. When we receive events from the system. The example I faced during my tests is switching focus to another window, then back to the frozen Unity window, as you have suggested. This triggers an OS event letting AltTab know that the user focused the unity Window. We track these things to keep track of the order of recent use of windows in AltTab. The issue again being that when the OS event arrived, we see that a window was focused. We check which window it is, and here the OS call blocks, as unity window is frozen.

So point 1 will be addressed, but point 2 is a whole category of issues that are extremely challenging to deal with. The only solution I can image is to put all these calls on another thread to avoid blocking the UI. However, this is not simply a technicality. It has impact on the user experience. If we now process OS events in parallel instead of in-sequence, we will be displaying potentially incorrect info to the user. Imagine this scenario for instance: you minimize the Unity window while it's frozen. The user then invoke AltTab. It will show the unity window as not minimized at this point, as AltTab has to wait for unity window to finish freezing, to get the info from it that it is minimized now. There may be other cases like this, and like changing focus where we may be in an incorrect state since we show the UI early before getting the information we need to know what changed.

At the technical level, it also would introduce great complexity as we need to upgrade to concurrent datastructures instead of the current Array, Set, and custom classes that we use. We would also have to avoid race conditions and other challenging aspects of concurrent code.

To be honest, I'm not sure it's worth it. Especially after I remove the code for point 1. Of course, my dream would be that a new contributor that's experienced with concurrent code steps in and shares a PR that tackles this challenge. That would be really cool

@luiskrikey
Copy link
Author

Thanks @lwouis for the clear explanation!

lwouis added a commit that referenced this issue May 21, 2020
Revert "fix: don't display invalid windows (may fix #292 #200)"

This reverts commit 1bca012
@lwouis
Copy link
Owner

lwouis commented May 21, 2020

I'll open a new ticket to discuss having the AX calls on a concurrent queue. This issue is broader than Unity. Even though it is a real-life use-case that demonstrates the issue, any app or window that stops responding could cause this, so I would like to discuss it generally.

This ticket will be closed when I release the next version which will fix point 1, which should make the situation a bit smoother for this use-case.

@koekeishiya
Copy link

koekeishiya commented May 21, 2020

Note that you can check if an application is responsive or not with the following function:
bool CGSEventIsAppUnresponsive(int cid, const ProcessSerialNumber *psn); I have not tested this lately, but it used to work at least. You could also (at least in the past) subscribe to get notified when an application becomes unresponsive/responsive:

extern CGError CGSRegisterNotifyProc(void  *callback, uint32_t type, void *context);

#define kCGSNotificationAppUnresponsive 750
#define kCGSNotificationAppResponsive 751

struct CGSProcessNotificationData {
	uint16_t minorVersion;
	uint16_t majorVersion;
	uint32_t length;	
        int cid;
	pid_t pid;
	ProcessSerialNumber psn;
};

// callback
void status_callback(uint32_t type, void *data, unsigned int length, void *context) 
{
    struct CGSProcessNotificationData *process_data = (struct CGSProcessNotificationData *) data;
    NSRunningApplication *application = [NSRunningApplication runningApplicationWithProcessIdentifier:process_data->pid];
    // do stuff
}

// register for notification with callback, usually performed at startup
CGSRegisterNotifyProc(status_callback, kCGSNotificationAppUnresponsive, NULL);

@lwouis lwouis closed this as completed in 41cb701 May 21, 2020
lwouis pushed a commit that referenced this issue May 21, 2020
# [3.24.0](v3.23.2...v3.24.0) (2020-05-21)

### Bug Fixes

* don't freeze when invoked while unity is recompiling (closes [#342](#342)) ([41cb701](41cb701)), closes [#292](#292) [#200](#200)
* don't freeze when sending a command to an frozen window ([408b800](408b800))
* show windows which are opened in fullscreen (closes [#335](#335)) ([2674c8f](2674c8f))

### Features

* show indicator for fullscreen windows ([0138cd1](0138cd1))
lwouis added a commit that referenced this issue May 25, 2020
BREAKING CHANGE: this rework should fix all sorts of issues when OS events happen in parallel: new windows, new apps, user shortcuts, etc. Here are example of use-cases that should work great now, without, and very quickly:

* AltTab is open and an app/window is launched/quit
* A window is minimized/deminimized, and while the animation is playing, the user invokes AltTab
* An app starts and takes a long time to boot (e.g. Gimp)
* An app becomes unresponsive, yet AltTab is unaffected and remains interactive while still processing the state of the window while its parent app finally stops being frozen

closes #348, closes #157, closes #342, closes #93
lwouis added a commit that referenced this issue May 25, 2020
BREAKING CHANGE: this rework should fix all sorts of issues when OS events happen in parallel: new windows, new apps, user shortcuts, etc. Here are example of use-cases that should work great now, without, and very quickly:

* AltTab is open and an app/window is launched/quit
* A window is minimized/deminimized, and while the animation is playing, the user invokes AltTab
* An app starts and takes a long time to boot (e.g. Gimp)
* An app becomes unresponsive, yet AltTab is unaffected and remains interactive while still processing the state of the window while its parent app finally stops being frozen

closes #348, closes #157, closes #342, closes #93
lwouis added a commit that referenced this issue May 25, 2020
BREAKING CHANGE: this rework should fix all sorts of issues when OS events happen in parallel: new windows, new apps, user shortcuts, etc. Here are example of use-cases that should work great now, without, and very quickly:

* AltTab is open and an app/window is launched/quit
* A window is minimized/deminimized, and while the animation is playing, the user invokes AltTab
* An app starts and takes a long time to boot (e.g. Gimp)
* An app becomes unresponsive, yet AltTab is unaffected and remains interactive while still processing the state of the window while its parent app finally stops being frozen

closes #348, closes #157, closes #342, closes #93
lwouis added a commit that referenced this issue May 25, 2020
BREAKING CHANGE: this rework should fix all sorts of issues when OS events happen in parallel: new windows, new apps, user shortcuts, etc. Here are example of use-cases that should work great now, without, and very quickly:

* AltTab is open and an app/window is launched/quit
* A window is minimized/deminimized, and while the animation is playing, the user invokes AltTab
* An app starts and takes a long time to boot (e.g. Gimp)
* An app becomes unresponsive, yet AltTab is unaffected and remains interactive while still processing the state of the window while its parent app finally stops being frozen

closes #348, closes #157, closes #342, closes #93
lwouis added a commit that referenced this issue May 25, 2020
BREAKING CHANGE: this rework should fix all sorts of issues when OS events happen in parallel: new windows, new apps, user shortcuts, etc. Here are example of use-cases that should work great now, without, and very quickly:

* AltTab is open and an app/window is launched/quit
* A window is minimized/deminimized, and while the animation is playing, the user invokes AltTab
* An app starts and takes a long time to boot (e.g. Gimp)
* An app becomes unresponsive, yet AltTab is unaffected and remains interactive while still processing the state of the window while its parent app finally stops being frozen

closes #348, closes #157, closes #342, closes #93
lwouis pushed a commit that referenced this issue May 25, 2020
# [4.0.0](v3.24.1...v4.0.0) (2020-05-25)

### Bug Fixes

* center-aligned layout was sometimes broken (closes [#352](#352)) ([e25dcd2](e25dcd2))
* crash in some rare scenarios with lots of windows ([a859347](a859347))
* potentially fix shortcuts not working sometimes ([8d833f5](8d833f5))
* rework all multi-threading to handle complex scenarios ([d144476](d144476)), closes [#348](#348) [#157](#157) [#342](#342) [#93](#93)
* sometimes windows titles use the wrong font ([fa1095e](fa1095e))
* update japanese localization ([acef0b2](acef0b2))

### BREAKING CHANGES

* this rework should fix all sorts of issues when OS events happen in parallel: new windows, new apps, user shortcuts, etc. Here are example of use-cases that should work great now, without, and very quickly:

* AltTab is open and an app/window is launched/quit
* A window is minimized/deminimized, and while the animation is playing, the user invokes AltTab
* An app starts and takes a long time to boot (e.g. Gimp)
* An app becomes unresponsive, yet AltTab is unaffected and remains interactive while still processing the state of the window while its parent app finally stops being frozen
@lwouis
Copy link
Owner

lwouis commented May 25, 2020

@luiskrikey I just released v4.0.0 which I believe will fix all sides of this problem. You should now be able to do anything with the frozen Unity window, and AltTab should stay 100% reactive and snappy in the meanwhile. Could you please let me know if that works for you? 👍

@luiskrikey
Copy link
Author

@lwouis Thank you so much, it works great. Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants