Skip to content

Enable support for CEF 6613+ (Chrome 128 to 150) and Chrome Runtime - #523

Open
WizardCM wants to merge 2 commits into
obsproject:masterfrom
WizardCM:chrome-runtime-changes
Open

Enable support for CEF 6613+ (Chrome 128 to 150) and Chrome Runtime#523
WizardCM wants to merge 2 commits into
obsproject:masterfrom
WizardCM:chrome-runtime-changes

Conversation

@WizardCM

@WizardCM WizardCM commented May 24, 2026

Copy link
Copy Markdown
Member

Description

We made it! After a lot of work, burnout, and testing, support for CEF 6613 (Chrome 128) and the Chrome Runtime is ready to be reviewed!

This (finally) gives us the ability to safely migrate to the Chrome Runtime, the replacement to the Alloy Runtime that CEF has been using forever. CEF/Chrome versions from 6613/128 to 7871/150 (yes, current stable) are now fully supported and work out of the box.

Tip

Test builds of CEF can be downloaded from https://cef-builds.spotifycdn.com/index.html (use Minimal, Current Stable)


Add a dummy Browser Client to introduce limitations into the Chrome UI windows that can be opened in uncontrolled edge cases. Chrome UI windows are unmanaged by default. By returning something other than null in GetDefaultClient() we can lock it down in various ways. https://magpcss.org/ceforum/viewtopic.php?f=6&t=19898

OnBeforePopup, OnOpenURLFromTab in the Dummy Client can probably be removed as they don't get called. There's no direct way to stop the Chrome UI window from being opened, so instead close it immediately. However, I've kept them just in case.

Disable Various Chrome Settings in custom docks & browser sources via SetPreferences. For more, check chrome/common/pref_names.h. We should actively keep an eye on this in future when updating CEF.

Chrome's default error display is now used by CEF, so on top of the existing override in browser docks, a similar override has been added to browser sources which just redirects to about:blank.

Also blocks

  • Chrome Extensions, as they are largely untested and unpredictable
  • MediaRouter, which provides Chrome's Cast.. functionality
  • CalculateNativeWinOcclusion, which lowers FPS for hidden pages
  • LiveCaption, which provides automatic captions
  • DocumentPictureInPictureAPI, which provides PiP widgets (YouTube)

A data migration function is included. It moves some directories into a new 'Default' profile subdirectory, and performs the necessary renaming of certain files to ensure the new Profile loads. This is necessary for user's data to be maintained, as the Alloy runtime used a bit of a custom structure which has been discarded in favour of Chrome Runtime's. CEF does not provide a migration path.

Additionally, the cookie directories for each service integration must be moved into the root config directory, as subdirectories in their current form (obs_profile_cookies/<cookie_id>) are not supported. This is intentional, and according to Marshall this was never a supported setup. cache_path must be a direct child of the root_cache_path. Invalid cache_path_ is silently treated as Incognito Mode and cookies are not stored.

To work around this, I've included some temporary code to translate the path received from the OBS frontend. When this PR is to be merged, I can submit a PR to obs-studio to match the intended behaviour.

Originally, I tracked down a number of crashes when loading various chrome:// urls in the new runtime. This also exposed the fact that users would be able to access pages we didn't want them to see, such as chrome://settings. My original implementation therefore added a filter to block such pages from loading. Since then, CEF added its own whitelist to protect users from crashes, so my PR in its current form no longer has such protection. If it comes up, I can re-implement such protections in the future.

Motivation and Context

Keeping CEF up to date is important - for security, reliability, support, and access to modern features.

How Has This Been Tested?

Tested on Windows 10 on CEF 147 with a plugin_config/obs-browser config directory from OBS 32.1 to ensure data is migrated correctly. Launched again after migration to ensure data was still accessible. cef_binary_147.0.14+g76d2442+chromium-147.0.7727.138_windows64_minimal

Tested again with our current CEF 127 build to ensure we can use 6533 unchanged if CEF tests themselves backfire.

Additionally tested over the past few months with the following versions as they were released. No regressions were found. Mostly my fault for taking so long.

cef_binary_128.0.0+g446b7d6+chromium-128.0.6613.0_windows64_minimal
cef_binary_132.3.2+g4997b2f+chromium-132.0.6834.161_windows64_minimal
cef_binary_136.1.5+g723b52b+chromium-136.0.7103.93_windows64_minimal
cef_binary_143.0.13+g30cb3bd+chromium-143.0.7499.170_windows64_minimal
cef_binary_145.0.28+g51162e8+chromium-145.0.7632.160_windows64_minimal

Additionally, @hoshinolina has done tremendous work testing this on Fedora, with users actively using the code in this PR since November 2025. As far as I know, users have had very few complaints.

Types of changes

  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (a change to documentation pages)

Checklist:

  • I have read the contributing document.
  • My code has been run through clang-format.
  • My code follows the project's style guidelines
  • My code is not on the master branch.
  • My code has been tested.
  • All commit messages are properly formatted and commits squashed where appropriate.
  • I have included updates to all appropriate documentation.

@WizardCM
WizardCM force-pushed the chrome-runtime-changes branch from f4f7da9 to 6087ad4 Compare May 24, 2026 03:48
@WizardCM WizardCM added kind/enhancement Enhancements are not bugs or new features but can improve usability or performance. Seeking Testers labels May 24, 2026
@hoshinolina

hoshinolina commented May 24, 2026

Copy link
Copy Markdown
Contributor

For reference, the only issues we've run into in Fedora as far as I remember have been:

  • Unrelated bugs in OBS (that affected CEF/obs-browser for computers-are-hard-tm reasons)
  • Fix stack smash crashes on Linux #493 & Require extra info for Linux hardware accel #491 (merged)
  • Do not try to create the browser before init #519 (this has always been broken but newer CEF makes it assert way more often when it fails the ABI version check, you probably want to get that one sorted out / added as a dependency to this)
  • Unrelated bugs in CEF (since fixed)
  • Binary compatibility issues: Newer versions of CEF have a stable ABI that allows decoupling CEF updates from OBS updates. Fedora takes advantage of this to ship CEF as a generic package (possibly usable by other consumers) and keep it as up to date as possible (in fact, Fedora decouples CEF and Chromium updates too, sometimes shipping Chromium security fixes within the CEF package before upstream CEF itself). This mechanism has had some teething issues with unexpected compat breaks. As long as OBS continues to ship updates in lockstep with CEF and against the EXPERIMENTAL API version (which is the default), this should not affect it (in all cases, rebuilding OBS against the current version/API of CEF would have fixed/worked around the ABI break we saw).
  • The whole no-docks-in-Wayland mess, which has nothing to do with this

