windo: cut idle and hidden CPU/energy use - #4

Merged
zackbart merged 2 commits into
mainfrom
agent/windo-perf
Aug 19, 2026
Merged

windo: cut idle and hidden CPU/energy use#4
zackbart merged 2 commits into
mainfrom
agent/windo-perf

Conversation

@zackbart

Copy link
Copy Markdown
Owner

Problem

Windo showed "significant energy" in the battery menu, including while hidden. Hiding did not stop the work: video kept decoding, and the tint sampler (takeSnapshot 3×/s) and a 22 Hz titlebar redraw ran forever while the window was on screen, even when fully covered.

Changes

  • Tint sampler runs only while on-screen, not occluded, not compact, not in page fullscreen. 1 s interval, one snapshot in flight, stale-tab results dropped. Lerp timer runs only until the color converges.
  • Hide (⌃⌘H / menu), red close button, and minimize pause playing media in all tabs; show resumes the active tab. Tab switch pauses the outgoing tab. New menu toggle Pause When Hidden (default on). Media the user paused stays paused.
  • Tab bar rebuild coalesced (150 ms) and skipped when unchanged.
  • Fullscreen state tracked per web view; cleared on navigation.
  • Opacity save debounced in .common run-loop mode; saved on quit.
  • Tab close removes script handlers, nils the delegate, stops loading.
  • README: hotkey corrected to ⌃⌘H; Pause When Hidden documented.

Measured (A/B vs main, Big Buck Bunny 4K60, % of one core, Windo + WebKit helpers)

Statemainthis PR
Static page7.51.0
Visible, playing34.423.5
Hidden ⌃⌘H8.11.5
Minimized1.3
Second tab active3.2

Zero crashes, no new log errors, no timer leak after 30 rapid toggles, tint still tracks the video.

Behavior change

The red close button now hides the window (same as ⌃⌘H) instead of closing it. Matches the hide/show model and applicationShouldTerminateAfterLastWindowClosed == false.

Not tested

True occlusion (window covered) — Windo floats over everything, so it could not be produced. Same code path as minimize, which passed. powermetrics needs sudo; skipped.

🤖 Generated with Claude Code

zackbartand others added 2 commits August 18, 2026 19:53
- Tint sampler runs only while on-screen, not occluded, not compact, not in
page fullscreen. 1 s interval, one snapshot in flight, stale-tab results
dropped. Lerp timer runs only until the color converges.
- Hide, close button, and minimize pause playing media in all tabs; show
resumes the active tab. Tab switch pauses the outgoing tab. New menu
toggle "Pause When Hidden" (default on).
- Tab bar rebuild coalesced and skipped when unchanged.
- Fullscreen state tracked per web view, cleared on navigation.
- Opacity save debounced in .common mode; saved on quit.
- Tab close removes handlers, delegate, stops loading.
- README: hotkey is ⌃⌘H; document Pause When Hidden.
Measured (A/B vs main, 4K60 video, % of one core): static 7.5→1.0,
playing 34→23.5, hidden 8.1→1.5.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parked tabs re-pause media that starts after the scan (autoplay-next, SPA
nav) via a capture-phase play listener, keep the resume tag until play()
actually takes, drop superseded snapshots by generation, and apply the
Pause When Hidden toggle while the window is already hidden.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zackbart

Copy link
Copy Markdown
OwnerAuthor

Second-round review (Codex, gpt-5.6-sol) — 6 findings, disposition:

Fixed in e33d13a:

  1. Media started after a tab is parked (autoplay-next, SPA nav) played while hidden → added kParkShim user script: capture-phase play listener re-pauses and tags while window.__windoParked; didCommit re-parks new documents in hidden/background tabs.
  2. Resume tag was cleared before play() resolved → cleared in .then.
  3. Quick hide/show could overlap two snapshots → snapshotGen token; superseded completions are dropped.
  4. Toggling Pause When Hidden while hidden did nothing → now pauses all / resumes active immediately.

Not fixed (known limitations, pre-existing for mute too):
2. Pause/resume evaluateJavaScript runs in the main frame only; cross-origin iframe players are not paused. The park shim is injected in all frames, but the parked flag is only set in the main frame.
4. Fullscreen state is per web view, not per frame; an iframe can clear another frame's state.

Runtime re-check after e33d13a: hidden 15 s → +0 s CPU time for Windo and both WebContent processes; resumes on show.

@zackbart
zackbart merged commit 769576d into mainAug 19, 2026
@zackbart
zackbart deleted the agent/windo-perf branch August 19, 2026 00:07
Sign up for freeto 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.

1 participant

@zackbart
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

