Page 1 of 1

CEF transparent overlay

PostPosted: Mon Mar 02, 2020 4:46 am
by yosoymin
We are using CEF for rendering games UI and we have some simple patches to CEF that makes possible to create a transparent window that we place over the game window as an overlay. This approach is simpler than off-screen rendering and works great in windows and linux desktop applications.
The only modifications needed for CEF are (3 lines of code):

Code: Select all
bool DesktopWindowTreeHostWin::ShouldWindowContentsBeTransparent() const {
   // but merely of the content Chrome draws, so even when the system titlebars
   // appear opaque (Win 8+), the content above them needs to be transparent, or
   // they'll be covered by a black (undrawn) region.
   return true;  // instead of return ShouldUseNativeFrame() && !IsFullscreen();
}

SkColor CefContext::GetBackgroundColor(
    const CefBrowserSettings* browser_settings,
    cef_state_t windowless_state) const {
{
   return SK_ColorTRANSPARENT;  // Enforces transparent background color
}

void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget,
                                 content::WebContents* web_contents,
                                 const gfx::Rect& bounds) {
    [...]
    params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;  // instead of views::Widget::InitParams::OPAQUE_WINDOW
    [...]
}

This modifications force the transparent window mode, but I can easily introduce a setting configuration in CefWindowInfo, something like CefWindowInfo::SetAsChild(parent, windowRect, bool transparentOverlay);

It's responsibility of the client code (who creates the parent window) to maintain the CEF window over the parent one and resize it to match the position and size of both windows.

When creating CEF, in Windows (Vista and above) you have to do:
Code: Select all
  CefWindowInfo window_info;
  window_info.SetAsPopup(parentWnd, "CEF");
  window_info.ex_style |= WS_EX_COMPOSITED;

In linux you have to create a parent XWindow that supoorts alpha channel, see https://stackoverflow.com/questions/4052940/how-to-make-an-opengl-rendering-context-with-transparent-background and https://github.com/datenwolf/codesamples/blob/master/samples/OpenGL/x11argb_opengl/x11argb_opengl.c.

If you think that this can be useful, and can be included in the base code of CEF, I can prepare a patch for any version you want.

Re: CEF transparent overlay

PostPosted: Mon Mar 02, 2020 11:15 am
by magreenblatt
There are some PRs for this already, including https://bitbucket.org/chromiumembedded/ ... views/diff. It looks like yours would be similar?

Re: CEF transparent overlay

PostPosted: Mon Mar 02, 2020 3:40 pm
by yosoymin
That's true, the only difference I can see is that the PRs you mentioned seems to work for the views framework, but I think that is not working for windowed mode. I've never used the views framework before, I'm going to give it a try. Maybe the final solution for this feature should be something that works in both modes.

Re: CEF transparent overlay

PostPosted: Mon Mar 02, 2020 4:08 pm
by magreenblatt
CEF windowed mode uses the views framework internally on Windows and Linux. Any changes should be in CEF code and not Chromium (e.g. not DesktopWindowTreeHostWin).

Re: CEF transparent overlay

PostPosted: Tue Sep 08, 2020 5:59 am
by yosoymin
Just for the record, if someone is looking for making CEF transparent, the Pull Request mentioned before in this thread (https://bitbucket.org/chromiumembedded/ ... w-in-views) is working ok both in Windows and Linux. It would be great if one day the code is integrated into CEF.
I have a list of 3 simple modifications to allow this in case anyone wants to apply fast and easy to any CEF version.

chromium_git/chromium/src/cef/libcef/browser/context.cc:
Code: Select all
CefContext::GetBackgroundColor() { return SK_ColorTRANSPARENT; } // Return always transparent color


chromium_git/chromium/src/cef/libcef/browser/views/window_view.cc:
Code: Select all
void CefWindowView::CreateWidget() {
[...]
    params.remove_standard_frame = true;
  }
#endif

  params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;  // This line is needed for trasnparency

  widget->Init(std::move(params));

[...]

    XChangeProperty(display, window, mwmHintsProperty, mwmHintsProperty, 32,
                    PropModeReplace, (unsigned char*)&hints, 5);
  }
#endif  // defined(OS_LINUX) && defined(USE_X11)

  // This is needed for trasnparency
  CefRefPtr<CefView> cef_view = view_util::GetFor(GetContentsView(), false);
  if (cef_view)
      cef_view->SetBackgroundColor(SK_ColorTRANSPARENT);
}