36

I'm trying to gauge the possibility of a patch to WebKit which would allow all rendered graphics to be rendered onto a fully transparent background.

The desired effect is to render web content without any background at all, it should appear to float over the desktop (or whatever is displayed behind the browser window).

Has anyone seen an app do this? (I can think of some terminal emulators that can.) If anyone has worked inside of WebKit (or possibly Gecko?) do you think it would be possible to do this?


Update: I've come to realize that Mac OSX dashboard widgets use this exact technique. So, this must be possible.


Update 2: I've compiled WebKit on linux and noticed the configure options include:

--enable-dashboard-support
enable Dashboard support default=yes

I'm getting closer. Can anyone help?


Update 3: I continue to find references to this in posts on various related mailing lists.

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
Mark Renouf
  • 30,697
  • 19
  • 94
  • 123
  • You may want to try building for the Adobe AIR platform if that's an option. There are a few ways to do it there. http://theflexmagazine.com/2009/01/29/transparent-application-window-with-adobe-air/ and http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=4&postId=8226 – Joey Robert Apr 28 '09 at 00:51
  • I realize this is possible, but not ideal due to licensing requirements (target is embedded player), we are trying to remain as unemcumbered as possible. I realize there are patches from Adobe that do not seem to have made their way back into WebKit yet. (Windowless plugin support in the Gtk build being a major one). – Mark Renouf Apr 28 '09 at 14:28

5 Answers5

31

Solved!

Through ongoing research, scouring forums and source code repositories, I peiced together the necessary steps to accomplish this using only libwebkit and a standard compiz desktop (any Xorg desktop with compositing should do).

For a current libwebkit (1.1.10-SVN), there is an Ubuntu PPA:

deb http://ppa.launchpad.net/webkit-team/ppa/ubuntu jaunty main
deb-src http://ppa.launchpad.net/webkit-team/ppa/ubuntu jaunty main

As far as the code goes, the key is calling webkit_web_view_set_transparent.

And of course the system you're running it on should have a capable graphics card (intel, radeon, or nvidia) and be running a compositing window manager (like Compiz).

And finally, to actually see transparency, the content you're viewing must set a transparent background using CSS3, otherwise it's still completely opaque.

It's as simple as:

BODY { background-color: rgba(0,0,0,0); }

Here' is the full sample for the simplest possible webkit browser app, with transparency support:

#include <gtk/gtk.h>
#include <webkit/webkit.h>

static void destroy_cb(GtkWidget* widget, gpointer data) {
  gtk_main_quit();
}

int main(int argc, char* argv[]) {
  gtk_init(&argc, &argv);

  if(!g_thread_supported())
    g_thread_init(NULL);

  // Create a Window, set colormap to RGBA
  GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  GdkScreen *screen = gtk_widget_get_screen(window);
  GdkColormap *rgba = gdk_screen_get_rgba_colormap (screen);

  if (rgba && gdk_screen_is_composited (screen)) {
    gtk_widget_set_default_colormap(rgba);
    gtk_widget_set_colormap(GTK_WIDGET(window), rgba);
  }

  gtk_window_set_default_size(GTK_WINDOW(window), 800, 800);
  g_signal_connect(window, "destroy", G_CALLBACK(destroy_cb), NULL);

  // Optional: for dashboard style borderless windows
  gtk_window_set_decorated(GTK_WINDOW(window), FALSE);


  // Create a WebView, set it transparent, add it to the window
  WebKitWebView* web_view = web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
  webkit_web_view_set_transparent(web_view, TRUE);
  gtk_container_add (GTK_CONTAINER(window), GTK_WIDGET(web_view));

  // Load a default page
  webkit_web_view_load_uri(web_view, "http://stackoverflow.com/");

  // Show it and continue running until the window closes
  gtk_widget_grab_focus(GTK_WIDGET(web_view));
  gtk_widget_show_all(window);
  gtk_main();
  return 0;
}

