[totem] main: Update OSD from gnome-settings-daemon
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [totem] main: Update OSD from gnome-settings-daemon
- Date: Tue, 17 Apr 2012 14:49:44 +0000 (UTC)
commit aff4968963426265a9dd8e267f68e3d472150cc5
Author: Bastien Nocera <hadess hadess net>
Date: Tue Apr 17 15:35:29 2012 +0100
main: Update OSD from gnome-settings-daemon
src/Makefile.am | 3 +-
src/gsd-media-keys-window.c | 710 --------------------------
src/gsd-media-keys-window.h | 74 ---
src/gsd-osd-window-private.h | 67 +++
src/gsd-osd-window.c | 1125 ++++++++++++++++++++++++++++++------------
src/gsd-osd-window.h | 32 +-
src/totem-fullscreen.c | 8 +-
7 files changed, 885 insertions(+), 1134 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 318c2dd..fb99218 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,10 +42,9 @@ libtotem_player_la_SOURCES = \
totem-fullscreen.h \
gd-fullscreen-filter.c \
gd-fullscreen-filter.h \
- gsd-media-keys-window.c \
- gsd-media-keys-window.h \
gsd-osd-window.c \
gsd-osd-window.h \
+ gsd-osd-window-private.h\
totem-time-label.c \
totem-time-label.h
diff --git a/src/gsd-osd-window-private.h b/src/gsd-osd-window-private.h
new file mode 100644
index 0000000..de3b2af
--- /dev/null
+++ b/src/gsd-osd-window-private.h
@@ -0,0 +1,67 @@
+/* -*- 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_PRIVATE_H
+#define GSD_OSD_WINDOW_PRIVATE_H
+
+#include <glib-object.h>
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ int size;
+ GtkStyleContext *style;
+ GtkTextDirection direction;
+
+ GsdOsdWindowAction action;
+ GtkIconTheme *theme;
+ const char *icon_name;
+
+ gboolean show_level;
+ int volume_level;
+ guint volume_muted : 1;
+} GsdOsdDrawContext;
+
+void gsd_osd_window_draw (GsdOsdDrawContext *ctx, cairo_t *cr);
+
+G_END_DECLS
+
+#endif
diff --git a/src/gsd-osd-window.c b/src/gsd-osd-window.c
index ab8e652..1206c2e 100644
--- a/src/gsd-osd-window.c
+++ b/src/gsd-osd-window.c
@@ -38,159 +38,39 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "gsd-osd-window.h"
+#include "gsd-osd-window-private.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 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 ICON_SCALE 0.50 /* size of the icon compared to the whole OSD */
+#define BG_ALPHA 0.75 /* background transparency */
#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;
+ gint screen_width;
+ gint screen_height;
+ gint primary_monitor;
+ guint monitors_changed_id;
+ guint monitor_changed : 1;
- 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);
-}
+ GsdOsdWindowAction action;
+ char *icon_name;
+ gboolean show_level;
-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;
+ int volume_level;
+ guint volume_muted : 1;
+};
- cairo_move_to (cr, x + radius, y);
+G_DEFINE_TYPE (GsdOsdWindow, gsd_osd_window, GTK_TYPE_WINDOW)
- 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 void gsd_osd_window_update_and_hide (GsdOsdWindow *window);
static void
rgb_to_hls (gdouble *r,
@@ -342,7 +222,7 @@ hls_to_rgb (gdouble *h,
}
}
-void
+static void
gsd_osd_window_color_shade (GdkRGBA *a,
gdouble k)
{
@@ -375,8 +255,7 @@ gsd_osd_window_color_shade (GdkRGBA *a,
a->blue = blue;
}
-
-void
+static void
gsd_osd_window_color_reverse (GdkRGBA *a)
{
gdouble red;
@@ -405,31 +284,712 @@ gsd_osd_window_color_reverse (GdkRGBA *a)
a->blue = blue;
}
-/* 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 *orig_cr)
-{
- GsdOsdWindow *window;
- cairo_t *cr;
- cairo_surface_t *surface;
- int width;
- int height;
- GtkStyleContext *context;
+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);
+}
+
+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)
+{
+ window->priv->hide_timeout_id = 0;
+ window->priv->fade_timeout_id = g_timeout_add (FADE_TIMEOUT,
+ (GSourceFunc) fade_timeout,
+ 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)
+{
+ window->priv->hide_timeout_id = g_timeout_add (DIALOG_FADE_TIMEOUT,
+ (GSourceFunc) hide_timeout,
+ window);
+}
+
+static const char *
+get_image_name_for_volume (gboolean muted,
+ int volume)
+{
+ static const char *icon_names[] = {
+ "audio-volume-muted-symbolic",
+ "audio-volume-low-symbolic",
+ "audio-volume-medium-symbolic",
+ "audio-volume-high-symbolic",
+ NULL
+ };
+ int n;
+
+ if (muted) {
+ n = 0;
+ } else {
+ /* select image */
+ n = 3 * volume / 100 + 1;
+ if (n < 1) {
+ n = 1;
+ } else if (n > 3) {
+ n = 3;
+ }
+ }
+
+ return icon_names[n];
+}
+
+static void
+action_changed (GsdOsdWindow *window)
+{
+ gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
+}
+
+static void
+volume_level_changed (GsdOsdWindow *window)
+{
+ gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
+}
+
+static void
+volume_muted_changed (GsdOsdWindow *window)
+{
+ gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
+}
+
+void
+gsd_osd_window_set_action (GsdOsdWindow *window,
+ GsdOsdWindowAction action)
+{
+ g_return_if_fail (GSD_IS_OSD_WINDOW (window));
+ g_return_if_fail (action == GSD_OSD_WINDOW_ACTION_VOLUME);
+
+ if (window->priv->action != action) {
+ window->priv->action = action;
+ action_changed (window);
+ } else {
+ gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
+ }
+}
+
+void
+gsd_osd_window_set_action_custom (GsdOsdWindow *window,
+ const char *icon_name,
+ gboolean show_level)
+{
+ g_return_if_fail (GSD_IS_OSD_WINDOW (window));
+ g_return_if_fail (icon_name != NULL);
+
+ if (window->priv->action != GSD_OSD_WINDOW_ACTION_CUSTOM ||
+ g_strcmp0 (window->priv->icon_name, icon_name) != 0 ||
+ window->priv->show_level != show_level) {
+ window->priv->action = GSD_OSD_WINDOW_ACTION_CUSTOM;
+ g_free (window->priv->icon_name);
+ window->priv->icon_name = g_strdup (icon_name);
+ window->priv->show_level = show_level;
+ action_changed (window);
+ } else {
+ gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
+ }
+}
+
+void
+gsd_osd_window_set_volume_muted (GsdOsdWindow *window,
+ gboolean muted)
+{
+ g_return_if_fail (GSD_IS_OSD_WINDOW (window));
+
+ if (window->priv->volume_muted != muted) {
+ window->priv->volume_muted = muted;
+ volume_muted_changed (window);
+ }
+}
+
+void
+gsd_osd_window_set_volume_level (GsdOsdWindow *window,
+ int level)
+{
+ g_return_if_fail (GSD_IS_OSD_WINDOW (window));
+
+ if (window->priv->volume_level != level) {
+ window->priv->volume_level = level;
+ volume_level_changed (window);
+ }
+}
+
+static GdkPixbuf *
+load_pixbuf (GsdOsdDrawContext *ctx,
+ const char *name,
+ int icon_size)
+{
+ GtkIconInfo *info;
+ GdkPixbuf *pixbuf;
+ GdkRGBA color;
+
+ gtk_style_context_get_background_color (ctx->style, GTK_STATE_NORMAL, &color);
+ info = gtk_icon_theme_lookup_icon (ctx->theme,
+ name,
+ icon_size,
+ GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_GENERIC_FALLBACK);
+
+ if (info == NULL) {
+ g_warning ("Failed to load '%s'", name);
+ return NULL;
+ }
+
+ pixbuf = gtk_icon_info_load_symbolic (info,
+ &color,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ gtk_icon_info_free (info);
+
+ return pixbuf;
+}
+
+static void
+draw_eject (cairo_t *cr,
+ double _x0,
+ double _y0,
+ double width,
+ double height)
+{
+ int box_height;
+ int tri_height;
+ int separation;
+
+ box_height = height * 0.2;
+ separation = box_height / 3;
+ tri_height = height - box_height - separation;
+
+ cairo_rectangle (cr, _x0, _y0 + height - box_height, width, box_height);
+
+ cairo_move_to (cr, _x0, _y0 + tri_height);
+ cairo_rel_line_to (cr, width, 0);
+ 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, GSD_OSD_WINDOW_FG_ALPHA);
+ cairo_fill_preserve (cr);
+
+ 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);
+}
+
+static void
+draw_waves (cairo_t *cr,
+ double cx,
+ double cy,
+ double max_radius,
+ int volume_level)
+{
+ const int n_waves = 3;
+ int last_wave;
+ int i;
+
+ last_wave = n_waves * volume_level / 100;
+
+ for (i = 0; i < n_waves; i++) {
+ double angle1;
+ double angle2;
+ double radius;
+ double alpha;
+
+ angle1 = -M_PI / 4;
+ angle2 = M_PI / 4;
+
+ if (i < last_wave)
+ alpha = 1.0;
+ else if (i > last_wave)
+ alpha = 0.1;
+ else alpha = 0.1 + 0.9 * (n_waves * volume_level % 100) / 100.0;
+
+ radius = (i + 1) * (max_radius / n_waves);
+ cairo_arc (cr, cx, cy, radius, angle1, angle2);
+ cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, 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, alpha);
+ cairo_set_line_width (cr, 10);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_stroke (cr);
+ }
+}
+
+static void
+draw_cross (cairo_t *cr,
+ double cx,
+ double cy,
+ double size)
+{
+ cairo_move_to (cr, cx, cy - size/2.0);
+ cairo_rel_line_to (cr, size, size);
+
+ 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, 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, GSD_OSD_WINDOW_FG_ALPHA);
+ cairo_set_line_width (cr, 10);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_stroke (cr);
+}
+
+static void
+draw_speaker (cairo_t *cr,
+ double cx,
+ double cy,
+ double width,
+ double height)
+{
+ double box_width;
+ double box_height;
+ double _x0;
+ double _y0;
+
+ box_width = width / 3;
+ box_height = height / 3;
+
+ _x0 = cx - (width / 2) + box_width;
+ _y0 = cy - box_height / 2;
+
+ cairo_move_to (cr, _x0, _y0);
+ cairo_rel_line_to (cr, - box_width, 0);
+ cairo_rel_line_to (cr, 0, box_height);
+ cairo_rel_line_to (cr, box_width, 0);
+
+ cairo_line_to (cr, cx + box_width, cy + height / 2);
+ cairo_rel_line_to (cr, 0, -height);
+ cairo_line_to (cr, _x0, _y0);
+ cairo_close_path (cr);
+
+ 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, GSD_OSD_WINDOW_FG_ALPHA / 2);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+}
+
+static gboolean
+render_speaker (GsdOsdDrawContext *ctx,
+ cairo_t *cr,
+ double _x0,
+ double _y0,
+ double width,
+ double height)
+{
+ GdkPixbuf *pixbuf;
+ const char *icon_name;
+ int icon_size;
+
+ icon_name = get_image_name_for_volume (ctx->volume_muted,
+ ctx->volume_level);
+
+ icon_size = (int) width;
+
+ pixbuf = load_pixbuf (ctx, icon_name, icon_size);
+
+ if (pixbuf == NULL) {
+ return FALSE;
+ }
+
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0);
+ cairo_paint_with_alpha (cr, GSD_OSD_WINDOW_FG_ALPHA);
+
+ g_object_unref (pixbuf);
+
+ return TRUE;
+}
+
+#define LIGHTNESS_MULT 1.3
+#define DARKNESS_MULT 0.7
+
+static void
+draw_volume_boxes (GsdOsdDrawContext *ctx,
+ cairo_t *cr,
+ double percentage,
+ double _x0,
+ double _y0,
+ double width,
+ double height)
+{
+ gdouble x1;
+ GdkRGBA acolor;
+
+ height = round (height) - 1;
+ width = round (width) - 1;
+ x1 = round ((width - 1) * percentage);
+
+ /* bar background */
+ gtk_style_context_get_background_color (ctx->style, GTK_STATE_NORMAL, &acolor);
+ gsd_osd_window_color_shade (&acolor, DARKNESS_MULT);
+ gsd_osd_window_color_reverse (&acolor);
+ acolor.alpha = GSD_OSD_WINDOW_FG_ALPHA / 2;
+ gsd_osd_window_draw_rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, width, height);
+ gdk_cairo_set_source_rgba (cr, &acolor);
+ cairo_fill (cr);
+
+ /* bar progress */
+ if (percentage < 0.01)
+ return;
+ gtk_style_context_get_background_color (ctx->style, GTK_STATE_NORMAL, &acolor);
+ acolor.alpha = GSD_OSD_WINDOW_FG_ALPHA;
+ gsd_osd_window_draw_rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, x1, height);
+ gdk_cairo_set_source_rgba (cr, &acolor);
+ cairo_fill (cr);
+}
+
+static void
+draw_action_volume (GsdOsdDrawContext *ctx,
+ cairo_t *cr)
+{
+ int window_width;
+ int window_height;
+ double icon_box_width;
+ double icon_box_height;
+ double icon_box_x0;
+ double icon_box_y0;
+ double volume_box_x0;
+ double volume_box_y0;
+ double volume_box_width;
+ double volume_box_height;
+ gboolean res;
+
+ window_width = window_height = ctx->size;
+
+ icon_box_width = round (window_width * ICON_SCALE);
+ icon_box_height = round (window_height * ICON_SCALE);
+ volume_box_width = icon_box_width;
+ volume_box_height = round (window_height * 0.05);
+
+ icon_box_x0 = round ((window_width - icon_box_width) / 2);
+ icon_box_y0 = round ((window_height - icon_box_height - volume_box_height) / 2 - volume_box_height);
+ volume_box_x0 = round (icon_box_x0);
+ volume_box_y0 = round (icon_box_height + icon_box_y0) + volume_box_height;
+
+#if 0
+ g_message ("icon box: w=%f h=%f _x0=%f _y0=%f",
+ icon_box_width,
+ icon_box_height,
+ icon_box_x0,
+ icon_box_y0);
+ g_message ("volume box: w=%f h=%f _x0=%f _y0=%f",
+ volume_box_width,
+ volume_box_height,
+ volume_box_x0,
+ volume_box_y0);
+#endif
+
+ res = render_speaker (ctx,
+ cr,
+ icon_box_x0, icon_box_y0,
+ icon_box_width, icon_box_height);
+ if (! res) {
+ double speaker_width;
+ double speaker_height;
+ double speaker_cx;
+ double speaker_cy;
+
+ speaker_width = icon_box_width * 0.5;
+ speaker_height = icon_box_height * 0.75;
+ speaker_cx = icon_box_x0 + speaker_width / 2;
+ speaker_cy = icon_box_y0 + speaker_height / 2;
+
+#if 0
+ g_message ("speaker box: w=%f h=%f cx=%f cy=%f",
+ speaker_width,
+ speaker_height,
+ speaker_cx,
+ speaker_cy);
+#endif
+
+ /* draw speaker symbol */
+ draw_speaker (cr, speaker_cx, speaker_cy, speaker_width, speaker_height);
+
+ if (!ctx->volume_muted) {
+ /* draw sound waves */
+ double wave_x0;
+ double wave_y0;
+ double wave_radius;
+
+ wave_x0 = window_width / 2;
+ wave_y0 = speaker_cy;
+ wave_radius = icon_box_width / 2;
+
+ draw_waves (cr, wave_x0, wave_y0, wave_radius, ctx->volume_level);
+ } else {
+ /* draw 'mute' cross */
+ double cross_x0;
+ double cross_y0;
+ double cross_size;
+
+ cross_size = speaker_width * 3 / 4;
+ cross_x0 = icon_box_x0 + icon_box_width - cross_size;
+ cross_y0 = speaker_cy;
+
+ draw_cross (cr, cross_x0, cross_y0, cross_size);
+ }
+ }
+
+ /* draw volume meter */
+ draw_volume_boxes (ctx,
+ cr,
+ (double) ctx->volume_level / 100.0,
+ volume_box_x0,
+ volume_box_y0,
+ volume_box_width,
+ volume_box_height);
+}
+
+static gboolean
+render_custom (GsdOsdDrawContext *ctx,
+ cairo_t *cr,
+ double _x0,
+ double _y0,
+ double width,
+ double height)
+{
+ GdkPixbuf *pixbuf;
+ int icon_size;
+
+ icon_size = (int)width;
+
+ pixbuf = load_pixbuf (ctx, ctx->icon_name, icon_size);
+
+ if (pixbuf == NULL) {
+ char *name;
+ if (ctx->direction == GTK_TEXT_DIR_RTL)
+ name = g_strdup_printf ("%s-rtl", ctx->icon_name);
+ else
+ name = g_strdup_printf ("%s-ltr", ctx->icon_name);
+ pixbuf = load_pixbuf (ctx, name, icon_size);
+ g_free (name);
+ if (pixbuf == NULL)
+ return FALSE;
+ }
+
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0);
+ cairo_paint_with_alpha (cr, GSD_OSD_WINDOW_FG_ALPHA);
+
+ g_object_unref (pixbuf);
+
+ return TRUE;
+}
+
+static void
+draw_action_custom (GsdOsdDrawContext *ctx,
+ cairo_t *cr)
+{
+ int window_width;
+ int window_height;
+ double icon_box_width;
+ double icon_box_height;
+ double icon_box_x0;
+ double icon_box_y0;
+ double bright_box_x0;
+ double bright_box_y0;
+ double bright_box_width;
+ double bright_box_height;
+ gboolean res;
+
+ window_width = window_height = ctx->size;
+
+ icon_box_width = round (window_width * ICON_SCALE);
+ icon_box_height = round (window_height * ICON_SCALE);
+ bright_box_width = round (icon_box_width);
+ bright_box_height = round (window_height * 0.05);
+
+ icon_box_x0 = round ((window_width - icon_box_width) / 2);
+ icon_box_y0 = round ((window_height - icon_box_height - bright_box_height) / 2 - bright_box_height);
+ bright_box_x0 = round (icon_box_x0);
+ bright_box_y0 = round (icon_box_height + icon_box_y0) + bright_box_height;
+
+#if 0
+ g_message ("icon box: w=%f h=%f _x0=%f _y0=%f",
+ icon_box_width,
+ icon_box_height,
+ icon_box_x0,
+ icon_box_y0);
+ g_message ("brightness box: w=%f h=%f _x0=%f _y0=%f",
+ bright_box_width,
+ bright_box_height,
+ bright_box_x0,
+ bright_box_y0);
+#endif
+
+ res = render_custom (ctx,
+ cr,
+ icon_box_x0, icon_box_y0,
+ icon_box_width, icon_box_height);
+ if (!res && g_str_has_prefix (ctx->icon_name, "media-eject")) {
+ /* draw eject symbol */
+ draw_eject (cr,
+ icon_box_x0, icon_box_y0,
+ icon_box_width, icon_box_height);
+ }
+
+ if (ctx->show_level != FALSE) {
+ /* draw volume meter */
+ draw_volume_boxes (ctx,
+ cr,
+ (double) ctx->volume_level / 100.0,
+ bright_box_x0,
+ bright_box_y0,
+ bright_box_width,
+ bright_box_height);
+ }
+}
+
+void
+gsd_osd_window_draw (GsdOsdDrawContext *ctx,
+ cairo_t *cr)
+{
+ gdouble corner_radius;
GdkRGBA acolor;
+ /* draw a box */
+ corner_radius = ctx->size / 10;
+ gsd_osd_window_draw_rounded_rectangle (cr, 1.0, 0.0, 0.0, corner_radius, ctx->size - 1, ctx->size - 1);
+ gtk_style_context_get_background_color (ctx->style, GTK_STATE_NORMAL, &acolor);
+ gsd_osd_window_color_reverse (&acolor);
+ acolor.alpha = BG_ALPHA;
+ gdk_cairo_set_source_rgba (cr, &acolor);
+ cairo_fill (cr);
+
+ switch (ctx->action) {
+ case GSD_OSD_WINDOW_ACTION_VOLUME:
+ draw_action_volume (ctx, cr);
+ break;
+ case GSD_OSD_WINDOW_ACTION_CUSTOM:
+ draw_action_custom (ctx, cr);
+ break;
+ default:
+ break;
+ }
+}
+
+static gboolean
+gsd_osd_window_obj_draw (GtkWidget *widget,
+ cairo_t *orig_cr)
+{
+ GsdOsdWindow *window;
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ GtkStyleContext *context;
+ GsdOsdDrawContext ctx;
+ int width, height, size;
+
window = GSD_OSD_WINDOW (widget);
+ gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
+ size = MIN (width, height);
context = gtk_widget_get_style_context (widget);
cairo_set_operator (orig_cr, CAIRO_OPERATOR_SOURCE);
- gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
surface = cairo_surface_create_similar (cairo_get_target (orig_cr),
CAIRO_CONTENT_COLOR_ALPHA,
- width,
- height);
+ size,
+ size);
if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
goto done;
@@ -443,28 +1003,25 @@ draw_when_composited (GtkWidget *widget, cairo_t *orig_cr)
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);
- gtk_style_context_get_background_color (context, GTK_STATE_NORMAL, &acolor);
- gsd_osd_window_color_reverse (&acolor);
- acolor.alpha = BG_ALPHA;
- gdk_cairo_set_source_rgba (cr, &acolor);
- cairo_fill_preserve (cr);
-
- /* FIXME use &style->text_aa[GTK_STATE_NORMAL] instead? */
- gtk_style_context_get_color (context, GTK_STATE_NORMAL, &acolor);
- gsd_osd_window_color_reverse (&acolor);
- acolor.alpha = BG_ALPHA / 2;
- gdk_cairo_set_source_rgba (cr, &acolor);
- cairo_set_line_width (cr, 1);
- cairo_stroke (cr);
-
- g_signal_emit (window, signals[DRAW_WHEN_COMPOSITED], 0, cr);
+ ctx.size = size;
+ ctx.style = context;
+ ctx.volume_level = window->priv->volume_level;
+ ctx.volume_muted = window->priv->volume_muted;
+ ctx.icon_name = window->priv->icon_name;
+ ctx.direction = gtk_widget_get_direction (GTK_WIDGET (window));
+ ctx.show_level = window->priv->show_level;
+ ctx.action = window->priv->action;
+ if (window != NULL && gtk_widget_has_screen (GTK_WIDGET (window))) {
+ ctx.theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
+ } else {
+ ctx.theme = gtk_icon_theme_get_default ();
+ }
+ gsd_osd_window_draw (&ctx, cr);
cairo_destroy (cr);
/* Make sure we have a transparent background */
- cairo_rectangle (orig_cr, 0, 0, width, height);
+ cairo_rectangle (orig_cr, 0, 0, size, size);
cairo_set_source_rgba (orig_cr, 0.0, 0.0, 0.0, 0.0);
cairo_fill (orig_cr);
@@ -475,51 +1032,6 @@ draw_when_composited (GtkWidget *widget, cairo_t *orig_cr)
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)
-{
- GtkStyleContext *context;
- int width;
- int height;
-
- width = gtk_widget_get_allocated_width (widget);
- height = gtk_widget_get_allocated_width (widget);
- context = gtk_widget_get_style_context (widget);
-
- gtk_style_context_set_state (context, GTK_STATE_FLAG_ACTIVE);
- gtk_render_frame (context,
- cr,
- 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;
}
@@ -576,62 +1088,6 @@ gsd_osd_window_real_realize (GtkWidget *widget)
cairo_region_destroy (region);
}
-static void
-gsd_osd_window_style_updated (GtkWidget *widget)
-{
- GtkStyleContext *context;
- GtkBorder padding;
-
- GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->style_updated (widget);
-
- /* 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.
- */
-
- context = gtk_widget_get_style_context (widget);
- gtk_style_context_get_padding (context, GTK_STATE_NORMAL, &padding);
- gtk_container_set_border_width (GTK_CONTAINER (widget), 12 + MAX (padding.left, padding.top));
-}
-
-static void
-gsd_osd_window_get_preferred_width (GtkWidget *widget,
- gint *minimum,
- gint *natural)
-{
- GtkStyleContext *context;
- GtkBorder padding;
-
- GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->get_preferred_width (widget, minimum, natural);
-
- /* See the comment in gsd_osd_window_style_updated() for why we add the padding here */
-
- context = gtk_widget_get_style_context (widget);
- gtk_style_context_get_padding (context, GTK_STATE_NORMAL, &padding);
-
- *minimum += padding.left;
- *natural += padding.left;
-}
-
-static void
-gsd_osd_window_get_preferred_height (GtkWidget *widget,
- gint *minimum,
- gint *natural)
-{
- GtkStyleContext *context;
- GtkBorder padding;
-
- GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->get_preferred_height (widget, minimum, natural);
-
- /* See the comment in gsd_osd_window_style_updated() for why we add the padding here */
-
- context = gtk_widget_get_style_context (widget);
- gtk_style_context_get_padding (context, GTK_STATE_NORMAL, &padding);
-
- *minimum += padding.top;
- *natural += padding.top;
-}
-
static GObject *
gsd_osd_window_constructor (GType type,
guint n_construct_properties,
@@ -653,89 +1109,106 @@ gsd_osd_window_constructor (GType type,
}
static void
+gsd_osd_window_finalize (GObject *object)
+{
+ GsdOsdWindow *window;
+
+ window = GSD_OSD_WINDOW (object);
+ if (window->priv->icon_name) {
+ g_free (window->priv->icon_name);
+ window->priv->icon_name = NULL;
+ }
+
+ if (window->priv->monitors_changed_id > 0) {
+ GdkScreen *screen;
+ screen = gtk_widget_get_screen (GTK_WIDGET (object));
+ g_signal_handler_disconnect (G_OBJECT (screen), window->priv->monitors_changed_id);
+ window->priv->monitors_changed_id = 0;
+ }
+
+ G_OBJECT_CLASS (gsd_osd_window_parent_class)->finalize (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;
+ gobject_class->finalize = gsd_osd_window_finalize;
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_updated = gsd_osd_window_style_updated;
- widget_class->get_preferred_width = gsd_osd_window_get_preferred_width;
- widget_class->get_preferred_height = gsd_osd_window_get_preferred_height;
- 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);
+ widget_class->draw = gsd_osd_window_obj_draw;
g_type_class_add_private (klass, sizeof (GsdOsdWindowPrivate));
}
-/*
- * gsd_osd_window_is_composited:
+/**
+ * gsd_osd_window_is_valid:
* @window: a #GsdOsdWindow
*
- * Return value: whether the window was created on a composited screen.
+ * Return value: TRUE if the @window's idea of the screen geometry is the
+ * same as the current screen's.
*/
gboolean
-gsd_osd_window_is_composited (GsdOsdWindow *window)
+gsd_osd_window_is_valid (GsdOsdWindow *window)
{
- return window->priv->is_composited;
+ return window->priv->monitor_changed;
}
-/*
- * 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)
+static void
+monitors_changed_cb (GdkScreen *screen,
+ GsdOsdWindow *window)
{
- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window));
- return gdk_screen_is_composited (screen) == window->priv->is_composited;
+ gint primary_monitor;
+ GdkRectangle mon_rect;
+
+ primary_monitor = gdk_screen_get_primary_monitor (screen);
+ if (primary_monitor != window->priv->primary_monitor) {
+ window->priv->monitor_changed = TRUE;
+ return;
+ }
+
+ gdk_screen_get_monitor_geometry (screen, primary_monitor, &mon_rect);
+
+ if (window->priv->screen_width != mon_rect.width ||
+ window->priv->screen_height != mon_rect.height)
+ window->priv->monitor_changed = TRUE;
}
static void
gsd_osd_window_init (GsdOsdWindow *window)
{
GdkScreen *screen;
+ gdouble scalew, scaleh, scale;
+ GdkRectangle monitor;
+ int size;
window->priv = GSD_OSD_WINDOW_GET_PRIVATE (window);
screen = gtk_widget_get_screen (GTK_WIDGET (window));
+ window->priv->monitors_changed_id = g_signal_connect (G_OBJECT (screen), "monitors-changed",
+ G_CALLBACK (monitors_changed_cb), window);
- window->priv->is_composited = gdk_screen_is_composited (screen);
-
- if (window->priv->is_composited) {
- gdouble scalew, scaleh, scale;
- gint size;
+ window->priv->primary_monitor = gdk_screen_get_primary_monitor (screen);
+ gdk_screen_get_monitor_geometry (screen, window->priv->primary_monitor, &monitor);
+ window->priv->screen_width = monitor.width;
+ window->priv->screen_height = monitor.height;
- gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
- gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
+ 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);
+ /* assume 130x130 on a 640x480 display and scale from there */
+ scalew = monitor.width / 640.0;
+ scaleh = monitor.height / 480.0;
+ scale = MIN (scalew, scaleh);
+ size = 130 * MAX (1, scale);
+ gtk_window_set_default_size (GTK_WINDOW (window), size, size);
- 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);
- }
+ window->priv->fade_out_alpha = 1.0;
}
GtkWidget *
@@ -750,13 +1223,11 @@ gsd_osd_window_new (void)
*
* Queues the @window for immediate drawing, and queues a timer to hide the window.
*/
-void
+static 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));
- }
+ gtk_widget_queue_draw (GTK_WIDGET (window));
}
diff --git a/src/gsd-osd-window.h b/src/gsd-osd-window.h
index 18ceb24..2513472 100644
--- a/src/gsd-osd-window.h
+++ b/src/gsd-osd-window.h
@@ -67,28 +67,26 @@ struct GsdOsdWindow {
struct GsdOsdWindowClass {
GtkWindowClass parent_class;
-
- void (* draw_when_composited) (GsdOsdWindow *window, cairo_t *cr);
};
+typedef enum {
+ GSD_OSD_WINDOW_ACTION_VOLUME,
+ GSD_OSD_WINDOW_ACTION_CUSTOM
+} GsdOsdWindowAction;
+
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 (GdkRGBA *a);
-void gsd_osd_window_color_shade (GdkRGBA *a,
- gdouble k);
+gboolean gsd_osd_window_is_valid (GsdOsdWindow *window);
+void gsd_osd_window_set_action (GsdOsdWindow *window,
+ GsdOsdWindowAction action);
+void gsd_osd_window_set_action_custom (GsdOsdWindow *window,
+ const char *icon_name,
+ gboolean show_level);
+void gsd_osd_window_set_volume_muted (GsdOsdWindow *window,
+ gboolean muted);
+void gsd_osd_window_set_volume_level (GsdOsdWindow *window,
+ int level);
G_END_DECLS
diff --git a/src/totem-fullscreen.c b/src/totem-fullscreen.c
index 3ef5040..b7a4ce4 100644
--- a/src/totem-fullscreen.c
+++ b/src/totem-fullscreen.c
@@ -37,7 +37,7 @@
#include "totem-time-label.h"
#include "bacon-video-widget.h"
#include "gd-fullscreen-filter.h"
-#include "gsd-media-keys-window.h"
+#include "gsd-osd-window.h"
#define FULLSCREEN_POPUP_TIMEOUT 5
#define FULLSCREEN_MOTION_TIME 200 /* in milliseconds */
@@ -376,8 +376,8 @@ totem_fullscreen_show_popups_or_osd (TotemFullscreen *fs,
else
gtk_window_move (GTK_WINDOW (fs->priv->osd), rect.x + 8, rect.y + 8);
- gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (fs->priv->osd),
- icon_name, FALSE);
+ gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (fs->priv->osd),
+ icon_name, FALSE);
gtk_widget_show (fs->priv->osd);
}
@@ -526,7 +526,7 @@ totem_fullscreen_init (TotemFullscreen *self)
G_CALLBACK (totem_fullscreen_exit_popup_draw_cb), self);
self->priv->control_popup = GTK_WIDGET (gtk_builder_get_object (self->priv->xml,
"totem_controls_window"));
- self->priv->osd = gsd_media_keys_window_new ();
+ self->priv->osd = gsd_osd_window_new ();
/* Motion notify */
gtk_widget_add_events (self->priv->exit_popup, GDK_POINTER_MOTION_MASK);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]