У меня возникла некоторая проблема с получением рабочих событий касания с CEF при рендеринге за кадром с использованием SDL2 в некоторых ситуациях:
Я пишу приложение SDL-CEF, которое должно выполнить некоторую онлайн-игру в видеолотери. поэтому я запускаю приложение из tty, используя startx, а не в DE. Более того, я не могу использовать мышь, но возможно использовать сенсорный экран только для взаимодействия с машиной. Событие касания работает довольно хорошо в большинстве случаев, но в некоторых играх событие щелчка не распознается веб-приложением.
Для передачи правильного события в браузер CEF я написал несколько специализированных функций-обработчиков, которые перехватывают SDL_Event и преобразуют их в CEF_Event. Например, для обработки событий тау у меня есть функция handleFingerEvent(SDL_Event, CEF_Browser*)
. Эта специализированная функция вызывается из обобщенной handleEvents(SDL_Event, VEF_Browser*)
функции-обработчика более высокого уровня.
// The Touch Event Hendler function
void handleFingerEvent(SDL_Event &e, CefBrowser* browser) {
CefMouseEvent event;
switch (e.type) {
case SDL_FINGERDOWN:
// W_SIZE and H_SIZE are the dimension of the screen in px
if (e.tfinger.pressure > 0.9) {
event.x = static_cast<int>(e.tfinger.x*W_SIZE);
event.y = static_cast<int>(e.tfinger.y*H_SIZE);
browser->GetHost()->SendMouseClickEvent(event,
MBT_LEFT,
false, 1);
}
break;
case SDL_FINGERUP:
event.x = static_cast<int>(e.tfinger.x*W_SIZE);
event.y = static_cast<int>(e.tfinger.y*H_SIZE);
browser->GetHost()->SendMouseClickEvent(event, MBT_LEFT, true, 1);
break;
case SDL_FINGERMOTION: {
int scrollX = static_cast<int>(e.tfinger.dx);
int scrollY = static_cast<int>(e.tfinger.dy);
event.x = static_cast<int>(e.tfinger.x*W_SIZE);
event.y = static_cast<int>(e.tfinger.y*H_SIZE);
browser->GetHost()->SendMouseWheelEvent(event, scrollX, scrollY);
break;
}
default:
break;
}
}
void handleEvents(SDL_Event &e, CefBrowser *browser) {
switch (e.type) {
// Key events
case SDL_KEYDOWN:
case SDL_KEYUP:
handleKeyEvent(e, browser);
break;
// Window events
case SDL_WINDOWEVENT:
handleWindowEvent(e, browser);
break;
//Mouse events
case SDL_MOUSEMOTION:
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEWHEEL:
handleMouseEvent(e, browser);
break;
// Touch events
case SDL_FINGERDOWN:
case SDL_FINGERMOTION:
case SDL_FINGERUP:
handleFingerEvent(e, browser);
break;
default:
break;
}
}
Я вызываю ее из цикла SDL_PollEvent (), в то время как:
browser = CefBrowserHost::CreateBrowserSync(window_info,
browserClient, //My BrowserClient implementation
"https://www.something.sometother",
browserSettings, // The cef setting
nullptr, nullptr);
while(!browserClient->closeAllowed()) {
//Send events to the browser
SDL_Event e;
while(SDL_PollEvent(&e) != 0){
//Quit and window resize
if(e.type == SDL_QUIT) {
browser->GetHost()->CloseBrowser(false);
}
else if (e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
renderHandler->resize(e.window.data1, e.window.data2);
browser->GetHost()->WasResized();
}
else {
handleEvents(e, browser.get());
}
}
// Cef main work loop
cefApp->doCefWork();
//Set background color
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
//Clear window/renderer
SDL_RenderClear(renderer);
renderHandler->render();
//Update screen contents
SDL_RenderPresent(renderer);
}
Теперь я действительно не знаю, почему в некоторых играх событие не перехватывается браузером. Более того, если я открою игру на машине с подключенной мышью и DM, и, таким образом, использую указатель мыши для взаимодействия с игрой, это работает без проблем. Может быть, есть ли лучший способ отправить событие click в CefBrowser?