Screenshot!

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Mark Renouf
  • 30,697
  • 19
  • 94
  • 123
  • 3
    Nice work. I'm not sure CSS3 is necessary for the transparent background; I would have though the old CSS1 `BODY{ background-color: transparent; }` would work. Haven't tried it though. – Paul D. Waite Jul 22 '09 at 11:13
  • 2
    One thing to note, this does crash when loading plugins like Flash which do not expect ARGB colorspace. The app crashes when they try to draw to the screen across the XEmbed API (X11: BadMatch error). – Mark Renouf Jul 22 '09 at 15:02
  • Probably, I'm no longer pursuing this work since I've changed jobs and am no longer developing the product this was intended for. You're welcome to pick it up. – Mark Renouf Aug 18 '11 at 20:52
  • 1
    This compiles for me on a 64-bit Arch Linux with `clang main.c -o program \`pkg-config --cflags --libs gtk+-2.0 webkit-1.0\`` but when I point it at a local web server serving a page with a transparent background, it shows as dark gray. – Anko - inactive in protest Jun 18 '14 at 16:28
2

Back in Safari 1.3 and 2, there was a hidden debug menu (invoked via the Terminal: defaults write com.apple.Safari IncludeDebugMenu 1) that included a “Use Transparent Window” option.

Not sure if this was a WebKit thing or a Safari thing though.

(In Safari 3, the debug menu seems to have been replaced by the “Develop” menu (enable in Preferences > Advanced) which doesn’t have the transparent window option.)

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
  • Thanks for the tip. This put me on the right trail. I bet the call to set_transparent function was controlled by that debug menu option back when it was available. – Mark Renouf Jul 15 '09 at 19:35
1

This gist works for me, as of 2013, tested only with ubuntu:

https://gist.github.com/pouria-mellati/7771779

Pouria
  • 159
  • 12
1

I have a new solution which is really easy to do, for a single screenshot. It's using node.js with phantom.js library.

  1. install node.js
  2. run 'npm install -g phantomjs' in console/terminal
  3. save the following as script.js and run it from console 'phantomjs script.js'

    var page = require('webpage').create();
    page.viewportSize = { width: 1920, height: 1500 };
    page.open("http://www.theWebYouWantToRender");
    page.onLoadFinished = function(status) {
        page.evaluate(function() {
            document.body.style.background = 'transparent';
        });
    
        page.render('render.png');
        phantom.exit();
    };
    
  4. profit? :) enjoy
Eskel
  • 795
  • 1
  • 8
  • 21
1

Basically you want to be setting the ARGB colour space to be sending to the window manager. Obviously only window managers that support compositing will be able to take advantage of this.

You might want to talk to the screenlet and compiz developers they should be able to help out more.

ewanm89
  • 919
  • 5
  • 22
  • I agree, that's half of it. But how do I set a background color in the web page so the final rendered image is not made to be always opaque. Is it as simple as setting BODY { opacity: 0; } ? – Mark Renouf Apr 27 '09 at 00:59
  • Should be, not sure. The compiz/screenlet guys already do rendering of desktop widget kind of windows. – ewanm89 Apr 27 '09 at 02:28
  • I think they even use webkit (in fact I think there are already a desktop widget rendering solution for every major rendering engine accept maybe gecko now). – ewanm89 Apr 27 '09 at 02:30
  • As far as I know screenlets are all straight Gtk/Cairo controlled by Python. I can't find any references to WebKit in their documentation. – Mark Renouf May 05 '09 at 02:33
  • 1
    As far as the web page goes, the opacity property applies to the content of an HTML element as well as its background, so BODY {opacity: 0;} would make everything inside your body tag invisible. I think WebKit supports colour values with alpha transparency though, so you’d do body { background-color: rgba(0,0,0,0); }. I think the default value of background colours is transparent though, so you probably don’t need to set it. – Paul D. Waite May 09 '09 at 11:38
  • Thanks for the help... your info was a key part of the solution! – Mark Renouf Jul 15 '09 at 19:34