Closed Bug 2053177 Opened 7 days ago Closed 7 days ago

nsIFilePicker invokes callback before another modal can be safely launched

Categories

(Core :: Widget: Cocoa, defect)

Unspecified
macOS
defect

Tracking

()

RESOLVED FIXED
154 Branch
Tracking Status
relnote-firefox --- 152+
firefox152 --- fixed
firefox153 --- fixed
firefox154 --- fixed

People

(Reporter: jtracey, Assigned: spohl)

References

Details

Attachments

(3 files)

In bug 2052844, Thunderbird is seeing a new behavior on macOS 25 ("new" with the OS version, not "new" with an application update) where launching another dialog immediately after the callback for filePicker.open resolves causes the application to hang. Adding an await new Promise(resolve => Services.tm.dispatchToMainThread(resolve)); line between them makes the problem disappear, which makes me suspect something is causing the callback to invoke when the file is chosen instead of when the modal is fully unwound. We can work around it in the meantime, but I suspect this is something that should be fixed more generally.

Assignee: nobody → spohl.mozilla.bugs
Status: NEW → ASSIGNED

On macOS 26, the NSSavePanel/NSOpenPanel sheet completion handler can run before the panel's modal session has fully unwound. We invoke nsIFilePickerShownCallback::Done() synchronously from inside that completion handler, so a consumer that opens another modal from Done() (for example Thunderbird's "Backup Secret Key to File" flow in bug 2052844) starts the new modal on top of a session that is still tearing down, which hangs.

Defer Done() to a fresh main-thread turn in all four picker modes (open, open-multiple, folder, save) so the modal finishes unwinding first. This matches the JS-side workaround of bouncing off Services.tm.dispatchToMainThread before launching the next modal, but fixes it once for every file-picker consumer. The callback still runs on the main thread exactly once with the same ResultCode; only its timing moves one turn later.

Pushed by spohl@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/74a71a4f0991 https://hg.mozilla.org/integration/autoland/rev/2a30e91b0728 Defer the macOS file picker callback until the modal has unwound. r=mac-reviewers,mstange,jtracey
Status: ASSIGNED → RESOLVED
Closed: 7 days ago
Resolution: --- → FIXED
Target Milestone: --- → 154 Branch
Duplicate of this bug: 2052844
See Also: 2052844
Duplicate of this bug: 2053690

Apparently this is affecting 153 (and even earlier) versions too (when they get the OS update). Can we uplift?

firefox-beta Uplift Approval Request

  • User impact if declined/Reason for urgency: Opening a second file picker dialog can cause a hang.
  • Code covered by automated testing?: no
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: This simply defers invoking filepicker callbacks to another main thread turn.
  • String changes made/needed?: none
  • Is Android affected?: no
Attachment #9606583 - Flags: approval-mozilla-beta?

On macOS 26, the NSSavePanel/NSOpenPanel sheet completion handler can run before the panel's modal session has fully unwound. We invoke nsIFilePickerShownCallback::Done() synchronously from inside that completion handler, so a consumer that opens another modal from Done() (for example Thunderbird's "Backup Secret Key to File" flow in bug 2052844) starts the new modal on top of a session that is still tearing down, which hangs.

Defer Done() to a fresh main-thread turn in all four picker modes (open, open-multiple, folder, save) so the modal finishes unwinding first. This matches the JS-side workaround of bouncing off Services.tm.dispatchToMainThread before launching the next modal, but fixes it once for every file-picker consumer. The callback still runs on the main thread exactly once with the same ResultCode; only its timing moves one turn later.

Original Revision: https://phabricator.services.mozilla.com/D310869

firefox-release Uplift Approval Request

  • User impact if declined/Reason for urgency: Opening a second file picker dialog can cause a hang.
  • Code covered by automated testing?: no
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: This simply defers invoking filepicker callbacks to another main thread turn.
  • String changes made/needed?: none
  • Is Android affected?: no
Attachment #9606584 - Flags: approval-mozilla-release?

On macOS 26, the NSSavePanel/NSOpenPanel sheet completion handler can run before the panel's modal session has fully unwound. We invoke nsIFilePickerShownCallback::Done() synchronously from inside that completion handler, so a consumer that opens another modal from Done() (for example Thunderbird's "Backup Secret Key to File" flow in bug 2052844) starts the new modal on top of a session that is still tearing down, which hangs.

Defer Done() to a fresh main-thread turn in all four picker modes (open, open-multiple, folder, save) so the modal finishes unwinding first. This matches the JS-side workaround of bouncing off Services.tm.dispatchToMainThread before launching the next modal, but fixes it once for every file-picker consumer. The callback still runs on the main thread exactly once with the same ResultCode; only its timing moves one turn later.

Original Revision: https://phabricator.services.mozilla.com/D310869

Attachment #9606583 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Attachment #9606584 - Flags: approval-mozilla-release? → approval-mozilla-release+

Added to the 152.0.6 relnotes.

QA Whiteboard: [qa-triage-done-c154/b153]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: