Repository navigation
[Bug]: Desktop app held a Chromium "Video Wake Lock" for 14 hours, so the Mac never turned off its display or locked #15343
Description
Activity
Note
Grok responding on behalf of Julius.
Triage
Thanks for the
pmsettrace and the careful write-up, @reowens! This is a real bug on currentmain(5e35272fda) and onv0.0.44, and I didn't find a duplicate. As you suspected, the app never asks for this lock itself. There's nopowerSaveBlockerand nonavigator.wakeLock.requestin the tree. ANoDisplaySleepAssertionnamed"Video Wake Lock"is Chromium's own display-sleep lock for anHTMLVideoElement.Chromium holds that lock only while the element is actually playing, the document is running, and one of these is true:
- the element is in picture-in-picture, or
- the page is visible and the video is audible (it has an audio track with volume above 0), or
- the page is visible and the video is both mostly on screen (about 75%) and large (about 20% of the viewport).
A
MediaStreamskips the size check but still has to be visible or audible. The lock drops when those conditions stop being true. In your log it dropped in the same second the process quit, so the element stayed alive until then.Where it can come from
Two parts of the app can do this without an obvious video on screen:
- Chat, pull-request, and file videos go through
MediaVideoPlayer(apps/web/src/components/media/MediaVideoPlayer.tsx). It pauses on unmount and when the document is hidden, including fullscreen, but not when the video scrolls out of view. An unmuted clip with an audio track keeps the lock while the window is visible, even after it scrolls away, until it ends, pauses, or unmounts. Inline chat videos aren't muted and can be up to 30rem, which is big enough to qualify while on screen. File previews also have a raw<video controls>inAttachmentFilePreviewwith no hidden-document pause. Playback that never reachesended(a long file, a live source, or a stalledplayingelement) holds the lock until quit. The message list isn't virtualized, so a started video stays mounted after you scroll past it. - Integrated-browser guests can hold it while they're composited inside the window. A tab that's showing does, and so does a tab that recording, preview automation, or picture-in-picture marks as rendering-active. In that case
HostedBrowserWebviewparks a full-sizevisibility: visiblewebview at the top-left of the window, behind the UI (z-index: -1), so Electron keeps compositing it. A playing video in that guest then satisfies Chromium even while you're looking at chat. On macOS, inactive tabs also stayvisibility: visible(the Electron 43 blanking workaround, already inv0.0.44), but they're placed fully outside the window and Electron stops compositing them, so that path shouldn't hold the lock unless something marks the tab rendering-active.
Less likely sources
The recording compositor is a weak fit.
createRecordingCompositorplays a muted<video>that's never inserted into the document, and only when key or mouse decoration is on. Muted and not intersecting, it shouldn't qualify. Thecoreaudiodpreventuseridledisplaysleepassertions are a separate mechanism: your log shows the display turning off while some were held, and they were released two seconds after quit, after the video lock. The shared notificationAudioContextinthreadNotifications.tsis never closed, but that isn't what kept the display on.Reading the timeline
The sub-second locks at 22:48:13 and 22:48:19 fit a video that qualified and then paused or left view within the same second. The 14h 15m lock started at 23:02:53, three seconds after the display turned on, and lasted until exit, so something entered
playingthen and never paused. The log can't tell us whether that was a chat or file video or a browser guest, but it does rule out an app-level sleep blocker.This also isn't the same as #663. That request was about
prevent-app-suspensionduring an active turn, so the display can still sleep and lock. This bug breaks that expectation from the other direction, because Chromium's video lock isprevent-display-sleep.Likely fix area
- One option is to pause
MediaVideoPlayer(and the raw preview<video>) when it scrolls out of view, not only on unmount or a hidden document. - Another is to check what a rendering-active browser guest can play while it's parked behind the UI.
Until then, quitting the app or locking with Control-Command-Q is the right workaround. A maintainer will decide on the fix direction.
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.via-triageFiled through npx t3 triageFiled through npx t3 triage
on Oct 3, 2026
Before submitting
Area
apps/desktop
Impact
Major degradation or frequent failure
Version or commit
0.0.44
Environment
macOS 26.7 (arm64), T3 Code (Alpha) desktop app 0.0.44
Steps to reproduce
I don't have a deterministic repro yet. What happened:
NoDisplaySleepAssertionnamed "Video Wake Lock".About 15 minutes earlier (22:48:13 and 22:48:19), T3 Code took the same assertion twice and released it within a second each time.
Expected behavior
An idle desktop app should not keep the display awake. If nothing visible is playing, the screen saver, display sleep and the lock screen should work normally.
Actual behavior
The display stayed on and the Mac stayed unlocked for 14 hours 15 minutes.
pmset -gshoweddisplaysleep 20 (display sleep prevented by T3 Code (Alpha)). No video was playing anywhere I could see in the app, and it made no sound."Video Wake Lock" is the name Chromium uses for the wake lock it takes on its own while a
<video>element plays, so I don't think T3 Code asks for this directly. I found nopowerSaveBlockercall ornavigator.wakeLock.requestinapp.asar. These parts of the bundle can play video:.mp4/.webm/.movlinks and GitHubuser-attachmentsvideosMediaStreamin a muted<video>it creates in script and doesn't add to the page (a.srcObject = e; ... await a.play())If one of these keeps playing after it scrolls offscreen, after its view closes, or after a recording ends without
dispose(), Chromium would hold the lock for as long as the element exists.Separately,
coreaudiodreleased 42 per-client assertions 2 seconds after T3 Code quit: 21 contexts, each with acom.apple.audio.context<N>.preventuseridlesleepand a.preventuseridledisplaysleep, some held for 17 hours. The display still turned off at 21:51 and 22:59 while some of them were open, so they didn't keep it awake. I can't tie them to a specific part of the app. The completion sound creates one sharedAudioContextand resumes it, and I didn't find aclose()for it.Logs
From
pmset -g log:From
pmset -g assertionswhile it was held:Workaround
Quit T3 Code before leaving the machine, or lock the screen manually (Control-Command-Q). To check whether it's happening, run
pmset -g assertions | grep -i "wake lock".Why this matters
A lock screen policy is a security control. On a shared office or a company Mac with a required auto-lock, an app that silently keeps the display awake leaves the machine unlocked. Issue #663 asked for keep-awake during agent runs and specified
prevent-app-suspensionso that the display can still sleep and auto-lock isn't affected. This bug breaks the same guarantee through Chromium's video wake lock.