windo: cut idle and hidden CPU/energy use - #4

Merged
zackbart merged 2 commits into
mainfrom
agent/windo-perf
Aug 19, 2026
Merged

windo: cut idle and hidden CPU/energy use#4
zackbart merged 2 commits into
mainfrom
agent/windo-perf

Conversation

@zackbart

Copy link
Copy Markdown
Owner

Problem

Windo showed "significant energy" in the battery menu, including while hidden. Hiding did not stop the work: video kept decoding, and the tint sampler (takeSnapshot 3×/s) and a 22 Hz titlebar redraw ran forever while the window was on screen, even when fully covered.

Changes

  • Tint sampler runs only while on-screen, not occluded, not compact, not in page fullscreen. 1 s interval, one snapshot in flight, stale-tab results dropped. Lerp timer runs only until the color converges.
  • Hide (⌃⌘H / menu), red close button, and minimize pause playing media in all tabs; show resumes the active tab. Tab switch pauses the outgoing tab. New menu toggle Pause When Hidden (default on). Media the user paused stays paused.
  • Tab bar rebuild coalesced (150 ms) and skipped when unchanged.
  • Fullscreen state tracked per web view; cleared on navigation.
  • Opacity save debounced in .common run-loop mode; saved on quit.
  • Tab close removes script handlers, nils the delegate, stops loading.
  • README: hotkey corrected to ⌃⌘H; Pause When Hidden documented.

Measured (A/B vs main, Big Buck Bunny 4K60, % of one core, Windo + WebKit helpers)

Statemainthis PR
Static page7.51.0
Visible, playing34.423.5
Hidden ⌃⌘H8.11.5
Minimized1.3
Second tab active3.2

Zero crashes, no new log errors, no timer leak after 30 rapid toggles, tint still tracks the video.

Behavior change

The red close button now hides the window (same as ⌃⌘H) instead of closing it. Matches the hide/show model and applicationShouldTerminateAfterLastWindowClosed == false.

Not tested

True occlusion (window covered) — Windo floats over everything, so it could not be produced. Same code path as minimize, which passed. powermetrics needs sudo; skipped.

🤖 Generated with Claude Code

zackbartand others added 2 commits August 18, 2026 19:53
- Tint sampler runs only while on-screen, not occluded, not compact, not in
page fullscreen. 1 s interval, one snapshot in flight, stale-tab results
dropped. Lerp timer runs only until the color converges.
- Hide, close button, and minimize pause playing media in all tabs; show
resumes the active tab. Tab switch pauses the outgoing tab. New menu
toggle "Pause When Hidden" (default on).
- Tab bar rebuild coalesced and skipped when unchanged.
- Fullscreen state tracked per web view, cleared on navigation.
- Opacity save debounced in .common mode; saved on quit.
- Tab close removes handlers, delegate, stops loading.
- README: hotkey is ⌃⌘H; document Pause When Hidden.
Measured (A/B vs main, 4K60 video, % of one core): static 7.5→1.0,
playing 34→23.5, hidden 8.1→1.5.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parked tabs re-pause media that starts after the scan (autoplay-next, SPA
nav) via a capture-phase play listener, keep the resume tag until play()
actually takes, drop superseded snapshots by generation, and apply the
Pause When Hidden toggle while the window is already hidden.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zackbart

Copy link
Copy Markdown
OwnerAuthor

Second-round review (Codex, gpt-5.6-sol) — 6 findings, disposition:

Fixed in e33d13a:

  1. Media started after a tab is parked (autoplay-next, SPA nav) played while hidden → added kParkShim user script: capture-phase play listener re-pauses and tags while window.__windoParked; didCommit re-parks new documents in hidden/background tabs.
  2. Resume tag was cleared before play() resolved → cleared in .then.
  3. Quick hide/show could overlap two snapshots → snapshotGen token; superseded completions are dropped.
  4. Toggling Pause When Hidden while hidden did nothing → now pauses all / resumes active immediately.

Not fixed (known limitations, pre-existing for mute too):
2. Pause/resume evaluateJavaScript runs in the main frame only; cross-origin iframe players are not paused. The park shim is injected in all frames, but the parked flag is only set in the main frame.
4. Fullscreen state is per web view, not per frame; an iframe can clear another frame's state.

Runtime re-check after e33d13a: hidden 15 s → +0 s CPU time for Windo and both WebContent processes; resumes on show.

@zackbart
zackbart merged commit 769576d into mainAug 19, 2026
@zackbart
zackbart deleted the agent/windo-perf branch August 19, 2026 00:07
Sign up for freeto 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.

1 participant

@zackbart
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

