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

Linux: Window is deactivated when CEF browser gains focus #329

Open
magreenblatt opened this issue Mar 8, 2019 · 3 comments
Open

Linux: Window is deactivated when CEF browser gains focus #329

magreenblatt opened this issue Mar 8, 2019 · 3 comments
Labels
bug Bug report linux Linux platform

Comments

@magreenblatt
Copy link
Collaborator

Original report by me.


What steps will reproduce the problem?

Add the following code in the simple application:

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowActivated(WindowEvent e) {
                System.out.println("windowActivated");
            }

            @Override
            public void windowDeactivated(WindowEvent e) {
                System.out.println("windowDeactivated");
            }
        });

Notice that the windowActivated/windowDeactivated messages are printed when clicking between the URL bar and the CEF browser window.

What is the expected output?

Window activation should not change.

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

Current JCEF master on Ubuntu 14.04.

The windowDeactivated event is originating from the WINDOW_LOST_FOCUS case in DefaultKeyboardFocusManager.dispatchEvent. Java appears to be synthesizing the windowDeactivated event because WindowEvent.getOppositeWindow is returning null. From the documentation, the opposite window should be "the Window that gained activation or focus", which in this case would be the MainFrame window.

The WINDOW_LOST_FOCUS event is originating from XWindowPeer.handleWindowFocusOut, which is called from the native event queue [1]. The oppositeWindow value is determined in XWindowPeer.handleFocusEvent by calling getNativeFocusedWindowPeer, which in this case returns null (XToolkit.windowToXWindow(xGetInputFocus()) returns null).

So, it looks like the root problem is that there's no XBaseWindow mapped to CEF's X11 Window handle. I suspect that we need something similar to XEmbedCanvasPeer, but to wrap a Window handle that already exists. Unfortunately the parent class (XCanvasPeer) is package scope restricted, so we can't just implement one outside of sun.awt.X11.

[1] Call stack:

at sun.awt.X11.XWindowPeer.handleWindowFocusOut(XWindowPeer.java:646)
at sun.awt.X11.XDecoratedPeer.handleWindowFocusOut(XDecoratedPeer.java:1232)
at sun.awt.X11.XWindowPeer.handleFocusEvent(XWindowPeer.java:913)
at sun.awt.X11.XDecoratedPeer.handleFocusEvent(XDecoratedPeer.java:230)
at sun.awt.X11.XFocusProxyWindow.handleFocusEvent(XFocusProxyWindow.java:77)
at sun.awt.X11.XFocusProxyWindow.dispatchEvent(XFocusProxyWindow.java:70)
at sun.awt.X11.XBaseWindow.dispatchToWindow(XBaseWindow.java:1090)
at sun.awt.X11.XToolkit.dispatchEvent(XToolkit.java:512)
at sun.awt.X11.XToolkit.run(XToolkit.java:621)
at sun.awt.X11.XToolkit.run(XToolkit.java:542)
at java.lang.Thread.run(Thread.java:744)
@magreenblatt
Copy link
Collaborator Author

  • edited description

@magreenblatt
Copy link
Collaborator Author

This issue was diagnosed using a local debug build of OpenJDK which is documented here.

@magreenblatt
Copy link
Collaborator Author

A simple fix (requiring a custom OpenJDK build) could patch XToolkit.windowToXWindow to walk the X11 parent hierarchy (using XlibWrapper.XQueryTree), and return the XBaseWindow for the parent, if any. For example, in C++ code this might look like:

#!c++
::Window FindXBaseWindowParent(::Display* display, ::Window window) {
  ::Window root = x11::None;
  ::Window parent = x11::None;
  ::Window* children = NULL;
  unsigned int nchildren = 0;
  while (XQueryTree(display, window, &root, &parent, &children, &nchildren)) {
    if (children) {
      XFree(children);
    }

    if (HasXBaseWindow(parent)) {
      return parent;
    }

    window = parent;
  }
  return x11::None;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug report linux Linux platform
Projects
None yet
Development

No branches or pull requests

1 participant