So overall, nothing really relevant to this PR. That said, I should point out that Fedora never shipped nor tested the profile migration code. While Fedora did briefly ship the old obs-cef at one point in the past, that was abandoned as unmaintainable (making it build with newer compilers/libs became a nightmare), so there was a period where OBS had no CEF support in Fedora before this was reintroduced, and therefore no good reason to worry about profile migrations (it would only benefit people who had used the old version, to revive their old dormant profiles, which we figured wasn't really worth it).

If anyone wants to build this PR in Fedora against system CEF, the only required changes should be:

  1. Install cef-devel
  2. rm cmake/finders/FindCEF.cmake (cef-devel provides this systemwide, interface-compatible with the OBS version)
  3. Either run with LD_LIBRARY_PATH=/usr/lib64/cef or change the rpath setting:
    sed -e 's,INSTALL_RPATH ".*",INSTALL_RPATH "/usr/lib64/cef/",' -i plugins/obs-browser/cmake/os-linux.cmake
  4. -DENABLE_BROWSER=ON and optionally, -DCEF_API_VERSION=xxxxx if you want to build against a specific versioned API/ABI (Fedora arbitrarily picks 13700 here, but I don't think CEF has actually changed any APIs in a source-incompatible way with OBS since 13300, the very first version, so you can pick whatever right now).

Note that unlike the standard OBS build, this setup embeds the libcef_dll_wrapper build into the OBS build, so you will see that being built alongside the rest of obs-browser (the wrapper source code is shipped in cef-devel). All that is taken care of by the system FindCEF.cmake and the way the CEF package itself is patched/configured, and in fact it turned out to be quite easy to do and it works very well. We settled on this approach after trying to pre-build the wrapper in cef-devel, because we realized that it was impractical to build a separate wrapper for every possible version and additionally, consumers may want to build the wrapper with their own choice of compile-time options making "universal" wrapper builds not really a good idea (upstream CEF confirmed this too). Relevant links: FindCEF.cmake cef.spec (search for libcef_dll for the few relevant lines). I would personally encourage OBS to consider exploring this approach instead of a separate libcef_dll_wrapper build for official binaries/CI, but that's just me (and it's not a blocker for this PR in any way) ^^

@Warchamp7 Warchamp7 added this to the OBS Studio 33.0 milestone May 26, 2026
@RytoEX
RytoEX requested review from PatTheMav, RytoEX and Warchamp7 May 26, 2026 18:49
Comment thread panel/browser-panel.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated
Comment thread browser-client.cpp Outdated
Comment thread browser-app.cpp
Comment thread browser-app.cpp Outdated
@Phr3d13

Phr3d13 commented May 27, 2026

Copy link
Copy Markdown

how would I test this on arch? (sorry, really new to arch at the moment)

@tippfehlr

Copy link
Copy Markdown

It’s very nice to see this 🎉

Also – @hoshinolina: thanks for the CEF package in Fedora, it was very helpful when creating the Arch package ^^

@Phr3d13: I pushed obs-studio 32.1.2-5 and obs-studio-plugin-browser 32.1.2-5 with these changes to the [extra-testing] repository. Look at the Arch Wiki on how to use the testing repositories. Though be warned, that will install all testing packages, not just obs.

@WizardCM
WizardCM force-pushed the chrome-runtime-changes branch from 6087ad4 to 8d898b5 Compare May 29, 2026 07:55

@tytan652 tytan652 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.

C strings leaks…

Comment thread obs-browser-plugin.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated

@tytan652 tytan652 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.

Issue met while building on Arch and Flatpak.

Comment thread panel/browser-panel-client.cpp Outdated
Comment thread browser-app.hpp Outdated
@WizardCM
WizardCM force-pushed the chrome-runtime-changes branch from 8d898b5 to d6f85aa Compare May 29, 2026 10:08
@Warchamp7 Warchamp7 added the priority/high This is an important PR label May 29, 2026
Comment thread browser-app.cpp
Comment thread browser-app.cpp
Comment thread browser-client.cpp Outdated
Comment thread panel/browser-panel.cpp Outdated
Comment thread browser-client.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated
Comment thread obs-browser-plugin.cpp Outdated
Comment thread obs-browser-plugin.cpp
Comment thread obs-browser-plugin.cpp Outdated

@PatTheMav PatTheMav left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks fine otherwise. Haven't given this a test on my machine yet though, will do so soon.

Comment thread panel/browser-panel.cpp Outdated
@WizardCM
WizardCM force-pushed the chrome-runtime-changes branch from 23ec123 to c8339c8 Compare May 31, 2026 13:42
@WizardCM

WizardCM commented May 31, 2026

Copy link
Copy Markdown
Member Author

I've rebased and pushed the latest review fixes, with a couple minor additions

  1. An os_event_try(cef_started_event) check to QCefWidgetInternal::Resize() to fix a crash when the user has no browser sources but does have browser docks. This is initiated by the restoreDockState function before CEF has initialised. Docks do correctly resize once they've loaded.
    • I could instead put this in bool QueueCEFTask for ultimate protection. Open to feedback on this.
  2. Disabling of StorageNotificationService just in case

Additionally, after some testing from Warchamp, we have confirmed the two following regressions

  1. The remote debugging hosted webpage doesn't load. Current running theory is the shell_devtools_discovery_page.html resource is not being shipped in the .pak file by CEF, so the website returns an empty string. We are experimenting with options. Users do have the alternative of using chrome://inspect from a desktop browser instead, though it is very slow to refresh its list and currently displays duplicates.
  2. Access to media devices (eg mic) and network devices is implicitly denied by browser docks due to running on the Alloy style. Our options are to either implicitly allow, or implement a permission UX of some kind. This will likely be via a separate PR.

Additional area I'm looking into, which may be separate PR

  1. Dev Tools windows (right click Inspect from a browser dock) currently display a Chromium icon and a profile badge on Windows. To fix, this may require a change to obs.rc.in in the main repo if I don't successfully guess the icon ID number.

Comment thread browser-app.cpp Outdated
@tippfehlr

Copy link
Copy Markdown

@tytan652 I saw your 👎, is that only related to generally using obs-browser with cef 148, or is it related to applying the patch? If it’s the latter, could you elaborate?

As far as I know, obs-browser worked before this patch, and it still works with this patch.

@mihawk90

Copy link
Copy Markdown

2. Access to media devices (eg mic) and network devices is implicitly denied by browser docks due to running on the Alloy style. Our options are to either implicitly allow, or implement a permission UX of some kind. This will likely be via a separate PR.

Is this not what the --enable-media-stream currently does? Is that removed in newer Chromium versions?

I've been using this for a while for browser docks to have access to output device listing, but AFAIK this also allows input device listing.

@WizardCM
WizardCM force-pushed the chrome-runtime-changes branch from c8339c8 to 6d1031e Compare June 1, 2026 08:08
@WizardCM

WizardCM commented Jun 1, 2026

Copy link
Copy Markdown
Member Author
  1. Access to media devices (eg mic) and network devices is implicitly denied by browser docks due to running on the Alloy style. Our options are to either implicitly allow, or implement a permission UX of some kind. This will likely be via a separate PR.

Is this not what the --enable-media-stream currently does? Is that removed in newer Chromium versions?

I've been using this for a while for browser docks to have access to output device listing, but AFAIK this also allows input device listing.

I'm unsure if it was removed, or deprecated in favour of other things. At the very least, CEF explicitly denies the request in the Chrome Runtime's Alloy Style when it didn't in the Alloy Runtime.

We could, as a temporary solution, read the flag and manually allow those calls for now, but ultimately I think having some kind of UI for it would be better, especially as there's a proper API for it.

@kurehajime

Copy link
Copy Markdown

Thanks a lot for working on this — I’m really looking forward to using a modern Chromium build in browser sources.

I have one request.
If possible, I’d like you to consider including IndexedDB in the scope of this migration.

https://github.com/WizardCM/obs-browser/blob/6d1031e0e88b31a19a0fbc96ed101cb1b1a596b3/obs-browser-plugin.cpp#L749-L755

Thanks again!

@WizardCM

Copy link
Copy Markdown
Member Author

I have one request. If possible, I’d like you to consider including IndexedDB in the scope of this migration.

Thanks again!

Thanks for the feedback! I see my mistake was using a barebones scene collection with basic browser sources & docks as a testing ground - there do seem to be other directories, like IndexedDB (and probably Service Worker or WebStorage) that should be migrated too. I'll have to do some additional research on this and I'll update the PR.

@WizardCM
WizardCM force-pushed the chrome-runtime-changes branch from 6d1031e to 4233ad8 Compare June 23, 2026 12:30
Comment thread panel/browser-panel.cpp Outdated
Comment thread panel/browser-panel.cpp
Comment thread browser-app.cpp Outdated
@WizardCM
WizardCM force-pushed the chrome-runtime-changes branch from 0c9f62d to 738d9d0 Compare June 28, 2026 04:00
@github-project-automation github-project-automation Bot moved this to Ready For Review in 33.0 Release Tracker Jul 6, 2026
@out out mentioned this pull request Jul 20, 2026
6 tasks
@out

out commented Jul 20, 2026

Copy link
Copy Markdown

Tested this on macOS arm64 (Apple silicon) against CEF 147 — browser sources render, Chrome Runtime initialises, and the Alloy→Chrome Runtime profile migration completes cleanly against a real long-lived profile. Thanks for grinding through this one.

Two macOS-specific notes:

#517 isn't quite enough on macOS. It bumps the plugin and the Linux helper, but cmake/os-macos.cmake builds four more helper executables that also compile the CEF headers, and they still fail on std::same_as / derived_from / convertible_to. One extra target_compile_features(... cxx_std_20) in the helper loop fixes it — details in #517.

The migration writes to the real profile even in portable mode. obs_module_config_path() doesn't honour --portable, so the migration runs against ~/Library/Application Support/obs-studio/plugin_config/obs-browser regardless. It's copy-only so nothing is destroyed, and I confirmed a stock OBS 32.1.2 (Alloy, CEF 127.0.6533.120) still loads and renders browser sources against the migrated profile afterwards — so the two can coexist on one profile. Worth mentioning to testers so they back up first, since --portable looks like it would isolate things but doesn't.

Environment

OS macOS 26.5.2, arm64
Toolchain Xcode 26.6 (17F113), Apple clang 21.0.0, CMake 4.1.2
CEF 147.0.14+g76d2442+chromium-147.0.7727.138 (macosarm64), wrapper built with USE_SANDBOX=OFF
obs-studio 0218aa658
PR head 738d9d0

@WizardCM WizardCM changed the title Enable support for CEF 6613+ (Chrome 128 to 147) and Chrome Runtime Enable support for CEF 6613+ (Chrome 128 to 150) and Chrome Runtime Aug 3, 2026
@WizardCM

WizardCM commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

Warchamp performed some quick testing and noticed that CEF 151 (7922) crashes when interacting with browser docks. I have verified that is the case, and that CEF 150 (7871) behaves normally. I have updated the title and description to reflect this, and will separately look into why CEF 151 is misbehaving.

@kurehajime

Copy link
Copy Markdown

Thanks for the huge effort on the Chrome runtime migration!

I wanted to flag a potential compatibility issue related to the permission handling that was deferred to a follow-up PR.

Chromium 142 introduced permission-gated Local Network Access (LNA) checks for requests from public HTTPS origins to local and loopback destinations (Chrome blog). Chromium 147 extends these checks to WebSocket connections, including loopback destinations such as ws://127.0.0.1 (Intent to Ship).

The CEF range supported by this PR includes Chromium 147+. Since OBS browser sources and docks use Alloy style, where permission prompts are not shown by default, I'm concerned that remotely hosted HTTPS overlays connecting to local WebSocket servers may no longer be able to connect.

Connecting from a remotely hosted page to a WebSocket server running on the local machine is a fairly common pattern among streaming tools and overlays, so the impact could be fairly broad in the streaming ecosystem.

Would this be worth taking into account in the follow-up permission work, or tracking as a separate issue?

I mainly wanted to make sure it was on the radar before a CEF 147+ build ships.

@WizardCM

Copy link
Copy Markdown
Member Author

Thanks for the feedback @kurehajime - it'll definitely be taken into account with an initial permission implementation alongside the release of this PR. Keep an eye out for a follow-up PR, likely once this one is merged.

@RytoEX RytoEX left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mostly nits.

Comment thread cmake/os-linux.cmake Outdated
Comment thread cmake/os-macos.cmake Outdated
Comment thread cmake/os-windows.cmake Outdated
Comment thread browser-app.cpp Outdated
Comment thread browser-app.cpp Outdated
Comment thread browser-client.cpp Outdated
Comment thread browser-dummy-client.cpp
Comment thread browser-dummy-client.hpp
Comment thread obs-browser-plugin.cpp Outdated
@github-project-automation github-project-automation Bot moved this from Ready For Review to Requires Changes in 33.0 Release Tracker Aug 20, 2026
Add a dummy Browser Client to introduce limitations into the Chrome UI
windows that can be opened in uncontrolled edge cases. Chrome UI windows
are unmanaged by default. By returning something other than null in
GetDefaultClient() we can lock it down in various ways.

OnBeforePopup, OnOpenURLFromTab can probably be removed as they don't
get called. There's no direct way to stop the Chrome UI window from
being opened, so instead close it immediately.

Disable Various Chrome Settings in custom docks & browser sources
via SetPreferences. For more, check `chrome/common/pref_names.h`.

Chrome's default error display is now used by CEF, so on top of the
existing override in browser docks, a similar override has been added
to browser sources which just redirects to about:blank.

Also blocks
 - Chrome Extensions, as they are largely untested and unpredictable
 - MediaRouter, which provides Cast.. functionality
 - CalculateNativeWinOcclusion, which lowers FPS for hidden pages
 - LiveCaption, which provides automatic captions
 - DocumentPictureInPictureAPI, which provides PiP widgets (YouTube)
 - StorageNotificationService, when approaching low cache space

A data migration function is included. It moves some directories into a
new 'Default' profile subdirectory, and performs the necessary renaming
of certain files to ensure the new Profile loads.
Additionally, the cookie directories for each service integration must
be moved into the root config directory, as subdirectories in their
current form (obs_profile_cookies/<cookie_id>) are not supported. This
is intentional, and according to Marshall this was never a supported
setup. cache_path *must* be a direct child of the root_cache_path.
Invalid cache_path_ is silently treated as Incognito Mode and cookies
are not stored.
@WizardCM
WizardCM force-pushed the chrome-runtime-changes branch from 738d9d0 to 6546824 Compare August 21, 2026 12:44
Comment thread browser-app.cpp Outdated
Comment thread browser-app.cpp
@WizardCM
WizardCM force-pushed the chrome-runtime-changes branch 2 times, most recently from 6a619a4 to d1988f0 Compare August 25, 2026 09:08
@RytoEX
RytoEX requested review from PatTheMav and RytoEX September 2, 2026 17:11

@RytoEX RytoEX left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nits.

Comment thread browser-app.cpp Outdated
Comment thread browser-app.cpp Outdated
@tytan652

tytan652 commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Adding GlobalShortcutsPortal in disabled features for the side Linux is needed (CEF should not meddle with this portal).

@WizardCM
WizardCM force-pushed the chrome-runtime-changes branch from d1988f0 to 7b30bf5 Compare September 3, 2026 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/enhancement Enhancements are not bugs or new features but can improve usability or performance. priority/high This is an important PR Seeking Testers

Projects

Status: Requires Changes

Development

Successfully merging this pull request may close these issues.