lwouis / alt-tab-macos

Windows alt-tab on macOS
https://alt-tab-macos.netlify.app
GNU General Public License v3.0
10.95k stars 331 forks source link

Incorrect order after opening a url from Telegram #951

Open PhilipDukhov opened 3 years ago

PhilipDukhov commented 3 years ago

Sometimes when I open a link from Telegram in Chrome, and wanna come back to Telegram, the top app is still Telegram, so I can't switch fast back to it.

As you can see on the screenshot, the selected app is Chrome, but in AltTab first app is still Telegram. screenshot

I tried to see the difference in logs, but haven't found any. My test scenario:

  1. clean Xcode logs
  2. open Telegram with Dock
  3. open link
  4. wait Chrome to open the page
  5. Try to switch back.

Same link may produce a bug and may not. I haven't found any pattern.

Log looks the same for both cases - when order is correct and when it's broken:

"Accessibility event" "AXApplicationActivated" "Telegram"
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXFocusedWindowChanged" "nil"
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXFocusedWindowChanged" "Telegram"
"Accessibility event" "AXApplicationActivated" "Chrome"
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXTitleChanged" "Untitled - Google Chrome – Philip (Work)"
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXWindowCreated" ""
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXTitleChanged" "... - Google Chrome – Philip (Work)"
"showUiOrCycleSelection"
"showUiOrCycleSelection: isFirstSummon"
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXFocusedWindowChanged" ""
"Accessibility event" "AXWindowCreated" ""
"hideUi"
"Accessibility event" "AXWindowCreated" ""
"Accessibility event" "AXApplicationActivated" "Xcode"

Any other logs I can collect that can help you?

p.s. Not sure if Telegram is essential here, I mostly open links from this app. Notes looks working without problem. Telegram shows an alert before actually opening the url, may this be the reason?

Screenshot 2021-05-12 at 21 57 08
lwouis commented 3 years ago

I downloaded Telegram on my phone + mac to test this.

I followed the steps you provided, yet it works correctly for me. See this video showcase:

https://user-images.githubusercontent.com/106195/117998543-f6097c00-b37e-11eb-982a-ed5bcb35d72d.mov

PhilipDukhov commented 3 years ago

Looks like it's indeed because of that alert. It's presented when you click on a hyperlink text. To send one you can select text and press CMD+U

lwouis commented 3 years ago

I'm getting a different UI than your screenshot:

image

The issue doesn't happen after I click Open

What version of macOS and Telegram are you using? It seems that you may be on Big Sur which is not supported yet. The alerts on that version seem to pose a problem: https://github.com/lwouis/alt-tab-macos/issues/718

PhilipDukhov commented 3 years ago

Mac 11.3.1 Telegram 7.7 (215786) AppStore

https://user-images.githubusercontent.com/6103621/118001083-9906c980-b370-11eb-8cac-1afb3e2cf1d4.mov

I see, so the problem is that Big Sur is not yet supported 🥲

I guess you could've add this information in red color to the documentation, because I personally haven't noticed "to 10.15" inside Compatibility 😁

Do you have a plan to add the support?

If no, do you have an idea where should I look for?

For now it's the only issue I've faced during a couple of days usage, but a pretty irritating one, so I'd like to try to fix it by myself.

lwouis commented 3 years ago

I guess you could've add this information in red color to the documentation, because I personally haven't noticed "to 10.15" inside Compatibility 😁

Seems pretty clear to me:

image

That being said, we could improve the experience by detecting the version of the OS from the web browser, and if it is outside of the supported range, we would show some UI like a red ribbon, or a popup when the user clicks to download it. I added this idea to https://github.com/lwouis/alt-tab-macos/issues/211. For homebrew user, this is already happening since compatibility is specified in the cask and homebrew will warn the user.

Update: I thought this over, and wrote more in-depth analysis here.

Do you have a plan to add the support?

There are already some issues reported by Big Sur users: https://github.com/lwouis/alt-tab-macos/issues?q=is%3Aissue+is%3Aopen+label%3A%22big+sur%22

I tried to work on some of these in a VM, but it's very hard to work that way, so I plan on looking at them once my main laptop is on Big Sur. I'm not in a hurry to upgrade though, so it may take a while.

If no, do you have an idea where should I look for? For now it's the only issue I've faced during a couple of days usage, but a pretty irritating one, so I'd like to try to fix it by myself.

After clicking the link, the Chrome window gets focused. It seems that AltTab never gets that event, and still think the Telegram window is still the latest which got focused.

In your video, you do the steps twice. The first time it works fine, and the second time the issue happens. You say that the logs are the same which surprises me. It would imply the "chrome window got focused" event is always received by AltTab.

Most of the relevant code should be in src/logic/events/AccessibilityEvents.swift

PhilipDukhov commented 3 years ago

Looks like a concurrency problem.

I've added some logs:

"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXFocusedWindowChanged" "Telegram"
"Accessibility event" "AXApplicationActivated" "Chrome"
2021-05-13 12:40:54.944967+0700 AltTab[12887:542611] applicationActivated(_:_:_:) send DispatchQueue.main.async AXApplicationActivated
"Accessibility event" "AXFocusedUIElementChanged" "nil"
"Accessibility event" "AXTitleChanged" "Untitled - Google Chrome – Philip (Work)"
2021-05-13 12:40:54.962711+0700 AltTab[12887:542802] focusedWindowChanged(_:_:_:) send DispatchQueue.main.async AXFocusedWindowChanged

As you can see focusedWindowChanged processing time is much longer than applicationActivated one, that's why updateLastFocus gets called at first for Chrome, and then for Telegram again.

Changing axCallsQueue type to serial solves this problem, which is fine for now, but maybe you can think for a better solution.

focusedWindowChanged Line

let axTitle = try element.title()

takes 0.038665 sec to execute.

lwouis commented 3 years ago

The commit where I made the queue concurrent references this ticket: https://github.com/lwouis/alt-tab-macos/issues/563

But beyond that I can tell you the following: this queue is concurrent because there will be many concurrent events to process at a given time. An app for instance can take a while to be subscribed to for its accessibility events. If we use a sequential queue, then that app would block any other event from being processed. This means all sorts of issues in AltTab. Even if we avoid blocking the main thread here, we would see inconsistent state of AltTab vs the real windows/OS state since any event can block the queue if it doesn't process right away (happens for many hard to reproduce reasons).

That being said, the fact that app activation and focus events should be processed in the right order means that current implementation is not satisfactory. I'm not sure how to do it best. It's a bit of a "pick your poison" situation:

I changed the implementation of focusedUiElementChanged somewhat recently to:

fileprivate func focusedUiElementChanged(_ pid: pid_t) throws {
    pid.retryToRefreshTabsUntilScreenIsNotAnimating { App.app.refreshOpenUi($0) }
}

The idea was to avoid guessing tabs (tabs are a mess with no public API so we have to guess and work-around the OS quirks) if the OS is animating a Space transition for example. Maybe on Big Sur, the pop-over you showed in the screenshot is detected as such OS animation since it's pretty slow. Maybe that's the reason the focusedUiElementChanged event is slow to process, and the AXApplicationActivated event ends up processed before it.

I think a fix to move forward would be either to improve the retryToRefreshTabsUntilScreenIsNotAnimating function so that it deals better with Big Sur. Another approach could be to have special handling of the focus events. We could immediately update the windows focus order, then process the rest of the things later.

I think digging into retryToRefreshTabsUntilScreenIsNotAnimating has the best trade-offs, so probably we should start there.