diff --git a/MR-DESCRIPTION.md b/MR-DESCRIPTION.md new file mode 100644 index 0000000..58077a5 --- /dev/null +++ b/MR-DESCRIPTION.md @@ -0,0 +1,50 @@ +# feat: expose client delegate hooks required by embedding hosts + +## Summary + +Adds four virtual hooks to `CefViewBrowserClientDelegate` that embedding +hosts currently have no way to observe. All have default implementations +and are purely additive — no existing override changes behavior. + +| Hook | Before | After | +|---|---|---| +| `onBeforeBrowse` | dropped after `message_router_->OnBeforeBrowse` | forwarded; return true cancels | +| `onRenderProcessTerminated` | dropped after message-router cleanup (TerminationStatus already scoped) | forwarded with status/error_code/error_string (CEF 124+; two-arg overload otherwise) | +| `onFindResult` | **result discarded entirely** (empty `OnFindResult` body) | forwarded with identifier/count/selectionRect/activeMatchOrdinal/finalUpdate | +| `onFileDialogEx` | — (CEF 126+ accept extensions/descriptions unavailable) | new; default falls back to `onFileDialog`, so existing subclasses are unaffected | + +## Why these four + +- **onBeforeBrowse** is the only interception point for in-page navigations, + redirects, iframes and `window.open` — an embedding host cannot implement a + navigation policy without it. +- **onRenderProcessTerminated** is the renderer-crash observability hook + (host-level auto-reload / telemetry). +- **onFindResult** powers find-in-page UI; the current code receives the + callback and drops it. +- **onFileDialogEx** exposes the accept extensions/descriptions CEF 126+ + provides; the legacy `onFileDialog` cannot carry them. + +## Compatibility + +- Default implementations only: overriding none of them is byte-for-byte + the previous behavior (verified: consumers that don't override compile and + run identically). +- `onFileDialogEx` guards `CEF_VERSION_MAJOR >= 126`; `onRenderProcessTerminated` + keeps a two-arg overload path for CEF < 124. +- No ABI change to existing symbols; `CefVersion.h` pin in this branch is a + local-baseline concern (drop that commit when merging — it reflects this + fork's 127.3.5 rollback, not an upstream recommendation). + +## Validation + +Downstream consumer (Unity embedding, private) runs these hooks through a +pfn callback ABI with machine-verified regressions: +- navigation-policy rejections observable end-to-end (`javascript:` scheme + blocked, machine-readable reasons) +- renderer kill injection → host receives termination + auto-reload +- find results streamed to a host UI +- file dialog extensions/descriptions cross the ABI as JSON + +Branch: `feat/unity-callbacks` (5 commits; the `CefVersion.h` pin commit +`0bba10b` is fork-local and should be excluded from the merge). diff --git a/include/CefVersion.h b/include/CefVersion.h index 1f20f07..da85c65 100644 --- a/include/CefVersion.h +++ b/include/CefVersion.h @@ -13,12 +13,12 @@ #pragma once // clang-format off -#define CEF_VERSION "142.0.15+g6dfdb28+chromium-142.0.7444.176" -#define CEF_VERSION_MAJOR 142 -#define CEF_VERSION_MINOR 0 -#define CEF_VERSION_PATCH 15 -#define CEF_COMMIT_NUMBER 3314 -#define CEF_COMMIT_HASH "6dfdb28d752a47e189d7a23b01f368ab0bdb378d" +#define CEF_VERSION "127.3.5+g114ea2a+chromium-127.0.6533.120" +#define CEF_VERSION_MAJOR 127 +#define CEF_VERSION_MINOR 3 +#define CEF_VERSION_PATCH 5 +#define CEF_COMMIT_NUMBER 3037 +#define CEF_COMMIT_HASH "114ea2af1ba9da18c4ac5e599ccdbb17d01ba75a" // clang-format on #endif // CefVersion diff --git a/include/CefViewBrowserClientDelegate.h b/include/CefViewBrowserClientDelegate.h index 38b4889..9f3d0da 100644 --- a/include/CefViewBrowserClientDelegate.h +++ b/include/CefViewBrowserClientDelegate.h @@ -123,6 +123,25 @@ class CefViewBrowserClientDelegateInterface { return false; }; + +#if CEF_VERSION_MAJOR >= 126 + /// + /// Same as onFileDialog plus the raw accept extensions and descriptions + /// that CEF 126+ provides. The default implementation discards the extra + /// information and falls back to onFileDialog. + /// + virtual bool onFileDialogEx(CefRefPtr& browser, + CefBrowserHost::FileDialogMode mode, + const CefString& title, + const CefString& default_file_path, + const std::vector& accept_filters, + const std::vector& accept_extensions, + const std::vector& accept_descriptions, + CefRefPtr& callback) + { + return onFileDialog(browser, mode, title, default_file_path, accept_filters, callback); + } +#endif #pragma endregion // display handler @@ -175,6 +194,27 @@ class CefViewBrowserClientDelegateInterface const std::vector& regions) = 0; #pragma endregion + // find handler +#pragma region FindHandler + /// + /// Called to report find results. + /// + /// + /// + /// + /// + /// + /// + virtual void onFindResult(CefRefPtr& browser, + int identifier, + int count, + const CefRect& selectionRect, + int activeMatchOrdinal, + bool finalUpdate) + { + } +#pragma endregion + // focus handler #pragma region FocusHandler virtual void takeFocus(CefRefPtr& browser, bool next) = 0; @@ -252,6 +292,40 @@ class CefViewBrowserClientDelegateInterface bool& handled) = 0; #pragma endregion + // request handler +#pragma region RequestHandler + /// + /// Called on the UI thread before browser navigation. + /// Return true to cancel the navigation. + /// + virtual bool onBeforeBrowse(CefRefPtr& browser, + CefRefPtr& frame, + CefRefPtr& request, + bool user_gesture, + bool is_redirect) + { + return false; + } + + /// + /// Called when the render process terminates abnormally. + /// + /// + /// + /// Only available for CEF 124 and above. + /// Only available for CEF 124 and above. + virtual void onRenderProcessTerminated(CefRefPtr& browser, + CefRequestHandler::TerminationStatus status +#if CEF_VERSION_MAJOR >= 124 + , + int errorCode, + const CefString& errorString +#endif + ) + { + } +#pragma endregion + #if CEF_VERSION_MAJOR >= 106 #pragma region PermissionHandler virtual bool onRequestMediaAccessPermission(CefRefPtr& browser, diff --git a/src/CefView/CefBrowserApp/CefViewBrowserClient_DialogHandler.cpp b/src/CefView/CefBrowserApp/CefViewBrowserClient_DialogHandler.cpp index 86bc04c..edc25eb 100644 --- a/src/CefView/CefBrowserApp/CefViewBrowserClient_DialogHandler.cpp +++ b/src/CefView/CefBrowserApp/CefViewBrowserClient_DialogHandler.cpp @@ -44,7 +44,17 @@ CefViewBrowserClient::OnFileDialog(CefRefPtr browser, #endif { auto delegate = client_delegate_.lock(); - if (delegate) + if (delegate) { +#if CEF_VERSION_MAJOR >= 126 + return delegate->onFileDialogEx(browser, + mode, + title, + default_file_path, + accept_filters, + accept_extensions, + accept_descriptions, + callback); +#else return delegate->onFileDialog(browser, mode, title, @@ -54,6 +64,8 @@ CefViewBrowserClient::OnFileDialog(CefRefPtr browser, selected_accept_filter, #endif callback); +#endif + } return false; } diff --git a/src/CefView/CefBrowserApp/CefViewBrowserClient_FindHandler.cpp b/src/CefView/CefBrowserApp/CefViewBrowserClient_FindHandler.cpp index 4f3d788..f401814 100644 --- a/src/CefView/CefBrowserApp/CefViewBrowserClient_FindHandler.cpp +++ b/src/CefView/CefBrowserApp/CefViewBrowserClient_FindHandler.cpp @@ -17,4 +17,7 @@ CefViewBrowserClient::OnFindResult(CefRefPtr browser, bool finalUpdate) { CEF_REQUIRE_UI_THREAD(); + + if (auto delegate = client_delegate_.lock()) + delegate->onFindResult(browser, identifier, count, selectionRect, activeMatchOrdinal, finalUpdate); } diff --git a/src/CefView/CefBrowserApp/CefViewBrowserClient_RequestHandler.cpp b/src/CefView/CefBrowserApp/CefViewBrowserClient_RequestHandler.cpp index 741c40d..a16287c 100644 --- a/src/CefView/CefBrowserApp/CefViewBrowserClient_RequestHandler.cpp +++ b/src/CefView/CefBrowserApp/CefViewBrowserClient_RequestHandler.cpp @@ -24,6 +24,10 @@ CefViewBrowserClient::OnBeforeBrowse(CefRefPtr browser, CEF_REQUIRE_UI_THREAD(); message_router_->OnBeforeBrowse(browser, frame); + + if (auto delegate = client_delegate_.lock()) + return delegate->onBeforeBrowse(browser, frame, request, user_gesture, is_redirect); + return false; } @@ -72,6 +76,14 @@ CefViewBrowserClient::OnRenderProcessTerminated(CefRefPtr browser, message_router_->OnRenderProcessTerminated(browser); + if (auto delegate = client_delegate_.lock()) { +#if CEF_VERSION_MAJOR >= 124 + delegate->onRenderProcessTerminated(browser, status, error_code, error_string); +#else + delegate->onRenderProcessTerminated(browser, status); +#endif + } + if (browser) { CefString url = browser->GetMainFrame()->GetURL(); if (!url.empty()) {