Page 1 of 1

windows events with external message pump

PostPosted: Tue Nov 30, 2021 3:49 pm
by mmaenz
Hi,

I am using cef with Java SWT and wrote a c++ wrapper for that. SWT has its own event queue and cef needs to use that so callbacks will be in the right thread. All of this works pretty nice. Except with events. I'd like to use KeePass to send username and password to cef window.
That does not work. Maybe it's some kind of weird focus problem or chromium/cef is capturing the windows (WM_KEYDOWN) events and not forwarding them to swt.

I tried it with cefclient and it works as expected! When debugging to see whats happending in the external message queue wndproc, there will never be any mouse or keyboard event?! The events must be processed somewhere else?!

This is my initialize code
Code: Select all
initCEF(bool useMTMessageProcessing, bool useExternalMesgPump, std::string subProcess, SwtCefAppHandler* listener, std::string cachePath, SwtCefLogLevel logLevel, bool disableGPU) {
#ifdef _WIN32
    CefMainArgs main_args(GetModuleHandle(NULL));
#else
    CefMainArgs main_args;
#endif
    CefSettings settings;
    CefRefPtr< SwtCefAppHandler> handler;
    handler = listener;

    if (disableGPU) {
        handler->setDisableGPU(disableGPU);
    }

    CefString(&settings.browser_subprocess_path) = subProcess;
    CefString(&settings.cache_path) = cachePath;
    settings.persist_session_cookies = TRUE;
    settings.multi_threaded_message_loop = useMTMessageProcessing;
    settings.external_message_pump = useExternalMesgPump;

#ifdef _DEBUG
    settings.log_severity = LOGSEVERITY_DEBUG;
    settings.remote_debugging_port = 2021;
#else
    settings.log_severity = static_cast<cef_log_severity_t>(static_cast<int>(logLevel));
#endif
    settings.no_sandbox = true;

    CefInitialize(main_args, settings, handler, NULL);
}


And to create a child window I do this
Code: Select all
SwtCefFrame* CefSingleton::createBrowser(long long windowId,
    SwtCefLifeSpanHandler* lifespanHandler,
    SwtCefContextHandler* contextHandler,
    SwtCefLoadHandler* loadHandler,
    SwtCefRequestHandler* requestHandler,
    SwtCefJSDialogHandler* jsDialogHandler,
    SwtCefDisplayHandler* displayHandler,
    SwtCefContextMenuHandler* contextMenuHandler,
    SwtCefFunctionHandler* functionHandler,
    SwtCefFocusHandler* focusHandler,
    SwtCefKeyboardHandler* keyboardHandler) {

    CefRefPtr<SwtCefFrameHandler> clientHandler(new SwtCefFrameHandler());
    clientHandler->setLifeSpanHandler(lifespanHandler);
    clientHandler->setContextHandler(contextHandler);
    clientHandler->setLoadHandler(loadHandler);
    clientHandler->setRequestHandler(requestHandler);
    clientHandler->setJSDialogHandler(jsDialogHandler);
    clientHandler->setDisplayHandler(displayHandler);
    clientHandler->setContextMenuHandler(contextMenuHandler);
    clientHandler->setFunctionHandler(functionHandler);
    clientHandler->setFocusHandler(focusHandler);
    clientHandler->setKeyboardHandler(keyboardHandler);

    // Register the window class.
    CefWindowHandle hMain = (CefWindowHandle)((void*)windowId);
    clientHandler->setParentHandle(hMain);
    CefString pageURL = CefString("");

    CefBrowserSettings   b_settings;
    SetPlatformSettings(b_settings);

    CefWindowInfo        info;

    // THIS IS NEEDED BC Windows Chromium steals focus!
    // FocusHandler needs to cancel setFocus from Java on first created!!
    // See https://magpcss.org/ceforum/viewtopic.php?f=6&t=13891&start=10 --> Last post!
    // See https://bitbucket.org/chromiumembedded/cef/src/master/tests/cefclient/browser/root_window_win.cc#lines-307
#ifdef _WIN32
    info.ex_style |= WS_EX_NOACTIVATE;
#endif
    info.SetAsChild(hMain, GetWindowSize(hMain));
    CefBrowserHost::CreateBrowserSync(info, clientHandler, pageURL, b_settings, nullptr, nullptr);
    return new SwtCefFrame(clientHandler, hMain);
}


All the handlers are created at Java site.

Then with onScheduleMessagePumpWork and additional timed calls I do CefDoMessageLoopWork.
But unfortunately there are no events fired or reaching SWT (I added filters to the Display, every keypress would be recognized), no events in javascript (document.addEventListener) and no events in MainMessageLoopExternalPumpWin::WndProc (https://github.com/chromiumembedded/cef/blob/50f627b07e034f7312f0c9cdfce7493e18bc0643/tests/shared/browser/main_message_loop_external_pump_win.cc#L127) when debugging.

I can't find any method or documentation on how to do this properly. I'm searching for over a week for a solution. Anyone may had the same problem? Any suggestion whats going on there?

Any help is appreciated! Thanks in regard...

Re: windows events with external message pump

PostPosted: Tue Nov 30, 2021 4:15 pm
by magreenblatt
What window has focus when you send the keyboard events? Is it a native CEF window? If so, do you get CefKeyboardHandler callbacks from CEF?

Re: windows events with external message pump

PostPosted: Wed Dec 01, 2021 3:09 pm
by mmaenz
Hi!

thanks for your quick reply.

I think I found the problem. The CefKeyboardHandler is firing his events but only once. When first event is coming the focus gets removed from browser window to the UI/Display thread of SWT which is processing the event loop. Further fired events aren't reaching the browser window. When shifting focus in onPreKeyEvent back to browser window everything works just fine!

Thank you very much for the hint with the focus.

-Michael