yueying0083 / javachromiumembedded

Automatically exported from code.google.com/p/javachromiumembedded
0 stars 0 forks source link

Regression from fix for issue 104 - can no longer have overlapping components over cef browser widget #120

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Get the latest on Windows (JCEF revision 104)
2. Add a few lines of code to JCEF sample app to bring up a "fast view" (code 
below). Compile. Run tests.detailed.MainFrame example.
3. Click on "Reload" button to bring up the overlapping "fast view".

What is the expected output? What do you see instead?
Prior to revision 100 (before it includes fix for issue 104), user can see the 
overlapping pane on top of the cef browser area.
After revision 100, the cef browser makes a Win32 call to SetWindowRgn which 
doesn't take into account areas covered by overlapping widgets. As a result, it 
draws on top of these widgets and interfere with how AWT / Swing manage 
lightweight and heavyweight components (canvas). 

To run the modified tests.detailed.MainFrame.java, add the following lines into 
ControlPanel.java

ControlPanel.java

    reloadButton_.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
+         {
+             JFrame frame = (JFrame)SwingUtilities.getRoot(ControlPanel.this);

+             JPanel fastView = new JPanel(new FlowLayout());
+             fastView.setBackground(Color.RED);
+             fastView.setBounds(0, 50, 200, 600);
+             for (int i = 0; i < 10; i++)
+                 fastView.add(new JButton("Button "+i));
+             frame.getLayeredPane().add(fastView, JLayeredPane.DEFAULT_LAYER);
+         }
        if (reloadButton_.getText().equalsIgnoreCase("reload")) {

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

Windows 7

Please provide any additional information below.

The current workaround to return to past behavior is to remove calls to 
CefBrowser_N.N_UpdateUI .

CefBrowser_N.java
  protected final void updateUI(Rectangle contentRect, Rectangle browserRect) {
    try {
-      N_UpdateUI(contentRect, browserRect);

Then the following code in CefBrowser_N.cpp introduced in revision 100 is not 
invoked
JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1UpdateUI
...
HRGN contentRgn = CreateRectRgn(contentRect.x, contentRect.y,
 contentRect.x + contentRect.width, contentRect.y + contentRect.height);
HWND hwnd = browser->GetHost()->GetWindowHandle();
SetWindowRgn(GetParent(hwnd), contentRgn, TRUE);

Fix for issue 104 is pretty delicate and elaborate. Unfortunately it breaks the 
case of overlapping panels.

Original issue reported on code.google.com by christop...@gmail.com on 22 Sep 2014 at 4:48

GoogleCodeExporter commented 8 years ago

Original comment by christop...@gmail.com on 22 Sep 2014 at 4:57

Attachments:

GoogleCodeExporter commented 8 years ago
Hi Christoph,
thanks for figuring that out. Simply removing the call to the native 
N_UpdateUI(..) doesn't fix your issue (see attached image). Other components 
like Java's progress bar still paint over the layered pane (e.g. if you press 
"reload").

Beside that it would break the fix for the two problems described on issue 104. 
To verify this, simply apply one of the patches testcase1 or testcase2 to 
simple MainFrame.java.

Btw: If you remove the call to N_UpdateUI(..) you will break the implementation 
for Mac as well. Please keep that in mind.

I think it is important to fix issue 104 as well as this issue 120. Not either 
issue 104 or issue 120. Do you have any ideas how to deal with that? Maybe 
there is another good approach to update the position, size as well as the 
clipping of the native browser overlay?

Have you tried to use OSR? Maybe this could be a workaround until a solution 
for this is found.

Original comment by k...@censhare.de on 23 Sep 2014 at 5:22

Attachments:

GoogleCodeExporter commented 8 years ago
Hi Kai:

Thanks for feedback. Regarding your screenshot, using JLayeredPane.DRAG_LAYER 
instead of JLayeredPane.DEFAULT_LAYER fixes the pb you noticed. So the patch to 
ControlPanel.java becomes:

ControlPanel.java

    reloadButton_.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
+         {
+             JFrame frame = (JFrame)SwingUtilities.getRoot(ControlPanel.this);

+             JPanel fastView = new JPanel(new FlowLayout());
+             fastView.setBackground(Color.RED);
+             fastView.setBounds(0, 50, 200, 600);
+             for (int i = 0; i < 10; i++)
+                 fastView.add(new JButton("Button "+i));
+             frame.getLayeredPane().add(fastView, JLayeredPane.DRAG_LAYER);
+         }
        if (reloadButton_.getText().equalsIgnoreCase("reload")) {

Then AWT/Swing get the Z-order right for their components, even when resizing 
or giving focus to the different areas. But the Cef browser forces its region 
over the others.

Yes, Mac is currently in the backburner in our project due to unrelated defect 
109 (we're a JavaWebStart app, not a native bundled app). But certainly will 
keep it in mind.

Luckily in our product we don't have to make the CefBrowser work on the sides 
of a border layout, we can parent it as a single child of a JPanel and stick to 
CENTER. But we have these fast views that must stay on top... Since overlapping 
can create arbitrary shapes (aka a region), that clearly becomes tricky to 
solve without being part of the AWT team itself.

For now, we can live with disabling part of issue 104 in our own code. Native 
WR works so much better than OSR for us (performance, WebGL support, 
mouse/keyboard (caret actually blinks!)) we decided OSR was not appropriate for 
us. So no rush to fix this complex problem. If it bothers me a lot, I might 
provide a patch to have a flag (clipping or z-order preference...) until we get 
everything right.

Original comment by christop...@gmail.com on 23 Sep 2014 at 2:59

GoogleCodeExporter commented 8 years ago
The fix for issue 104 in revision 100 also has introduced issue 121. We can 
pursue discussion on issue 121 over there.

Original comment by christop...@gmail.com on 23 Sep 2014 at 6:53

GoogleCodeExporter commented 8 years ago
Layering light-weight Swing components on top of heavy-weight AWT components 
has always been problematic. Have you considered implementing the overlay as 
web content (via JavaScript injected into the browser) instead of trying to do 
it with Swing overlays?

Original comment by magreenb...@gmail.com on 29 Sep 2014 at 4:41

GoogleCodeExporter commented 8 years ago
In our case, we have a large legacy Java app and these overlapping Swing panes 
can't be rewritten. If these were new features, we'd have more freedom...

It's true LW/HW wasn't supported for a long time by Sun/Oracle, but it has gone 
much much better starting with 1.6 and 1.7. e.g. 
https://bugs.openjdk.java.net/browse/JDK-4811096 . It works pretty well as long 
as components are opaque.

I might have to add a flag to avoid the SetWindowRgn code introduced in issue 
104. Or find a workaround that works for everyone, but it's certainly is a 
tricky pb to get right on the different platforms.

Original comment by christop...@gmail.com on 29 Sep 2014 at 5:03

GoogleCodeExporter commented 8 years ago
JCEF is transitioning from Google Code to Bitbucket project hosting. If you 
would like to continue receiving notifications on this issue please add 
yourself as a Watcher at the new location: 
https://bitbucket.org/chromiumembedded/java-cef/issue/120

Original comment by magreenb...@gmail.com on 18 Mar 2015 at 6:00