diff --git a/documentation/doxygen/Doxyfile b/documentation/doxygen/Doxyfile index 50515a212a3d5..a46142f3c676f 100644 --- a/documentation/doxygen/Doxyfile +++ b/documentation/doxygen/Doxyfile @@ -1123,7 +1123,6 @@ EXCLUDE_PATTERNS = */G__* \ *.xml \ *.dtd \ */graf3d/eve7/glu/* \ - */gui/cefdisplay/* \ */gui/qt6webdisplay/* \ */tutorials/visualisation/webgui/qtweb/* \ */math/mathcore/src/CDT* diff --git a/gui/cefdisplay/CMakeLists.txt b/gui/cefdisplay/CMakeLists.txt index 32f2ad2c131e4..90a178b2ccb48 100644 --- a/gui/cefdisplay/CMakeLists.txt +++ b/gui/cefdisplay/CMakeLists.txt @@ -55,7 +55,7 @@ set(CEF_MAIN src/cef_main.cxx) ROOT_LINKER_LIBRARY(${libname} ${CEF_sources} ${CEF_platform} LIBRARIES ${CMAKE_DL_LIBS} ${CEF_LIBRARY} ${CEF_DLL_WRAPPER} ${CEF_LIB_DEPENDENCY} - DEPENDENCIES RHTTP ROOTWebDisplay) + DEPENDENCIES RHTTP ASImage ROOTWebDisplay) target_compile_definitions(${libname} PRIVATE NDEBUG) diff --git a/gui/cefdisplay/Readme.md b/gui/cefdisplay/Readme.md index 474842f28a23d..ab8228353292a 100644 --- a/gui/cefdisplay/Readme.md +++ b/gui/cefdisplay/Readme.md @@ -4,8 +4,7 @@ See details about [Chromium Embedded Framework](https://bitbucket.org/chromiumembedded/cef) -1. Current code tested with CEF3 branch 6998, Chromium 134 (April 2025) - Some older CEF versions (like 107 or 124) may also be supported. +1. Current code tested with CEF3 branch 778, Chromium 148 (June 2026) 2. Download binary code from [https://cef-builds.spotifycdn.com/index.html](https://cef-builds.spotifycdn.com/index.html) and unpack it in directory without spaces and special symbols: @@ -13,8 +12,8 @@ See details about [Chromium Embedded Framework](https://bitbucket.org/chromiumem ~~~ $ mkdir /d/cef $ cd /d/cef/ - $ wget https://cef-builds.spotifycdn.com/cef_binary_134.3.9%2Bg5dc6f2f%2Bchromium-134.0.6998.178_linux64_minimal.tar.bz2 - $ tar xjf cef_binary_134.3.9+g5dc6f2f+chromium-134.0.6998.178_linux64_minimal.tar.bz2 + $ wget https://cef-builds.spotifycdn.com/cef_binary_148.0.10%2Bg7ee53f5%2Bchromium-148.0.7778.218_linux64.tar.bz2 + $ tar xjf cef_binary_148.0.10+g7ee53f5+chromium-148.0.7778.218_linux64.tar.bz2 ~~~ @@ -24,7 +23,7 @@ See details about [Chromium Embedded Framework](https://bitbucket.org/chromiumem 4. Compile CEF to produce `libcef_dll_wrapper`: ~~~ - $ cd cef_binary_134.3.9+g5dc6f2f+chromium-134.0.6998.178_linux64_minimal + $ cd xjf cef_binary_148.0.10+g7ee53f5+chromium-148.0.7778.218_linux64 $ mkdir build $ cd build $ cmake .. @@ -34,13 +33,10 @@ See details about [Chromium Embedded Framework](https://bitbucket.org/chromiumem 5. Set CEF_ROOT variable to unpacked directory: ~~~ - $ export CEF_ROOT=/d/cef/cef_binary_134.3.9+g5dc6f2f+chromium-134.0.6998.178_linux64_minimal + $ export CEF_ROOT=/d/cef/xjf cef_binary_148.0.10+g7ee53f5+chromium-148.0.7778.218_linux64 ~~~ -6. When configure ROOT compilation with `cmake -Dwebgui=ON -Dcefweb=ON ...`, CEF_ROOT shell variable should be set appropriately. - During compilation library `$ROOTSYS/lib/libROOTCefDisplay.so` and executable `$ROOTSYS/bin/cef_main` - should be created. Also check that several files like `icudtl.dat`, `v8_context_snapshot_blob.bin`, `snapshot_blob.bin` - copied into ROOT library directory +6. When configure ROOT compilation with `cmake -Dwebgui=ON -Dcefweb=ON ...`, CEF_ROOT shell variable should be set appropriately. During compilation library `$ROOTSYS/lib/libROOTCefDisplay.so` and executable `$ROOTSYS/bin/cef_main` should be created. Also check that several files like `icudtl.dat`, `v8_context_snapshot_blob.bin`, `snapshot_blob.bin` copied into ROOT library directory 7. Run ROOT with `--web=cef` argument to use CEF web display like: @@ -51,7 +47,7 @@ See details about [Chromium Embedded Framework](https://bitbucket.org/chromiumem ## Compile libcef_dll_wrapper on Windows -1. Download binary win32 build like https://cef-builds.spotifycdn.com/cef_binary_95.7.12%2Bg99c4ac0%2Bchromium-95.0.4638.54_windows32.tar.bz2 +1. Download binary win32 build like [win64](https://cef-builds.spotifycdn.com/cef_binary_148.0.10%2Bg7ee53f5%2Bchromium-148.0.7778.218_windows64.tar.bz2) 2. Extract in directory without spaces like `C:\Soft\cef` @@ -62,45 +58,18 @@ See details about [Chromium Embedded Framework](https://bitbucket.org/chromiumem $ cd C:\Soft\cef $ mkdir build $ cd build - $ cmake -G"Visual Studio 16 2019" -A Win32 -Thost=x64 .. + $ cmake .. $ cmake --build . --config Release --target libcef_dll_wrapper ~~~ 5. Before compiling ROOT, `set CEF_ROOT=C:\Soft\cef` variable -## Using plain CEF in ROOT batch mode on Linux +## Using plain CEF in ROOT batch mode on Linux and Windows -Default CEF builds, provided by [https://cef-builds.spotifycdn.com/index.html](https://cef-builds.spotifycdn.com/index.html), do -not include support of Ozone framework, which the only support headless mode in CEF. To run ROOT in headless (or batch) made with such CEF distribution, -one can use `Xvfb` server. Most simple way is to use `xvfb-run` utility like: +Default CEF builds, provided by [https://cef-builds.spotifycdn.com/index.html](https://cef-builds.spotifycdn.com/index.html), now (June 2026) **INCLUDES!** support of Ozone framework, which allows to run CEF in headless mode on Linux and Windows. So one can run different ROOT macros and tests in batch mode like ~~~ - $ xvfb-run --server-args='-screen 0, 1024x768x16' root.exe --web=cef $ROOTSYS/tutorials/experimental/rcanvas/rline.cxx -q + $ cd $ROOTSYS/test + $ ./stressGraphics -b --web=cef ~~~ - -Or run `Xvfb` before starting ROOT: - -~~~ - $ Xvfb :99 & - $ export DISPLAY=:99 - $ root.exe --web=cef $ROOTSYS/tutorials/experimental/rcanvas/rline.cxx -q -~~~ - - -## Compile CEF with ozone support - -Since March 2019 one can compile [CEF without X11](https://bitbucket.org/chromiumembedded/cef/issues/2296/), but such builds not provided. -Therefore to be able to use real headless mode in CEF, one should compile it from sources. -On [CEF build tutorial](https://bitbucket.org/chromiumembedded/cef/wiki/AutomatedBuildSetup.md) one can find complete compilation documentation. -Several Ubuntu distributions are supported by CEF, all others may require extra work. Once all depndencies are installed, CEF with ozone support can be compiled with following commands: - -~~~ - $ export GN_DEFINES="is_official_build=true use_sysroot=true use_allocator=none symbol_level=1 is_cfi=false use_thin_lto=false use_ozone=true" - $ python automate-git.py --download-dir=/home/user/cef --branch=4638 --minimal-distrib --client-distrib --force-clean --x64-build --build-target=cefsimple -~~~ - -With little luck one get prepared tarballs in `/home/user/cef/chromium/src/cef/binary_distrib`. -Just install it in the same way as described before in this document. -ROOT will automatically detect that CEF build with `ozone` support and will use it for both interactive and headless modes. - diff --git a/gui/cefdisplay/inc/gui_handler.h b/gui/cefdisplay/inc/gui_handler.h index ed8ed4270c24b..c230c7e8c5390 100644 --- a/gui/cefdisplay/inc/gui_handler.h +++ b/gui/cefdisplay/inc/gui_handler.h @@ -109,7 +109,7 @@ class GuiHandler : public CefClient, std::string MakePageUrl(THttpServer *serv, const std::string &addr); - static bool PlatformInit(); + static void PlatformInit(); static std::string GetDataURI(const std::string& data, const std::string& mime_type); diff --git a/gui/cefdisplay/inc/simple_app.h b/gui/cefdisplay/inc/simple_app.h index c7f47697e6206..f9540bed25d3a 100644 --- a/gui/cefdisplay/inc/simple_app.h +++ b/gui/cefdisplay/inc/simple_app.h @@ -35,22 +35,24 @@ class SimpleApp : public CefApp, /*, public CefRenderProcessHandler */ public CefBrowserProcessHandler { protected: - bool fUseViewes{false}; /// fGuiHandler; /// GetBrowserProcessHandler() override { return this; } diff --git a/gui/cefdisplay/src/RCefWebDisplayHandle.cxx b/gui/cefdisplay/src/RCefWebDisplayHandle.cxx index 51319fb52abfb..4386043f4777d 100644 --- a/gui/cefdisplay/src/RCefWebDisplayHandle.cxx +++ b/gui/cefdisplay/src/RCefWebDisplayHandle.cxx @@ -87,8 +87,10 @@ std::unique_ptr RCefWebDisplayHandle::CefCreator::Displ if (!args.IsStandalone()) handle->fCloseBrowser = false; + Int_t wait_tmout = args.IsHeadless() ? gEnv->GetValue("WebGui.CefHeadlessTimeout", 30) : -1; + if (fCefApp) { - fCefApp->SetNextHandle(handle.get()); + fCefApp->SetNextHandle(handle.get(), args.IsHeadless()); CefRect rect((args.GetX() > 0) ? args.GetX() : 0, (args.GetY() > 0) ? args.GetY() : 0, (args.GetWidth() > 0) ? args.GetWidth() : 800, (args.GetHeight() > 0) ? args.GetHeight() : 600); @@ -96,12 +98,13 @@ std::unique_ptr RCefWebDisplayHandle::CefCreator::Displ fCefApp->StartWindow(args.GetHttpServer(), args.GetFullUrl(), args.GetPageContent(), rect); if (args.IsHeadless()) - handle->WaitForContent(30, args.GetExtraArgs()); // 30 seconds + handle->WaitForContent(wait_tmout, args.GetExtraArgs()); return handle; } - bool use_views = GuiHandler::PlatformInit(); + GuiHandler::PlatformInit(); + bool use_views = true; TString env_use_views = gEnv->GetValue("WebGui.CefUseViews", ""); if ((env_use_views == "yes") || (env_use_views == "1")) @@ -109,25 +112,63 @@ std::unique_ptr RCefWebDisplayHandle::CefCreator::Displ else if ((env_use_views == "no") || (env_use_views == "0")) use_views = false; + // Specify CEF global settings here. + CefSettings settings; + + TString ceflog = gEnv->GetValue("WebGui.CefLogSeveriry", "fatal"); + if (ceflog == "fatal") + settings.log_severity = LOGSEVERITY_FATAL; + else if (ceflog == "verbose") + settings.log_severity = LOGSEVERITY_VERBOSE; + else if (ceflog == "info") + settings.log_severity = LOGSEVERITY_INFO; + else if (ceflog == "warning") + settings.log_severity = LOGSEVERITY_WARNING; + else if (ceflog == "error") + settings.log_severity = LOGSEVERITY_ERROR; + else if (ceflog == "disable") + settings.log_severity = LOGSEVERITY_DISABLE; + else + settings.log_severity = LOGSEVERITY_FATAL; + + bool supress_log = (settings.log_severity == LOGSEVERITY_DISABLE) || + (settings.log_severity == LOGSEVERITY_FATAL); + + TApplication *root_app = gROOT->GetApplication(); + + std::vector cef_argv = { root_app->Argv(0) }; + #ifdef OS_WIN - CefMainArgs main_args(GetModuleHandle(nullptr)); + + CefMainArgs main_args(args.IsHeadless() ? (HINSTANCE) 0 : GetModuleHandle(nullptr)); + #else - TApplication *root_app = gROOT->GetApplication(); - int cef_argc = 1; - const char *arg2 = nullptr, *arg3 = nullptr; if (args.IsHeadless()) { - // arg2 = "--allow-file-access-from-files"; - arg2 = "--disable-web-security"; - cef_argc++; - if (use_views) { - arg3 = "--ozone-platform=headless"; - cef_argc++; - } + cef_argv.emplace_back("--user-data-dir=."); + cef_argv.emplace_back("--allow-file-access-from-files"); + cef_argv.emplace_back("--disable-web-security"); + cef_argv.emplace_back("--disable-gpu"); + cef_argv.emplace_back("--ignore-gpu-blocklist"); +#ifdef OS_LINUX + cef_argv.emplace_back("--use-gl=swiftshader"); + cef_argv.emplace_back("--enable-unsafe-swiftshader"); +#endif + cef_argv.emplace_back("--off-screen-rendering-enabled"); + if (use_views) + cef_argv.emplace_back("--ozone-platform=headless"); + } + + if (supress_log) { + cef_argv.emplace_back("--disable-logging"); + cef_argv.emplace_back("--enable-logging=none"); + cef_argv.emplace_back("--v=-1"); } - char *cef_argv[] = {root_app->Argv(0), (char *) arg2, (char *) arg3, nullptr}; - CefMainArgs main_args(cef_argc, cef_argv); + cef_argv.emplace_back(nullptr); + + CefMainArgs main_args(cef_argv.size() - 1, (char **) cef_argv.data()); + #endif // CEF applications have multiple sub-processes (render, plugin, GPU, etc) @@ -146,8 +187,6 @@ std::unique_ptr RCefWebDisplayHandle::CefCreator::Displ // XSetErrorHandler(XErrorHandlerImpl); // XSetIOErrorHandler(XIOErrorHandlerImpl); - // Specify CEF global settings here. - CefSettings settings; TString cef_main = TROOT::GetBinDir() + "/cef_main"; cef_string_ascii_to_utf16(cef_main.Data(), cef_main.Length(), &settings.browser_subprocess_path); @@ -177,8 +216,8 @@ std::unique_ptr RCefWebDisplayHandle::CefCreator::Displ settings.no_sandbox = true; // if (gROOT->IsWebDisplayBatch()) settings.single_process = true; - // if (batch_mode) - // settings.windowless_rendering_enabled = true; + if (args.IsHeadless()) + settings.windowless_rendering_enabled = true; // settings.external_message_pump = true; // settings.multi_threaded_message_loop = false; @@ -186,8 +225,6 @@ std::unique_ptr RCefWebDisplayHandle::CefCreator::Displ std::string plog = "cef.log"; cef_string_ascii_to_utf16(plog.c_str(), plog.length(), &settings.log_file); - settings.log_severity = LOGSEVERITY_ERROR; // LOGSEVERITY_VERBOSE, LOGSEVERITY_INFO, LOGSEVERITY_WARNING, - // LOGSEVERITY_ERROR, LOGSEVERITY_DISABLE // settings.uncaught_exception_stack_size = 100; // settings.ignore_certificate_errors = true; @@ -196,18 +233,19 @@ std::unique_ptr RCefWebDisplayHandle::CefCreator::Displ // SimpleApp implements application-level callbacks for the browser process. // It will create the first browser instance in OnContextInitialized() after // CEF has initialized. - fCefApp = new SimpleApp(use_views, args.GetHttpServer(), args.GetFullUrl(), args.GetPageContent(), - args.GetWidth() > 0 ? args.GetWidth() : 800, - args.GetHeight() > 0 ? args.GetHeight() : 600, - args.IsHeadless()); + fCefApp = new SimpleApp(use_views, supress_log, + args.GetHttpServer(), args.GetFullUrl(), args.GetPageContent(), + args.GetWidth() > 0 ? args.GetWidth() : 800, + args.GetHeight() > 0 ? args.GetHeight() : 600, + args.IsHeadless()); - fCefApp->SetNextHandle(handle.get()); + fCefApp->SetNextHandle(handle.get(), args.IsHeadless()); // Initialize CEF for the browser process. CefInitialize(main_args, settings, fCefApp.get(), nullptr); if (args.IsHeadless()) { - handle->WaitForContent(30, args.GetExtraArgs()); // 30 seconds + handle->WaitForContent(wait_tmout, args.GetExtraArgs()); } else { // Create timer to let run CEF message loop together with ROOT event loop Int_t interval = gEnv->GetValue("WebGui.CefTimer", 10); diff --git a/gui/cefdisplay/src/gui_handler.cxx b/gui/cefdisplay/src/gui_handler.cxx index 6edfee46bb54f..3c172d73409ce 100644 --- a/gui/cefdisplay/src/gui_handler.cxx +++ b/gui/cefdisplay/src/gui_handler.cxx @@ -21,6 +21,7 @@ #include #include +#include #include #include "include/base/cef_bind.h" @@ -175,21 +176,22 @@ bool GuiHandler::OnConsoleMessage(CefRefPtr browser, switch (level) { case LOGSEVERITY_WARNING: if (fConsole > -1) - R__LOG_WARNING(CefWebDisplayLog()) << Form("CEF: %s:%d: %s", src.c_str(), line, message.ToString().c_str()); + std::cout << TString::Format("CEF: %s:%d: %s", src.c_str(), line, message.ToString().c_str()) << std::endl; break; case LOGSEVERITY_ERROR: if (fConsole > -2) - R__LOG_ERROR(CefWebDisplayLog()) << Form("CEF: %s:%d: %s", src.c_str(), line, message.ToString().c_str()); + std::cerr << TString::Format("CEF: %s:%d: %s", src.c_str(), line, message.ToString().c_str()) << std::endl; break; default: if (fConsole > 0) - R__LOG_DEBUG(0, CefWebDisplayLog()) << Form("CEF: %s:%d: %s", src.c_str(), line, message.ToString().c_str()); + std::cout << TString::Format("CEF: %s:%d: %s", src.c_str(), line, message.ToString().c_str()) << std::endl; break; } return true; } + cef_return_value_t GuiHandler::OnBeforeResourceLoad( CefRefPtr browser, CefRefPtr frame, diff --git a/gui/cefdisplay/src/gui_handler_linux.cxx b/gui/cefdisplay/src/gui_handler_linux.cxx index 6996f024c6eac..87a719421acc3 100644 --- a/gui/cefdisplay/src/gui_handler_linux.cxx +++ b/gui/cefdisplay/src/gui_handler_linux.cxx @@ -48,16 +48,10 @@ int x11_errhandler( Display *dpy, XErrorEvent *err ) return 0; } -bool GuiHandler::PlatformInit() +void GuiHandler::PlatformInit() { // install custom X11 error handler to avoid application exit in case of X11 failure XSetErrorHandler( x11_errhandler ); - - #if CEF_VERSION_MAJOR > 130 - return true; // use CEF view framework - #else - return false; // do not use CEF view framework - #endif } void GuiHandler::PlatformTitleChange(CefRefPtr browser, const CefString &title) @@ -116,9 +110,8 @@ bool GuiHandler::PlatformResize(CefRefPtr browser, int width, int he #else -bool GuiHandler::PlatformInit() +void GuiHandler::PlatformInit() { - return true; // use view framework } void GuiHandler::PlatformTitleChange(CefRefPtr, const CefString &) diff --git a/gui/cefdisplay/src/gui_handler_mac.mm b/gui/cefdisplay/src/gui_handler_mac.mm index 579b79945dfe6..ff0b736021f4c 100644 --- a/gui/cefdisplay/src/gui_handler_mac.mm +++ b/gui/cefdisplay/src/gui_handler_mac.mm @@ -16,10 +16,8 @@ #include "include/cef_browser.h" - -bool GuiHandler::PlatformInit() +void GuiHandler::PlatformInit() { - return false; // MAC not yet support ozone and headless mode } void GuiHandler::PlatformTitleChange(CefRefPtr browser, const CefString &title) diff --git a/gui/cefdisplay/src/gui_handler_win.cc b/gui/cefdisplay/src/gui_handler_win.cc index a6eade413d23c..54b86cb23ce23 100644 --- a/gui/cefdisplay/src/gui_handler_win.cc +++ b/gui/cefdisplay/src/gui_handler_win.cc @@ -22,13 +22,8 @@ #include "include/cef_browser.h" #include "include/cef_config.h" -bool GuiHandler::PlatformInit() +void GuiHandler::PlatformInit() { -#ifdef CEF_X11 - return false; // compiled without ozone support -#else - return true; // compiled with ozone support -#endif } void GuiHandler::PlatformTitleChange(CefRefPtr browser, const CefString &title) diff --git a/gui/cefdisplay/src/simple_app.cxx b/gui/cefdisplay/src/simple_app.cxx index 9dc77b44a0167..58971c817d37a 100644 --- a/gui/cefdisplay/src/simple_app.cxx +++ b/gui/cefdisplay/src/simple_app.cxx @@ -44,22 +44,26 @@ namespace { // implementation for the CefWindow that hosts the Views-based browser. class SimpleWindowDelegate : public CefWindowDelegate { CefRefPtr fBrowserView; - int fWidth{800}; ///< preferred window width - int fHeight{600}; ///< preferred window height + int fWidth = 800; ///< preferred window width + int fHeight = 600; ///< preferred window height + bool fBatch = false; public: - explicit SimpleWindowDelegate(CefRefPtr browser_view, int width = 800, int height = 600) - : fBrowserView(browser_view), fWidth(width), fHeight(height) + explicit SimpleWindowDelegate(CefRefPtr browser_view, int width = 800, int height = 600, bool batch = false) + : fBrowserView(browser_view), fWidth(width), fHeight(height), fBatch(batch) { } void OnWindowCreated(CefRefPtr window) override { - // Add the browser view and show the window. window->AddChildView(fBrowserView); - window->Show(); - // Give keyboard focus to the browser view. - fBrowserView->RequestFocus(); + if (fBatch) { + window->Hide(); + } else { + window->Show(); + // Give keyboard focus to the browser view. + fBrowserView->RequestFocus(); + } } void OnWindowDestroyed(CefRefPtr window) override { fBrowserView = nullptr; } @@ -109,10 +113,10 @@ class SimpleBrowserViewDelegate : public CefBrowserViewDelegate { } // namespace -SimpleApp::SimpleApp(bool use_viewes, +SimpleApp::SimpleApp(bool use_viewes, bool supress_log, THttpServer *serv, const std::string &url, const std::string &cont, int width, int height, bool headless) - : CefApp(), CefBrowserProcessHandler(), fUseViewes(use_viewes), fFirstServer(serv), fFirstUrl(url), fFirstContent(cont), fFirstHeadless(headless) + : CefApp(), CefBrowserProcessHandler(), fUseViewes(use_viewes), fSupressLog(supress_log), fFirstServer(serv), fFirstUrl(url), fFirstContent(cont), fFirstHeadless(headless) { fFirstRect.Set(0, 0, width, height); @@ -122,18 +126,19 @@ SimpleApp::SimpleApp(bool use_viewes, // platform framework. The Views framework is currently only supported on // Windows and Linux. #else - if (fUseViewes) { - R__LOG_ERROR(CefWebDisplayLog()) << "view framework does not supported by CEF on the platform, switching off"; - fUseViewes = false; - } +// if (fUseViewes) { +// R__LOG_ERROR(CefWebDisplayLog()) << "view framework does not supported by CEF on the platform, switching off"; +// fUseViewes = false; +// } #endif } -void SimpleApp::SetNextHandle(RCefWebDisplayHandle *handle) +void SimpleApp::SetNextHandle(RCefWebDisplayHandle *handle, bool headless) { fNextHandle = handle; + fNextHeadless = headless; } @@ -145,24 +150,15 @@ void SimpleApp::OnRegisterCustomSchemes(CefRawPtr registrar) void SimpleApp::OnBeforeCommandLineProcessing(const CefString &process_type, CefRefPtr command_line) { -// command_line->AppendSwitch("allow-file-access-from-files"); -// command_line->AppendSwitch("disable-web-security"); -// if (fBatch) { -// command_line->AppendSwitch("disable-gpu"); -// command_line->AppendSwitch("disable-gpu-compositing"); -// command_line->AppendSwitch("disable-gpu-sandbox"); -// } + if (fSupressLog) { + command_line->AppendSwitchWithValue("v", "-1"); + command_line->AppendSwitch("disable-logging"); + command_line->AppendSwitchWithValue("enable-logging", "none"); + } } void SimpleApp::OnBeforeChildProcessLaunch(CefRefPtr command_line) { -// command_line->AppendSwitch("allow-file-access-from-files"); -// command_line->AppendSwitch("disable-web-security"); -// if (fLastBatch) { -// command_line->AppendSwitch("disable-webgl"); -// command_line->AppendSwitch("disable-gpu"); -// command_line->AppendSwitch("disable-gpu-compositing"); -// } } void SimpleApp::OnContextInitialized() @@ -181,24 +177,24 @@ void SimpleApp::StartWindow(THttpServer *serv, const std::string &addr, const st { CEF_REQUIRE_UI_THREAD(); + bool is_batch = addr.empty() && !cont.empty(); + if (!fGuiHandler) fGuiHandler = new GuiHandler(fUseViewes); std::string url; - //bool is_batch = false; - - if(addr.empty() && !cont.empty()) { + if(is_batch) url = fGuiHandler->AddBatchPage(cont); - // is_batch = true; - } else if (serv) { + else if (serv) url = fGuiHandler->MakePageUrl(serv, addr); - } else { + else url = addr; - } // Specify CEF browser settings here. CefBrowserSettings browser_settings; + if (is_batch) + browser_settings.windowless_frame_rate = 30; // browser_settings.plugins = STATE_DISABLED; // browser_settings.file_access_from_file_urls = STATE_ENABLED; // browser_settings.universal_access_from_file_urls = STATE_ENABLED; @@ -210,7 +206,7 @@ void SimpleApp::StartWindow(THttpServer *serv, const std::string &addr, const st CefBrowserView::CreateBrowserView(fGuiHandler, url, browser_settings, nullptr, nullptr, new SimpleBrowserViewDelegate()); // Create the Window. It will show itself after creation. - CefWindow::CreateTopLevelWindow(new SimpleWindowDelegate(browser_view, rect.width, rect.height)); + CefWindow::CreateTopLevelWindow(new SimpleWindowDelegate(browser_view, rect.width, rect.height, is_batch)); if (fNextHandle) { fNextHandle->SetBrowser(browser_view->GetBrowser()); @@ -225,22 +221,19 @@ void SimpleApp::StartWindow(THttpServer *serv, const std::string &addr, const st // one should implement CefRenderHandler #if defined(OS_WIN) - RECT wnd_rect = {rect.x, rect.y, rect.x + rect.width, rect.y + rect.height}; - if (!rect.IsEmpty()) window_info.SetAsChild(0, wnd_rect); + if (!rect.IsEmpty()) + window_info.SetAsChild(0, rect); // On Windows we need to specify certain flags that will be passed to // CreateWindowEx(). window_info.SetAsPopup(0, "cefsimple"); - //if (is_batch) - // window_info.SetAsWindowless(GetDesktopWindow()); - #elif defined(OS_LINUX) - if (!rect.IsEmpty()) window_info.SetAsChild(0, rect); - //if (is_batch) - // window_info.SetAsWindowless(kNullWindowHandle); + if (is_batch) + // window_info.SetAsWindowless(GetDesktopWindow()); + window_info.SetAsWindowless(kNullWindowHandle); #else if (!rect.IsEmpty()) - window_info.SetAsChild(0, rect.x, rect.y, rect.width, rect.height ); - //if (is_batch) - // window_info.SetAsWindowless(kNullWindowHandle); + window_info.SetAsChild(0, rect); + if (is_batch) + window_info.SetAsWindowless(kNullWindowHandle); #endif // Create the first browser window. diff --git a/gui/webdisplay/src/RWebWindowsManager.cxx b/gui/webdisplay/src/RWebWindowsManager.cxx index f6e628b9635df..7ad3b5bc4e531 100644 --- a/gui/webdisplay/src/RWebWindowsManager.cxx +++ b/gui/webdisplay/src/RWebWindowsManager.cxx @@ -788,6 +788,8 @@ std::string RWebWindowsManager::GetUrl(RWebWindow &win, bool remote, std::string /// WebGui.ReconnectTmout: time to reconnect for already existing connection, if negative - no reconnecting possible (default 15 s) /// WebGui.CefTimer: periodic time to run CEF event loop (default 10 ms) /// WebGui.CefUseViews: "yes" - enable / "no" - disable usage of CEF views frameworks (default is platform/version dependent) +/// WebGui.CefLogSeveriry: "disable", "fatal", "error", "warning", "info", "verbose" (default is "fatal") +/// WebGui.CefHeadlessTimeout: timeout to wait produce result of headless output (default is 30 s) /// WebGui.OperationTmout: time required to perform WebWindow operation like execute command or update drawings /// WebGui.RecordData: if specified enables data recording for each web window; "yes" or "no" (default) /// WebGui.JsonComp: compression factor for JSON conversion, if not specified - each widget uses own default values