Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows: CEF seemingly won't relinquish focus back to Swing #321

Open
magreenblatt opened this issue Jan 24, 2019 · 11 comments
Open

Windows: CEF seemingly won't relinquish focus back to Swing #321

magreenblatt opened this issue Jan 24, 2019 · 11 comments
Labels
bug Bug report windows Windows platform

Comments

@magreenblatt
Copy link
Collaborator

Original report by Matt Lilley (Bitbucket: Matt Lilley).


What steps will reproduce the problem?

Simple test case: Creates a JFrame with a CEF component and a Swing component. Once the CEF component has loaded, clicking into the Swing component and typing has no effect. If a textarea is focused in the CEF component, the keystrokes go to CEF and appear in the textarea even though the Swing component is focused and has a flashing caret.

#!Java

import javax.swing.*;
import org.cef.*;
import java.awt.*;

public class XX extends JFrame
  {
  static CefApp cefApp;
  public static void main(String[] args) throws Exception
    {
    CefApp.startup();
    CefSettings settings = new CefSettings();
    settings.windowless_rendering_enabled = false;
    cefApp = CefApp.getInstance(settings);
    new XX();
    }


  public XX() throws Exception
    {
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    getContentPane().setLayout(new BorderLayout());
    getContentPane().add(new JTextField(), BorderLayout.NORTH);
    getContentPane().add(cefApp.createClient().createBrowser("http://www.google.com", false, true).getUIComponent(), BorderLayout.CENTER);
    setSize(1024, 768);
    setVisible(true);
    }
  }

What is the expected output? What do you see instead?

I expect that if a Swing component has focus and I type characters that they appear in the Swing component, not in the (unfocused) CEF component.

What version of the product are you using? On what operating system?

I'm using a build using the source code as of 2018-12-06 (ie commit d64cd6c266d5a (bb)). The problem reproduces on Windows 7 and Windows 10. The issue does not occur on macOS High Sierra, so this looks like a Windows-specific problem. I've also tried it with a few older versions back to mid 2018 with no change in the symptoms

Does the problem reproduce with the JCEF simple or detailed sample application at the same version? How about with a newer or older version?

Yes - the problem seems to reproduce on the JCEF simple version. Running the

#!sh

run win64 Release simple

and then focusing the Google search field and typing 'foo', then selecting the URL bar at the top and typing 'bar' results in 'foobar' appearing in the Google search field, even though the caret is showing and blinking in the URL bar

Does the problem reproduce with the cefclient or cefsimple application at the same version? How about with a newer or older version?

This isn't really relevant - the problem relates to embedding CEF into Java explicitly.

Additional information:

I've read a few bug reports about focus and JCEF. Many of them relate to the opposite problem (that Swing components get the focus and that the CEF component won't receive it). Others suggested adding a CefFocusHandler to the client and overriding onSetFocus to return true. This doesn't solve the issue. I've also tried commenting out the calls to FocusParent in the native code (after reading issue 297), but the problem persists.

My actual use case is quite different to the example - I have a JTabbedPane where one tab is a JPanel containing a CEF component, and the other tabs contain various other components. The problem I'm facing in reality is that once I load the CEF component, switching tabs to modify the other fields becomes impossible. The example was just a much simpler demonstration of the issue.

Am I doing something obviously wrong? Is there something wrong with my build? Or is this an actual bug that others are seeing too?

@magreenblatt
Copy link
Collaborator Author

Original changes by Matt Lilley (Bitbucket: Matt Lilley).


  • edited description

1 similar comment
@magreenblatt
Copy link
Collaborator Author

Original changes by Matt Lilley (Bitbucket: Matt Lilley).


  • edited description

@magreenblatt
Copy link
Collaborator Author

Original comment by Matt Lilley (Bitbucket: Matt Lilley).


After a bit of investigation I noticed that the simple sample client worked on 1 Jan 2017. A git-bisect shows that the problems started with this:

045302f591e53057a011b4b1df1d26fbee15e35d is the first bad commit
commit [045302f591e53057a011b4b1df1d26fbee15e35d (bb)](https://bitbucket.org/chromiumembedded/java-cef/commits/045302f591e53057a011b4b1df1d26fbee15e35d)
Author: Rene Schneider <[email protected]>
Date:   Fri Aug 31 18:33:23 2018 +0200

    Linux: Add support for windowed rendering (issue #312)

    - This requires a CEF version that supports multi-threaded message
      loop on Linux (3.3497.1831.g461fa1f or newer).
    - The application must invoke XInitThreads very early during
      process startup to allow multi-threading. See the sample
      applications for an example.

This seems a bit surprising at first, since the changes are aimed at Linux, but I wonder if the rationalisation broke something in Windows. I've also noticed that the problem only occurs when mixing Swing and CEF components in a single frame - if you put them into separate Frames then everything works normally.

@magreenblatt
Copy link
Collaborator Author

Original comment by Matt Lilley (Bitbucket: Matt Lilley).


Specifically, this commit involves this change:

#!patch

--- a/java/org/cef/CefClient.java
+++ b/java/org/cef/CefClient.java
@@ -405,21 +405,6 @@ public class CefClient extends CefClientHandler
 
         boolean alreadyHandled = false;
         if (focusHandler_ != null) alreadyHandled = focusHandler_.onSetFocus(browser, source);
-        if (!alreadyHandled) {
-            Runnable r = new Runnable() {
-                @Override
-                public void run() {
-                    Component uiComponent = browser.getUIComponent();
-                    if (uiComponent != null) {
-                        uiComponent.requestFocus();
-                    }
-                }
-            };
-            if (SwingUtilities.isEventDispatchThread())
-                r.run();
-            else
-                SwingUtilities.invokeLater(r);
-        }
         return alreadyHandled;
     }

If I checkout that version (045302f), build it and run the simple test app, I observe the problem. If I reverse just this hunk, (restoring that bit of code that handles events), then the problem disappears and the focus starts behaving normally again. I'll see whether this fixes the code at the tip of master as well, or if there are other competing changes

@magreenblatt
Copy link
Collaborator Author

Original comment by Matt Lilley (Bitbucket: Matt Lilley).


It looks like 51ccf5b031e87a (bb) is also involved. After this commit, reversing the above hunk (alone) is not enough to make the symptoms go away.

If I reverse all three hunks then the sample app seems to work correctly. Based on the commit comment in 51ccf5b031e87a (bb) this sounds dangerous - it looks like this was changed for a good reason (though unfortunately I don't have a test case for the reason to see if there's an alternative solution).

This might be about as far as I can go - I'll put the patch here that I came up with which fixed the sample app, and hope someone can determine what needs to be done to fix things correctly (safely!).

@magreenblatt
Copy link
Collaborator Author

Original comment by Matt Lilley (Bitbucket: Matt Lilley).


Patch which makes focus work correctly in the simple sample application (though potentially at a risk of a crash since it undoes some important looking work)

@magreenblatt
Copy link
Collaborator Author

Original changes by Matt Lilley (Bitbucket: Matt Lilley).


  • set attachment to "focus-fix.patch"

@magreenblatt
Copy link
Collaborator Author

Original comment by Christian Sommer (Bitbucket: Christian Sommer).


Hi,

I stumbled across the same bug recently.

I tested your patch and can confirm that it fixes this strange behaviour of text input (environment: Windows 7, adoptopenjdk 11 and oracle jdk 8_201). The commit message of 51ccf5b031e87a says something about multiple browsers. I tested this a bit too with multiple JFrames and CefClient+CefBrowser instances at the same time - no negative result. Too bad that there is no corresponding issue for it.

Maybe @magreenblatt can provide some insights here?

@magreenblatt
Copy link
Collaborator Author

Original comment by Roland (Bitbucket: yef01068).


The same thing happens using JCEF Version 73.1.11.214+g4efdff2 , Windows 10, oracle JDK 1.8u112.
I also have the browserview in a JPanel on a JTabbedPane tab.

Is there a way to expedite a fix for this issue?

Hi @Matt Lilley did you find a way around it? Do you know why it doesn’t happen with the JCEF detailed example, but does with the simple one?

@magreenblatt
Copy link
Collaborator Author

Original comment by Johann Scheiterbauer (Bitbucket: Phylanx, GitHub: Phylanx).


We also had the problem with the swing TextFields having the focus (with blinking caret directly after a mouse click) but where nothing happens when something is typed in the keyboard.

Using the attached Patch changes this behavior in our usecase (Version 3325 with many focus patches applied).

@magreenblatt
Copy link
Collaborator Author

Original comment by Klemen Pevec (Bitbucket: Klemen Pevec).


I can confirm this issue with the latest release too. Is there any chance one of the devs takes a look at this patch and potentially applies it to the current master branch?

JScheiterbauer added a commit to JScheiterbauer/java-cef that referenced this issue Oct 30, 2024
Sometimes (timing issue) the JCEF native code in CefBrowser_N.cpp uses a wrong parent window handle.
With this change the problem was gone, also see chromiumembedded#321.

Reproduction:
The problem can happen on physical machines too but happen much more often when connected to remote machines (e.g. Citrix sessions, Remote Desktop, VMWares,...).
- Start detailed MainFrame
- Menu -> Tests -> Reparent
- Press the "Reparent </>" Button as fast as you can (Space bar helps)
The bug then sometimes happens on the 5th try or you have to do this for a minute or so.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug report windows Windows platform
Projects
None yet
Development

No branches or pull requests

1 participant