user573949
user573949

Reputation: 760

SDL causes CEF3 to spawn additional windows

I'm trying to get CEF3 (Chromium Embedded Framework: https://bitbucket.org/chromiumembedded/cef) to work in conjunction with SDL (Simple DirectMedia Layer: https://www.libsdl.org/).

My intended use of these two libraries is to use SDL to open a window, receive events from it and render OpenGL graphics (in conjunction with other libraries such as GLEW). I want to use CEF3 to render graphical elements for the user interface off screen and then display them on the screen via OpenGL textures. All of this works, I can open SDL windows, handle events, I can draw OpenGL textures and get OpenGL compatible data from an off screen render in CEF3.

The problem is that if I run SDL and CEF3 together in a test environment CEF3 spawns multiple additional windows.

This is the code I use for CEF3.

void Example::webTest()
{
    //Args
    CefMainArgs cefArgs;

    //Settings
    CefSettings cefSettings;
    cefSettings.pack_loading_disabled = true;
    cefSettings.windowless_rendering_enabled = true;

    //Initialize
    CefInitialize(cefArgs, cefSettings, nullptr, nullptr);

    //Render Handler
    renderHandler = new InterfaceRenderHandler();

    //Window Info
    CefWindowInfo cefWindowInfo;
    //cefWindowInfo.SetAsWindowless(0, true);
    cefWindowInfo.windowless_rendering_enabled = true;
    cefWindowInfo.transparent_painting_enabled = true;

    //Interface Browser
    CefRefPtr<InterfaceBrowserClient> cefClient;
    cefClient = new InterfaceBrowserClient(renderHandler);

    //Browser
    CefBrowserSettings cefBrowserSettings;
    cefBrowserSettings.windowless_frame_rate = 60;

    CefBrowserHost::CreateBrowser(cefWindowInfo, cefClient.get(), "http://www.stackoverflow.com", cefBrowserSettings, nullptr);

    //Threaded Loops
    thread renderThread(renderLoop);
    thread sdlThread(sdlLoop);

    //Main Loop
    CefRunMessageLoop();

    //Unthread
    renderThread.join();
    sdlThread.join();

    //Shutdown
    CefShutdown();
}

A few notes on this code:

If I initialize an SDL window prior to running this code, two extra windows appear, one appears at new InterfaceBrowserClient(renderHandler); and the other appears when CefRunMessageLoop(); is reached. These windows are the same dimensions as the SDL window and have the same title and the same content (pure white). Then even sit at exactly the same position on the screen, such that only the top one is visible. However while the original window is responsive, Windows considers these windows unresponsive, as though they don't have event loops running. I have tried changing the render size to be different to the window size (this is done inside InterfaceRenderHandler) and I am certain that it is the size of the SDL window they are copying, not the size of the render area.

If I don't initialize an SDL window, no windows appear at all (except the command prompt of course) and the render proceeds as normal (this can be identified from the console printing out warnings as it loads the page).

Does anyone who knows more about the windowing system understand why this is occurring and more importantly, how do I get rid of these additional windows? I have not tested this on any other OSes because I don't know much about Linux C++ compilation but I'll attempt it if this problem persists.

Thanks.

Upvotes: 1

Views: 2134

Answers (1)

amaitland
amaitland

Reputation: 4420

The multiple windows are likely CEF spawning it's sub processes, GPU, Render etc.

In the case of the sub processes you simply need to call CefExecuteProcess and return it's exit code. This must happen before your other code executes. You can see a working example as part of the cefsimple application.

https://bitbucket.org/chromiumembedded/cef/src/aefb5ccce879f308f0bcc3ac719c86defe2f9715/tests/cefsimple/cefsimple_win.cc?at=master#cl-51

// CEF applications have multiple sub-processes (render, plugin, GPU, etc)
// that share the same executable. This function checks the command-line and,
// if this is a sub-process, executes the appropriate logic.
int exit_code = CefExecuteProcess(main_args, app.get(), sandbox_info);
if (exit_code >= 0) {
  // The sub-process has completed so return here.
  return exit_code;
}

Upvotes: 1

Related Questions