windo: cut idle and hidden CPU/energy use - #4

Merged
zackbart merged 2 commits into
mainfrom
agent/windo-perf
Aug 19, 2026
Merged

windo: cut idle and hidden CPU/energy use#4
zackbart merged 2 commits into
mainfrom
agent/windo-perf

Conversation

@zackbart

Copy link
Copy Markdown
Owner

Problem

Windo showed "significant energy" in the battery menu, including while hidden. Hiding did not stop the work: video kept decoding, and the tint sampler (takeSnapshot 3×/s) and a 22 Hz titlebar redraw ran forever while the window was on screen, even when fully covered.

Changes

  • Tint sampler runs only while on-screen, not occluded, not compact, not in page fullscreen. 1 s interval, one snapshot in flight, stale-tab results dropped. Lerp timer runs only until the color converges.
  • Hide (⌃⌘H / menu), red close button, and minimize pause playing media in all tabs; show resumes the active tab. Tab switch pauses the outgoing tab. New menu toggle Pause When Hidden (default on). Media the user paused stays paused.
  • Tab bar rebuild coalesced (150 ms) and skipped when unchanged.
  • Fullscreen state tracked per web view; cleared on navigation.
  • Opacity save debounced in .common run-loop mode; saved on quit.
  • Tab close removes script handlers, nils the delegate, stops loading.
  • README: hotkey corrected to ⌃⌘H; Pause When Hidden documented.

Measured (A/B vs main, Big Buck Bunny 4K60, % of one core, Windo + WebKit helpers)

Statemainthis PR
Static page7.51.0
Visible, playing34.423.5
Hidden ⌃⌘H8.11.5
Minimized1.3
Second tab active3.2

Zero crashes, no new log errors, no timer leak after 30 rapid toggles, tint still tracks the video.

Behavior change

The red close button now hides the window (same as ⌃⌘H) instead of closing it. Matches the hide/show model and applicationShouldTerminateAfterLastWindowClosed == false.

Not tested

True occlusion (window covered) — Windo floats over everything, so it could not be produced. Same code path as minimize, which passed. powermetrics needs sudo; skipped.

🤖 Generated with Claude Code

zackbartand others added 2 commits August 18, 2026 19:53
- Tint sampler runs only while on-screen, not occluded, not compact, not in
page fullscreen. 1 s interval, one snapshot in flight, stale-tab results
dropped. Lerp timer runs only until the color converges.
- Hide, close button, and minimize pause playing media in all tabs; show
resumes the active tab. Tab switch pauses the outgoing tab. New menu
toggle "Pause When Hidden" (default on).
- Tab bar rebuild coalesced and skipped when unchanged.
- Fullscreen state tracked per web view, cleared on navigation.
- Opacity save debounced in .common mode; saved on quit.
- Tab close removes handlers, delegate, stops loading.
- README: hotkey is ⌃⌘H; document Pause When Hidden.
Measured (A/B vs main, 4K60 video, % of one core): static 7.5→1.0,
playing 34→23.5, hidden 8.1→1.5.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parked tabs re-pause media that starts after the scan (autoplay-next, SPA
nav) via a capture-phase play listener, keep the resume tag until play()
actually takes, drop superseded snapshots by generation, and apply the
Pause When Hidden toggle while the window is already hidden.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zackbart

Copy link
Copy Markdown
OwnerAuthor

Second-round review (Codex, gpt-5.6-sol) — 6 findings, disposition:

Fixed in e33d13a:

  1. Media started after a tab is parked (autoplay-next, SPA nav) played while hidden → added kParkShim user script: capture-phase play listener re-pauses and tags while window.__windoParked; didCommit re-parks new documents in hidden/background tabs.
  2. Resume tag was cleared before play() resolved → cleared in .then.
  3. Quick hide/show could overlap two snapshots → snapshotGen token; superseded completions are dropped.
  4. Toggling Pause When Hidden while hidden did nothing → now pauses all / resumes active immediately.

Not fixed (known limitations, pre-existing for mute too):
2. Pause/resume evaluateJavaScript runs in the main frame only; cross-origin iframe players are not paused. The park shim is injected in all frames, but the parked flag is only set in the main frame.
4. Fullscreen state is per web view, not per frame; an iframe can clear another frame's state.

Runtime re-check after e33d13a: hidden 15 s → +0 s CPU time for Windo and both WebContent processes; resumes on show.

@zackbart
zackbart merged commit 769576d into mainAug 19, 2026
@zackbart
zackbart deleted the agent/windo-perf branch August 19, 2026 00:07
Sign up for freeto 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.

1 participant

@zackbart
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

windo: cut idle and hidden CPU/energy use - #4

Merged
zackbart merged 2 commits into
mainfrom
agent/windo-perf
Aug 19, 2026
Merged

windo: cut idle and hidden CPU/energy use#4
zackbart merged 2 commits into
mainfrom
agent/windo-perf

Conversation

@zackbart

Copy link
Copy Markdown
Owner

Problem

Windo showed "significant energy" in the battery menu, including while hidden. Hiding did not stop the work: video kept decoding, and the tint sampler (takeSnapshot 3×/s) and a 22 Hz titlebar redraw ran forever while the window was on screen, even when fully covered.

Changes

  • Tint sampler runs only while on-screen, not occluded, not compact, not in page fullscreen. 1 s interval, one snapshot in flight, stale-tab results dropped. Lerp timer runs only until the color converges.
  • Hide (⌃⌘H / menu), red close button, and minimize pause playing media in all tabs; show resumes the active tab. Tab switch pauses the outgoing tab. New menu toggle Pause When Hidden (default on). Media the user paused stays paused.
  • Tab bar rebuild coalesced (150 ms) and skipped when unchanged.
  • Fullscreen state tracked per web view; cleared on navigation.
  • Opacity save debounced in .common run-loop mode; saved on quit.
  • Tab close removes script handlers, nils the delegate, stops loading.
  • README: hotkey corrected to ⌃⌘H; Pause When Hidden documented.

Measured (A/B vs main, Big Buck Bunny 4K60, % of one core, Windo + WebKit helpers)

Statemainthis PR
Static page7.51.0
Visible, playing34.423.5
Hidden ⌃⌘H8.11.5
Minimized1.3
Second tab active3.2

Zero crashes, no new log errors, no timer leak after 30 rapid toggles, tint still tracks the video.

Behavior change

The red close button now hides the window (same as ⌃⌘H) instead of closing it. Matches the hide/show model and applicationShouldTerminateAfterLastWindowClosed == false.

Not tested

True occlusion (window covered) — Windo floats over everything, so it could not be produced. Same code path as minimize, which passed. powermetrics needs sudo; skipped.

🤖 Generated with Claude Code

zackbartand others added 2 commits August 18, 2026 19:53
- Tint sampler runs only while on-screen, not occluded, not compact, not in
page fullscreen. 1 s interval, one snapshot in flight, stale-tab results
dropped. Lerp timer runs only until the color converges.
- Hide, close button, and minimize pause playing media in all tabs; show
resumes the active tab. Tab switch pauses the outgoing tab. New menu
toggle "Pause When Hidden" (default on).
- Tab bar rebuild coalesced and skipped when unchanged.
- Fullscreen state tracked per web view, cleared on navigation.
- Opacity save debounced in .common mode; saved on quit.
- Tab close removes handlers, delegate, stops loading.
- README: hotkey is ⌃⌘H; document Pause When Hidden.
Measured (A/B vs main, 4K60 video, % of one core): static 7.5→1.0,
playing 34→23.5, hidden 8.1→1.5.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parked tabs re-pause media that starts after the scan (autoplay-next, SPA
nav) via a capture-phase play listener, keep the resume tag until play()
actually takes, drop superseded snapshots by generation, and apply the
Pause When Hidden toggle while the window is already hidden.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zackbart

Copy link
Copy Markdown
OwnerAuthor

Second-round review (Codex, gpt-5.6-sol) — 6 findings, disposition:

Fixed in e33d13a:

  1. Media started after a tab is parked (autoplay-next, SPA nav) played while hidden → added kParkShim user script: capture-phase play listener re-pauses and tags while window.__windoParked; didCommit re-parks new documents in hidden/background tabs.
  2. Resume tag was cleared before play() resolved → cleared in .then.
  3. Quick hide/show could overlap two snapshots → snapshotGen token; superseded completions are dropped.
  4. Toggling Pause When Hidden while hidden did nothing → now pauses all / resumes active immediately.

Not fixed (known limitations, pre-existing for mute too):
2. Pause/resume evaluateJavaScript runs in the main frame only; cross-origin iframe players are not paused. The park shim is injected in all frames, but the parked flag is only set in the main frame.
4. Fullscreen state is per web view, not per frame; an iframe can clear another frame's state.

Runtime re-check after e33d13a: hidden 15 s → +0 s CPU time for Windo and both WebContent processes; resumes on show.

@zackbart
zackbart merged commit 769576d into mainAug 19, 2026
@zackbart
zackbart deleted the agent/windo-perf branch August 19, 2026 00:07
Sign up for freeto 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.

1 participant

@zackbart
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

