JCEF browser flashes from corner of IDE
There are some issues which suggest a flashing problem with JCEF but I'm not sure they are what I'm dealing with:
- https://youtrack.jetbrains.com/issue/IDEA-232927
- https://youtrack.jetbrains.com/issue/IDEA-230863
This is what I see when I load a JCEF browser from a gutter icon via LineMarkerProviderDescriptor.

This happens on both Ubuntu 18.04 and Windows 10. The issue is a bit worse on Windows as CefBrowser.createImmediately() results in a blank white screen and the browser never loads.
In the gif above, notice that the browser flashes from the top left corner of the IDE and then it flashes an additional time once it teleports to where the mouse is. Both of these flashes shouldn't be happening. It does not flash from the corner of the IDE on the first time it's shown but only once it's displayed again after that. There are two gutter icons in this example so I show how the first hover results in no flash from the corner but subsequent hovers will result in flashes. You can also tell when it's the first time opening that browser because I close out the "Cookies and IP addresses allow us to deliver..." warning on the first display.
The code which I'm using to create this issue is here: https://github.com/sourceplusplus/SourceMarker
The logic behind this code is simply:
- Add a gutter icon on each method (works for Java/Groovy/Kotlin)
- When the mouse hovers over the gutter icon display a Balloon near the mouse
- Use JBPopupFactory.getInstance().createBalloonBuilder() to set the component to be JBCefBrowser.component
All of this logic works correctly the first time it's triggered. The issue occurs when steps 2 & 3 are repeated.
I believe this issue is specific to JCEF because this same logic works when step 3 is modified to instead be a Swing component, like so:

As you can see, no flashing or teleporting from the top left of the IDE.
I've extracted this example from a much larger project though this example is still around 2000 lines of Kotlin and 300 lines of Java so I'm not expecting anyone to dig through the code. I would honestly just appreciate some steps or information about how I can try to isolate where the issue is occurring.
IDE
IntelliJ IDEA 2020.1 EAP (Community Edition)
Build #IC-201.6073.9, built on March 4, 2020
Runtime version: 11.0.6+8-b765.1 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Linux 5.3.0-40-generic
GC: G1 Young Generation, G1 Old Generation
Memory: 512M
Cores: 16
Registry: ide.browser.jcef.enabled=true
Non-Bundled Plugins: org.example.example-plugin
Current Desktop: ubuntu:GNOME
请先登录再写评论。
Brandon,
Could you please add JBCefClient.addLoadHandler before the browser component is shown, and log the loading callbacks? It looks like the problem is that the web page is loaded subsequently.
Anton,
There are no calls that hit CefLoadHandler after the browser is created for the first time. I tried some other handlers and found that CefLifeSpanHandler yields some interesting results. The first time the browser is displayed onAfterParentChanged is called twice. All subsequent times the browser is displayed it is only called once. It is called again when the balloon is closed but the first time the browser is displayed it is called twice (not including the third call when the balloon is closed).
I was also able to set some breakpoints which show the browser teleporting to the correct place:
The first time I hover over the gutter icon nothing is displayed when I step past "myLayeredPane.add(myComp);". The browser is only displayed when I step past "myComp.validate();". The second time I hover over the gutter icon I get the invalid placement of the browser at the top left of the IDE when I step past "myLayeredPane.add(myComp);" and it's only when I step past "myComp.validate();" that it goes to the correct location.
I believe the reason the webpage doesn't load under debug is because of IntelliJ's PerformanceWatcher. How can I disable this during debugging?
I would like to debug this issue further but I'm not able to get IntelliJ to stop with "Source code does not match the bytecode" whenever I try to step into the JCEF code. I'm using IntelliJ version 201.6073-EAP-CANDIDATE-SNAPSHOT and I've got the dependency:
I've checked the jars which 201.6073-EAP-CANDIDATE-SNAPSHOT is packed with and the jar for JCEF is the same so I'm not sure how the sources don't match the bytecode. Because of this, stepping through the code is difficult and not all the breakpoints I set work.
Simplified this issue down to <400 lines of Kotlin.
Source code: https://github.com/BFergerson/jcef-flash-issue
Demonstration:
This gif additionally shows the webpage is being resized once it's teleported to the correct location. I believe this is the reason for the additional flashing when the webpage is shown.
Brandon,
I've reproduced the problem with your simplified plugin, thanks. It seems like an issue with JCEF heavyweight window. Could you please file the bug on YouTrack? As a workaround I can suggest that you show JCEF via heavyweight popup window instead. I've tried and it worked that way.
Thanks again, Anton. I created issue: https://youtrack.jetbrains.com/issue/IDEA-235155
I was also able to solve this issue by using JBPopupFactory.createComponentPopupBuilder() instead of JBPopupFactory.createBalloonBuilder(). I did find two issues with this approach and it's that for some reason the popup is immediately closed the first time it's open when CefBrowser.createImmediately() is used and the second issue is once browser is displayed the second time clicking anywhere in the browser will close it.
You can see this issue with the same code at: https://github.com/BFergerson/jcef-flash-issue
First issue:
The first issue is the browser immediately closes the first time it's displayed.
Using configuration:
Results in:
Second issue:
The second issue is wherever you click in the browser the second time it's displayed results in the browser being closed.
Using configuration:
Results in:
I can make the first issue go away by using var preloadJcefBrowser: Boolean = false and I can make the second issue go away by using var heavyPopupCancelDelay: Int = Integer.MAX_VALUE, but then the browser can't be closed. The heavyPopupCancelDelay is used like so:
My main question now is what is causing the browser to think it needs to be canceled when I click on something within the browser? Is there something I should be calling to ensure the browser has focus so it responds correctly to mouse events and doesn't think it's being closed?
Brandon,
Sorry for the delay. I've tried your latest changes, I was not able to reproduce neither the 1st nor the 2nd issue. It worked ok for me. SDK - Build #IU-201.6073.9, built on March 4, 2020
Could you please try to display the popup so that it appears from a distance to the mouse pointer, does it make a difference?
Anton,
I appreciate you following up on this. I've updated to 201.6073.9 and I've changed the example on https://github.com/BFergerson/jcef-flash-issue/tree/trigger-on-0 to display the browser when the number key '0' is typed instead of on mouse hover. The only difference I'm seeing is I'm not able to reproduce the second issue when I add a value to heavyPopupCancelDelay. If I use no delay on that variable I can still produce both issues: