Skip to content

Improve the performance of firo-qt on Mac when the UI is out of focus#1867

Open
psolstice wants to merge 1 commit into
masterfrom
mac-inhibit-nap
Open

Improve the performance of firo-qt on Mac when the UI is out of focus#1867
psolstice wants to merge 1 commit into
masterfrom
mac-inhibit-nap

Conversation

@psolstice

Copy link
Copy Markdown
Contributor

PR intention

When main window is out of focus on Mac the OS prioritises the performance of the application. This PR prevents that.

Code changes brief

Additional code in src/qt/macnapinhibitor.h/ .mm prevents nap from happening

@codeant-ai

codeant-ai Bot commented Jul 5, 2026

Copy link
Copy Markdown

User peter@shugalev.com does not have a PR Review subscription.

Go to Team management and add this email to the PR Review subscription.

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • Bug Fixes
    • Improved macOS behavior so the app is less likely to slow down background activity when the window is hidden or unfocused.
    • Preserved smoother wallet responsiveness during startup and shutdown on macOS.

Walkthrough

Adds a new MacNapInhibitor class for macOS, implemented using NSProcessInfo activity tokens, to disable and re-enable App Nap. Integrates calls into Qt application startup and shutdown, and adds the new source files to the macOS build configuration.

Changes

App Nap Inhibitor

Layer / File(s) Summary
MacNapInhibitor class definition and implementation
src/qt/macnapinhibitor.h, src/qt/macnapinhibitor.mm
New MacNapInhibitor class with static disableAppNap()/enableAppNap() methods, implemented via NSProcessInfo activity tokens with a file-local global tracking the active token, guarded against repeated calls.
Qt startup/shutdown wiring and build integration
src/qt/bitcoin.cpp, src/qt/CMakeLists.txt
Includes the new header on macOS, calls disableAppNap() at startup and enableAppNap() before shutdown return, and adds the new source files to the firoqt macOS build sources.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested labels: enhancement, GUI

Suggested reviewers: levonpetrosyan93

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main macOS App Nap performance change.
Description check ✅ Passed The description matches the required template and includes both the PR intention and a code changes brief.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mac-inhibit-nap

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot requested a review from levonpetrosyan93 July 5, 2026 12:24
@coderabbitai coderabbitai Bot added enhancement GUI GUI related issues labels Jul 5, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/qt/bitcoin.cpp (1)

759-764: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Early-return paths bypass enableAppNap().

Several return statements between disableAppNap() (Line 763) and enableAppNap() (Lines 933-935) — e.g. Lines 806, 816, 822, 832, 839, 853, 879, 888 — exit main() without re-enabling App Nap. Since the process terminates in all these cases, the OS reclaims the activity assertion regardless, so this is not currently harmful, but it breaks the disable/enable symmetry the class documents.

A scope-guard (RAII) wrapper around disableAppNap()/enableAppNap() would guarantee the pairing regardless of how main() exits, and is more in line with using RAII instead of manual paired calls.

Also applies to: 919-936

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/qt/bitcoin.cpp` around lines 759 - 764, The App Nap handling in main() is
manually paired and several early return paths bypass the later enableAppNap()
call, breaking the intended symmetry. Refactor the MacNapInhibitor usage in
bitcoin.cpp around the existing disableAppNap() and enableAppNap() calls into a
small RAII/scope-guard helper so App Nap is re-enabled automatically whenever
main() exits, regardless of which return path is taken.

Source: Coding guidelines

src/qt/macnapinhibitor.mm (1)

10-38: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

No synchronization on shared activity-token state.

g_napActivityToken is a plain global mutated by both disableAppNap() and enableAppNap(). Current call sites (main thread only, per bitcoin.cpp) don't race, but nothing in the header prevents future callers from invoking these from other threads, which would race on the check-then-act pattern (if (g_napActivityToken != nil) return; followed by assignment).

Given the header guidelines call for LOCK/TRY_LOCK macros for multi-threaded state, consider guarding the token with a lock if this API is expected to be called from more than one thread.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/qt/macnapinhibitor.mm` around lines 10 - 38, The shared App Nap activity
token is mutated without synchronization, so `MacNapInhibitor::disableAppNap()`
and `MacNapInhibitor::enableAppNap()` should guard `g_napActivityToken` with a
lock if there is any chance of multi-threaded use. Update the check-then-act
logic in both methods to use the project’s locking pattern (`LOCK`/`TRY_LOCK`)
around the token’s read/write/endActivity/release sequence, keeping the global
state consistent even if future callers invoke these entry points off the main
thread.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/qt/bitcoin.cpp`:
- Around line 759-764: The App Nap handling in main() is manually paired and
several early return paths bypass the later enableAppNap() call, breaking the
intended symmetry. Refactor the MacNapInhibitor usage in bitcoin.cpp around the
existing disableAppNap() and enableAppNap() calls into a small RAII/scope-guard
helper so App Nap is re-enabled automatically whenever main() exits, regardless
of which return path is taken.

In `@src/qt/macnapinhibitor.mm`:
- Around line 10-38: The shared App Nap activity token is mutated without
synchronization, so `MacNapInhibitor::disableAppNap()` and
`MacNapInhibitor::enableAppNap()` should guard `g_napActivityToken` with a lock
if there is any chance of multi-threaded use. Update the check-then-act logic in
both methods to use the project’s locking pattern (`LOCK`/`TRY_LOCK`) around the
token’s read/write/endActivity/release sequence, keeping the global state
consistent even if future callers invoke these entry points off the main thread.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8891303a-e4d8-4112-8ebc-59ba891d032a

📥 Commits

Reviewing files that changed from the base of the PR and between 7fabe1e and 38f2abf.

📒 Files selected for processing (4)
  • src/qt/CMakeLists.txt
  • src/qt/bitcoin.cpp
  • src/qt/macnapinhibitor.h
  • src/qt/macnapinhibitor.mm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement GUI GUI related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant