Repository navigation
Initialise dock later to bypass startup crash - #13
Merged
Merged
Conversation
QCefWidgetInternal::showEvent created the browser at once (Init()). While OBS restores a saved dock layout at startup, Qt can show a browser dock and close it again straight away; on Windows, creating the browser in between crashes CEF. This is most often seen with a Twitch Chat dock that was closed before OBS quit. Create the browser on the next event loop pass instead, through a zero-delay single-shot timer with the widget as its context: Qt drops the call if the widget is destroyed before it runs. The upstream change captured `this` in a lambda without a context object, which would call Init() on a destroyed widget in that case. The 500 ms retry timer is unchanged. Ported from upstream obs-browser PR 554 (open upstream at the time of porting). Refs obs-rust/obs-studio#2524 Co-Authored-By: Matt Gajownik <matt@obsproject.com>
5 of 7 tasks
zackees
approved these changes
Oct 26, 2026
zackees
left a comment
Member
There was a problem hiding this comment.
Reviewed: the deferred Init() uses the widget as its context object, which is safer than upstream's lambda. Init() already guards against re-entry from the 500 ms timer. The reason there's no RED test (no Windows app CI with a saved layout) is reasonable and documented. Merging.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs obs-rust/obs-studio#2524
Port of upstream obsproject/obs-browser#554 (open upstream, no review decision yet; the only review comment asks whether one delayed single-shot call would be cleaner than the retry timer, which the author wants to leave for a later rework). The upstream author is credited with a Co-Authored-By line.
What and why
On Windows, OBS crashes at startup when a browser dock was closed before OBS quit. The Twitch Chat dock is the usual case: it is the dock people close. Upstream now gives this as the cause of obsproject/obs-studio#14088.
QCefWidgetInternal::showEventcalledInit()straight away, andInit()creates the browser.QTimer::singleShot(0, this, &QCefWidgetInternal::Init). The 500 ms retry timer is unchanged.Difference from upstream: upstream uses
QTimer::singleShot(0, [this]() { Init(); }). That overload has no context object, so if the widget is destroyed before the event loop runs,Init()runs on a destroyed widget. Passing the widget as the context makes Qt drop the call in that case. The review comment on upstream suggestsQMetaObject::invokeMethod(this, &QCefWidgetInternal::Init), but that would not defer anything: with the default connection type and the widget on the calling thread, the call is direct.RED → GREEN
OBSBasic::OBSInitrestores the dock layout before the main window is shown, so a dock saved closed is never shown at startup andshowEvent/Init()never run for it.QCefWidgetInternal::showEventandInitwere never hit for either dock.setVisible(true)and thensetVisible(false)on the Chat dock in the same event loop pass, and showed the Other dock. 10 runs on 63fd678 and 10 with this fix: no crash in any run.Init()is not called fromshowEventwould test the code's shape, not the crash.e4d577e. The same 10 startup launches with the fix: no crash, and the closed dock stays closed. In the forced show/hide runs, the Other dock creates its browser through the deferredInit()and renders its page (screenshot checked).Notes