windo: cut idle and hidden CPU/energy use - #4

Merged
zackbart merged 2 commits into
mainfrom
agent/windo-perf
Aug 19, 2026
Merged

windo: cut idle and hidden CPU/energy use#4
zackbart merged 2 commits into
mainfrom
agent/windo-perf

Conversation

@zackbart

Copy link
Copy Markdown
Owner

Problem

Windo showed "significant energy" in the battery menu, including while hidden. Hiding did not stop the work: video kept decoding, and the tint sampler (takeSnapshot 3×/s) and a 22 Hz titlebar redraw ran forever while the window was on screen, even when fully covered.

Changes

  • Tint sampler runs only while on-screen, not occluded, not compact, not in page fullscreen. 1 s interval, one snapshot in flight, stale-tab results dropped. Lerp timer runs only until the color converges.
  • Hide (⌃⌘H / menu), red close button, and minimize pause playing media in all tabs; show resumes the active tab. Tab switch pauses the outgoing tab. New menu toggle Pause When Hidden (default on). Media the user paused stays paused.
  • Tab bar rebuild coalesced (150 ms) and skipped when unchanged.
  • Fullscreen state tracked per web view; cleared on navigation.
  • Opacity save debounced in .common run-loop mode; saved on quit.
  • Tab close removes script handlers, nils the delegate, stops loading.
  • README: hotkey corrected to ⌃⌘H; Pause When Hidden documented.

Measured (A/B vs main, Big Buck Bunny 4K60, % of one core, Windo + WebKit helpers)

Statemainthis PR
Static page7.51.0
Visible, playing34.423.5
Hidden ⌃⌘H8.11.5
Minimized1.3
Second tab active3.2

Zero crashes, no new log errors, no timer leak after 30 rapid toggles, tint still tracks the video.

Behavior change

The red close button now hides the window (same as ⌃⌘H) instead of closing it. Matches the hide/show model and applicationShouldTerminateAfterLastWindowClosed == false.

Not tested

True occlusion (window covered) — Windo floats over everything, so it could not be produced. Same code path as minimize, which passed. powermetrics needs sudo; skipped.

🤖 Generated with Claude Code

zackbartand others added 2 commits August 18, 2026 19:53
- Tint sampler runs only while on-screen, not occluded, not compact, not in
page fullscreen. 1 s interval, one snapshot in flight, stale-tab results
dropped. Lerp timer runs only until the color converges.
- Hide, close button, and minimize pause playing media in all tabs; show
resumes the active tab. Tab switch pauses the outgoing tab. New menu
toggle "Pause When Hidden" (default on).
- Tab bar rebuild coalesced and skipped when unchanged.
- Fullscreen state tracked per web view, cleared on navigation.
- Opacity save debounced in .common mode; saved on quit.
- Tab close removes handlers, delegate, stops loading.
- README: hotkey is ⌃⌘H; document Pause When Hidden.
Measured (A/B vs main, 4K60 video, % of one core): static 7.5→1.0,
playing 34→23.5, hidden 8.1→1.5.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parked tabs re-pause media that starts after the scan (autoplay-next, SPA
nav) via a capture-phase play listener, keep the resume tag until play()
actually takes, drop superseded snapshots by generation, and apply the
Pause When Hidden toggle while the window is already hidden.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zackbart

Copy link
Copy Markdown
OwnerAuthor

Second-round review (Codex, gpt-5.6-sol) — 6 findings, disposition:

Fixed in e33d13a:

  1. Media started after a tab is parked (autoplay-next, SPA nav) played while hidden → added kParkShim user script: capture-phase play listener re-pauses and tags while window.__windoParked; didCommit re-parks new documents in hidden/background tabs.
  2. Resume tag was cleared before play() resolved → cleared in .then.
  3. Quick hide/show could overlap two snapshots → snapshotGen token; superseded completions are dropped.
  4. Toggling Pause When Hidden while hidden did nothing → now pauses all / resumes active immediately.

Not fixed (known limitations, pre-existing for mute too):
2. Pause/resume evaluateJavaScript runs in the main frame only; cross-origin iframe players are not paused. The park shim is injected in all frames, but the parked flag is only set in the main frame.
4. Fullscreen state is per web view, not per frame; an iframe can clear another frame's state.

Runtime re-check after e33d13a: hidden 15 s → +0 s CPU time for Windo and both WebContent processes; resumes on show.

@zackbart
zackbart merged commit 769576d into mainAug 19, 2026
@zackbart
zackbart deleted the agent/windo-perf branch August 19, 2026 00:07
Sign up for freeto 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.

1 participant

@zackbart
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

windo: cut idle and hidden CPU/energy use - #4

Merged
zackbart merged 2 commits into
mainfrom
agent/windo-perf
Aug 19, 2026
Merged

windo: cut idle and hidden CPU/energy use#4
zackbart merged 2 commits into
mainfrom
agent/windo-perf

Conversation

@zackbart

Copy link
Copy Markdown
Owner

Problem

Windo showed "significant energy" in the battery menu, including while hidden. Hiding did not stop the work: video kept decoding, and the tint sampler (takeSnapshot 3×/s) and a 22 Hz titlebar redraw ran forever while the window was on screen, even when fully covered.

Changes

  • Tint sampler runs only while on-screen, not occluded, not compact, not in page fullscreen. 1 s interval, one snapshot in flight, stale-tab results dropped. Lerp timer runs only until the color converges.
  • Hide (⌃⌘H / menu), red close button, and minimize pause playing media in all tabs; show resumes the active tab. Tab switch pauses the outgoing tab. New menu toggle Pause When Hidden (default on). Media the user paused stays paused.
  • Tab bar rebuild coalesced (150 ms) and skipped when unchanged.
  • Fullscreen state tracked per web view; cleared on navigation.
  • Opacity save debounced in .common run-loop mode; saved on quit.
  • Tab close removes script handlers, nils the delegate, stops loading.
  • README: hotkey corrected to ⌃⌘H; Pause When Hidden documented.

Measured (A/B vs main, Big Buck Bunny 4K60, % of one core, Windo + WebKit helpers)

Statemainthis PR
Static page7.51.0
Visible, playing34.423.5
Hidden ⌃⌘H8.11.5
Minimized1.3
Second tab active3.2

Zero crashes, no new log errors, no timer leak after 30 rapid toggles, tint still tracks the video.

Behavior change

The red close button now hides the window (same as ⌃⌘H) instead of closing it. Matches the hide/show model and applicationShouldTerminateAfterLastWindowClosed == false.

Not tested

True occlusion (window covered) — Windo floats over everything, so it could not be produced. Same code path as minimize, which passed. powermetrics needs sudo; skipped.

🤖 Generated with Claude Code

zackbartand others added 2 commits August 18, 2026 19:53
- Tint sampler runs only while on-screen, not occluded, not compact, not in
page fullscreen. 1 s interval, one snapshot in flight, stale-tab results
dropped. Lerp timer runs only until the color converges.
- Hide, close button, and minimize pause playing media in all tabs; show
resumes the active tab. Tab switch pauses the outgoing tab. New menu
toggle "Pause When Hidden" (default on).
- Tab bar rebuild coalesced and skipped when unchanged.
- Fullscreen state tracked per web view, cleared on navigation.
- Opacity save debounced in .common mode; saved on quit.
- Tab close removes handlers, delegate, stops loading.
- README: hotkey is ⌃⌘H; document Pause When Hidden.
Measured (A/B vs main, 4K60 video, % of one core): static 7.5→1.0,
playing 34→23.5, hidden 8.1→1.5.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parked tabs re-pause media that starts after the scan (autoplay-next, SPA
nav) via a capture-phase play listener, keep the resume tag until play()
actually takes, drop superseded snapshots by generation, and apply the
Pause When Hidden toggle while the window is already hidden.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zackbart

Copy link
Copy Markdown
OwnerAuthor

Second-round review (Codex, gpt-5.6-sol) — 6 findings, disposition:

Fixed in e33d13a:

  1. Media started after a tab is parked (autoplay-next, SPA nav) played while hidden → added kParkShim user script: capture-phase play listener re-pauses and tags while window.__windoParked; didCommit re-parks new documents in hidden/background tabs.
  2. Resume tag was cleared before play() resolved → cleared in .then.
  3. Quick hide/show could overlap two snapshots → snapshotGen token; superseded completions are dropped.
  4. Toggling Pause When Hidden while hidden did nothing → now pauses all / resumes active immediately.

Not fixed (known limitations, pre-existing for mute too):
2. Pause/resume evaluateJavaScript runs in the main frame only; cross-origin iframe players are not paused. The park shim is injected in all frames, but the parked flag is only set in the main frame.
4. Fullscreen state is per web view, not per frame; an iframe can clear another frame's state.

Runtime re-check after e33d13a: hidden 15 s → +0 s CPU time for Windo and both WebContent processes; resumes on show.

@zackbart
zackbart merged commit 769576d into mainAug 19, 2026
@zackbart
zackbart deleted the agent/windo-perf branch August 19, 2026 00:07
Sign up for freeto 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.

1 participant

@zackbart
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

