Skip to content

Add low memory mode for supported utilities#47487

Open
Michaelihc wants to merge 1 commit into
microsoft:mainfrom
Michaelihc:main
Open

Add low memory mode for supported utilities#47487
Michaelihc wants to merge 1 commit into
microsoft:mainfrom
Michaelihc:main

Conversation

@Michaelihc
Copy link
Copy Markdown

@Michaelihc Michaelihc commented Apr 30, 2026

Summary of the Pull Request

Adds an optional low memory mode for supported utilities so PowerToys can reduce idle memory usage by closing helper/UI processes when they are not in use.

image image

This currently covers:

  • Text Extractor
  • Color Picker
  • Advanced Paste
  • Peek

The change keeps the current warm-process behavior as the default and adds per-utility low memory toggles plus enable-all/disable-all helpers in General settings.

Links:

PR Checklist

  • Closes: Reduce idle memory usage from utility helper processes #47518
  • Addresses: [Color Picker] Option to not run in background #10357
  • Communication: Posted proposed scope in the contribution thread; awaiting maintainer confirmation on whether
    the broader scope is acceptable
  • Tests: Added/updated tests; relevant builds pass locally
  • Localization: All end-user-facing strings can be localized
  • Dev docs: Not applicable
  • New binaries: Not applicable
    • JSON for signing for new binaries
    • WXS for installer for new binaries and localization folder
    • YML for CI pipeline for new test projects
    • YML for signed pipeline
  • Documentation updated: Not applicable

Detailed Description of the Pull Request / Additional comments

This adds a shared low_memory_modules settings map and helper APIs so supported utilities can opt into idle-close behavior without adding a new schema field per module. Each supported utility defaults to false, preserving the existing warm-process behavior unless the user enables low memory mode.

The runner refreshes the cached low-memory settings and reapplies the policy by restarting only affected enabled modules when a supported utility's low memory setting changes. Supported module interfaces use PTSettingsHelper::is_low_memory_mode_enabled(...) to decide whether to keep the app process warm or launch with exit-after-use behavior.

The Settings UI exposes the behavior in General settings as a status-like group of per-utility toggles, with enable-all/disable-all actions, and also adds each utility-specific toggle to the individual supported module pages.

Validation Steps Performed

  • Built src/runner ARM64 Release successfully.
  • Built src/settings-ui/Settings.UI ARM64 Release successfully.
  • Built src/settings-ui/Settings.UI.UnitTests ARM64 Release successfully.
  • Ran focused Settings.UI.UnitTests filter for ViewModelTests.General; 16 tests passed.
  • Manually installed and tested the ARM64 build locally: Settings opens, low memory UI renders, toggles work, supported processes close while idle and relaunch from hotkeys.
  • Verified no versioning/build metadata, signing, installer, pipeline, or dependency files are changed.

@Michaelihc
Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@Michaelihc Michaelihc force-pushed the main branch 3 times, most recently from 22b007f to 2ba5686 Compare April 30, 2026 13:45
@daverayment
Copy link
Copy Markdown
Collaborator

For the Communication part of the checklist, it should read "I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected".

Have you discussed this with core contributors and had approval to start? I ask because this work seems to be of far larger scope than required to resolve the linked Color Picker issue.

@Michaelihc
Copy link
Copy Markdown
Author

Thanks for calling this out.

The original motivation here is broader idle memory usage, not only Color Picker. I used #10357 because it is the existing issue that describes the same background-process tradeoff in a concrete way.

I have also opened a separate issue for the broader low memory mode scope: #47518

I agree the checklist wording should not imply explicit approval. I have updated the PR body to say that the scope was posted in the contribution thread and is awaiting maintainer confirmation.

If maintainers prefer a narrower first step, I can reduce this PR to Color Picker only and leave the broader per-utility low memory behavior for separate discussion.

@MatteoBax
Copy link
Copy Markdown

This PR could solve #44397

@Jay-o-Way
Copy link
Copy Markdown
Collaborator

"Low memory mode" does not describe an action and is not the most common phrase. I (and Copilot) recommend "Close app when inactive".

Copy link
Copy Markdown
Collaborator

@Jay-o-Way Jay-o-Way left a comment

Choose a reason for hiding this comment

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

Strings are very redundant. Just saying.


internal bool ExitAfterUse => exitAfterUse;

internal void ExitAfterUseIfNeeded()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I dunno, maybe it's me, but "if needed" sounds weird

<value>Low memory mode</value>
</data>
<data name="GeneralPage_LowMemoryMode.Description" xml:space="preserve">
<value>Supported utilities close when not in use to use less memory, but may open slower.</value>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

To me, this is almost too verbose. Especially "supported utilities" feels weird. Everything that is supported is show.

<value>Supported utilities close when not in use to use less memory, but may open slower.</value>
</data>
<data name="GeneralPage_LowMemoryModeAllSupported.Header" xml:space="preserve">
<value>All supported utilities</value>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same.

<value>Disable all</value>
</data>
<data name="GeneralPage_LowMemoryTextExtractor.Header" xml:space="preserve">
<value>Text Extractor</value>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Larger scope: can't we just re-use one string?

<value>Low memory mode for Text Extractor</value>
</data>
<data name="GeneralPage_LowMemoryTextExtractorDetails.Description" xml:space="preserve">
<value>Close Text Extractor when not in use. Uses less memory but may open slower.</value>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not use one "anonymous" description for every string?

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.

Reduce idle memory usage from utility helper processes

4 participants