Search code examples
javaswingjframewindowchromium-embedded

Jcef windows behaving strange


This seems to me a rare problem so I'm not sure I will get an answer here. I am posting the procedure to reproduce this error and hope you'll be able to help me.

Have you ever tried opening a new window by executing window.open(url) in the browser instance obtained by doing client.createBrowser(startUrl, useOSR, isTransparent) in Jcef (Java-Chromium Embedded Framework) example app (simple or detailed) and noticed strange behavior? Whenever a new window is created apart from the main window, clicking on the new window does not bring it to front (or in focus). The main window (JFrame containing the browser's UIComponent) steals focus immediately and sends the other window back. In the picture below, the tryit editor from w3schools is opened in the main window and I'm opening https://stackoverflow.com in a new window.

enter image description here

Now if I try to bring the window that opened stackoveflow to the front by clicking it, for around 100 miliseconds (or less) it stays in front but then the main window "steals" focus back and is displayed above it, like it is in the picture.

You can check if it happens in your case too by loading the url https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_win_open while creating a MainFrame instance in Jcef.

//inside main method
MainFrame mf = new MainFrame("https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_win_open", OS.isLinux(), false);

and then to open a new window, simply run this code in w3schools' tryit editor and click 'Try it' on the right:

<!DOCTYPE html>
<html>
<body>

<p>Click the button to open a new browser window.</p>

<button onclick="myFunction()">Try it</button>

<script>
function myFunction() {
    window.open("https://www.stackoverflow.com");
}
</script>

</body>
</html>

I badly need help on this. I posted this question in CEF forums too but didn't get any response from the maintainers. Also, I think I should mention that this happens every time a new window is created, it doesn't have to be created using JavaScript. For example, if I open a JDialog containing the developer toolbar obtained by doing browser.getDevTools(), the app behaves the same. I might be doing something very silly here but I can't figure it out. Let me know what I'm doing wrong. Also, if you tried reproducing the error and found nothing wrong about the windows, please let me know in the comments. I am using Jcef (Java bindings for CEF3) library built from source in Visual Studio 2015. I am running windows 10 64-bit. Thanks!


Solution

  • Thanks to the CEF forums, I was able to fix this.

    The focus problem on Windows is due to the FocusParent call in Java_org_cef_browser_CefBrowser_1N_N_1SetFocus.

    To fix it, comment out the following macro (lines 1269 to 1278) in java_cef/src/native/CefBrowser_N.cpp.

    #if defined(OS_WIN)
      if (enable == JNI_FALSE) {
        HWND browserHandle = browser->GetHost()->GetWindowHandle();
        if (CefCurrentlyOn(TID_UI))
          FocusParent(browserHandle);
        else
          CefPostTask(TID_UI, base::Bind(&FocusParent, browserHandle));
      }
    #endif
    

    Rebuild the solution in Visual Studio, rebuild the java classes (compile.bat win64) and then run it (run.bat win64 Release detailed). The problem should be gone by now.