[gnome-power-manager] Update gnome-settings-daemon copy pasted code



commit cc2510569530e32ce09898f226c1861543420120
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Wed Oct 27 18:00:55 2010 +0200

    Update gnome-settings-daemon copy pasted code
    
    Copy paste the new code for OSD windows, which was updated to Gtk 3
    
    https://bugzilla.gnome.org/show_bug.cgi?id=633270
    
    Signed-off-by: Richard Hughes <richard hughsie com>

 data/acme.ui                |   44 ++--
 src/Makefile.am             |    2 +
 src/gpm-backlight.c         |    2 +-
 src/gsd-media-keys-window.c |  463 ++++-------------------------------
 src/gsd-media-keys-window.h |   25 +-
 src/gsd-osd-window.c        |  561 +++++++++++++++++++++++++++++++++++++++++++
 src/gsd-osd-window.h        |   94 +++++++
 7 files changed, 744 insertions(+), 447 deletions(-)
---
diff --git a/data/acme.ui b/data/acme.ui
index 3222ecb..e0457ed 100644
--- a/data/acme.ui
+++ b/data/acme.ui
@@ -4,36 +4,28 @@
   <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkWindow" id="dialog">
     <child>
-      <object class="GtkFrame" id="acme_frame">
+      <object class="GtkVBox" id="acme_box">
         <property name="visible">True</property>
-        <property name="label_xalign">0</property>
-        <property name="shadow_type">out</property>
+        <property name="spacing">6</property>
         <child>
-          <object class="GtkVBox" id="acme_vbox">
+          <object class="GtkImage" id="acme_image">
             <property name="visible">True</property>
-            <property name="border_width">12</property>
-            <property name="spacing">6</property>
-            <child>
-              <object class="GtkImage" id="acme_image">
-                <property name="visible">True</property>
-                <property name="icon_name">audio-volume-high</property>
-                <property name="icon-size">6</property>
-              </object>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkProgressBar" id="acme_volume_progressbar">
-                <property name="visible">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
+            <property name="icon_name">audio-volume-high</property>
+            <property name="icon-size">6</property>
           </object>
+          <packing>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkProgressBar" id="acme_volume_progressbar">
+            <property name="visible">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
         </child>
       </object>
     </child>
diff --git a/src/Makefile.am b/src/Makefile.am
index 2d3a06f..8069b1d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -140,6 +140,8 @@ gnome_power_manager_SOURCES =				\
 	gpm-stock-icons.h				\
 	gsd-media-keys-window.h				\
 	gsd-media-keys-window.c				\
+	gsd-osd-window.h				\
+	gsd-osd-window.c				\
 	gpm-engine.h					\
 	gpm-engine.c
 
diff --git a/src/gpm-backlight.c b/src/gpm-backlight.c
index fed4b2c..de14e42 100644
--- a/src/gpm-backlight.c
+++ b/src/gpm-backlight.c
@@ -191,7 +191,7 @@ static void
 gpm_backlight_dialog_init (GpmBacklight *backlight)
 {
 	if (backlight->priv->popup != NULL
-	    && !gsd_media_keys_window_is_valid (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup))) {
+	    && !gsd_osd_window_is_valid (GSD_OSD_WINDOW (backlight->priv->popup))) {
 		gtk_widget_destroy (backlight->priv->popup);
 		backlight->priv->popup = NULL;
 	}
diff --git a/src/gsd-media-keys-window.c b/src/gsd-media-keys-window.c
index 2cdc084..627c648 100644
--- a/src/gsd-media-keys-window.c
+++ b/src/gsd-media-keys-window.c
@@ -2,19 +2,22 @@
  *
  * Copyright (C) 2006-2007 William Jon McCann <mccann jhu edu>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2, or (at your option) any later version.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  *
  */
 
@@ -29,21 +32,10 @@
 
 #include "gsd-media-keys-window.h"
 
-#define DIALOG_TIMEOUT 2000     /* dialog timeout in ms */
-#define DIALOG_FADE_TIMEOUT 1500 /* timeout before fade starts */
-#define FADE_TIMEOUT 10        /* timeout in ms between each frame of the fade */
-
-#define BG_ALPHA 0.75
-#define FG_ALPHA 1.00
-
 #define GSD_MEDIA_KEYS_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindowPrivate))
 
 struct GsdMediaKeysWindowPrivate
 {
-        guint                    is_composited : 1;
-        guint                    hide_timeout_id;
-        guint                    fade_timeout_id;
-        double                   fade_out_alpha;
         GsdMediaKeysWindowAction action;
         char                    *icon_name;
         gboolean                 show_level;
@@ -55,94 +47,7 @@ struct GsdMediaKeysWindowPrivate
         GtkWidget               *progress;
 };
 
-G_DEFINE_TYPE (GsdMediaKeysWindow, gsd_media_keys_window, GTK_TYPE_WINDOW)
-
-static gboolean
-fade_timeout (GsdMediaKeysWindow *window)
-{
-        if (window->priv->fade_out_alpha <= 0.0) {
-                gtk_widget_hide (GTK_WIDGET (window));
-
-                /* Reset it for the next time */
-                window->priv->fade_out_alpha = 1.0;
-                window->priv->fade_timeout_id = 0;
-
-                return FALSE;
-        } else {
-                GdkRectangle rect;
-                GtkWidget *win = GTK_WIDGET (window);
-                GtkAllocation allocation;
-
-                window->priv->fade_out_alpha -= 0.10;
-
-                rect.x = 0;
-                rect.y = 0;
-                gtk_widget_get_allocation (win, &allocation);
-                rect.width = allocation.width;
-                rect.height = allocation.height;
-
-                gtk_widget_realize (win);
-                gdk_window_invalidate_rect (gtk_widget_get_window (win), &rect, FALSE);
-        }
-
-        return TRUE;
-}
-
-static gboolean
-hide_timeout (GsdMediaKeysWindow *window)
-{
-        if (window->priv->is_composited) {
-                window->priv->hide_timeout_id = 0;
-                window->priv->fade_timeout_id = g_timeout_add (FADE_TIMEOUT,
-                                                               (GSourceFunc) fade_timeout,
-                                                               window);
-        } else {
-                gtk_widget_hide (GTK_WIDGET (window));
-        }
-
-        return FALSE;
-}
-
-static void
-remove_hide_timeout (GsdMediaKeysWindow *window)
-{
-        if (window->priv->hide_timeout_id != 0) {
-                g_source_remove (window->priv->hide_timeout_id);
-                window->priv->hide_timeout_id = 0;
-        }
-
-        if (window->priv->fade_timeout_id != 0) {
-                g_source_remove (window->priv->fade_timeout_id);
-                window->priv->fade_timeout_id = 0;
-                window->priv->fade_out_alpha = 1.0;
-        }
-}
-
-static void
-add_hide_timeout (GsdMediaKeysWindow *window)
-{
-        int timeout;
-
-        if (window->priv->is_composited) {
-                timeout = DIALOG_FADE_TIMEOUT;
-        } else {
-                timeout = DIALOG_TIMEOUT;
-        }
-        window->priv->hide_timeout_id = g_timeout_add (timeout,
-                                                       (GSourceFunc) hide_timeout,
-                                                       window);
-}
-
-static void
-update_window (GsdMediaKeysWindow *window)
-{
-        remove_hide_timeout (window);
-        add_hide_timeout (window);
-
-        if (window->priv->is_composited) {
-                gtk_widget_queue_draw (GTK_WIDGET (window));
-        }
-}
+G_DEFINE_TYPE (GsdMediaKeysWindow, gsd_media_keys_window, GSD_TYPE_OSD_WINDOW)
 
 static void
 volume_controls_set_visible (GsdMediaKeysWindow *window,
@@ -172,7 +77,7 @@ window_set_icon_name (GsdMediaKeysWindow *window,
 static void
 action_changed (GsdMediaKeysWindow *window)
 {
-        if (! window->priv->is_composited) {
+        if (!gsd_osd_window_is_composited (GSD_OSD_WINDOW (window))) {
                 switch (window->priv->action) {
                 case GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME:
                         volume_controls_set_visible (window, TRUE);
@@ -194,15 +99,15 @@ action_changed (GsdMediaKeysWindow *window)
                 }
         }
 
-        update_window (window);
+        gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
 }
 
 static void
 volume_level_changed (GsdMediaKeysWindow *window)
 {
-        update_window (window);
+        gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
 
-        if (!window->priv->is_composited && window->priv->progress != NULL) {
+        if (!gsd_osd_window_is_composited (GSD_OSD_WINDOW (window)) && window->priv->progress != NULL) {
                 double fraction;
 
                 fraction = (double) window->priv->volume_level / 100.0;
@@ -215,9 +120,9 @@ volume_level_changed (GsdMediaKeysWindow *window)
 static void
 volume_muted_changed (GsdMediaKeysWindow *window)
 {
-        update_window (window);
+        gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
 
-        if (! window->priv->is_composited) {
+        if (!gsd_osd_window_is_composited (GSD_OSD_WINDOW (window))) {
                 if (window->priv->volume_muted) {
                         window_set_icon_name (window, "audio-volume-muted");
                 } else {
@@ -237,7 +142,7 @@ gsd_media_keys_window_set_action (GsdMediaKeysWindow      *window,
                 window->priv->action = action;
                 action_changed (window);
         } else {
-                update_window (window);
+                gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
         }
 }
 
@@ -258,7 +163,7 @@ gsd_media_keys_window_set_action_custom (GsdMediaKeysWindow      *window,
                 window->priv->show_level = show_level;
                 action_changed (window);
         } else {
-                update_window (window);
+                gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
         }
 }
 
@@ -286,58 +191,6 @@ gsd_media_keys_window_set_volume_level (GsdMediaKeysWindow *window,
         }
 }
 
-static void
-rounded_rectangle (cairo_t* cr,
-                   gdouble  aspect,
-                   gdouble  x,
-                   gdouble  y,
-                   gdouble  corner_radius,
-                   gdouble  width,
-                   gdouble  height)
-{
-        gdouble radius = corner_radius / aspect;
-
-        cairo_move_to (cr, x + radius, y);
-
-        cairo_line_to (cr,
-                       x + width - radius,
-                       y);
-        cairo_arc (cr,
-                   x + width - radius,
-                   y + radius,
-                   radius,
-                   -90.0f * G_PI / 180.0f,
-                   0.0f * G_PI / 180.0f);
-        cairo_line_to (cr,
-                       x + width,
-                       y + height - radius);
-        cairo_arc (cr,
-                   x + width - radius,
-                   y + height - radius,
-                   radius,
-                   0.0f * G_PI / 180.0f,
-                   90.0f * G_PI / 180.0f);
-        cairo_line_to (cr,
-                       x + radius,
-                       y + height);
-        cairo_arc (cr,
-                   x + radius,
-                   y + height - radius,
-                   radius,
-                   90.0f * G_PI / 180.0f,
-                   180.0f * G_PI / 180.0f);
-        cairo_line_to (cr,
-                       x,
-                       y + radius);
-        cairo_arc (cr,
-                   x + radius,
-                   y + radius,
-                   radius,
-                   180.0f * G_PI / 180.0f,
-                   270.0f * G_PI / 180.0f);
-        cairo_close_path (cr);
-}
-
 static GdkPixbuf *
 load_pixbuf (GsdMediaKeysWindow *window,
              const char         *name,
@@ -355,22 +208,9 @@ load_pixbuf (GsdMediaKeysWindow *window,
         pixbuf = gtk_icon_theme_load_icon (theme,
                                            name,
                                            icon_size,
-                                           GTK_ICON_LOOKUP_FORCE_SVG,
+                                           GTK_ICON_LOOKUP_FORCE_SIZE,
                                            NULL);
 
-        /* make sure the pixbuf is close to the requested size
-         * this is necessary because GTK_ICON_LOOKUP_FORCE_SVG
-         * seems to be broken */
-        if (pixbuf != NULL) {
-                int width;
-
-                width = gdk_pixbuf_get_width (pixbuf);
-                if (width < (float)icon_size * 0.75) {
-                        g_object_unref (pixbuf);
-                        pixbuf = NULL;
-                }
-        }
-
         return pixbuf;
 }
 
@@ -396,10 +236,10 @@ draw_eject (cairo_t *cr,
         cairo_rel_line_to (cr, -width / 2, -tri_height);
         cairo_rel_line_to (cr, -width / 2, tri_height);
         cairo_close_path (cr);
-        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, FG_ALPHA);
+        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, GSD_OSD_WINDOW_FG_ALPHA);
         cairo_fill_preserve (cr);
 
-        cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, FG_ALPHA / 2);
+        cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, GSD_OSD_WINDOW_FG_ALPHA / 2);
         cairo_set_line_width (cr, 2);
         cairo_stroke (cr);
 }
@@ -458,12 +298,12 @@ draw_cross (cairo_t *cr,
         cairo_move_to (cr, cx, cy + size/2.0);
         cairo_rel_line_to (cr, size, -size);
 
-        cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, FG_ALPHA / 2);
+        cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, GSD_OSD_WINDOW_FG_ALPHA / 2);
         cairo_set_line_width (cr, 14);
         cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
         cairo_stroke_preserve (cr);
 
-        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, FG_ALPHA);
+        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, GSD_OSD_WINDOW_FG_ALPHA);
         cairo_set_line_width (cr, 10);
         cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
         cairo_stroke (cr);
@@ -497,10 +337,10 @@ draw_speaker (cairo_t *cr,
         cairo_line_to (cr, _x0, _y0);
         cairo_close_path (cr);
 
-        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, FG_ALPHA);
+        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, GSD_OSD_WINDOW_FG_ALPHA);
         cairo_fill_preserve (cr);
 