windo: cut idle and hidden CPU/energy use - #4

Merged
zackbart merged 2 commits into
mainfrom
agent/windo-perf
Aug 19, 2026
Merged

windo: cut idle and hidden CPU/energy use#4
zackbart merged 2 commits into
mainfrom
agent/windo-perf

Conversation

@zackbart

Copy link
Copy Markdown
Owner

Problem

Windo showed "significant energy" in the battery menu, including while hidden. Hiding did not stop the work: video kept decoding, and the tint sampler (takeSnapshot 3×/s) and a 22 Hz titlebar redraw ran forever while the window was on screen, even when fully covered.

Changes

  • Tint sampler runs only while on-screen, not occluded, not compact, not in page fullscreen. 1 s interval, one snapshot in flight, stale-tab results dropped. Lerp timer runs only until the color converges.
  • Hide (⌃⌘H / menu), red close button, and minimize pause playing media in all tabs; show resumes the active tab. Tab switch pauses the outgoing tab. New menu toggle Pause When Hidden (default on). Media the user paused stays paused.
  • Tab bar rebuild coalesced (150 ms) and skipped when unchanged.
  • Fullscreen state tracked per web view; cleared on navigation.
  • Opacity save debounced in .common run-loop mode; saved on quit.
  • Tab close removes script handlers, nils the delegate, stops loading.
  • README: hotkey corrected to ⌃⌘H; Pause When Hidden documented.

Measured (A/B vs main, Big Buck Bunny 4K60, % of one core, Windo + WebKit helpers)

Statemainthis PR
Static page7.51.0
Visible, playing34.423.5
Hidden ⌃⌘H8.11.5
Minimized1.3
Second tab active3.2

Zero crashes, no new log errors, no timer leak after 30 rapid toggles, tint still tracks the video.

Behavior change

The red close button now hides the window (same as ⌃⌘H) instead of closing it. Matches the hide/show model and applicationShouldTerminateAfterLastWindowClosed == false.

Not tested

True occlusion (window covered) — Windo floats over everything, so it could not be produced. Same code path as minimize, which passed. powermetrics needs sudo; skipped.

🤖 Generated with Claude Code

zackbartand others added 2 commits August 18, 2026 19:53
- Tint sampler runs only while on-screen, not occluded, not compact, not in
page fullscreen. 1 s interval, one snapshot in flight, stale-tab results
dropped. Lerp timer runs only until the color converges.
- Hide, close button, and minimize pause playing media in all tabs; show
resumes the active tab. Tab switch pauses the outgoing tab. New menu
toggle "Pause When Hidden" (default on).
- Tab bar rebuild coalesced and skipped when unchanged.
- Fullscreen state tracked per web view, cleared on navigation.
- Opacity save debounced in .common mode; saved on quit.
- Tab close removes handlers, delegate, stops loading.
- README: hotkey is ⌃⌘H; document Pause When Hidden.
Measured (A/B vs main, 4K60 video, % of one core): static 7.5→1.0,
playing 34→23.5, hidden 8.1→1.5.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parked tabs re-pause media that starts after the scan (autoplay-next, SPA
nav) via a capture-phase play listener, keep the resume tag until play()
actually takes, drop superseded snapshots by generation, and apply the
Pause When Hidden toggle while the window is already hidden.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zackbart

Copy link
Copy Markdown
OwnerAuthor

Second-round review (Codex, gpt-5.6-sol) — 6 findings, disposition:

Fixed in e33d13a:

  1. Media started after a tab is parked (autoplay-next, SPA nav) played while hidden → added kParkShim user script: capture-phase play listener re-pauses and tags while window.__windoParked; didCommit re-parks new documents in hidden/background tabs.
  2. Resume tag was cleared before play() resolved → cleared in .then.
  3. Quick hide/show could overlap two snapshots → snapshotGen token; superseded completions are dropped.
  4. Toggling Pause When Hidden while hidden did nothing → now pauses all / resumes active immediately.

Not fixed (known limitations, pre-existing for mute too):
2. Pause/resume evaluateJavaScript runs in the main frame only; cross-origin iframe players are not paused. The park shim is injected in all frames, but the parked flag is only set in the main frame.
4. Fullscreen state is per web view, not per frame; an iframe can clear another frame's state.

Runtime re-check after e33d13a: hidden 15 s → +0 s CPU time for Windo and both WebContent processes; resumes on show.

@zackbart
zackbart merged commit 769576d into mainAug 19, 2026
@zackbart
zackbart deleted the agent/windo-perf branch August 19, 2026 00:07
Sign up for freeto 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.

1 participant

@zackbart
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

