Skip to content

Fix: Discard Changes no longer pauses when window loses focus#21739

Merged
niik merged 2 commits intodevelopmentfrom
copilot/fix-discard-changes-window
Mar 5, 2026
Merged

Fix: Discard Changes no longer pauses when window loses focus#21739
niik merged 2 commits intodevelopmentfrom
copilot/fix-discard-changes-window

Conversation

Copy link
Contributor

Copilot AI commented Mar 5, 2026

Discarding a large set of files would stall whenever the user switched away from the Desktop window, because the per-file work was scheduled via requestAnimationFrame — which Electron/browsers throttle to 0 fps on blur.

queueWorkHigh was introduced when moveItemToTrash was synchronous and blocked the render loop. That API is now async, so the animation-frame queue buys nothing and only introduces the focus dependency.

Description

  • git-store.ts: Replace queueWorkHigh(files, async file => { … }) with a plain for…of loop. Each await this.shell.moveItemToTrash(…) call is already non-blocking; no frame-budget coordination needed.
  • queue-work.ts: Delete. No remaining callers.
// Before – stalls when window loses focus
await queueWorkHigh(files, async file => {  })

// After – runs to completion regardless of window focus
for (const file of files) {  }

Screenshots

N/A – no UI changes.

Release notes

Notes: [Fixed] Discard Changes now completes even when the GitHub Desktop window is not focused

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • electronjs.org
    • Triggering command: /opt/hostedtoolcache/node/24.14.0/x64/bin/node /opt/hostedtoolcache/node/24.14.0/x64/bin/node /opt/hostedtoolcache/node/24.14.0/x64/lib/node_modules/npm/bin/node-gyp-bin/../../node_modules/node-gyp/bin/node-gyp.js rebuild (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>"Discard Changes" Only Runs if Window is Active</issue_title>
<issue_description>### The problem

Since I'm working in angular, I always have tons of build artifacts to discard which takes a minute or two (also seems to be getting slower lately). As such, I used to start the discard process, then switch to another window and do something else, then it would be done when I returned. Recently it's changed so that it won't complete the process unless I remain in the GitHub Desktop window until it's finished.

UPDATE
I recently tried with a much smaller number of files, and it finished while I was in another window. Either the problem is dependent on the number/size of files being discarded, and/or it's just that the process is taking so long that it seems like the only way to complete it is to have the window open.

Release version

Version 3.5.5 (x64)

Operating system

Windows 11

Steps to reproduce the behavior

  1. Highlight files in the changes tab
  2. Right click → discard changes
  3. Switch to another window for a while
  4. Return to GitHub Desktop and see that the discard process is still running
  5. Remain in the window and it will finish (eventually..)

Log files

2026-02-26.desktop.production.log

Screenshots

Image

Additional context

In this project, build artifacts are intentionally tracked in Git due to deployment requirements. They cannot be added to .gitignore, as automated deployment scripts rely on committing these artifacts. Therefore, ignoring the build output is not a viable workaround.</issue_description>

Comments on the Issue (you are @copilot in this section)

@niik This is almost certainly due to our queuing logic using `requestAnimationFrame`. I thought we had disabled energy saving functions (such as stopping animations on blur) but I may be mistaken

export async function queueWorkHigh<T>(
items: Iterable<T>,
worker: (item: T) => Promise<any> | any
) {
const iterator = items[Symbol.iterator]()
let next = iterator.next()
while (!next.done) {
const start = await awaitAnimationFrame()

Seems like we should probably switch this to using setImmediate instead but before we do so we should investigate whether we even need the work queue any more. I recall adding the work queue because moving to trash on Windows was synchronous and blocked the render loop. I would be surprised if that's still the case.</comment_new>
<comment_new>@niik
Yeah, as I suspected, trashItem is asynchronous now. When the work queue was written it used the moveItemToTrash API which was synchronous. We can just get rid of the queueWorkHigh method and call trashItem directly.</comment_new>

Custom agent used: deskocat
Takes an unstructured issue or idea and produces a planned, tested, risk-assessed implementation with a well-documented PR


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…op in discardChanges

The queueWorkHigh utility used requestAnimationFrame to spread synchronous
moveItemToTrash work across frames. Since moveItemToTrash is now async, this
is no longer necessary — and the use of requestAnimationFrame caused the
discard loop to stall whenever the window lost focus (energy-saving behavior).

Replace the queueWorkHigh call in GitStore.discardChanges with a simple
for...of + await loop, and remove the now-unused queue-work.ts file.

Co-authored-by: niik <634063+niik@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix discard changes functionality when window is inactive Fix: Discard Changes no longer pauses when window loses focus Mar 5, 2026
Copilot finished work on behalf of niik March 5, 2026 08:53
@niik niik marked this pull request as ready for review March 5, 2026 08:58
@niik niik enabled auto-merge March 5, 2026 13:50
@niik niik merged commit 0a0a0fc into development Mar 5, 2026
21 checks passed
@niik niik deleted the copilot/fix-discard-changes-window branch March 5, 2026 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"Discard Changes" Only Runs if Window is Active

3 participants