--- src/compositor.c	2005-07-12 02:12:32.000000000 +0100
+++ src/compositor.c	2005-07-13 14:00:30.000000000 +0100
@@ -26,6 +26,7 @@
 #include "errors.h"
 #include "window.h"
 #include "frame.h"
+#include "xprops.h"
 
 #ifdef HAVE_COMPOSITE_EXTENSIONS
 #include <X11/extensions/Xcomposite.h>
@@ -40,6 +41,7 @@
 
 #define SHADOW_OFFSET 3
 #define FRAME_INTERVAL_MILLISECONDS ((int)(1000.0/40.0))
+#define OPAQUE 0xffffffff
 
 /* Unlike MetaWindow, there's one of these for _all_ toplevel windows,
  * override redirect or not. We also track unmapped windows as
@@ -65,6 +67,7 @@
   XserverRegion   last_painted_extents;
   
   Picture         picture;
+  Picture         alpha_picture;
   XserverRegion   border_size;
 
 #if HAVE_NAME_WINDOW_PIXMAP
@@ -77,6 +80,8 @@
 
   unsigned int screen_index : 8;
 
+  unsigned int opacity : 8;
+
 #endif  
 } MetaCompositorWindow;
 
@@ -435,6 +440,21 @@
                             0, 0, 0, 0,
                             x, y, w, h);
         }
+      else if (cwindow->alpha_picture)
+        {
+          /* Draw window transparent if it has requested */
+          int x, y, w, h;
+
+          window_get_paint_bounds (cwindow, &x, &y, &w, &h);
+
+          XRenderComposite (xdisplay,
+                            PictOpOver, /* PictOpOver for alpha, PictOpSrc without */
+                            cwindow->picture,
+                            cwindow->alpha_picture,
+                            screen->buffer_picture,
+                            0, 0, 0, 0,
+                            x, y, w, h);
+        }
       else
         {
           /* Draw window normally */
@@ -823,6 +843,19 @@
       return; /* MapNotify wasn't for a child of the root */
     }
   
+  /* This needs to be here or else we lose transparency messages */
+  {
+    XWindowAttributes attrs;
+    attrs.your_event_mask = NoEventMask;
+
+    XGetWindowAttributes (compositor->display->xdisplay,
+                          event->window, &attrs);
+
+    XSelectInput (compositor->display->xdisplay,
+                  event->window,
+                  PropertyChangeMask | attrs.your_event_mask);
+  }
+  
   cwindow = g_hash_table_lookup (compositor->window_hash,
                                  &event->window);
   if (cwindow == NULL)
@@ -1370,3 +1403,100 @@
                                    window_extents (cwindow));
 #endif /* HAVE_COMPOSITE_EXTENSIONS */
 }
+
+#ifdef HAVE_COMPOSITE_EXTENSIONS
+static void
+update_alpha_pict (MetaCompositor       *compositor,
+                   MetaCompositorWindow *cwindow,
+                   MetaScreen           *screen,
+                   gulong                opacity)
+{
+  Pixmap pixmap;
+  Picture picture;
+  XRenderPictureAttributes pa;
+  XRenderColor c;
+
+  if (opacity == OPAQUE)
+    {
+      if (cwindow->alpha_picture)
+        {
+            XRenderFreePicture (compositor->display->xdisplay, cwindow->alpha_picture);
+            cwindow->alpha_picture = None;
+        }
+      return;
+    }
+
+  pixmap = XCreatePixmap (compositor->display->xdisplay, screen->xroot, 1, 1, 8);
+  if (!pixmap)
+    return;
+
+  pa.repeat = True;
+  picture = XRenderCreatePicture (compositor->display->xdisplay, pixmap,
+                                  XRenderFindStandardFormat (compositor->display->xdisplay,
+                                                             PictStandardA8),
+                                  CPRepeat,
+                                  &pa);
+  if (!picture)
+    {
+      XFreePixmap (compositor->display->xdisplay, pixmap);
+      return;
+    }
+
+  c.alpha = ((double)opacity / OPAQUE) * 0xffff;
+  c.red = 0;
+  c.green = 0;
+  c.blue = 0;
+  XRenderFillRectangle (compositor->display->xdisplay, PictOpSrc, picture, &c, 0, 0, 1, 1);
+  XFreePixmap (compositor->display->xdisplay, pixmap);
+
+  if (cwindow->alpha_picture)
+    XRenderFreePicture (compositor->display->xdisplay, cwindow->alpha_picture);
+
+  cwindow->alpha_picture = picture;
+}
+#endif /* HAVE_COMPOSITE_EXTENSIONS */
+
+void
+meta_compositor_update_opacity (MetaCompositor *compositor,
+                                MetaWindow     *window,
+                                Window          xwindow)
+{
+#ifdef HAVE_COMPOSITE_EXTENSIONS
+  MetaCompositorWindow *cwindow;
+  MetaScreen *screen;
+  gulong opacity;
+  gint result;
+
+  if (window && !window->frame)
+    return;
+
+  if (window)
+    cwindow = g_hash_table_lookup (compositor->window_hash,
+                                   &window->frame->xwindow);
+  else
+    cwindow = g_hash_table_lookup (compositor->window_hash,
+                                   &xwindow);
+  if (!cwindow)
+    return;
+
+  screen = meta_compositor_window_get_screen (cwindow);
+
+  result = meta_prop_get_cardinal (compositor->display, xwindow,
+                                   compositor->display->atom_net_wm_window_opacity,
+                                   &opacity);
+  if (!result || !opacity)
+    opacity = OPAQUE;
+
+  update_alpha_pict (compositor, cwindow, screen, opacity);
+
+  cwindow->opacity = opacity;
+
+  if (window)
+    meta_compositor_damage_window (compositor, window);
+  else
+    merge_and_destroy_damage_region (compositor,
+                                     screen,
+                                     window_extents (cwindow));
+
+#endif /* HAVE_COMPOSITE_EXTENSIONS */
+}
--- src/compositor.h	2005-07-12 02:12:32.000000000 +0100
+++ src/compositor.h	2005-07-13 03:13:07.000000000 +0100
@@ -44,6 +44,10 @@
 void meta_compositor_damage_window   (MetaCompositor *compositor,
                                       MetaWindow     *window);
 
+void meta_compositor_update_opacity  (MetaCompositor *compositor,
+                                      MetaWindow     *window,
+                                      Window          xwindow);
+
 #endif /* META_COMPOSITOR_H */
 
 
--- src/display.c	2005-07-12 02:12:32.000000000 +0100
+++ src/display.c	2005-07-13 03:13:41.000000000 +0100
@@ -299,6 +299,7 @@
     "_NET_MOVERESIZE_WINDOW",
     "_NET_DESKTOP_GEOMETRY",
     "_NET_DESKTOP_VIEWPORT",
+    "_NET_WM_WINDOW_OPACITY",
     "_METACITY_VERSION"
   };
   Atom atoms[G_N_ELEMENTS(atom_names)];
@@ -456,7 +457,8 @@
   display->atom_net_moveresize_window = atoms[88];
   display->atom_net_desktop_geometry = atoms[89];
   display->atom_net_desktop_viewport = atoms[90];
-  display->atom_metacity_version = atoms[91];
+  display->atom_net_wm_window_opacity = atoms[91];
+  display->atom_metacity_version = atoms[92];
 
   display->prop_hooks = NULL;
   meta_display_init_window_prop_hooks (display);
@@ -2091,6 +2093,8 @@
         MetaGroup *group;
         MetaScreen *screen;
         
+        if (event->xproperty.atom == display->atom_net_wm_window_opacity)
+          meta_compositor_update_opacity (display->compositor, window, event->xproperty.window);
         if (window && !frame_was_receiver)
           meta_window_property_notify (window, event);
 
--- src/display.h	2005-07-12 02:12:32.000000000 +0100
+++ src/display.h	2005-07-12 02:24:59.000000000 +0100
@@ -182,6 +182,7 @@
   Atom atom_net_moveresize_window;
   Atom atom_net_desktop_geometry;
   Atom atom_net_desktop_viewport;
+  Atom atom_net_wm_window_opacity;
   Atom atom_metacity_version;
 
   /* This is the actual window from focus events,
--- src/screen.c	2005-07-12 02:12:32.000000000 +0100
+++ src/screen.c	2005-07-12 02:22:58.000000000 +0100
@@ -85,7 +85,7 @@
 static int
 set_supported_hint (MetaScreen *screen)
 {
-#define N_SUPPORTED 58
+#define N_SUPPORTED 59
   Atom atoms[N_SUPPORTED];
   
   atoms[0] = screen->display->atom_net_wm_name;
@@ -146,8 +146,9 @@
   atoms[55] = screen->display->atom_net_wm_state_demands_attention;
   atoms[56] = screen->display->atom_net_desktop_geometry;
   atoms[57] = screen->display->atom_net_desktop_viewport;
-  //atoms[58] = screen->display->atom_net_restack_window;
-  //atoms[59] = screen->display->atom_net_moveresize_window;
+  atoms[58] = screen->display->atom_net_wm_window_opacity;
+  //atoms[59] = screen->display->atom_net_restack_window;
+  //atoms[60] = screen->display->atom_net_moveresize_window;
   
   XChangeProperty (screen->display->xdisplay, screen->xroot,
                    screen->display->atom_net_supported,
