summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@novell.com>2010-01-05 14:19:01 -0600
committerFederico Mena Quintero <federico@novell.com>2010-01-05 14:19:01 -0600
commit641c6d86a599458f237701ee48de051f4582ba95 (patch)
treec382574fc678cc26aecbc1d9ecfcae64393af335
parentd663db1b852373a93694dad9c6e0c843ffee94ce (diff)
parent0bea6c511c43149ee13ef39ae6db4373b809c832 (diff)
downloadgnome-settings-daemon-641c6d86a599458f237701ee48de051f4582ba95.tar.gz
Merge the reusable-osd-window branch.
Several plugins need to use an on-screen-display (OSD) window like the media-keys plugin does. However, the media-keys plugin had a heavily hard-coded OSD window for its own purposes. This branch takes the basis of GsdMediaKeysWindow and turns it into a generic GsdOsdWindow. You can use that widget as a normal GtkWindow and pack your widgets in it. The GsdOsdWindow draws itself as a nice, semi-opaque, rounded rectangle and takes care of hiding itself after a timeout after it is shown. Now, GsdMediaKeysWindow is simply a subclass of GsdOsdWindow that knows the specifics of the media-keys plugin. The GsdOsdWindow will get used by the XRANDR plugin and hopefully others if they need it. Merge branch 'reusable-osd-window'
-rw-r--r--plugins/common/Makefile.am4
-rw-r--r--plugins/common/gsd-osd-window.c569
-rw-r--r--plugins/common/gsd-osd-window.h94
-rw-r--r--plugins/media-keys/Makefile.am2
-rw-r--r--plugins/media-keys/acme.ui44
-rw-r--r--plugins/media-keys/gsd-media-keys-manager.c2
-rw-r--r--plugins/media-keys/gsd-media-keys-window.c432
-rw-r--r--plugins/media-keys/gsd-media-keys-window.h6
8 files changed, 730 insertions, 423 deletions
diff --git a/plugins/common/Makefile.am b/plugins/common/Makefile.am
index 4c90114c..03d4bc8e 100644
--- a/plugins/common/Makefile.am
+++ b/plugins/common/Makefile.am
@@ -5,7 +5,9 @@ libcommon_la_SOURCES = \
eggaccelerators.c \
eggaccelerators.h \
gsd-keygrab.c \
- gsd-keygrab.h
+ gsd-keygrab.h \
+ gsd-osd-window.c \
+ gsd-osd-window.h
libcommon_la_CPPFLAGS = \
$(AM_CPPFLAGS)
diff --git a/plugins/common/gsd-osd-window.c b/plugins/common/gsd-osd-window.c
new file mode 100644
index 00000000..5fa2d79a
--- /dev/null
+++ b/plugins/common/gsd-osd-window.c
@@ -0,0 +1,569 @@
+/* -*- 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 "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 {
+ EXPOSE_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;
+
+ 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 expose-event 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
+expose_when_composited (GtkWidget *widget, GdkEventExpose *event)
+{
+ GsdOsdWindow *window;
+ cairo_t *context;
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ int width;
+ int height;
+ GtkStyle *style;
+ GdkColor color;
+ double r, g, b;
+
+ window = GSD_OSD_WINDOW (widget);
+
+ 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 */
+ 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[EXPOSE_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);
+ }
+ cairo_destroy (context);
+}
+
+/* This is our expose-event 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
+expose_when_not_composited (GtkWidget *widget, GdkEventExpose *event)
+{
+ GsdOsdWindow *window;
+
+ window = GSD_OSD_WINDOW (widget);
+
+ gtk_paint_shadow (gtk_widget_get_style (widget),
+ gtk_widget_get_window (widget),
+ gtk_widget_get_state (widget),
+ GTK_SHADOW_OUT,
+ &event->area,
+ widget,
+ NULL, /* NULL detail -> themes should use the GsdOsdWindow widget name, probably */
+ 0,
+ 0,
+ widget->allocation.width,
+ widget->allocation.height);
+}
+
+static gboolean
+gsd_osd_window_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ GsdOsdWindow *window;
+ GtkWidget *child;
+
+ window = GSD_OSD_WINDOW (widget);
+
+ if (window->priv->is_composited)
+ expose_when_composited (widget, event);
+ else
+ expose_when_not_composited (widget, event);
+
+ child = gtk_bin_get_child (GTK_BIN (window));
+ if (child)
+ gtk_container_propagate_expose (GTK_CONTAINER (window), child, event);
+
+ 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)
+{
+ GdkColormap *colormap;
+ GtkAllocation allocation;
+ GdkBitmap *mask;
+ cairo_t *cr;
+
+ colormap = gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget));
+
+ if (colormap != NULL) {
+ gtk_widget_set_colormap (widget, colormap);
+ }
+
+ if (GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->realize) {
+ GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->realize (widget);
+ }
+
+ gtk_widget_get_allocation (widget, &allocation);
+ mask = gdk_pixmap_new (gtk_widget_get_window (widget),
+ allocation.width,
+ allocation.height,
+ 1);
+ cr = gdk_cairo_create (mask);
+
+ cairo_set_source_rgba (cr, 1., 1., 1., 0.);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ /* make the whole window ignore events */
+ gdk_window_input_shape_combine_mask (gtk_widget_get_window (widget), mask, 0, 0);
+ g_object_unref (mask);
+ cairo_destroy (cr);
+}
+
+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 expose 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->expose_event = gsd_osd_window_expose_event;
+
+ signals[EXPOSE_WHEN_COMPOSITED] = g_signal_new ("expose-when-composited",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GsdOsdWindowClass, expose_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/plugins/common/gsd-osd-window.h b/plugins/common/gsd-osd-window.h
new file mode 100644
index 00000000..40bfa2b3
--- /dev/null
+++ b/plugins/common/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 (* expose_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
diff --git a/plugins/media-keys/Makefile.am b/plugins/media-keys/Makefile.am
index b662da8c..4447de44 100644
--- a/plugins/media-keys/Makefile.am
+++ b/plugins/media-keys/Makefile.am
@@ -78,6 +78,7 @@ test_media_window_SOURCES = \
test_media_window_CPPFLAGS = \
-I$(top_srcdir)/gnome-settings-daemon \
+ -I$(top_srcdir)/plugins/common \
-I$(top_srcdir)/plugins/media-keys/cut-n-paste \
-DDATADIR=\""$(datadir)"\" \
-DPIXMAPDIR=\""$(pkgdatadir)"\" \
@@ -90,6 +91,7 @@ test_media_window_CFLAGS = \
$(AM_CFLAGS)
test_media_window_LDADD = \
+ $(top_builddir)/plugins/common/libcommon.la \
$(SETTINGS_DAEMON_LIBS) \
$(SETTINGS_PLUGIN_LIBS) \
$(XF86MISC_LIBS) \
diff --git a/plugins/media-keys/acme.ui b/plugins/media-keys/acme.ui
index 3222ecb0..e0457ed5 100644
--- a/plugins/media-keys/acme.ui
+++ b/plugins/media-keys/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/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
index 5b0290a2..8e0d3ddb 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -261,7 +261,7 @@ static void
dialog_init (GsdMediaKeysManager *manager)
{
if (manager->priv->dialog != NULL
- && !gsd_media_keys_window_is_valid (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog))) {
+ && !gsd_osd_window_is_valid (GSD_OSD_WINDOW (manager->priv->dialog))) {
gtk_widget_destroy (manager->priv->dialog);
manager->priv->dialog = NULL;
}
diff --git a/plugins/media-keys/gsd-media-keys-window.c b/plugins/media-keys/gsd-media-keys-window.c
index 9b8b36e7..4b736e9c 100644
--- a/plugins/media-keys/gsd-media-keys-window.c
+++ b/plugins/media-keys/gsd-media-keys-window.c
@@ -32,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;
@@ -58,93 +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;
-
- 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,
@@ -174,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);
@@ -196,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;
@@ -217,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 {
@@ -239,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));
}
}
@@ -260,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));
}
}
@@ -288,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,
@@ -398,10 +249,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);
}
@@ -460,12 +311,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);
@@ -499,10 +350,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);
}
@@ -547,7 +398,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);
@@ -555,36 +406,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,
@@ -606,20 +427,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);
@@ -630,8 +451,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);
}
@@ -765,7 +586,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);
@@ -837,9 +658,11 @@ draw_action_custom (GsdMediaKeysWindow *window,
}
static void
-draw_action (GsdMediaKeysWindow *window,
- cairo_t *cr)
+gsd_media_keys_window_expose_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);
@@ -852,163 +675,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)
-{
- GdkColormap *colormap;
- GtkAllocation allocation;
- GdkBitmap *mask;
- cairo_t *cr;
-
- colormap = gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget));
-
- if (colormap != NULL) {
- gtk_widget_set_colormap (widget, colormap);
- }
-
- if (GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->realize) {
- GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->realize (widget);
- }
-
- gtk_widget_get_allocation (widget, &allocation);
- mask = gdk_pixmap_new (gtk_widget_get_window (widget),
- allocation.width,
- allocation.height,
- 1);
- cr = gdk_cairo_create (mask);
-
- cairo_set_source_rgba (cr, 1., 1., 1., 0.);
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint (cr);
-
- /* make the whole window ignore events */
- gdk_window_input_shape_combine_mask (gtk_widget_get_window (widget), mask, 0, 0);
- g_object_unref (mask);
- cairo_destroy (cr);
-}
-
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->expose_when_composited = gsd_media_keys_window_expose_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)
{
@@ -1018,29 +694,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,
@@ -1050,16 +707,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);
}
}
@@ -1067,15 +723,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/plugins/media-keys/gsd-media-keys-window.h b/plugins/media-keys/gsd-media-keys-window.h
index 0f8d23b8..7fbad7b6 100644
--- a/plugins/media-keys/gsd-media-keys-window.h
+++ b/plugins/media-keys/gsd-media-keys-window.h
@@ -26,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 ())
@@ -39,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 {