Chromium on Windows 7 + Transparency

2,662 views
Skip to first unread message

Trevor Linton

unread,
Dec 30, 2012, 3:48:42 PM12/30/12
to chromi...@chromium.org
Hi All,

I'm trying to implement transparency on Windows 7, I realize chromium doesn't support this, which is why i'm trying to. I've set my WHND to become a layered window and applied alpha bending as a window option. However when I do this (regardless if I set the webview setIsTransparent=true or false) the webview doesn't render at all.  Any thoughts?  The view isn't rendering because of the transparency alpha blending, it seems to stop rendering as soon as layered window option is set on WHND.

- t

Wez

unread,
Dec 31, 2012, 6:00:32 AM12/31/12
to trevor...@gmail.com, chromi...@chromium.org
Are you calling SetLayerWindowAttributes() as well as setting the layered style on the window?  If not then IIRC you'll need to change the rendering code in Chromium to use UpdateLayeredWindow() to re-draw the window contents (see http://msdn.microsoft.com/en-us/library/ms997507.aspx).

Cheers,

Wez
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev

Trevor Linton

unread,
Dec 31, 2012, 4:09:31 PM12/31/12
to chromi...@chromium.org, trevor...@gmail.com
I've tried using the UpdateLayteredWindow, i've read on microsofts forums SetLayerWindowAttributes (although I have no idea why) has severe performance hits. And from my own experience its resulted in very sluggish performance (using WS_EX_LAYERED | WS_EX_TRANSPARENT). At the moment i'm looking into using a method implemented here: 

http://www.codeproject.com/Articles/17727/Unmanaged-Vista-Power

From a first run things look OK, although this requires a tight window style contract between the hosting window and chromium renderer which isn't optimal but does seem to perform very well.

Trevor Linton

unread,
Jan 6, 2013, 6:26:46 PM1/6/13
to chromi...@chromium.org, trevor...@gmail.com
I've added support for transparency in windows, I thought i'd leave this here incase anyone ever thought to add support to it. 

Support is actually quite simple, hWnd with WS_POPUP (WS_SIZEBOX nor WS_THICKFRAME can be used).  In addition the DWM needs to be passed:

MARGINS mgMarInset = { -1, -1, -1, -1 };
DwmExtendFrameIntoClientArea(window_->GetNativeWindow(), &mgMarInset);

In addition setIsTransparent needs to be set to true on the hosting webview.

Cheers,
Trevor

fddima

unread,
Jan 15, 2013, 7:34:53 PM1/15/13
to chromi...@chromium.org, trevor...@gmail.com
Hi, Trevor.

I'm tried last way with CEF3, so first steps are done.
But little confused with 'In addition setIsTransparent needs to be set to true on the hosting webview.'... Can you give may be more explicit pointers? I.e. actually i see that it is possible do via content RenderWidgetHostView.SetBackground method. May be you have some limited sample?

And as i'm understand, systems with limited DWM support, or Windows XP - desn't work via this way and requires WS_EX_LAYERED... ?

Jeremy Apthorp

unread,
Jan 15, 2013, 7:59:48 PM1/15/13
to fdd...@gmail.com, Chromium-dev, trevor...@gmail.com
Trevor- we do some of that style of trickery for new-style packaged apps on windows (see chrome/browser/ui/extensions/views/shell_window_frame_view.cc and ui/views/widget/native_widget_win.cc), but that DwmExtendFrameIntoClientArea puts the glass background behind the window. Is that what you were after, or have you discovered another way of making the window truly transparent?

This would certainly require WS_EX_LAYERED on WinXP, but layered windows don't support child windows, which are currently required by Chrome's rendering architecture.

Trevor Linton

unread,
Jan 26, 2013, 3:24:29 PM1/26/13
to chromi...@chromium.org
Hi Dobromir, 

How is it failling?  I've found some issues with using DwmExtendFrameIntoClientArea method. Specifically you must set your window to be a WS_POPUP, setIsTransparent to true on webview, ensure you're using compositing and hardware accelerated rendering, make sure your body tag has a background:transparent or some other RGBA and (obviously) call DwmExtendFrameIntoClientArea once with negative margins. This results in a frameless webview rendered with transparent background. Where this becomes a problem is having to use WS_POPUP.  Minimize, maximize, resizing, menuing go out the window, you have to create custom controls to control these and believe me its not easy, all in all it just produces more problems.  The performance is good.

This is sort of a windows hack however.  If you're using just a standard window instead of WS_POP it will produce a aero glass affect. The bug in windows is the glass affect is not rendered on WS_POP, it just renders transparent. Obviously this turns out to be somewhat of a bad solution, if aero glass is disabled (as it is in Vista Basic and Win7 Basic) it just renders on a black background...

I'm looping back and seeing if UpdateLayeredWindow can help...

On Tuesday, January 15, 2013 7:02:50 AM UTC-7, Dobromir Enchev wrote:
Hello, Trevor. I tried to make this, but failed. Can you post an example somewhere?

