c++ - 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 发送点击事件?
解决方案
推荐阅读
- javascript - VueJS 强制更新
- javascript - 循环遍历一个 JS 对象并确认它的属性之一
- apache-spark - 为什么内存接收器被拉到驱动程序并因此限制尺寸很小?
- c# - AvalonDock - 如何禁用所有可锚定对象的自动隐藏功能
- c - 如何解决Linux内核中C中的错误“初始化元素不是常量”
- sql - 主触发器
- jmeter - 即使在使用 JMeter 的非 GUI 模式下,如何使应用程序崩溃?
- java - ExecutorServicve.invokeAll() 不进入 Call()
- azure - 无法在 Azure SQL 上启用读取横向扩展
- android - 这是什么意思:return@OnNavigationItemSelectedListener