首页 > 解决方案 > cef 和 SDL2 的触摸事件的一些问题

问题描述

在某些情况下,我在使用 SDL2 在屏幕外渲染中使用 CEF 获取工作触摸事件时遇到了一些问题:

我正在编写一个 SDL-CEF 应用程序,该应用程序需要将一些在线游戏执行到视频彩票中。所以我使用 startx 而不是在 DE 中从 tty 启动应用程序。此外,我不能使用鼠标,只能使用触摸屏与机器交互。触摸事件在大多数操作系统情况下工作得很好,但在某些游戏中,单击事件无法被 Web 应用程序识别。

为了将正确的事件传递给 CEF 浏览器,我编写了一些专门的处理函数来捕获 SDL_Event 并将它们转换为 CEF_Event。对于处理 tauch 事件的示例,我有一个名为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() while 循环中调用它,如下所示:


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 的机器上打开游戏,然后使用鼠标指针与游戏交互,它可以正常工作。也许有更好的方法来向 CefBrowser 发送点击事件?

标签: c++linuxmouseeventsdlchromium-embedded

解决方案


推荐阅读