Некоторая проблема с сенсорными событиями с cef и SDL2 - PullRequest
0 голосов
/ 03 октября 2019

У меня возникла некоторая проблема с получением рабочих событий касания с 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?

...