From a1fac4049d79171dc40f0cd416c1358fd4dc2d3c Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 25 Feb 2018 23:30:49 +0100 Subject: [PATCH] When asked to execute JavaScript, defer until the current page load is done. --- cef_capture.cpp | 29 ++++++++++++++++++++++++++--- cef_capture.h | 24 +++++++++++++++++++++++- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/cef_capture.cpp b/cef_capture.cpp index 1836eb8..76c5c7f 100644 --- a/cef_capture.cpp +++ b/cef_capture.cpp @@ -52,6 +52,7 @@ void CEFCapture::post_to_cef_ui_thread(std::function &&func) void CEFCapture::set_url(const string &url) { post_to_cef_ui_thread([this, url] { + loaded = false; browser->GetMainFrame()->LoadURL(url); }); } @@ -74,9 +75,13 @@ void CEFCapture::set_max_fps(int max_fps) void CEFCapture::execute_javascript_async(const string &js) { post_to_cef_ui_thread([this, js] { - CefString script_url(""); - int start_line = 1; - browser->GetMainFrame()->ExecuteJavaScript(js, script_url, start_line); + if (loaded) { + CefString script_url(""); + int start_line = 1; + browser->GetMainFrame()->ExecuteJavaScript(js, script_url, start_line); + } else { + deferred_javascript.push_back(js); + } }); } @@ -106,6 +111,19 @@ void CEFCapture::OnPaint(const void *buffer, int width, int height) FrameAllocator::Frame(), 0, AudioFormat()); } +void CEFCapture::OnLoadEnd() +{ + post_to_cef_ui_thread([this] { + loaded = true; + for (const string &js : deferred_javascript) { + CefString script_url(""); + int start_line = 1; + browser->GetMainFrame()->ExecuteJavaScript(js, script_url, start_line); + } + deferred_javascript.clear(); + }); +} + #define FRAME_SIZE (8 << 20) // 8 MB. void CEFCapture::configure_card() @@ -199,3 +217,8 @@ bool NageruCEFClient::GetViewRect(CefRefPtr browser, CefRect &rect) rect = CefRect(0, 0, width, height); return true; } + +void NageruCEFClient::OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) +{ + parent->OnLoadEnd(); +} diff --git a/cef_capture.h b/cef_capture.h index 11cdc33..c497179 100644 --- a/cef_capture.h +++ b/cef_capture.h @@ -17,6 +17,7 @@ #include #include #include +#include #undef CHECK #include @@ -31,7 +32,7 @@ class CEFCapture; // A helper class for CEFCapture to proxy information to CEF, without becoming // CEF-refcounted itself. -class NageruCEFClient : public CefClient, public CefRenderHandler +class NageruCEFClient : public CefClient, public CefRenderHandler, public CefLoadHandler { public: NageruCEFClient(int width, int height, CEFCapture *parent) @@ -42,10 +43,21 @@ public: return this; } + CefRefPtr GetLoadHandler() override + { + return this; + } + + // CefRenderHandler. + void OnPaint(CefRefPtr browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height) override; bool GetViewRect(CefRefPtr browser, CefRect &rect); + // CefLoadHandler. + + void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) override; + private: int width, height; CEFCapture *parent; @@ -76,6 +88,8 @@ public: void OnPaint(const void *buffer, int width, int height); + void OnLoadEnd(); + // CaptureInterface. void set_video_frame_allocator(bmusb::FrameAllocator *allocator) override { @@ -173,6 +187,14 @@ private: // Tasks waiting for to get ready. Under . std::vector> deferred_tasks; + // Whether the last set_url() (includes the implicit one in the constructor) + // has loaded yet. Accessed from the CEF thread only. + bool loaded = false; + + // JavaScript waiting for the first page (well, any page) to have loaded. + // Accessed from the CEF thread only. + std::vector deferred_javascript; + int timecode = 0; }; -- 2.39.2