Trevor Linton

unread,
Jan 26, 2013, 3:28:35 PM1/26/13
to chromi...@chromium.org, trevor...@gmail.com
Hi, Fddima,

setIsTransparent is on the webview class, it instructs the webview not to paint in an opaque manner. This can't be controlled with SetBackground. I made a new message for SetIsTransparent on RenderWidgetHostView that passed the message to the RenderWidgetViewImpl which then set webview()->setIsTranparent(true);  See my above comments on the down sides of using DwmExtendFrameIntoClientArea, this approach only works on Vista+. I'm still investigating an avenue for UpdateLayeredWindow. 

Trevor Linton

unread,
Jan 26, 2013, 3:32:56 PM1/26/13
to chromi...@chromium.org, fdd...@gmail.com, trevor...@gmail.com
Hi Jeremy,

You're correct that DwmExtendFrameIntoClientArea will just produce the glass background, however if you set your window type to WS_POPUP it'll render completely transparent (although using WS_POPUP has its own downsides, specifically you loose maximize, minimize, menus and resizing, these have to manually handled). This is due to a windows "hack" or bug. I'm trying to figure out a better way using UpdateLayeredWindow. Child windows aren't supported by layered windows (e.g., they still render, but do not support layered blending operations), they do now in Windows 8.  What this effectively means is a child window will not render as transparent (as my understanding from MSDN).  I'm still in the process of trying to get this to work correctly.

Cheers

Dobromir Enchev

unread,
Jan 30, 2013, 8:11:46 AM1/30/13
to chromi...@chromium.org, trevor...@gmail.com
I know how to do maximizing on a popup window, but even if I test your solution on my Windows 8 machine, I think here the DWM is disabled and it won't produce transparent window.

Trevor Linton

unread,
Jan 30, 2013, 11:06:45 AM1/30/13
to chromi...@chromium.org, trevor...@gmail.com
Hi Dobromir,  

I'll try and post an example once I work out a few more bugs. I did realize there's a few other things that need to be done to get this to work, hit tests on transparent areas still dont work but otherwise everything is functional in composite, hardware accelerated and normal blit rendering modes.  This works in everything Vista+ but there is one bug i'm tracking down in Vista Basic (which doesn't support aero):

  1. You can only set your shell window style to GWL_STYLE to WS_POPUP | WS_SYSMENU, anything else will produce the "Aero Glass" effect or break the transparency.
  2. Set the GWL_EXSTYLE to WS_EX_COMPOSITED on the shell window extended style.
  3. If you're using SetWindowLong to set the GWL_STYLE and GWL_EXSTYLE make sure to run SetWindowPos to reset the state of the shell window.
  4. Have DwmExtendFrameIntoClientArea run with {-1,-1,-1,-1} margins once the window is shown.
  5. Have DwmExtendFrameIntoClientArea run with {-1,-1,-1,-1} anytime the compositing state is changed, you'll need to capture this message in WndProc, see: http://msdn.microsoft.com/en-us/library/windows/desktop/dd388199(v=vs.85).aspx
  6. You cannot have any other child windows other than the main chrome rendering window.  Setting the style above to WS_POPUP | WS_SYSMENU removes the menu child window and max/min/close box so this is usually handled automatically.
  7. Since we're using a WS_POPUP style you'll need to listen for maximize messages in WndProc and manually handle.
  8. You'll need to create custom controls to handle min/max/close/move/resize events, this can be done in HTML
  9. Set the background of your body/html tag to something transparent, either a RGBA value or 'transparent'
  10. Make sure to execute the following code in your shell ONLY ON THE OnRenderCreated, the following code will only work if the webview and render have been successfully instantiated (usually the OnRenderCreated can be overloaded from, i believe, widgetdelegate in the shell code):
SkBitmap background;
background.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
background.allocPixels();
background.eraseARGB(0x00, 0x00, 0x00, 0x00);
content::RenderWidgetHostView* view = render_view_host->GetView();
DCHECK(view);
view->SetBackground(background);

Dobromir Enchev

unread,
May 7, 2013, 10:23:05 AM5/7/13
to chromi...@chromium.org, trevor...@gmail.com
What version of CEF are you using? On mine there is no SkBitmap. Can you upload an example somewhere with your version?

fddima

unread,
May 8, 2013, 9:40:55 AM5/8/13
to chromi...@chromium.org, trevor...@gmail.com
Hi Trevor.

You are make it with CEF3?

On Wednesday, January 30, 2013 6:06:45 PM UTC+2, Trevor Linton wrote:

Trevor Linton

unread,
Dec 28, 2013, 3:23:23 PM12/28/13
to chromi...@chromium.org, trevor...@gmail.com
Sorry for the late response, no its with chromium+nodejs project based on node-webkit:


So far everything works great in Mac/Win except if desktop compositing isn't available on Windows (e.g., no Aero theme, Windows Vista Home Basic, XP, etc..)
Reply all
Reply to author
Forward
0 new messages