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: Browser window always keeps focus #297

Open
magreenblatt opened this issue Apr 18, 2018 · 8 comments
Open

Windows: Browser window always keeps focus #297

magreenblatt opened this issue Apr 18, 2018 · 8 comments
Labels
bug Bug report windows Windows platform

Comments

@magreenblatt
Copy link
Collaborator

Original report by me.


What steps will reproduce the problem?

  1. Create a JCEF application with multiple windows. For example, by applying the attached multiwindow.patch to the detailed sample app.
  2. Click the "createBrowser" button to create the browser window.
  3. Try to focus the Java Application Window.

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

It should be possible to switch focus between the Java windows. Instead, the browser window always keeps focus.

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

Current master build on Windows 10.

The problem is due to the FocusParent call in Java_org_cef_browser_CefBrowser_1N_N_1SetFocus: https://bitbucket.org/chromiumembedded/java-cef/src/694bda5a7d1c006c982fd0254a2195d28e2f7074/native/CefBrowser_N.cpp?at=master&fileviewer=file-view-default#CefBrowser_N.cpp-1269

Commenting out that call will work around the problem.

@magreenblatt
Copy link
Collaborator Author

Original comment by Andrei Pivkine (Bitbucket: andreiPiv, GitHub: andreiPiv).


Much thanks, I will give the workaround a try.

I also found some issues between 1 Browser in 1 Java window focus issue

The current workaround I'm using in Java:

#!java

final KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
	
focusManager.addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() {
			
	 boolean cefWasPermanentFocusOwner = false;
	 
	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		System.out.println("Perm Focus Owner: " + focusManager.getPermanentFocusOwner());
		System.out.println("Focus Owner: " + focusManager.getFocusOwner());
		if (ChromiumBrowser.isInternalCefCanvas(evt.getOldValue())) {
			cefWasPermanentFocusOwner = true;
			return;
		}
		
		if(evt.getOldValue() instanceof Component) {
			
			Component c = (Component)evt.getOldValue();
			
                       //Currently browsers are given name "CEFBrowser"
			if(c.getName() == "CEFBrowser") { 
				System.out.println("CEF browser found!");
				cefWasPermanentFocusOwner = true;
			}
		}
		if (!cefWasPermanentFocusOwner)
			return;
		if (!(evt.getNewValue() instanceof Component))
			return;
		
		final Component newValue = (Component)evt.getNewValue();
		Class<? extends Component> clazz = newValue.getClass();
		if (JTextComponent.class.isAssignableFrom(clazz) || JComboBox.class.isAssignableFrom(clazz)) {
			cefWasPermanentFocusOwner = false;
			System.out.println("Resetting the owner!");
			focusManager.clearGlobalFocusOwner();
			newValue.requestFocusInWindow();
		}
	}
});

@magreenblatt
Copy link
Collaborator Author

Original comment by János Gerevich (Bitbucket: JohnTheHun, GitHub: JohnTheHun).


I commented it the line you were referring to, but getting focus in a multi-window environment is still not working good: i have to click multiple times until the other window finally receives focus and comes to front.

(I didn't use / do anything with your attached patch file, I just ran the following under java-cef\src\tools

run.bat win64 Release detailed

and used the test menu / new window
)

My Java_org_cef_browser_CefBrowser_1N_N_1SetFocus looks like this:

#!c++

JNIEXPORT void JNICALL
Java_org_cef_browser_CefBrowser_1N_N_1SetFocus(JNIEnv* env,
                                               jobject obj,
                                               jboolean enable) {
  CefRefPtr<CefBrowser> browser = JNI_GET_BROWSER_OR_RETURN(env, obj);
  if (browser->GetHost()->IsWindowRenderingDisabled()) {
    browser->GetHost()->SendFocusEvent(enable != JNI_FALSE);
  } else {
    browser->GetHost()->SetFocus(enable != JNI_FALSE);
  }

#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
}

@magreenblatt
Copy link
Collaborator Author

Original comment by János Gerevich (Bitbucket: JohnTheHun, GitHub: JohnTheHun).


Can any of you upload or send me a 64bit jcef.dll which by your experience handles window focus with multiple browser windows correctly? So I can test it in my environment.
(JCEF Version: 3.3396.184.gc995bbd, CEF Version: 3.3396.1775.g5340bb0)

@magreenblatt
Copy link
Collaborator Author

Original comment by Mike van Afferden (Bitbucket: locosmike, GitHub: locosmike).


We've had a similar issue to this one in our JCEF app (we only use a single Java window in our app): Once the JCEF browser window looses focus, the app icon on the task bar at the bottom of the screen (Windows 10 Pro x64) starts blinking. This usually happens, when an application in the background requests focus.

We fixed the issues by changing the if condition in line 1270 of Java_org_cef_browser_CefBrowser_1N_N_1SetFocus to if (enable != JNI_FALSE). We guess that it was a typo in the code as this change fixed the behaviour of our JCEF app.

You can see the change in our forked repository at GitHub. We also cloned the AppVeyor project of guusdk so you can check out the resulting binary distribution files too.

@magreenblatt
Copy link
Collaborator Author

Original comment by János Gerevich (Bitbucket: JohnTheHun, GitHub: JohnTheHun).


Many thanks, Mike's solution seems to work for me. I hope this doesn't ruin anything important.

@magreenblatt
Copy link
Collaborator Author

Original comment by Andrei Pivkine (Bitbucket: andreiPiv, GitHub: andreiPiv).


There is also another FocusParent code in focus_handler.cpp

There is also an issue where FocusParent might be called on a component that is not visible. This can cause an issue with focus and appear to hang the Java application.

My solution was to remove both FocusParent calls and handling setting focus to the parent in Java

@magreenblatt
Copy link
Collaborator Author

Original comment by János Gerevich (Bitbucket: JohnTheHun, GitHub: JohnTheHun).


Andrei, is this focus handling java code the code you pasted a few comments before?
In focus_handler.cpp did you just comment out the 64. line "FocusParent(browserHandle);" ?
Could you paste the code you now use in focus_handler.cpp?
Thanks

@magreenblatt
Copy link
Collaborator Author

Issue #310 was marked as a duplicate of this issue.

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