-        cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, FG_ALPHA / 2);
+        cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, GSD_OSD_WINDOW_FG_ALPHA / 2);
         cairo_set_line_width (cr, 2);
         cairo_stroke (cr);
 }
@@ -545,7 +385,7 @@ render_speaker (GsdMediaKeysWindow *window,
         }
 
         gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0);
-        cairo_paint_with_alpha (cr, FG_ALPHA);
+        cairo_paint_with_alpha (cr, GSD_OSD_WINDOW_FG_ALPHA);
 
         g_object_unref (pixbuf);
 
@@ -553,36 +393,6 @@ render_speaker (GsdMediaKeysWindow *window,
 }
 
 static void
-color_reverse (const GdkColor *a,
-               GdkColor       *b)
-{
-        gdouble red;
-        gdouble green;
-        gdouble blue;
-        gdouble h;
-        gdouble s;
-        gdouble v;
-
-        red = (gdouble) a->red / 65535.0;
-        green = (gdouble) a->green / 65535.0;
-        blue = (gdouble) a->blue / 65535.0;
-
-        gtk_rgb_to_hsv (red, green, blue, &h, &s, &v);
-
-        v = 0.5 + (0.5 - v);
-        if (v > 1.0)
-                v = 1.0;
-        else if (v < 0.0)
-                v = 0.0;
-
-        gtk_hsv_to_rgb (h, s, v, &red, &green, &blue);
-
-        b->red = red * 65535.0;
-        b->green = green * 65535.0;
-        b->blue = blue * 65535.0;
-}
-
-static void
 draw_volume_boxes (GsdMediaKeysWindow *window,
                    cairo_t            *cr,
                    double              percentage,
@@ -604,20 +414,20 @@ draw_volume_boxes (GsdMediaKeysWindow *window,
         style = gtk_widget_get_style (GTK_WIDGET (window));
 
         /* bar background */
-        color_reverse (&style->dark[GTK_STATE_NORMAL], &color);
+        gsd_osd_window_color_reverse (&style->dark[GTK_STATE_NORMAL], &color);
         r = (float)color.red / 65535.0;
         g = (float)color.green / 65535.0;
         b = (float)color.blue / 65535.0;
-        rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, width, height);
-        cairo_set_source_rgba (cr, r, g, b, FG_ALPHA / 2);
+        gsd_osd_window_draw_rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, width, height);
+        cairo_set_source_rgba (cr, r, g, b, GSD_OSD_WINDOW_FG_ALPHA / 2);
         cairo_fill_preserve (cr);
 
         /* bar border */
-        color_reverse (&style->light[GTK_STATE_NORMAL], &color);
+        gsd_osd_window_color_reverse (&style->light[GTK_STATE_NORMAL], &color);
         r = (float)color.red / 65535.0;
         g = (float)color.green / 65535.0;
         b = (float)color.blue / 65535.0;
-        cairo_set_source_rgba (cr, r, g, b, FG_ALPHA / 2);
+        cairo_set_source_rgba (cr, r, g, b, GSD_OSD_WINDOW_FG_ALPHA / 2);
         cairo_set_line_width (cr, 1);
         cairo_stroke (cr);
 
@@ -628,8 +438,8 @@ draw_volume_boxes (GsdMediaKeysWindow *window,
         r = (float)color.red / 65535.0;
         g = (float)color.green / 65535.0;
         b = (float)color.blue / 65535.0;
-        rounded_rectangle (cr, 1.0, _x0 + 0.5, _y0 + 0.5, height / 6 - 0.5, x1, height - 1);
-        cairo_set_source_rgba (cr, r, g, b, FG_ALPHA);
+        gsd_osd_window_draw_rounded_rectangle (cr, 1.0, _x0 + 0.5, _y0 + 0.5, height / 6 - 0.5, x1, height - 1);
+        cairo_set_source_rgba (cr, r, g, b, GSD_OSD_WINDOW_FG_ALPHA);
         cairo_fill (cr);
 }
 
@@ -763,7 +573,7 @@ render_custom (GsdMediaKeysWindow *window,
         }
 
         gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0);
-        cairo_paint_with_alpha (cr, FG_ALPHA);
+        cairo_paint_with_alpha (cr, GSD_OSD_WINDOW_FG_ALPHA);
 
         g_object_unref (pixbuf);
 
@@ -835,9 +645,11 @@ draw_action_custom (GsdMediaKeysWindow *window,
 }
 
 static void
-draw_action (GsdMediaKeysWindow *window,
-             cairo_t            *cr)
+gsd_media_keys_window_draw_when_composited (GsdOsdWindow *osd_window,
+                                            cairo_t      *cr)
 {
+        GsdMediaKeysWindow *window = GSD_MEDIA_KEYS_WINDOW (osd_window);
+
         switch (window->priv->action) {
         case GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME:
                 draw_action_volume (window, cr);
@@ -850,153 +662,16 @@ draw_action (GsdMediaKeysWindow *window,
         }
 }
 
-static gboolean
-on_expose_event (GtkWidget          *widget,
-                 GdkEventExpose     *event,
-                 GsdMediaKeysWindow *window)
-{
-        cairo_t         *context;
-        cairo_t         *cr;
-        cairo_surface_t *surface;
-        int              width;
-        int              height;
-        GtkStyle        *style;
-        GdkColor         color;
-        double           r, g, b;
-
-        context = gdk_cairo_create (gtk_widget_get_window (widget));
-
-        style = gtk_widget_get_style (widget);
-        cairo_set_operator (context, CAIRO_OPERATOR_SOURCE);
-        gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
-
-        surface = cairo_surface_create_similar (cairo_get_target (context),
-                                                CAIRO_CONTENT_COLOR_ALPHA,
-                                                width,
-                                                height);
-
-        if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
-                goto done;
-        }
-
-        cr = cairo_create (surface);
-        if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
-                goto done;
-        }
-        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
-        cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
-        cairo_paint (cr);
-
-        /* draw a box */
-        rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1);
-        color_reverse (&style->bg[GTK_STATE_NORMAL], &color);
-        r = (float)color.red / 65535.0;
-        g = (float)color.green / 65535.0;
-        b = (float)color.blue / 65535.0;
-        cairo_set_source_rgba (cr, r, g, b, BG_ALPHA);
-        cairo_fill_preserve (cr);
-
-        color_reverse (&style->text_aa[GTK_STATE_NORMAL], &color);
-        r = (float)color.red / 65535.0;
-        g = (float)color.green / 65535.0;
-        b = (float)color.blue / 65535.0;
-        cairo_set_source_rgba (cr, r, g, b, BG_ALPHA / 2);
-        cairo_set_line_width (cr, 1);
-        cairo_stroke (cr);
-
-        /* draw action */
-        draw_action (window, cr);
-
-        cairo_destroy (cr);
-
-        /* Make sure we have a transparent background */
-        cairo_rectangle (context, 0, 0, width, height);
-        cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0);
-        cairo_fill (context);
-
-        cairo_set_source_surface (context, surface, 0, 0);
-        cairo_paint_with_alpha (context, window->priv->fade_out_alpha);
-
- done:
-        if (surface != NULL) {
-                cairo_surface_destroy (surface);
-        }
-        cairo_destroy (context);
-
-        return FALSE;
-}
-
-static void
-gsd_media_keys_window_real_show (GtkWidget *widget)
-{
-        GsdMediaKeysWindow *window;
-
-        if (GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->show) {
-                GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->show (widget);
-        }
-
-        window = GSD_MEDIA_KEYS_WINDOW (widget);
-        remove_hide_timeout (window);
-        add_hide_timeout (window);
-}
-
-static void
-gsd_media_keys_window_real_hide (GtkWidget *widget)
-{
-        GsdMediaKeysWindow *window;
-
-        if (GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->hide) {
-                GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->hide (widget);
-        }
-
-        window = GSD_MEDIA_KEYS_WINDOW (widget);
-        remove_hide_timeout (window);
-}
-
-static void
-gsd_media_keys_window_real_realize (GtkWidget *widget)
-{
-        cairo_region_t *region;
-        GdkScreen *screen;
-        GdkVisual *visual;
-
-        screen = gtk_widget_get_screen (widget);
-        visual = gdk_screen_get_rgba_visual (screen);
-        if (visual == NULL) {
-                visual = gdk_screen_get_system_visual (screen);
-        }
-
-        gtk_widget_set_visual (widget, visual);
-
-        if (GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->realize) {
-                GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->realize (widget);
-        }
-
-        /* make the whole window ignore events */
-        region = cairo_region_create ();
-        gtk_widget_input_shape_combine_region (widget, region);
-        cairo_region_destroy (region);
-}
-
 static void
 gsd_media_keys_window_class_init (GsdMediaKeysWindowClass *klass)
 {
-        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+        GsdOsdWindowClass *osd_window_class = GSD_OSD_WINDOW_CLASS (klass);
 
-        widget_class->show = gsd_media_keys_window_real_show;
-        widget_class->hide = gsd_media_keys_window_real_hide;
-        widget_class->realize = gsd_media_keys_window_real_realize;
+        osd_window_class->draw_when_composited = gsd_media_keys_window_draw_when_composited;
 
         g_type_class_add_private (klass, sizeof (GsdMediaKeysWindowPrivate));
 }
 
