Mac OS: missing keyboard events w/ CefDoMessageLoopWork()

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Mac OS: missing keyboard events w/ CefDoMessageLoopWork()

Postby blackjack » Tue Nov 12, 2013 6:40 am

Hi,

I'm running CEF in OSR mode on Mac OS X, integrated into an existing SDL application ported from Windows. While testing, I noticed that every now and then, single characters were missing when typing, both when entering text on a CEF-rendered website and within our application (we have our own custom edit fields).

The program is running on a 10ms SDL timer, with CefDoMessageLoopWork() being called 25 times per second. Some debugging showed that, depending on the frequency of CEF updates, the SDL keyboard events (SDL_KEYDOWN) go missing occasionally.

Adding an option to temporarily disable the CefDoMessageLoopWork() call led to no more keystrokes being lost (but of course stopped all the browser windows from responding). Calling 10 times per second resulted in only a small number of missing keystrokes, but poor responsiveness of the browsers, let alone Flash videos. Calling the update in sync with the application - 100 times per second - renders our program pretty unusable, as hardly any key events are being received. There seems to be no connection to the number of running browser windows, and not creating any browser window at all (via CreateBrowserSync) did not change anything.

The original Windows implementation is running the same CEF code, but uses a hand-coded, native message loop (WndProc, WinMain etc) instead of SDL. The problem does not occur on Windows. My initial suspect was SDL, updating from the pretty old version 1.2.15 to 2.0.0 and recently to 2.0.1 did not help either.

So, my questions are: has anyone else heard of this issue or experienced the same effects? Am I doing something wrong, maybe specific to the internals of Mac OS? Could CefDoMessageLoopWork() starve away my input events even though all my OSR browsers actually get their keyboard (and mouse) events injected from the outside? Or maybe is there some additional configuration required in order to stop CEF in connection with OSR browsers from sniffing events?

Summary:
- CEF version used: 3.1547.1412_macosx32
- problem occurs only on Mac OS
- all browsers are running in OSR mode
- keyboard input gets injected into the browsers via SendKeyEvent()
- problem occurs even when no browser windows exist


Thanks a lot,
Werner
blackjack
Newbie
 
Posts: 1
Joined: Tue Nov 12, 2013 6:27 am

Re: Mac OS: missing keyboard events w/ CefDoMessageLoopWork(

Postby Marcus » Tue Dec 02, 2014 9:16 am

Hi, I just found this old topic because I'm experiencing the exact same issues, where after I have created a browser my keyboard inputs start dropping. Did you get any clarity what was going on?
I'm using 3.2171.1932 and SDL 2.0.3.
I must admit that my OS X knowledge is basically 0, so I'm probably doing/not doing something wierd here.

I do not use any of the objective-C code yet, basically because I do not understand what it does yet :) (What does it do/is it needed?) But the browser starts anyways and loads my pages anyway.

Could someone explain or point me somewhere that explains how the input is supposed to be handled on OS X? On windows we just use the SendKeyEvent() for the input. But when playing around in the cefclient example on OS X I removed that line of code and the offscreen browser still gets inputs?
Marcus
Newbie
 
Posts: 1
Joined: Tue Dec 02, 2014 8:28 am