windo: cut idle and hidden CPU/energy use - #4

Merged
zackbart merged 2 commits into
mainfrom
agent/windo-perf
Aug 19, 2026
Merged

windo: cut idle and hidden CPU/energy use#4
zackbart merged 2 commits into
mainfrom
agent/windo-perf

Conversation

@zackbart

Copy link
Copy Markdown
Owner

Problem

Windo showed "significant energy" in the battery menu, including while hidden. Hiding did not stop the work: video kept decoding, and the tint sampler (takeSnapshot 3×/s) and a 22 Hz titlebar redraw ran forever while the window was on screen, even when fully covered.

Changes

  • Tint sampler runs only while on-screen, not occluded, not compact, not in page fullscreen. 1 s interval, one snapshot in flight, stale-tab results dropped. Lerp timer runs only until the color converges.
  • Hide (⌃⌘H / menu), red close button, and minimize pause playing media in all tabs; show resumes the active tab. Tab switch pauses the outgoing tab. New menu toggle Pause When Hidden (default on). Media the user paused stays paused.
  • Tab bar rebuild coalesced (150 ms) and skipped when unchanged.
  • Fullscreen state tracked per web view; cleared on navigation.
  • Opacity save debounced in .common run-loop mode; saved on quit.
  • Tab close removes script handlers, nils the delegate, stops loading.
  • README: hotkey corrected to ⌃⌘H; Pause When Hidden documented.

Measured (A/B vs main, Big Buck Bunny 4K60, % of one core, Windo + WebKit helpers)

Statemainthis PR
Static page7.51.0
Visible, playing34.423.5
Hidden ⌃⌘H8.11.5
Minimized1.3
Second tab active3.2

Zero crashes, no new log errors, no timer leak after 30 rapid toggles, tint still tracks the video.

Behavior change

The red close button now hides the window (same as ⌃⌘H) instead of closing it. Matches the hide/show model and applicationShouldTerminateAfterLastWindowClosed == false.

Not tested

True occlusion (window covered) — Windo floats over everything, so it could not be produced. Same code path as minimize, which passed. powermetrics needs sudo; skipped.

🤖 Generated with Claude Code

zackbartand others added 2 commits August 18, 2026 19:53
- Tint sampler runs only while on-screen, not occluded, not compact, not in
page fullscreen. 1 s interval, one snapshot in flight, stale-tab results
dropped. Lerp timer runs only until the color converges.
- Hide, close button, and minimize pause playing media in all tabs; show
resumes the active tab. Tab switch pauses the outgoing tab. New menu
toggle "Pause When Hidden" (default on).
- Tab bar rebuild coalesced and skipped when unchanged.
- Fullscreen state tracked per web view, cleared on navigation.
- Opacity save debounced in .common mode; saved on quit.
- Tab close removes handlers, delegate, stops loading.
- README: hotkey is ⌃⌘H; document Pause When Hidden.
Measured (A/B vs main, 4K60 video, % of one core): static 7.5→1.0,
playing 34→23.5, hidden 8.1→1.5.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parked tabs re-pause media that starts after the scan (autoplay-next, SPA
nav) via a capture-phase play listener, keep the resume tag until play()
actually takes, drop superseded snapshots by generation, and apply the
Pause When Hidden toggle while the window is already hidden.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zackbart

Copy link
Copy Markdown
OwnerAuthor

Second-round review (Codex, gpt-5.6-sol) — 6 findings, disposition:

Fixed in e33d13a:

  1. Media started after a tab is parked (autoplay-next, SPA nav) played while hidden → added kParkShim user script: capture-phase play listener re-pauses and tags while window.__windoParked; didCommit re-parks new documents in hidden/background tabs.
  2. Resume tag was cleared before play() resolved → cleared in .then.
  3. Quick hide/show could overlap two snapshots → snapshotGen token; superseded completions are dropped.
  4. Toggling Pause When Hidden while hidden did nothing → now pauses all / resumes active immediately.

Not fixed (known limitations, pre-existing for mute too):
2. Pause/resume evaluateJavaScript runs in the main frame only; cross-origin iframe players are not paused. The park shim is injected in all frames, but the parked flag is only set in the main frame.
4. Fullscreen state is per web view, not per frame; an iframe can clear another frame's state.

Runtime re-check after e33d13a: hidden 15 s → +0 s CPU time for Windo and both WebContent processes; resumes on show.

@zackbart
zackbart merged commit 769576d into mainAug 19, 2026
@zackbart
zackbart deleted the agent/windo-perf branch August 19, 2026 00:07
Sign up for freeto 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.

1 participant

@zackbart