-gboolean
-gsd_media_keys_window_is_valid (GsdMediaKeysWindow *window)
-{
-        GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window));
-        return gdk_screen_is_composited (screen) == window->priv->is_composited;
-}
-
 static void
 gsd_media_keys_window_init (GsdMediaKeysWindow *window)
 {
@@ -1006,29 +681,10 @@ gsd_media_keys_window_init (GsdMediaKeysWindow *window)
 
         screen = gtk_widget_get_screen (GTK_WIDGET (window));
 
-        window->priv->is_composited = gdk_screen_is_composited (screen);
-
-        if (window->priv->is_composited) {
-                gdouble scalew, scaleh, scale;
-                gint size;
-
-                gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
-                gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
-
-                /* assume 130x130 on a 640x480 display and scale from there */
-                scalew = gdk_screen_get_width (screen) / 640.0;
-                scaleh = gdk_screen_get_height (screen) / 480.0;
-                scale = MIN (scalew, scaleh);
-                size = 130 * MAX (1, scale);
-
-                gtk_window_set_default_size (GTK_WINDOW (window), size, size);
-                g_signal_connect (window, "expose-event", G_CALLBACK (on_expose_event), window);
-
-                window->priv->fade_out_alpha = 1.0;
-        } else {
+        if (!gsd_osd_window_is_composited (GSD_OSD_WINDOW (window))) {
                 GtkBuilder *builder;
-                const gchar *objects[] = {"acme_frame", NULL};
-                GtkWidget *frame;
+                const gchar *objects[] = {"acme_box", NULL};
+                GtkWidget *box;
 
                 builder = gtk_builder_new ();
                 gtk_builder_add_objects_from_file (builder,
@@ -1038,16 +694,15 @@ gsd_media_keys_window_init (GsdMediaKeysWindow *window)
 
                 window->priv->image = GTK_IMAGE (gtk_builder_get_object (builder, "acme_image"));
                 window->priv->progress = GTK_WIDGET (gtk_builder_get_object (builder, "acme_volume_progressbar"));
-                frame = GTK_WIDGET (gtk_builder_get_object (builder,
-                                                            "acme_frame"));
+                box = GTK_WIDGET (gtk_builder_get_object (builder, "acme_box"));
 
-                if (frame != NULL) {
-                        gtk_container_add (GTK_CONTAINER (window), frame);
-                        gtk_widget_show_all (frame);
+                if (box != NULL) {
+                        gtk_container_add (GTK_CONTAINER (window), box);
+                        gtk_widget_show_all (box);
                 }
 
                 /* The builder needs to stay alive until the window
-                   takes ownership of the frame (and its children)  */
+                   takes ownership of the box (and its children)  */
                 g_object_unref (builder);
         }
 }
@@ -1055,15 +710,5 @@ gsd_media_keys_window_init (GsdMediaKeysWindow *window)
 GtkWidget *
 gsd_media_keys_window_new (void)
 {
-        GObject *object;
-
-        object = g_object_new (GSD_TYPE_MEDIA_KEYS_WINDOW,
-                               "type", GTK_WINDOW_POPUP,
-                               "type-hint", GDK_WINDOW_TYPE_HINT_NOTIFICATION,
-                               "skip-taskbar-hint", TRUE,
-                               "skip-pager-hint", TRUE,
-                               "focus-on-map", FALSE,
-                               NULL);
-
-        return GTK_WIDGET (object);
+        return g_object_new (GSD_TYPE_MEDIA_KEYS_WINDOW, NULL);
 }
diff --git a/src/gsd-media-keys-window.h b/src/gsd-media-keys-window.h
index 9c74bf5..7fbad7b 100644
--- a/src/gsd-media-keys-window.h
+++ b/src/gsd-media-keys-window.h
@@ -3,17 +3,18 @@
  * Copyright (C) 2006 William Jon McCann <mccann jhu edu>
  *
  * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2, or (at your option) any later version.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU Lesser General Public License for more
+ * details.
  *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  *
@@ -25,6 +26,8 @@
 #include <glib-object.h>
 #include <gtk/gtk.h>
 
+#include "gsd-osd-window.h"
+
 G_BEGIN_DECLS
 
 #define GSD_TYPE_MEDIA_KEYS_WINDOW            (gsd_media_keys_window_get_type ())
@@ -38,13 +41,13 @@ typedef struct GsdMediaKeysWindowClass              GsdMediaKeysWindowClass;
 typedef struct GsdMediaKeysWindowPrivate            GsdMediaKeysWindowPrivate;
 
 struct GsdMediaKeysWindow {
-        GtkWindow                   parent;
+        GsdOsdWindow parent;
 
         GsdMediaKeysWindowPrivate  *priv;
 };
 
 struct GsdMediaKeysWindowClass {
-        GtkWindowClass parent_class;
+        GsdOsdWindowClass parent_class;
 };
 
 typedef enum {
diff --git a/src/gsd-osd-window.c b/src/gsd-osd-window.c
new file mode 100644
index 0000000..64719dd
--- /dev/null
+++ b/src/gsd-osd-window.c
@@ -0,0 +1,561 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * On-screen-display (OSD) window for gnome-settings-daemon's plugins
+ *
+ * Copyright (C) 2006-2007 William Jon McCann <mccann jhu edu> 
+ * Copyright (C) 2009 Novell, Inc
+ *
+ * Authors:
+ *   William Jon McCann <mccann jhu edu>
+ *   Federico Mena-Quintero <federico novell com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "gsd-osd-window.h"
+
+#define DIALOG_TIMEOUT 2000     /* dialog timeout in ms */
+#define DIALOG_FADE_TIMEOUT 1500 /* timeout before fade starts */
+#define FADE_TIMEOUT 10        /* timeout in ms between each frame of the fade */
+
+#define BG_ALPHA 0.75
+
+#define GSD_OSD_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_OSD_WINDOW, GsdOsdWindowPrivate))
+
+struct GsdOsdWindowPrivate
+{
+        guint                    is_composited : 1;
+        guint                    hide_timeout_id;
+        guint                    fade_timeout_id;
+        double                   fade_out_alpha;
+};
+
+enum {
+        DRAW_WHEN_COMPOSITED,
+        LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GsdOsdWindow, gsd_osd_window, GTK_TYPE_WINDOW)
+
+static gboolean
+fade_timeout (GsdOsdWindow *window)
+{
+        if (window->priv->fade_out_alpha <= 0.0) {
+                gtk_widget_hide (GTK_WIDGET (window));
+
+                /* Reset it for the next time */
+                window->priv->fade_out_alpha = 1.0;
+                window->priv->fade_timeout_id = 0;
+
+                return FALSE;
+        } else {
+                GdkRectangle rect;
+                GtkWidget *win = GTK_WIDGET (window);
+                GtkAllocation allocation;
+
+                window->priv->fade_out_alpha -= 0.10;
+
+                rect.x = 0;
+                rect.y = 0;
+                gtk_widget_get_allocation (win, &allocation);
+                rect.width = allocation.width;
+                rect.height = allocation.height;
+
+                gtk_widget_realize (win);
+                gdk_window_invalidate_rect (gtk_widget_get_window (win), &rect, FALSE);
+        }
+
+        return TRUE;
+}
+
+static gboolean
+hide_timeout (GsdOsdWindow *window)
+{
+        if (window->priv->is_composited) {
+                window->priv->hide_timeout_id = 0;
+                window->priv->fade_timeout_id = g_timeout_add (FADE_TIMEOUT,
+                                                               (GSourceFunc) fade_timeout,
+                                                               window);
+        } else {
+                gtk_widget_hide (GTK_WIDGET (window));
+        }
+
+        return FALSE;
+}
+
+static void
+remove_hide_timeout (GsdOsdWindow *window)
+{
+        if (window->priv->hide_timeout_id != 0) {
+                g_source_remove (window->priv->hide_timeout_id);
+                window->priv->hide_timeout_id = 0;
+        }
+
+        if (window->priv->fade_timeout_id != 0) {
+                g_source_remove (window->priv->fade_timeout_id);
+                window->priv->fade_timeout_id = 0;
+                window->priv->fade_out_alpha = 1.0;
+        }
+}
+
+static void
+add_hide_timeout (GsdOsdWindow *window)
+{
+        int timeout;
+
+        if (window->priv->is_composited) {
+                timeout = DIALOG_FADE_TIMEOUT;
+        } else {
+                timeout = DIALOG_TIMEOUT;
+        }
+        window->priv->hide_timeout_id = g_timeout_add (timeout,
+                                                       (GSourceFunc) hide_timeout,
+                                                       window);
+}
+
+void
+gsd_osd_window_draw_rounded_rectangle (cairo_t* cr,
+                                       gdouble  aspect,
+                                       gdouble  x,
+                                       gdouble  y,
+                                       gdouble  corner_radius,
+                                       gdouble  width,
+                                       gdouble  height)
+{
+        gdouble radius = corner_radius / aspect;
+
+        cairo_move_to (cr, x + radius, y);
+
+        cairo_line_to (cr,
+                       x + width - radius,
+                       y);
+        cairo_arc (cr,
+                   x + width - radius,
+                   y + radius,
+                   radius,
+                   -90.0f * G_PI / 180.0f,
+                   0.0f * G_PI / 180.0f);
+        cairo_line_to (cr,
+                       x + width,
+                       y + height - radius);
+        cairo_arc (cr,
+                   x + width - radius,
+                   y + height - radius,
+                   radius,
+                   0.0f * G_PI / 180.0f,
+                   90.0f * G_PI / 180.0f);
+        cairo_line_to (cr,
+                       x + radius,
+                       y + height);
+        cairo_arc (cr,
+                   x + radius,
+                   y + height - radius,
+                   radius,
+                   90.0f * G_PI / 180.0f,
+                   180.0f * G_PI / 180.0f);
+        cairo_line_to (cr,
+                       x,
+                       y + radius);
+        cairo_arc (cr,
+                   x + radius,
+                   y + radius,
+                   radius,
+                   180.0f * G_PI / 180.0f,
+                   270.0f * G_PI / 180.0f);
+        cairo_close_path (cr);
+}
+
+void
+gsd_osd_window_color_reverse (const GdkColor *a,
+                              GdkColor       *b)
+{
+        gdouble red;
+        gdouble green;
+        gdouble blue;
+        gdouble h;
+        gdouble s;
+        gdouble v;
+
+        red = (gdouble) a->red / 65535.0;
+        green = (gdouble) a->green / 65535.0;
+        blue = (gdouble) a->blue / 65535.0;
+
+        gtk_rgb_to_hsv (red, green, blue, &h, &s, &v);
+
+        v = 0.5 + (0.5 - v);
+        if (v > 1.0)
+                v = 1.0;
+        else if (v < 0.0)
+                v = 0.0;
+
+        gtk_hsv_to_rgb (h, s, v, &red, &green, &blue);
+
+        b->red = red * 65535.0;
+        b->green = green * 65535.0;
+        b->blue = blue * 65535.0;
+}
+
+/* This is our draw handler when the window is in a compositing manager.
+ * We draw everything by hand, using Cairo, so that we can have a nice
+ * transparent/rounded look.
+ */
+static void
+draw_when_composited (GtkWidget *widget, cairo_t *context)
+{
+        GsdOsdWindow    *window;
+        cairo_t         *cr;
+        cairo_surface_t *surface;
+        int              width;
+        int              height;
+        GtkStyle        *style;
+        GdkColor         color;
+        double           r, g, b;
+
+        window = GSD_OSD_WINDOW (widget);
+
+        style = gtk_widget_get_style (widget);
+        cairo_set_operator (context, CAIRO_OPERATOR_SOURCE);
+        gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
+
+        surface = cairo_surface_create_similar (cairo_get_target (context),
+                                                CAIRO_CONTENT_COLOR_ALPHA,
+                                                width,
+                                                height);
+
+        if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
+                goto done;
+        }
+
+        cr = cairo_create (surface);
+        if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
+                goto done;
+        }
+        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
+        cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+        cairo_paint (cr);
+
+        /* draw a box */
+        gsd_osd_window_draw_rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1);
+        gsd_osd_window_color_reverse (&style->bg[GTK_STATE_NORMAL], &color);
+        r = (float)color.red / 65535.0;
+        g = (float)color.green / 65535.0;
+        b = (float)color.blue / 65535.0;
+        cairo_set_source_rgba (cr, r, g, b, BG_ALPHA);
+        cairo_fill_preserve (cr);
+
+        gsd_osd_window_color_reverse (&style->text_aa[GTK_STATE_NORMAL], &color);
+        r = (float)color.red / 65535.0;
+        g = (float)color.green / 65535.0;
+        b = (float)color.blue / 65535.0;
+        cairo_set_source_rgba (cr, r, g, b, BG_ALPHA / 2);
+        cairo_set_line_width (cr, 1);
+        cairo_stroke (cr);
+
+        g_signal_emit (window, signals[DRAW_WHEN_COMPOSITED], 0, cr);
+
+        cairo_destroy (cr);
+
+        /* Make sure we have a transparent background */
+        cairo_rectangle (context, 0, 0, width, height);
+        cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0);
+        cairo_fill (context);
+
+        cairo_set_source_surface (context, surface, 0, 0);
+        cairo_paint_with_alpha (context, window->priv->fade_out_alpha);
+
+ done:
+        if (surface != NULL) {
+                cairo_surface_destroy (surface);
+        }
+}
+
+/* This is our draw handler when the window is *not* in a compositing manager.
+ * We just draw a rectangular frame by hand.  We do this with hardcoded drawing code,
+ * instead of GtkFrame, to avoid changing the window's internal widget hierarchy:  in
+ * either case (composited or non-composited), callers can assume that this works
+ * identically to a GtkWindow without any intermediate widgetry.
+ */
+static void
+draw_when_not_composited (GtkWidget *widget, cairo_t *cr)
+{
+        GsdOsdWindow *window;
+        int width;
+        int height;
+
+        window = GSD_OSD_WINDOW (widget);
+
+        width = gtk_widget_get_allocated_width (widget);
+        height = gtk_widget_get_allocated_width (widget);
+
+        gtk_paint_shadow (gtk_widget_get_style (widget),
+                          cr,
+                          gtk_widget_get_state (widget),
+                          GTK_SHADOW_OUT,
+                          widget,
+                          NULL, /* NULL detail -> themes should use the GsdOsdWindow widget name, probably */
+                          0,
+                          0,
+                          width,
+                          height);
+}
+
+static gboolean
+gsd_osd_window_draw (GtkWidget *widget,
+                     cairo_t   *cr)
+{
+        GsdOsdWindow *window;
+        GtkWidget *child;
+
+        window = GSD_OSD_WINDOW (widget);
+
+        if (window->priv->is_composited)
+                draw_when_composited (widget, cr);
+        else
+                draw_when_not_composited (widget, cr);
+
+        child = gtk_bin_get_child (GTK_BIN (window));
+        if (child)
+                gtk_container_propagate_draw (GTK_CONTAINER (window), child, cr);
+
+        return FALSE;
+}
+
+static void
+gsd_osd_window_real_show (GtkWidget *widget)
+{
+        GsdOsdWindow *window;
+
+        if (GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->show) {
+                GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->show (widget);
+        }
+
+        window = GSD_OSD_WINDOW (widget);
+        remove_hide_timeout (window);
+        add_hide_timeout (window);
+}
+
+static void
+gsd_osd_window_real_hide (GtkWidget *widget)
+{
+        GsdOsdWindow *window;
+
+        if (GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->hide) {
+                GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->hide (widget);
+        }
+
+        window = GSD_OSD_WINDOW (widget);
+        remove_hide_timeout (window);
+}
+
+static void
+gsd_osd_window_real_realize (GtkWidget *widget)
+{
+        cairo_region_t *region;
+        GdkScreen *screen;
+        GdkVisual *visual;
+
+        screen = gtk_widget_get_screen (widget);
+        visual = gdk_screen_get_rgba_visual (screen);
+        if (visual == NULL) {
+                visual = gdk_screen_get_system_visual (screen);
+        }
+
+        gtk_widget_set_visual (widget, visual);
+
+        if (GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->realize) {
+                GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->realize (widget);
+        }
+
+        /* make the whole window ignore events */
+        region = cairo_region_create ();
+        gtk_widget_input_shape_combine_region (widget, region);
+        cairo_region_destroy (region);
+}
+
+static void
+gsd_osd_window_style_set (GtkWidget *widget,
+                          GtkStyle  *previous_style)
+{
+        GtkStyle *style;
+
+        GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->style_set (widget, previous_style);
+
+        /* We set our border width to 12 (per the GNOME standard), plus the
+         * thickness of the frame that we draw in our draw handler.  This will
+         * make our child be 12 pixels away from the frame.
+         */
+
+        style = gtk_widget_get_style (widget);
+        gtk_container_set_border_width (GTK_CONTAINER (widget), 12 + MAX (style->xthickness, style->ythickness));
+}
+
+static void
+gsd_osd_window_size_request (GtkWidget      *widget,
+                             GtkRequisition *requisition)
+{
+        GtkStyle *style;
+
+        GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->size_request (widget, requisition);
+
+        /* See the comment in gsd_osd_window_style_set() for why we add the thickness here */
+
+        style = gtk_widget_get_style (widget);
+
+        requisition->width  += style->xthickness;
+        requisition->height += style->ythickness;
+}
+
+static GObject *
+gsd_osd_window_constructor (GType                  type,
+                            guint                  n_construct_properties,
+                            GObjectConstructParam *construct_params)
+{
+        GObject *object;
+
+        object = G_OBJECT_CLASS (gsd_osd_window_parent_class)->constructor (type, n_construct_properties, construct_params);
+
+        g_object_set (object,
+                      "type", GTK_WINDOW_POPUP,
+                      "type-hint", GDK_WINDOW_TYPE_HINT_NOTIFICATION,
+                      "skip-taskbar-hint", TRUE,
+                      "skip-pager-hint", TRUE,
+                      "focus-on-map", FALSE,
+                      NULL);
+
+        return object;
+}
+
+static void
+gsd_osd_window_class_init (GsdOsdWindowClass *klass)
+{
+        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+        gobject_class->constructor = gsd_osd_window_constructor;
+
+        widget_class->show = gsd_osd_window_real_show;
+        widget_class->hide = gsd_osd_window_real_hide;
+        widget_class->realize = gsd_osd_window_real_realize;
+        widget_class->style_set = gsd_osd_window_style_set;
+        widget_class->size_request = gsd_osd_window_size_request;
+        widget_class->draw = gsd_osd_window_draw;
+
+        signals[DRAW_WHEN_COMPOSITED] = g_signal_new ("draw-when-composited",
+                                                      G_TYPE_FROM_CLASS (gobject_class),
+                                                      G_SIGNAL_RUN_FIRST,
+                                                      G_STRUCT_OFFSET (GsdOsdWindowClass, draw_when_composited),
+                                                      NULL, NULL,
+                                                      g_cclosure_marshal_VOID__POINTER,
+                                                      G_TYPE_NONE, 1,
+                                                      G_TYPE_POINTER);
+
+        g_type_class_add_private (klass, sizeof (GsdOsdWindowPrivate));
+}
+
+/**
+ * gsd_osd_window_is_composited:
+ * @window: a #GsdOsdWindow
+ *
+ * Return value: whether the window was created on a composited screen.
+ */
+gboolean
+gsd_osd_window_is_composited (GsdOsdWindow *window)
+{
+        return window->priv->is_composited;
+}
+
+/**
+ * gsd_osd_window_is_valid:
+ * @window: a #GsdOsdWindow
+ *
+ * Return value: TRUE if the @window's idea of being composited matches whether
+ * its current screen is actually composited.
+ */
+gboolean
+gsd_osd_window_is_valid (GsdOsdWindow *window)
+{
+        GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window));
+        return gdk_screen_is_composited (screen) == window->priv->is_composited;
+}
+
+static void
+gsd_osd_window_init (GsdOsdWindow *window)
+{
+        GdkScreen *screen;
+
+        window->priv = GSD_OSD_WINDOW_GET_PRIVATE (window);
+
+        screen = gtk_widget_get_screen (GTK_WIDGET (window));
+
+        window->priv->is_composited = gdk_screen_is_composited (screen);
+
+        if (window->priv->is_composited) {
+                gdouble scalew, scaleh, scale;
+                gint size;
+
+                gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
+                gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
+
+                /* assume 130x130 on a 640x480 display and scale from there */
+                scalew = gdk_screen_get_width (screen) / 640.0;
+                scaleh = gdk_screen_get_height (screen) / 480.0;
+                scale = MIN (scalew, scaleh);
+                size = 130 * MAX (1, scale);
+
+                gtk_window_set_default_size (GTK_WINDOW (window), size, size);
+
+                window->priv->fade_out_alpha = 1.0;
+        } else {
+                gtk_container_set_border_width (GTK_CONTAINER (window), 12);
+        }
+}
+
+GtkWidget *
+gsd_osd_window_new (void)
+{
+        return g_object_new (GSD_TYPE_OSD_WINDOW, NULL);
+}
+
+/**
+ * gsd_osd_window_update_and_hide:
+ * @window: a #GsdOsdWindow
+ *
+ * Queues the @window for immediate drawing, and queues a timer to hide the window.
+ */
+void
+gsd_osd_window_update_and_hide (GsdOsdWindow *window)
+{
+        remove_hide_timeout (window);
+        add_hide_timeout (window);
+
+        if (window->priv->is_composited) {
+                gtk_widget_queue_draw (GTK_WIDGET (window));
+        }
+}
diff --git a/src/gsd-osd-window.h b/src/gsd-osd-window.h
new file mode 100644
index 0000000..1cdab4c
--- /dev/null
+++ b/src/gsd-osd-window.h
@@ -0,0 +1,94 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8 -*-
+ *
+ * On-screen-display (OSD) window for gnome-settings-daemon's plugins
+ *
+ * Copyright (C) 2006 William Jon McCann <mccann jhu edu> 
+ * Copyright (C) 2009 Novell, Inc
+ *
+ * Authors:
+ *   William Jon McCann <mccann jhu edu>
+ *   Federico Mena-Quintero <federico novell com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/* GsdOsdWindow is an "on-screen-display" window (OSD).  It is the cute,
+ * semi-transparent, curved popup that appears when you press a hotkey global to
+ * the desktop, such as to change the volume, switch your monitor's parameters,
+ * etc.
+ *
+ * You can create a GsdOsdWindow and use it as a normal GtkWindow.  It will
+ * automatically center itself, figure out if it needs to be composited, etc.
+ * Just pack your widgets in it, sit back, and enjoy the ride.
+ */
+
+#ifndef GSD_OSD_WINDOW_H
+#define GSD_OSD_WINDOW_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/* Alpha value to be used for foreground objects drawn in an OSD window */
+#define GSD_OSD_WINDOW_FG_ALPHA 1.0
+
+#define GSD_TYPE_OSD_WINDOW            (gsd_osd_window_get_type ())
+#define GSD_OSD_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),  GSD_TYPE_OSD_WINDOW, GsdOsdWindow))
+#define GSD_OSD_WINDOW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),   GSD_TYPE_OSD_WINDOW, GsdOsdWindowClass))
+#define GSD_IS_OSD_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),  GSD_TYPE_OSD_WINDOW))
+#define GSD_IS_OSD_WINDOW_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS ((klass), GSD_TYPE_OSD_WINDOW))
+#define GSD_OSD_WINDOW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GSD_TYPE_OSD_WINDOW, GsdOsdWindowClass))
+
+typedef struct GsdOsdWindow                   GsdOsdWindow;
+typedef struct GsdOsdWindowClass              GsdOsdWindowClass;
+typedef struct GsdOsdWindowPrivate            GsdOsdWindowPrivate;
+
+struct GsdOsdWindow {
+        GtkWindow                   parent;
+
+        GsdOsdWindowPrivate  *priv;
+};
+
+struct GsdOsdWindowClass {
+        GtkWindowClass parent_class;
+
+        void (* draw_when_composited) (GsdOsdWindow *window, cairo_t *cr);
+};
+
+GType                 gsd_osd_window_get_type          (void);
+
+GtkWidget *           gsd_osd_window_new               (void);
+gboolean              gsd_osd_window_is_composited     (GsdOsdWindow      *window);
+gboolean              gsd_osd_window_is_valid          (GsdOsdWindow      *window);
+void                  gsd_osd_window_update_and_hide   (GsdOsdWindow      *window);
+
+void                  gsd_osd_window_draw_rounded_rectangle (cairo_t *cr,
+                                                             gdouble  aspect,
+                                                             gdouble  x,
+                                                             gdouble  y,
+                                                             gdouble  corner_radius,
+                                                             gdouble  width,
+                                                             gdouble  height);
+
+void                  gsd_osd_window_color_reverse          (const GdkColor *a,
+                                                             GdkColor       *b);
+
+G_END_DECLS
+
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]