Re: Mac OS: missing keyboard events w/ CefDoMessageLoopWork(

Postby JohnWordsworth » Thu Aug 27, 2015 4:36 am

We recently ran into this problem in our project too. After loading CEF in our application, approximately 50% of all input events were lost on OSX.

The problem exists because both SDL and Chromium expect to take events manually using [NSApp nextEventMatchingMask:...]. However, as Chromium forwards events on to NSApp, I have moved the processing of events in SDL to [SDLApplication sentEvent:], so that it receives events from both CEF and ones it has grabbed itself.

I have submitted a patch request to SDL with my fix. I'm not sure if it will be accepted, but you should be able to apply it locally if you want to fix this issue in your own projects.

https://bugzilla.libsdl.org/show_bug.cgi?id=3107
JohnWordsworth
Newbie
 
Posts: 1
Joined: Thu Aug 27, 2015 4:31 am

Re: Mac OS: missing keyboard events w/ CefDoMessageLoopWork(

Postby fokz » Wed Aug 31, 2016 8:40 am

There must be something fishy with this as I have exactly the same issue but on Windows (Windows 10 to be exact, and new branch of CEF3). So this is not OSX-exclusive issue.

What is more interesting I am using my own message loop (no SDL here, but same scenario, I use offscreen rendering and call CefDoMessageLoopWork on my own. I update it at the same rate as my app is updated which is more than 100 frames per second). In addition I suppress default Windows events by using RawInput with NOLEGACY flags so the only 'input' related message that should go through message loop is WM_INPUT.

What I think all of this cases have in common is that I use single threaded message loop and I think multithreaded message loop is optional and only available on Windows so maybe this is why you didnt have the issue on Windows?

I guess CEF must be poping events from message queue on its own perhaps if initialized with the hWnd of the main app window and running its UI process on the same thread that the main app?

I would really like some help to sort this out properly as at the moment I have really broken input in my engine.

If I stop calling CefDoMessageLoopWork everything is back to normal.
fokz
Techie
 
Posts: 22
Joined: Sat Jun 18, 2016 10:53 am

Re: Mac OS: missing keyboard events w/ CefDoMessageLoopWork(

Postby magreenblatt » Wed Aug 31, 2016 9:28 am

Does the problem reproduce in cefclient at 2743 branch or newer when running with the `--external-message-pump` command-line flag?
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: Mac OS: missing keyboard events w/ CefDoMessageLoopWork(

Postby fokz » Wed Aug 31, 2016 10:10 am

It is hard to tell, I don't think so, yet I was basing my integration of cefsimple and worked my way up step by step on my own.
What I am doing now is simply creating windowless app with custom render handler what I am doing though that I see is different in ExternalPump from cefclient is that I use hWnd of my main window, and the sample creates its own window.

Code: Select all
      CefWindowInfo windowInfo;
      windowInfo.SetAsWindowless((HWND)handle, true); // <-- this is my main windows handle
      windowInfo.windowless_rendering_enabled = true;
      windowInfo.width = g_config.width;
      windowInfo.height = g_config.height;

      m_osrClient = new EditorOsrCefClient{ m_renderHandler }; // this is an app with custom RenderHandler


When I pass NULL as a handle nothing changes so I don't think this is the issue.
fokz
Techie
 
Posts: 22
Joined: Sat Jun 18, 2016 10:53 am

Re: Mac OS: missing keyboard events w/ CefDoMessageLoopWork(

Postby magreenblatt » Wed Aug 31, 2016 10:20 am

How are you implementing the message pump in your application?
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: Mac OS: missing keyboard events w/ CefDoMessageLoopWork(

Postby fokz » Wed Aug 31, 2016 10:24 am

Well its quite simple actually:
Code: Select all
  void WindowsView::_runMessageLoop() {
    MSG msg;
    ZeroMemory(&msg, sizeof(MSG));

    // Loop until there is a quit message from the window or the user.
    bool terminate = false;
    while (!terminate) {
      // Handle the windows messages.
      while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);

        if (msg.message == WM_QUIT)
          terminate = true;

        if (msg.message == WM_INPUT) {
            auto input = (RawInput*)Input::Current;
            input->OnMessage(msg.message, msg.wParam, msg.lParam);
        }
      }
      if (!terminate) {
        Engine::Tick(); // <- this is where the application gets updated and CefDoMessageLoopWork() is called
        if (Input::Current) {
          Input::Current->Tick(); // <- just so you know this is irrelevant ;)
        }
      }
    }
    Log.i("Leaving message loop.");
  }
fokz
Techie
 
Posts: 22
Joined: Sat Jun 18, 2016 10:53 am

Re: Mac OS: missing keyboard events w/ CefDoMessageLoopWork(

Postby magreenblatt » Wed Aug 31, 2016 10:34 am

fokz wrote:Well its quite simple actually:
Code: Select all
  void WindowsView::_runMessageLoop() {
    MSG msg;
    ZeroMemory(&msg, sizeof(MSG));

    // Loop until there is a quit message from the window or the user.
    bool terminate = false;
    while (!terminate) {
      // Handle the windows messages.
      while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);

        if (msg.message == WM_QUIT)
          terminate = true;

        if (msg.message == WM_INPUT) {
            auto input = (RawInput*)Input::Current;
            input->OnMessage(msg.message, msg.wParam, msg.lParam);
        }
      }
      if (!terminate) {
        Engine::Tick(); // <- this is where the application gets updated and CefDoMessageLoopWork() is called
        if (Input::Current) {
          Input::Current->Tick(); // <- just so you know this is irrelevant ;)
        }
      }
    }
    Log.i("Leaving message loop.");
  }


This implementation does not guarantee that CefDoMessageLoopWork() is called in a timely manner. For example, if you're performing an input-intensive action like resizing the window then the PeekMessage loop might not exit for extended periods of time. You should consider an implementation closer to what cefclient demonstrates with ExternalPump.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: Mac OS: missing keyboard events w/ CefDoMessageLoopWork(

Postby fokz » Wed Aug 31, 2016 10:45 am

What do you mean a timely manner? 60 times per second? I wrote in the first post that the Tick function is called easily 100-200+ times per second so does CefDoMessageLoopWork. Lets put the CPU hoging aside, PeekMessage does not block waiting for a message to come to the queue. I am not talking about scenarios where I resize a window and have a problem with something. I have a problem that when CefDoMessageLoopWork is running somehow my application starts skipping messages and I dont understand why.
fokz
Techie
 
Posts: 22
Joined: Sat Jun 18, 2016 10:53 am

Next

Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 64 guests