Я пытаюсь получить CEF3 (Chromium Embedded Framework: https://bitbucket.org/chromiumembedded/cef) для совместной работы с SDL (простой DirectMedia Layer: https://www.libsdl.org/).SDL заставляет CEF3 создавать дополнительные окна
Назначение этих двух библиотек - использование SDL для открытия окна, получения от него событий и визуализации графики OpenGL (в сочетании с другими библиотеками, такими как GLEW). Я хочу использовать CEF3 для визуализации графических элементов для пользовательского интерфейса, а затем отображать их на экране через текстуры OpenGL. Все это работает, я могу открывать окна SDL, обрабатывать события, рисовать текстуры OpenGL и получать совместимые с OpenGL данные из выпадающего экрана в CEF3.
Проблема в том, что если я запускаю SDL и CEF3 вместе в тестовой среде, CEF3 создает несколько дополнительных окон.
Это код, который я использую для 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();
}
Несколько замечаний по этому коду:
- Функция renderLoop предназначена для сбора готовых текстур, но в данный момент ничего не делает.
- Функция sdlLoop просто проверяет окно SDL для событий и затем отбрасывает их.
- CefRunMessageLoop блокирует программу. (Я предполагаю, что внутри есть петля).
- CefRunMessageLoop должен выполняться для визуализации страницы, и, похоже, он не работает корректно, если не запускается в основном потоке.
- ИнтерфейсBrowserClient - это класс, реализованный на основе CefClient, который просто возвращает renderHandler, когда он был создан, и ничего не делает.
- InterfaceRenderHandler - это класс, реализованный на основе CefRenderHandler. Он предоставляет размеры предполагаемой области визуализации для CEF3 и получает готовые данные изображения из CEF3.
- Я разместил код для классов здесь http://pastebin.com/sBm9AAQZ в случае, если кто-то должен их увидеть.
Если я инициализировать SDL окно перед запуском этого кода, появляются два дополнительных окна, один появляется new InterfaceBrowserClient(renderHandler);
, а другой появляется, когда CefRunMessageLoop();
достигается. Эти окна имеют те же размеры, что и окно SDL, и имеют одинаковый заголовок и один и тот же контент (чистый белый). Затем даже сидите в точно таком же положении на экране, чтобы видна только верхняя. Однако, когда исходное окно реагирует, Windows считает эти окна неактивными, как будто они не имеют циклов событий. Я попытался изменить размер рендеринга, чтобы он отличался от размера окна (это делается внутри InterfaceRenderHandler), и я уверен, что это размер окна SDL, которое они копируют, а не размер области визуализации.
Если я не инициализирую окно SDL, окна вообще не отображаются (за исключением командной строки), и рендеринг выполняется как обычно (это можно идентифицировать из предупреждений консоли при печати при загрузке страницы) ,
Кто-нибудь, кто знает больше об оконной системе, понимает, почему это происходит и что еще более важно, как мне избавиться от этих дополнительных окон? Я не тестировал это на каких-либо других операционных системах, потому что я мало разбираюсь в компиляции Linux C++, но я попытаюсь, если эта проблема сохранится.
Спасибо.
Я не вижу CefExecuteProcess() вызывается. Вам нужно проверить его код выхода и вернуть его, поскольку CEF запускает несколько процессов. См. Примеры cefclient и cefsimple: https://bitbucket.org/chromiumembedded/cef/src/aefb5ccce879f308f0bcc3ac719c86defe2f9715/tests/cefsimple/cefsimple_win.cc?at=master –
Я вставил 'CefExecuteProcess (cefArgs, nullptr, nullptr);' перед вызов CefInitialize, никаких изменений в поведении, рендеринг по-прежнему прекрасен (как и раньше, мне удалось извлечь файл изображения, а рендеринг действительно работает по назначению), и окна все еще появляются. – user573949