XcodesOrg / XcodesApp

The easiest way to install and switch between multiple versions of Xcode - with a mouse click.
MIT License
6.87k stars 299 forks source link

App icon install progress bar stuck #529

Closed jnozzi closed 3 months ago

jnozzi commented 6 months ago

Describe the bug After a successful installation, the app icon's progress bar remained at mostly-done. This is visible both in the dock and in the app switcher.

To Reproduce I'm not exactly sure; I clicked to install 15.2, then clicked the iOS 17.2 installer shortly after, while the Xcode install was in progress. I haven't tried it again (I'm a bit swamped).

Expected behavior When there're no running tasks, the app icon (both Dock and in app switcher) shouldn't show a progress bar.

Screenshots I didn't think to take a screenshot. The progress bar had maybe <=10% left.

Version

Kyle-Ye commented 6 months ago

+1 for this issue.

This seems to be related with resetDockProgressTracking and setupDockProgress call.

cc @senmu

I will also try to debug and solve it if I'm available this week.

Kyle-Ye commented 6 months ago

Found the issue here

image
  1. First we hit line 431 unxipProgress.completedUnitCount = AppState.totalProgressUnits and set progress to 0.9987682686384189
  2. Then we hit line 432 to call resetDockProgressTracking()

This should remove the overlay as the comments is saying. (At first, I suspect the bug is because we are missing resetDockProgressTracking call somewhere)

func resetDockProgressTracking() {
    DockProgress.progress = 1 // Only way to completely remove overlay with DockProgress is setting progress to complete
}

But it will actually do nothing in this case, because the previous progress is 0.9987682686384189 and the diff is less than 0.01 so the DockProgress just ignores the update.

// DockProgress.swift
public static var progress: Double = 0 {
    didSet {
        if previousProgress == 0 || (progress - previousProgress).magnitude > 0.01 {
            previousProgress = progress
            updateDockIcon()
        }
    }
}

We can fix it on our side or update the library version.

The latest upstream version has removed such limitation. https://github.com/sindresorhus/DockProgress/blob/fb80c50c8eac4c1143da6ec602b8fad760c1613a/Sources/DockProgress/DockProgress.swift#L107-L115

Also I was wondering why DockProgress.resetProgress is not working previously so that the original contributor is using DockProgress.progress = 1 here.

Would you help to tell use what's the suggested way to reset/remove it? cc @sindresorhus

Kyle-Ye commented 6 months ago

XcodesApp is using DockProgress 3.2.0 now.

To solve the issue, I think upgrade the latest 4.3.0 would probably fix it. (DockProgress.progress.setter logic has been updated on 4.3.0)

And also we'd like to confirm the preferred way to reset the Dock bar: DockProgress.progress = 1 or DockProgress.resetProgress()

Kyle-Ye commented 6 months ago

Update:

  1. Update DockProgress 3.2.0 -> 4.3.0. XcodesApp will need some code change to adopt the new @MainActor check

  2. Keep DockProgress.progress = 1 or change it to DockProgress.resetProgress() will present a full progress bar and never disappear after the dependency update.

image

We may need to call other API to achieve the same effect(Present full progress bar and then disappear) after the update.

image

~There may also be other issues on XcodesApp which cause the DockProgress API is not called on the main thread.~ Identified the issue and fixed it.

Kyle-Ye commented 6 months ago

This issue and #491 seems to be duplicated. Would you help close one as duplicated? (Prefer to close the latter since we have more context on this issue here)cc @MattKiazyk

Kyle-Ye commented 6 months ago

This upstream has patched a commit to fix the issue.

~Opened #545 and make it a draft due to a missing new release version from the upstream.~

Update the PR. It's ready for a review.

See detail here https://github.com/sindresorhus/DockProgress/issues/20#issuecomment-2028082964